接着上篇一元线性回归的结果,我们可以实现多元线性回归吗?
lm_s = ols('avg_exp ~ Income+Age+dist_home_val+dist_avg_income', data=exp).fit()
lm_s.summary()
可以看到的是,R 平方确实提升了,但是红框中的 t 检验得到的 p 值似乎太大(样本量100,显著度取10%),也就是说这些变量与 Y 的相关性不大,也就是我们接下来要解决的问题,变量的筛选。
多元线性回归在选择自变量进入模型的方式时,有以下几种技术:
- 向前法
- 向后法
- 逐步法
决策的指标可为偏回归平方和,AIC/BIC、R方等。
AIC=2k+n(log(RSS/n)), k—解释变量个数,RSS—残差的离差平方和
具体的步骤是:
- 先用每一个 X 与 Y 做相关性检验,留下两者有相关性
- 上一步检测的只是每一个单独的 X 与 Y 的关系,有可能多个 X 放一起的话,增量信息会变少,因此需要在筛选掉那些增量信息较少的变量 X。
关于各种方法的具体介绍:
- 向前回归法:首先第一个变量进入回归方程,并进行F检验和T检验,计算残差平方和,记为S1,如果通过检验,则该变量保留,引入第二个变量,重新构建一个新的估计方程,并进行F检验和T检验,同
时计算残差平方和,记为S2。从直观上看,增加一个新的变量后,回归平方和应该增大,残差平方和相应应该减少,即S2小于等于S1,即S1-S2的值是第二个变量的偏回归平方和,直观地说,如果该值
明显偏大,则说明第二个变量对因变量有显著影响,反之则没有显著影响。 - 向后回归法:同向前回归法正好相反,首先,所有的X变量一次性进入模型进行F检验和T检验,然后逐个删除不显著的变量,删除的原则是根据其偏回归平方和的大小决定去留。如果偏回归平方和很大则保留,反之则删除。
- 逐步回归法:综合向前和向后回归法的特点,变量一个个进入方程,在引入变量时需要利用偏回归平方和进行检验,当显著时才加入该变量,当方程加入了该变量后,又要对原有的老变量重新用偏回归平方和进行检验,一旦某变量变得不显著时要删除该变量,如此下去,直到老变量均不可删除,新变量也无法加入为止。
向前选择具体步骤:
后向消元:
逐步选择:
而在 python 中,没有实现好的方法,所以我们需要自己写一个函数实现向前回归法:
# ### 多元线性回归的变量筛选
'''forward select'''
def forward_select(data, response):
remaining = set(data.columns)
remaining.remove(response)
selected = []
current_score, best_new_score = float('inf'), float('inf')
while remaining:
aic_with_candidates=[]
for candidate in remaining:
formula = "{} ~ {}".format(
response,' + '.join(selected + [candidate]))
aic = ols(formula=formula, data=data).fit().aic
# 这里去的是 aic ,bic 也可以,越小越好
aic_with_candidates.append((aic, candidate))
aic_with_candidates.sort(reverse=True)
best_new_score, best_candidate=aic_with_candidates.pop()
if current_score > best_new_score:
remaining.remove(best_candidate)
selected.append(best_candidate)
current_score = best_new_score
print ('aic is {},continuing!'.format(current_score))
else:
print ('forward selection over!')
break
formula = "{} ~ {} ".format(response,' + '.join(selected))
print('final formula is {}'.format(formula))
model = ols(formula=formula, data=data).fit()
return(model)
data_for_select = exp[['avg_exp', 'Income', 'Age', 'dist_home_val',
'dist_avg_income']]
lm_m = forward_select(data=data_for_select, response='avg_exp')
print(lm_m.rsquared)
aic is 1007.6801413968115,continuing!
aic is 1005.4969816306302,continuing!
aic is 1005.2487355956046,continuing!
forward selection over!
final formula is avg_exp ~ dist_avg_income + Income + dist_home_val
0.5411512928411949
这里使用的评价依据是 AIC ,但是筛选之后结果如下
lm_s = ols('avg_exp ~ Income+dist_home_val+dist_avg_income', data=exp).fit()
lm_s.summary()
重新构建的模型,图中红框的结果仍然 p 值大于0.1,原因是向前回归法,是一种贪婪算法,只求 AIC
最小,但是经过这个过程之后,不符合要求的变量会大大减小。实际应用中,不会只靠一种方法就能够完全解决问题,需要多种方式结合。