feature extraction

这里主要是介绍几种特征提取的方法

Stepwise Regression

逐步回归算法可以用来筛选以及拟合特征,来实现特征的降维,主要是再Y对应多个x_i的情况(即一个因变量对应多个自变量的情况,也可称为多元回归)

  • 其实可以理解为:

    在线性条件下,哪些变量组合能够解释更多的因变量变异,则将其保留。

    1
    Y=W_1 X_1+W_2X_2+......W_iX_i

    逐步回归算法的主要方法


具体操作方法有三种:

  1. Forward selection: 首先模型中只有一个单独解释因变量变异最大的自变量,之后尝试将加入另一自变量,看加入后整个模型所能解释的因变量变异是否显著增加(这里需要进行检疫,可以用 F-test, t-test 等等);这一过程反复迭代,直到没有自变量再符合加入模型的条件。
  2. Backward elimination: 与 Forward selection 相反,此时,所有变量均放入模型,之后尝试将其中一个自变量从模型中剔除,看整个模型解释因变量的变异是否有显著变化,之后将使解释量减少最少的变量剔除;此过程不断迭代,直到没有自变量符合剔除的条件。
  3. Bidirectional elimination: 这种方法相当于将前两种结合起来。可以想象,如果采用第一种方法,每加入一个自变量,可能会使已存在于模型中的变量单独对因变量的解释度减小,当其的作用很小(不显著)时,则可将其从模型中剔除。而第三种方法就做了这么一件事,不是一味的增加变量,而是增加一个后,对整个模型中的所有变量进行检验,剔除作用不显著的变量。最终尽可能得到一个最优的变量组合。

主要操作方法如上面所示,那么如何去评价那个变量是真的有价值的呢,这个时候再公式上可以去看一个指标,那就是观察R方的变化,那么到底什么是R方呢,一句话描述下它的功能就是

来表示回归直线对观测值的拟合程度,其主要的公式如下
R^2=SSR/SST=1-SSE/SST
(其中SSR是组间变异,SST是总变异)
进一步的详细描述下如下:

看这个式子式用1减去y对回归方程的方差(未解释离差)与y的总方差的比值,y减去 \hat{y}也就是残差,是拟合方程中不能解释的部分,用1减去不能解释的部分,那么剩下的就是解释的部分,也就是说自变量解释了因变量变动的百分比的多少,那么r方的值肯定是越大越好,意味着该模型把y的变动解释得好,R方的范围显然是0到1,在预测实践中,人们往往采纳R方最高的模型,其中cov(y,y_i)是协方差函数.同时跟R_square相似的指标,相关系数R

还有一个定义就是调整R方(R_adjusted):当给模型增加自变量时,复决定系数也随之逐步增大,然而复决定系数的增大代价是残差自由度的减少,因为残差自由度等于样本个数与字变量个数之差。自由度小意味着估计和预测可靠性低

其中,n为样本容量,p为自变量的个数。在实际问题的回归建模中,自由度调整负决定系数R方越大,所对应的回归方程越好。则所有回归子集中调整R方最大者对应的回归方程就是最优方程。

Python Achievement

下面是基于statsnidels中的回归函数实现的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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函数,主要是先设置拟合式子,然后用函数进行逐步回归,最终会返回各个变量的贡献比以及系数

1
2
3
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函数来返回各个系数的值

再就是R里面还有个glmnet的包,里面有个glmnet的线性拟合函数,同时可以通过alpha来设置正则项,0为岭回归,1为lasso回归,0.5就是弹性网络,同时一起用的还有cv.glmnet函数,主要是用来挑选参数的,返回的最近的lamda,可以通过下面的代码来选出通过交叉验证来选出最好的lamda对应的系数,以及拟合的系数值,后面可以直接用。

1
2
3
4
5
fit=glmnet(as.matrix(train_ydata),y_predict,alpha = 0.5,family ="gaussian",standardize = FALSE) #family 对应变量的类型,是一维连续(gaussian),二维,或者多维的非连续的,对应不同的核函数,具体可以看下
cv_fit=cv.glmnet(as.matrix(train_ydata),y_predict,type.measure='mae',family="gaussian",gamma =0)
plot(cv_fit)
coefficients<-coef(cv_fit,s=cv_fit$lambda.min)## 通过10折交叉验证来选出最佳的lamda,然后来选择特征
Active.Index<-which(coefficients!=0)//把选择的系统的下标拿出来