sklearn数据预处理和特征工程

1 数据挖掘的五大流程

1. 获取数据html

2. 数据预处理
数据预处理是从数据中检测,纠正或删除损坏,不许确或不适用于模型的记录的过程
可能面对的问题有:数据类型不一样,好比有的是文字,有的是数字,有的含时间序列,有的连续,有的间断。
也可能,数据的质量不行,有噪声,有异常,有缺失,数据出错,量纲不一,有重复,数据是偏态,数据量太
大或过小
数据预处理的目的:让数据适应模型,匹配模型的需求python

3. 特征工程:
特征工程是将原始数据转换为更能表明预测模型的潜在问题的特征的过程,能够经过挑选最相关的特征,提取
特征以及创造特征来实现。其中创造特征又常常以降维算法的方式实现。
可能面对的问题有:特征之间有相关性,特征和标签无关,特征太多或过小,或者干脆就没法表现出应有的数
据现象或没法展现数据的真实面貌
特征工程的目的:1) 下降计算成本,2) 提高模型上限git

4. 建模,测试模型并预测出结果web

5. 上线,验证模型效果算法

2 sklearn中数据处理和特征工程的模块

  • preprocessing: 包含数据预处理的全部内容
  • Impute:填补缺失值专用
  • feature_selection:包含特征选择的各类方法实践
  • decomposition:包含降维算法

3 数据预测处理Preprocessing和Impute

3.1 数据无量纲化

什么是?数组

  • 将不一样规格的数据转换到同一规格,或不一样分布的数据转换到某个特定分布
    的需求,这种需求统称为将数据“无量纲化”

好处bash

  • 在梯度和矩阵为核心的算法中,如逻辑回归、svm、bp,无量纲化能够加快求解速度
  • 在距离模型中,如k-means,k-近邻,能够帮助提高模型精度,避免某一个取值范围特别大的特征对距离计算形成的影响。
  • 特例:决策树和树的集成算法们,不用进行无量钢化。

数据的无量纲化能够是线性的,也能够是非线性的。线性的包括中心化(Zero-centered或Mean-subtraction)和缩放处理(Scale)中心化的本质是让全部的值减去一个固定值,即让数据样本平移到某个位置。缩放的本质是除以某个值,将数据固定在某个范围之中,取对数也算是一种缩放。网络

preprocess.MinMaxScalerapp

  • 公式以下

x = x m i n ( x ) m a x ( x ) m i n ( x ) x^* = \frac{x-min(x)}{max(x)-min(x)} dom

  • 代码
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]

pd.DataFrame(data)
#实现归一化
scaler = MinMaxScaler() #实例化
scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(data) #经过接口导出结果
print result
result_ = scaler.fit_transform(data) #训练和导出结果一步达成
scaler.inverse_transform(result) #将归一化后的结果逆转

#使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]之外的范围中
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化
result = scaler.fit_transform(data) #fit_transform一步导出结果

#当X中的特征数量很是多的时候,fit会报错并表示,数据量太大了 计算不了
#此时使用partial_fit做为训练接口 ****
scaler = scaler.partial_fit(data)

使用numpy来实现归一化

import numpy as np
X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]])
#归一化
X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_nor
#逆转归一化
X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
X_returned

preprocessing.StandardScaler
数据按照均值中心化后,再按照标准差缩放,数据将服从均值为0,方差为1的正太分布。称之为数据标准化(又称Z-score normalization),公式以下:
x = x μ σ x^* = \frac{x-\mu}{\sigma}

  • 代码
from sklearn.preprocessing import StandardScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = StandardScaler() #实例化
scaler.fit(data) #fit,本质是生成均值和方差
scaler.mean_ #查看均值的属性mean_
scaler.var_ #查看方差的属性var_
x_std = scaler.transform(data) #经过接口导出结果
x_std.mean() #导出的结果是一个数组,用mean()查看均值
x_std.std() #用std()查看方差
scaler.fit_transform(data) #使用fit_transform(data)一步达成结果
scaler.inverse_transform(x_std) #使用inverse_transform逆转标准化

对于StandardScaler和MinMaxScaler来讲,空值NaN会别当成缺失值,在fit的时候忽略,在transform的时候保持NaN的状态显示。
另外,fit时只容许至少导入二维数组,一维数组会报错

StandardScaler和MinMaxScaler如何选择
大多数机器学习算法中,会选择StandardScaler来进行特征缩放,由于MinMaxScaler对异常值很是敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler每每是最好的选择。

MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据须要被压缩到特定区间时使用普遍,好比数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于[0,1]区间之中。

建议先试试看StandardScaler,效果很差再试试看MinMaxScaler。

sklearn中还提供了其余的缩放处理。例如,在但愿压缩数据,却不影响数据的稀疏性时(不影响矩阵中取值为0的个数时),可使用MaxAbsScaler。在异常值多,噪声很是大时,选择分位数来无量纲化,使用RobustScaler。详细参考下表:

在这里插入图片描述

3.2 缺失值

加载数据

import pandas as pd
data = pd.read_csv("../data/Narrativedata.csv",index_col=0)
data.head()

缺失值处理

data.info()
#填补年龄
Age = data.loc[:,"Age"].values.reshape(-1,1) #sklearn当中特征矩阵必须是二维
Age[:20]
from sklearn.impute import SimpleImputer
imp_mean = SimpleImputer() #实例化,默认均值填补
imp_median = SimpleImputer(strategy="median") #用中位数填补
imp_0 = SimpleImputer(strategy="constant",fill_value=0) #用0填补
imp_mean = imp_mean.fit_transform(Age) #fit_transform一步完成调取结果
imp_median = imp_median.fit_transform(Age)
imp_0 = imp_0.fit_transform(Age)
imp_mean[:20]
imp_median[:20]
imp_0[:20]

#在这里咱们使用中位数填补Age
data.loc[:,"Age"] = imp_median
data.info()

#使用众数填补Embarked
Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)
imp_mode = SimpleImputer(strategy = "most_frequent")
data.loc[:,"Embarked"] = imp_mode.fit_transform(Embarked)
data.info() # 直接能够看出每列的空值状况

3.3 处理分类型特征

preprocessing.LabelEncoder:标签专用,可以将分类转换为分类数值

from sklearn.preprocessing import LabelEncoder
y = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,因此容许一维
le = LabelEncoder() #实例化
le = le.fit(y) 		#导入数据
label = le.transform(y) #transform接口调取结果
print le.classes_ 	#属性.classes_查看标签中究竟有多少类别
print label 			#查看获取的结果label

le.fit_transform(y) #也能够直接fit_transform一步到位
le.inverse_transform(label) #使用inverse_transform能够逆转

data.iloc[:,-1] = label #让标签等于咱们运行出来的结果
data.head()

#能够直接转化
from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])

preprocessing.OrdinalEncoder: 特征专用,可以将分类特征转换为分类数值, 输入不能有NaN

from sklearn.preprocessing import OrdinalEncoder
#接口categories_对应LabelEncoder的接口classes_,如出一辙的功能
data_ = data.copy()
print data_.head()
print OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_
data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
print data_.head()  # 所有转成数字编码

preprocessing.OneHotEncoder:独热编码,建立哑变量

三种不一样性质的分类数据
1) 舱门(S,C,Q)
三种取值S,C,Q是相互独立的,彼此之间彻底没有联系,表达的是S≠C≠Q的概念。这是名义变量。
2) 学历(小学,初中,高中)
三种取值不是彻底独立的,咱们能够明显看出,在性质上能够有高中>初中>小学这样的联系,学历有高低,可是学历取值之间却不是能够计算的,咱们不能说小学 + 某个取值 = 初中。这是有序变量。
3) 体重(>45kg,>90kg,>135kg)
各个取值之间有联系,且是能够互相计算的,好比120kg - 45kg = 90kg,分类之间能够经过数学计算互相转换。这是有距变量。

from sklearn.preprocessing import OneHotEncoder
X = data.iloc[:,1:-1]
enc = OneHotEncoder(categories='auto').fit(X) # auto 在0.19版本中是不支持的
result = enc.transform(X).toarray() # 若是不to_array则是稀疏矩阵
print result 

#依然能够直接一步到位,
OneHotEncoder(categories='auto').fit_transform(X).toarray()

#依然能够还原
pd.DataFrame(enc.inverse_transform(result))


enc.get_feature_names() # 稀疏矩阵中列的名字

#axis=1,表示跨行进行合并,axis=1是将两表左右相连,若是是axis=0,就是将量表上下相连
newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
print newdata.head()

# 丢失没用的列
newdata.drop(["Sex","Embarked"],axis=1,inplace=True)
newdata.columns =
["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
print newdata.head()

小结
在这里插入图片描述
数据类型及经常使用的统计量
在这里插入图片描述

3.4 处理连续型特征:二值化和分箱

sklearn.preprocessing.Binarizer
根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。默认阈值为0时,特征中全部的正值都映射到1。二值化是对文本计数数据的常见操做,分析人员能够决定仅考虑某种现象的存在与否。它还能够用做考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。

#将年龄二值化
data_2 = data.copy()
from sklearn.preprocessing import Binarizer
X = data_2.iloc[:,0].values.reshape(-1,1) # 类为特征专用,因此不能使用一维数组
transformer = Binarizer(threshold=30).fit_transform(X) # 阈值
print transformer  # 获得0 和 1的数组
data_2.iloc[:,0] = transformer

preprocessing.KBinsDiscretizer
分类变量的类,可以将连续型变量排序后按顺序分箱后编码
在这里插入图片描述

from sklearn.preprocessing import KBinsDiscretizer
X = data.iloc[:,0].values.reshape(-1,1)
est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
est.fit_transform(X)

#查看转换后分的箱:变成了一列中的三箱
set(est.fit_transform(X).ravel())
est = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform')

#查看转换后分的箱:变成了哑变量
est.fit_transform(X).toarray()

4 特征选择 feature_selection

特征提取(feature extraction)
从文字,图像,声音等其余非结构化数据中提取新信息做为特征。好比说,从淘宝宝贝的名称中提取出产品类别,产品颜色,是不是网红产品等等
特征创造(feature creation)
把现有特征进行组合,或互相计算,获得新的特征。好比说,咱们有一列特征是速度,一列特征是距离,咱们就能够经过让两列相处,创造新的特征:经过距离所花的时间
特征选择(feature selection)
从全部的特征中,选择出有意义,对模型有帮助的特征,以免必须将全部特征都导入模型
去训练的状况

四种方法能够用来选择特征:过滤法,嵌入法,包装法,和降维算法

导入数据

import pandas as pd
data = pd.read_csv(r"digitrecognizor.csv")
X = data.iloc[:,1:]
y = data.iloc[:,0]
X.shape

4.1 Filter过滤法

过滤方法一般用做预处理步骤,特征选择彻底独立于任何机器学习算法。它是根据各类统计检验中的分数以及相关性的各项指标来选择特征。

4.1.1方差过滤

VariancThreshold
某个特征若是方差很小,说明该特征的值都是差很少的,则该特征对样本区分没有什么做用。因此要优先消除方差为0的特征。

from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold() 		#实例化,不填参数默认方差为0
X_var0 = selector.fit_transform(X) #获取删除不合格特征以后的新特征矩阵
#也能够直接写成 X = VairanceThreshold().fit_transform(X)
print X_var0.shape  # 打印去除方差为0后的数据维度
# 设置方差的中位数为阈值
import numpy as np
x_fsvar = VarianceThreshold(np.median(x.var().values)).fit_transform(x)

当特征是二分类时,特征的取值就是伯努利随机变量,这些变量的方差能够计算为:
V a r [ X ] = p ( 1 p ) Var[X] = p(1-p)
其中X是特征矩阵,p是二分类特征中的一类在这个特征中所占的几率。

#若特征是伯努利随机变量,假设p=0.8,即二分类中某类分类占到80%以上的时候删除特征。
x_bar = VarianceThreshold(.8 * (1 - .8)).fit_transform(X)

为何随机森林运行如此之快为何方差过滤对随机森林没很大的有影响
这是因为两种算法的原理中涉及到的计算量不一样。最近邻算法KNN,单棵决策树,支持向量机SVM,神经网络,回归算法,都须要遍历特征或升维来进行运算,因此他们自己的运算量就很大,须要的时间就很长,所以方差过滤这样的特征选择对他们来讲就尤其重要。
但对于不须要遍历特征的算法,好比随机森林,它随机选取特征进行分枝,自己运算就很是快速,所以特征选择对它来讲效果平平。这其实很容易理解,不管过滤法如何下降特征的数量,随机森林也只会选取固定数量的特征来建模;而最近邻算法就不一样了,特征越少,距离计算的维度就越少,模型明显会随着特征的减小变得轻量。所以,过滤法的主要对象是:须要遍历特征或升维的算法们,而过滤法的主要目是:在维持算法表现的前提下,帮助算法们下降计算成本

方差过滤的影响总结

阈值很小,被过滤掉的特征比较少 阈值较大
模型表现 影响不大 可能会变好,表明过滤掉的都是噪音,也可能变糟糕,表明被过滤掉的不少都是有效特征
运行时间 可能较低模型的运行时间 必定时间上能下降模型的运行时间,算法下遍历特征时的计算特征越复杂,运行时间降低的越多

选择超参数threshold
通常会先使用阈值为0,或者阈值很小的方差过滤。而后选用更优秀的特征选择方法继续消减特征数量。

4.1.2 相关性过滤

卡方过滤是专门针对离散型标签,即分类问题
卡方检验类feature_selection.chi2计算每一个非负特征和标签之间的卡方统计量,而且依照卡方统计量由高到低为特征排名。再结合feature_selection.SelectKBest选出前K个分数最高的特征类。借此能够去除最可能独立于标签,与咱们分类目的无关的特征。

若是卡方检验检测到某个特征中中的特征值都相同,则是提示咱们须要先进行方差过滤。
若是先使用了方差过滤,模型效果好了,则进行卡方检测时就用方差过滤之后的数据,反之则直接用原始数据。

# 导包
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()

验证一下模型的效果如何

cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

选择超参数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()

方法二:看p值选择k
卡方检验返回卡方值和P值两个统计变量,其中卡方值很难界定有效的范围,可是P值,通常使用0.01或者0.05做为显著性水平。即p值判断的边界。

p值 <=0.05或0.01 >0.05或0.01
数据差别 差别不是天然造成的 这些差别是很天然的样本偏差
相关性 两组数据是相关的 两组数据是独立的
原假设 拒绝原假设,接受备选假设 接受原假设

从特征工程的角度,通常但愿选取卡方值很大,p值小于0.05的特征,即和标签是相关联的在调用SelectKBest以前,能够直接从chi2实例化后的模型中得到各个特征所对应的卡方值和P值。

chivalue, pvalues_chi = chi2(X_fsvar,y)

# 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()

能够观察到,全部的特征的p值都是0,说明对于digit recognizor数据集来讲,方差验证已经把全部和标签无关的特征都剔除掉了。所以,舍弃任何一个特征都会使模型效果降低。

F检验
F检验又称ANOVA,方差齐性检验,能够捕捉,每一个特征与标签之间的线性关系的过滤方法。可用于回归又能够用户分类。所以,包含feature_section.f_classif(用于标签是离散型)和feature_selection.f_regression(用于标签是连续性)两个类。

相似于卡方检验,这两个类都须要结合SelectKBest使用。所以也须要设定K的值。F检验在数据服从正态分布时效果很是稳定,所以通常会先将数据转换成正太分布,再使用F检验过滤。

F检验的本质是寻找两组数据之间的线性关系,其原假设是“数据不存在显著的线性关系”。它返回F值和p值两个统计量。和卡方过滤同样,选取p值小于0.05或者0.01的特征,这些特征与标签是显著线性相关的。,反之则该特征应该被删除。

from sklearn.feature_selection import f_classif
F, pvalues_f = f_classif(X_fsvar,y)
print F
print 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() 

互信息法
互信息发用来捕捉每一个特征与标签之间的任意关系(线性和非线性)的过滤方法。也是能够作回归和分类。包含feature_selection.mutual_info_classif和feature_selection.mutual_info_regression。

互信息法不返回p值或者F值之类的统计量。它返回每一个特征与目标之间的互信息量的估计。这个估计量在[0,1]之间。0表示两个变量独立,1表示两个变量彻底相关。

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()

全部特征的互信息量估计都大于0,所以全部特征都与标签相关。

4.1.3 过滤法总结

一般来讲,会先使用方差过滤,而后使用互信息法来捕捉相关性,不过各式各样的过滤方式也是要考虑的。各种方法的总结以下:

说明 超参数选择
VarianceThreshold 方差过滤,可输入方差的阈值,返回方差大于阈值的新特征矩阵 通常选择0或1来筛选,也能够画一学习曲线或中位数模型来帮助确认
SelectKBest 用来选取K个统计量结果最佳的特征,生成符合统计量要求的新特征矩阵 看配合使用的统计量
chi2 卡方检验,专用于分类算法,捕捉相关性 追求p小于显著性水平的特征
f_classif / f_regression F检验,要求数据服从正太分布 追求p小于显著水平的特征
mutual_info_classif / mutual_info_regression 互信息检测,不能用于稀疏矩阵 追求互信息估计大于0特征

4.2 Embedded嵌入法

嵌入法是一种让算法本身决定使用哪些特征的方法,即特征选择和算法训练同是进行。例如决策树和树的集成模型中的feature_importances_属性。
在这里插入图片描述
嵌入法的缺点
至关于过滤法,嵌入法没法找到一个固定的值来衡量哪一个特征对模型有做用。至关于权重系数就是一个超参数。
另外,嵌入法和应用的算法的计算速度有关,若是采用计算量很大的算法,嵌入法自己也会十分耗时。

feature_selection.SelectFromModel
class sklearn.feature_selection.SelectFromModel (estimator, threshold=None, prefit=False, norm_order=1, max_features=None)

SelectFromModel是一个元变换器,能够与任何拟合后具备coef_,feature_importances_属性或参数中可选惩罚项的评估器一块儿使用(随机森林和树模型就具备属性feature_importances_,逻辑回归就带有l1和l2惩罚项,svm也支持l2惩罚项)

对于有feature_importances_的模型来讲,若重要性低于提供的阈值,则认为这些特征不重要。
对于使用惩罚项的模型嵌入法,正则化惩罚越大,特征在模型中的对于系数就会越小。当正则化惩罚项打到必定程度的时候,部分特征系数就会变0,当正则化惩罚项增大到必定程度时,全部特征系数都会趋于0,此时咱们能够观察哪一部分特征更容易变成0,这部分特征能够被筛掉。另外对于SVM和LR使用参数C来控制返回的特征的系数性,参数C越小,返回费特征越少。Lasso回归,用alpha参数来控制返回的特征矩阵,alpha的纸越大,返回的特征越少。

参数说明

参数 说明
estimator 使用的模型评估器,只要带feature_importances_或coef_属性,或者带有l1和l2惩罚项的模型均可以使用
threshold 特征重要性阈值,重要性小于该阈值的会被删除
prefit 默认为False,判断是否将实例化后的模型直接传递给构造函数。若是为True,则必须直接调用fit和transform,不能使用fit_transform,而且SelectFromModel不能与cross_val_score,GridSearchCV一块儿使用
norm_order k能够在非0整数,正无穷,负无穷,默认为1。在评估器的coef_属性高于1维的状况下,用于过滤低于阈值的系数的向量的范数的阶数
max_features 要选择的最大特征数,要禁用阈值而且根据max_features选择,则设置threshold=-np.inf

通常主要考虑前两个参数。以随机森林为例:

from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import RandomForestClassifier as RFC
RFC_ = RFC(n_estimators =10,random_state=0)
X_embedded = SelectFromModel(RFC_,threshold=0.005).fit_transform(X,y)
 
#在这里我只想取出来有限的特征。0.005这个阈值对于有780个特征的数据来讲,是很是高的阈值,由于平均每一个特征 只可以分到大约0.001的feature_importances_
 
X_embedded.shape
 
#模型的维度明显被下降了 #一样的,咱们也能够画学习曲线来找最佳阈值
 
#======【TIME WARNING:10 mins】======#
import numpy as np import matplotlib.pyplot as plt
RFC_.fit(X,y).feature_importances_
threshold = np.linspace(0,(RFC_.fit(X,y).feature_importances_).max(),20)
score = [] for i in threshold:    
	X_embedded = SelectFromModel(RFC_,threshold=i).fit_transform(X,y)
	once = cross_val_score(RFC_,X_embedded,y,cv=5).mean()
	score.append(once)
	plt.plot(threshold,score) plt.show()

在嵌入法下,咱们很容易就可以实现特征选择的目标:减小计算量,提高模型表现。所以,比起要思考不少统计量 的过滤法来讲,嵌入法多是更有效的一种方法。然而,在算法自己很复杂的时候,过滤法的计算远远比嵌入法要 快,因此大型数据中,咱们仍是会优先考虑过滤法。

4.3 Wrapper包装法

和嵌入法的区别:使用一个目标函数做为黑盒来帮助咱们选取特征,而不是本身输入某个评估指标或者统计量的阈值。另外,过滤法和嵌入法是一次训练解决全部问题,包装法要使用特征子集进行屡次训练,所以计算成本更高。
在这里插入图片描述
最典型的目标函数是递归特征消除法(Recursive feature elimination, 简写为RFE)它是一种贪婪优化算法,旨在找到性能最佳的特征子集。

feature_selection.RFE
class sklearn.feature_selection.RFE (estimator, n_features_to_select=None, step=1, verbose=0)
参数说明

参数 说明
estimator 须要填写实例化后的评估器
n_features_to_select 想要选择的特征个数
step 每次迭代中但愿移除的特征个数

重要属性
.support: 返回全部特征最后是否被选择的布尔矩阵
.ranking 返回特征的按次数迭代中综合重要性排名。
feature_selection.RFECV
会在交叉验证中循环执行RFE以找到最佳数量的特征,增长cv,其余用户都和RFE同样。

from sklearn.feature_selection import RFE 
RFC_ = RFC(n_estimators =10,random_state=0) 
selector = RFE(RFC_, n_features_to_select=340, step=50).fit(X, y)
print selector.support_.sum()
print selector.ranking_

X_wrapper = selector.transform(X)
cross_val_score(RFC_,X_wrapper,y,cv=5).mean()

学习曲线

#======【TIME WARNING: 15 mins】======#
 
score = [] for i in range(1,751,50):   
	X_wrapper = RFE(RFC_,n_features_to_select=i, step=50).fit_transform(X,y)  
	once = cross_val_score(RFC_,X_wrapper,y,cv=5).mean()
	score.append(once) 
plt.figure(figsize=[20,5]) 	
plt.plot(range(1,751,50),score) 
plt.xticks(range(1,751,50)) 
plt.show()

在这里插入图片描述
能够看出,在包装法下,应用50个特征时,模型的表现已经达到了90%以上,比嵌入法和过滤法都高效。

4.4 特征选择总结

经验来讲,过滤法更快速,但更粗糙。包装法和嵌入法更精确,比较适合具体到算 法去调整,但计算量比较大,运行时间长。 当数据量很大的时候,优先使用方差过滤和互信息法调整,再上其余特 征选择方法。使用逻辑回归时,优先使用嵌入法。使用支持向量机时,优先使用包装法。迷茫的时候,从过滤法走起,看具体数据具体分析.