机器学习sklearn(46): 特征工程(十三) 特征选择(四)简介 /Filter过滤法

当数据预处理完成后,我们就要开始进行特征工程了。

 

 

 

#导入数据,让我们使用digit recognizor数据来一展身手
import pandas as pd
data = pd.read_csv(r"C:\work\learnbetter\micro-class\week 3 Preprocessing\digit recognizor.csv") 
X = data.iloc[:,1:]
y = data.iloc[:,0]
X.shape
""" 这个数据量相对夸张,如果使用支持向量机和神经网络,很可能会直接跑不出来。使用KNN跑一次大概需要半个小时。 用这个数据举例,能更够体现特征工程的重要性。 """

1 Filter过滤法

过滤方法通常用作预处理步骤,特征选择完全独立于任何机器学习算法。它是根据各种统计检验中的分数以及相关性的各项指标来选择特征。 
1.1 方差过滤
1.1.1 VarianceThreshold

from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold() #实例化,不填参数默认方差为0
X_var0 = selector.fit_transform(X) #获取删除不合格特征之后的新特征矩阵
#也可以直接写成 X = VairanceThreshold().fit_transform(X)
X_var0.shape

import numpy as np
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X) 
X.var().values np.median(X.var().values) X_fsvar.shape

 

 

#若特征是伯努利随机变量,假设p=0.8,即二分类特征中某种分类占到80%以上的时候删除特征
X_bvar = VarianceThreshold(.8 * (1 - .8)).fit_transform(X)
X_bvar.shape
1.1.2 方差过滤对模型的影响

1. 导入模块并准备数据 
#KNN vs 随机森林在不同方差过滤效果下的对比
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn.model_selection import cross_val_score
import numpy as np
X = data.iloc[:,1:]
y = data.iloc[:,0]
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X)

2. KNN方差过滤前 
#======【TIME WARNING:35mins +】======#
cross_val_score(KNN(),X,y,cv=5).mean()
#python中的魔法命令,可以直接使用%%timeit来计算运行这个cell中的代码所需的时间
#为了计算所需的时间,需要将这个cell中的代码运行很多次(通常是7次)后求平均值,因此运行%%timeit的时间会
远远超过cell中的代码单独运行的时间
#======【TIME WARNING:4 hours】======#
%%timeit
cross_val_score(KNN(),X,y,cv=5).mean()

3. KNN方差过滤后 
#======【TIME WARNING:20 mins+】======#
cross_val_score(KNN(),X_fsvar,y,cv=5).mean()
#======【TIME WARNING:2 hours】======#
%%timeit
cross_val_score(KNN(),X,y,cv=5).mean()
cross_val_score(RFC(n_estimators=10,random_state=0),X,y,cv=5).mean()

4. 随机森林方差过滤前 
cross_val_score(RFC(n_estimators=10,random_state=0),X,y,cv=5).mean()

5. 随机森林方差过滤后
cross_val_score(RFC(n_estimators=10,random_state=0),X_fsvar,y,cv=5).mean()

 

 

 

对受影响的算法来说,我们可以将方差过滤的影响总结如下:

 

 

 

1.1.3 选取超参数threshold

1.2 相关性过滤

1.2.1 卡方过滤

 

 

from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#假设在这里我一直我需要300个特征
X_fschi = SelectKBest(chi2, k=300).fit_transform(X_fsvar, y)
X_fschi.shape
验证一下模型的效果如何: 
cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

1.2.2 选取超参数K

 

 

#======【TIME WARNING: 5 mins】======#
%matplotlib inline
import matplotlib.pyplot as plt
score = []
for i in range(390,200,-10):
    X_fschi = SelectKBest(chi2, k=i).fit_transform(X_fsvar, y)
    once = cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()
    score.append(once)
plt.plot(range(350,200,-10),score)
plt.show()

 

 

chivalue, pvalues_chi = chi2(X_fsvar,y)
chivalue
pvalues_chi
#k取多少?我们想要消除所有p值大于设定值,比如0.05或0.01的特征:
k = chivalue.shape[0] - (pvalues_chi > 0.05).sum()
#X_fschi = SelectKBest(chi2, k=填写具体的k).fit_transform(X_fsvar, y)
#cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

 

 

from sklearn.feature_selection import f_classif
F, pvalues_f = f_classif(X_fsvar,y) 
F pvalues_f k
= F.shape[0] - (pvalues_f > 0.05).sum() #X_fsF = SelectKBest(f_classif, k=填写具体的k).fit_transform(X_fsvar, y) #cross_val_score(RFC(n_estimators=10,random_state=0),X_fsF,y,cv=5).mean()

1.2.4 互信息法

from sklearn.feature_selection import mutual_info_classif as MIC
result = MIC(X_fsvar,y) k = result.shape[0] - sum(result <= 0)
#X_fsmic = SelectKBest(MIC, k=填写具体的k).fit_transform(X_fsvar, y)
#cross_val_score(RFC(n_estimators=10,random_state=0),X_fsmic,y,cv=5).mean()

 

posted @ 2021-06-24 23:58  秋华  阅读(677)  评论(0编辑  收藏  举报