将预测残差和rsquared附加到pandas数据帧 - 按组

时间:2017-12-09 12:23:29

标签: python pandas regression linear-regression

这样的问题已经存在,但我想要修改,并尝试了一些没有太多运气的方法。

我有数据,并希望按群组添加回归的R平方作为pandas数据框中的单独列。这里需要注意的是,我只想对每组中没有极端残差值的值进行回归(即,在1个标准偏差内或-1和1个z分数之间)。

以下是 SAMPLE 数据框:

df = pd.DataFrame({'gp': [1,1,1,1,1,2,2,2,2,2],
               'x1': [3.17, 4.76, 4.17, 8.70, 11.45, 3.17, 4.76, 4.17, 8.70, 1.45],
               'x2': [23, 26, 73, 72, 16, 26, 73, 72, 16, 25],
               'y': [880.37, 716.20, 974.79, 322.80, 1054.25, 980.37, 816.20, 1074.79, 522.80, 1254.25]},
               index=np.arange(10, 30, 2))

现在另一篇文章的回答是这样的,这对我来说可以获得小组中的残差。这是解决方案:

import pandas as pd
import numpy as np
import statsmodels.formula.api as sm

regmodel = 'y ~ x1 + x2'

def groupreg(g):
    g['residual'] = sm.ols(formula=regmodel, data=g).fit().resid
    return g

df = df.groupby('gp').apply(groupreg)
print(df)

现在这很好,因为我有一个列残差,它给出了每组内线性回归的残差。

但是现在我想添加另一个列,这是R平方,我想在每个组中添加回归的R平方,仅用于残差在+内的点每组内1 / -1的zscore 。所以我们的目标是增加一个R平方,它正在消除回归中的极端异常值(这应该改善使用所有数据的正常R平方的R平方值)。任何帮助将不胜感激。

编辑**

仅仅添加一个正常的R平方函数就可以了:

def groupreg(g):
    g['residual'] = sm.ols(formula=regmodel, data=g).fit().resid
    g['rsquared'] = sm.ols(formula=regmodel, data=g).fit().rsquared
   return g

编辑2 **

这是我的代码:

import pandas as pd
import numpy as np
import statsmodels.formula.api as sm

df = pd.DataFrame({'gp': [1,1,1,1,1,2,2,2,2,2],
               'x1': [3.17, 4.76, 4.17, 8.70, 11.45, 3.17, 4.76, 4.17, 8.70, 1.45],
               'x2': [23, 26, 73, 72, 16, 26, 73, 72, 16, 25],
               'y': [880.37, 716.20, 974.79, 322.80, 1054.25, 980.37, 816.20, 1074.79, 522.80, 1254.25]},
               index=np.arange(10, 30, 2))

regmodel = 'y ~ x1 + x2'

def groupreg(g):
    g['residual'] = sm.ols(formula=regmodel, data=g).fit().resid

    return g

df = df.groupby('gp').apply(groupreg)
print(df)

df['z_score'] = df.groupby('gp')['residual'].apply(lambda x: (x - x.mean())/x.std())

输出:

    gp     x1  x2        y    residual   z_score
10   1   3.17  23   880.37  -43.579309 -0.173726
12   1   4.76  26   716.20 -174.532201 -0.695759
14   1   4.17  73   974.79  318.634921  1.270214
16   1   8.70  72   322.80 -287.710952 -1.146938
18   1  11.45  16  1054.25  187.187542  0.746209
20   2   3.17  26   980.37  -67.245089 -0.822329
22   2   4.76  73   816.20  -96.883281 -1.184770
24   2   4.17  72  1074.79  104.400010  1.276691
26   2   8.70  16   522.80   21.017543  0.257020
28   2   1.45  25  1254.25   38.710817  0.473388

所以这里我想要每组的另一列R平方,而不使用分数大于且分别小于1和-1的点(例如,不会使用指数14,16,22和24通过r平方计算分组。

1 个答案:

答案 0 :(得分:0)

首先,使用分配groupregresid列的rsquared的完整定义:

def groupreg(g):
    g['residual'] = sm.ols(formula=regmodel, data=g).fit().resid
    g['rsquared'] = sm.ols(formula=regmodel, data=g).fit().rsquared
   return g

然后,在当前代码的最后(创建z_score列之后),尝试以下操作以删除rsquared中<{1}}行的-1 < z_score < 1个条目:

df.loc[df['z_score'].abs() < 1, 'rsquared'] = np.NaN

输出:

    gp     x1  x2        y    residual  rsquared   z_score
10   1   3.17  23   880.37  -43.579309       NaN -0.173726
12   1   4.76  26   716.20 -174.532201       NaN -0.695759
14   1   4.17  73   974.79  318.634921  0.250573  1.270214
16   1   8.70  72   322.80 -287.710952  0.250573 -1.146938
18   1  11.45  16  1054.25  187.187542       NaN  0.746209
20   2   3.17  26   980.37  -67.245089       NaN -0.822329
22   2   4.76  73   816.20  -96.883281  0.912987 -1.184770
24   2   4.17  72  1074.79  104.400010  0.912987  1.276691
26   2   8.70  16   522.80   21.017543       NaN  0.257020
28   2   1.45  25  1254.25   38.710817       NaN  0.473388