逐步回归
2019-11-26 本文已影响0人
STACK_ZHAO
Stepwise Regression
逐步回归算法可以用来筛选以及拟合特征,来实现特征的降维,主要是再Y对应多个x_i的情况(即一个因变量对应多个自变量的情况,也可称为多元回归)
- 其实可以理解为:
在线性条件下,哪些变量组合能够解释更多的因变量变异,则将其保留。
$ Y=W_1 X_1+W_2X_2+......W_iX_i
逐步回归算法的主要方法
具体操作方法有三种:
- Forward selection: 首先模型中只有一个单独解释因变量变异最大的自变量,之后尝试将加入另一自变量,看加入后整个模型所能解释的因变量变异是否显著增加(这里需要进行检疫,可以用 F-test, t-test 等等);这一过程反复迭代,直到没有自变量再符合加入模型的条件。
- Backward elimination: 与 Forward selection 相反,此时,所有变量均放入模型,之后尝试将其中一个自变量从模型中剔除,看整个模型解释因变量的变异是否有显著变化,之后将使解释量减少最少的变量剔除;此过程不断迭代,直到没有自变量符合剔除的条件。
- Bidirectional elimination: 这种方法相当于将前两种结合起来。可以想象,如果采用第一种方法,每加入一个自变量,可能会使已存在于模型中的变量单独对因变量的解释度减小,当其的作用很小(不显著)时,则可将其从模型中剔除。而第三种方法就做了这么一件事,不是一味的增加变量,而是增加一个后,对整个模型中的所有变量进行检验,剔除作用不显著的变量。最终尽可能得到一个最优的变量组合。
主要操作方法如上面所示,那么如何去评价那个变量是真的有价值的呢,这个时候再公式上可以去看一个指标,那就是观察R方的变化,那么到底什么是R方呢,一句话描述下它的功能就是
来表示回归直线对观测值的拟合程度,其主要的公式如下
R^2=SSR/SST=1-SSE/SST
(其中SSR是组间变异,SST是总变异)
进一步的详细描述下如下:
R^2=1-\frac{\sum{(y-\hat{y})^2}}{\sum{(y-\bar{y})^2}}=cov(y,y_i)^2
看这个式子式用1减去y对回归方程的方差(未解释离差)与y的总方差的比值,y减去 \hat{y}也就是残差,是拟合方程中不能解释的部分,用1减去不能解释的部分,那么剩下的就是解释的部分,也就是说自变量解释了因变量变动的百分比的多少,那么r方的值肯定是越大越好,意味着该模型把y的变动解释得好,R方的范围显然是0到1,在预测实践中,人们往往采纳R方最高的模型,其中cov(y,y_i)是协方差函数.同时跟R_square相似的指标,相关系数R
R=\frac{\sum_{i=1}^{n}(x-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(x-\bar{x})^2 \sum_{i=1}^{n}(y_i-\bar{y})^2}}
还有一个定义就是调整R方(R_adjusted):当给模型增加自变量时,复决定系数也随之逐步增大,然而复决定系数的增大代价是残差自由度的减少,因为残差自由度等于样本个数与字变量个数之差。自由度小意味着估计和预测可靠性低
R^{2}_{adjusted}=1-\frac{(1-R^2)(n-1)}{n-p-1}
其中,n为样本容量,p为自变量的个数。在实际问题的回归建模中,自由度调整负决定系数R方越大,所对应的回归方程越好。则所有回归子集中调整R方最大者对应的回归方程就是最优方程。
Python Achievement
下面是基于statsnidels中的回归函数实现的代码
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
data_columns=data.columns.tolist()
#此部分剔除掉不需要的变量
need_remove=['value']
for i in need_remove:
data_columns.remove(i)
new_scores={}
best_variable=[]
#先一开始设定一个最初的变量,以此来迭代循环
best_property='OverallQual'
best_property_1='a'
new_data=pd.DataFrame()
best_score=0.0
while data_columns:
if best_property_1 != best_property:
data_columns.remove(best_property)
best_variable.append(best_property)
best_property_1=best_property
new_data=pd.concat([new_data,x_train[best_property]],axis=1)
for c in data_columns:
new_data_1=pd.concat([new_data,x_train[c]],axis=1)
number_property=len(new_data_1.columns.tolist())
a=np.array(new_data_1).reshape(-1,number_property)
b=np.array(y_train).reshape(-1,1)
regr=smf.OLS(b,a).fit()
scores=regr.rsquared_adj
if scores>best_score:
best_score=scores
best_property=c
print(best_variable)
count=len(best_variable)
else:
print('此时得分最高的为 %s,且变量只有%s个为%s' % (best_score,count,best_variable))
print(best_variable)
break
R code
R中的实现相对比较简单,主要是step函数,主要是先设置拟合式子,然后用函数进行逐步回归,最终会返回各个变量的贡献比以及系数
lmo3.1<-lm(y~1,data=data3.1)
lm3.1.for<-step(lmo3.1,scope=list(upper=~x1+x2+x3+x4+x5+x6+x7+x8+x9,lower=~1),direction="forward")
summary(lm3.1.for)//direction参数来设置是前进法还是后退法,summary函数来返回各个系数的值