【机器学习】sklearn特征选择(feature selection)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
文章目录
特征工程
特征提取(feature extraction) | 特征创造(feature creation) | 特征选择(feature selection) |
---|---|---|
从文字图像声音等其他非结构化数据中提取新信息作为特征。比如说从淘宝宝贝的名称中提取出产品类别产品颜色是否是网红产品等等。 | 把现有特征进行组合或互相计算得到新的特征。比如说我们有一列特征是速度一列特征是距离我们就可以通过让两列相除创造新的特征通过距离所花的时间。 | 从所有的特征中选择出有意义对模型有帮助的特征以避免必须将所有特征都导入模型去训练的情况。 |
特征选择是特征工程中最为简单的一个在做特征选择时第一步是根据我们的目标用业务常识来选择特征做一些基本的判断也就是需要理解业务。
理解业务对特征做出基本的判断只适用于特征量不多且好分辨的数据集多特征不易分辨的数据集可以采用四种方法可以用来选
择特征过滤法嵌入法包装法和降维算法。
本文主要对过滤法嵌入法包装法进行解释说明并用sklearn进行实践操作降维算法可以看下一篇博客详解。
过滤法Filter
过滤方法通常用作预处理步骤特征选择完全独立于任何机器学习算法。它是根据各种统计检验中的分数以及相关。
选择特征时不管模型该方法基于特征的通用表现去选择比如: 目标相关性、自相关性和发散性等。
方差过滤
方差越大的特征那么我们可以认为它是比较有用的。如果方差较小比如小于1那么这个特征可能对我们的算法作用没有那么大。最极端的如果某个特征方差为0即所有的样本该特征的取值都是一样的那么它对我们的模型训练没有任何作用可以直接舍弃。
方差过滤就是设置一个阈值方差小于这个阈值的全部过滤掉舍弃掉。sklearn中使用类VarianceThreshold
只需要填写一个阈值参数不填默认0就是把毫无关联的特征删除掉。
VarianceThreshold(阈值).fit_transform(特征矩阵数据集)
比如说我要删除一半的特征那么我们需要找到所有特征方差的中位数来作为阈值
from sklearn.feature_selection import VarianceThreshold
import numpy as np
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X) # X.var()每一列的方差
当特征是二分类时特征的取值就是伯努利随机变量这些变量的方差可以计算为
V
[
x
]
=
p
(
1
−
p
)
V[x] = p(1-p)
V[x]=p(1−p)
其中X是特征矩阵p是二分类特征中的一类在这个特征中所占的概率。
二分类特征中某种分类占到80%以上的时候删除该特征
X_bvar = VarianceThreshold(.8 * (1 - .8)).fit_transform(X)
可以对进行方差过滤后的特征集进行交叉验证看看效果如何效果其实主要看超参数threshold阈值
的选取
阈值很小 被过滤掉得特征比较少 | 阈值比较大 被过滤掉的特征有很多 | |
---|---|---|
模型表现 | 不会有太大影响 | 可能变更好代表被滤掉的特征大部分是噪音 也可能变糟糕代表被滤掉的特征中很多都是有效特征 |
运行时间 | 可能降低模型的运行时间基于方差很小的特征有多少当方差很小的特征不多时对模型没有太大影响 | 一定能够降低模型的运行时间算法在遍历特征时的计算越复杂运行时间下降得越多 |
现实中我们只会使用阈值为0或者阈值很小的方差过滤来为我们优先消除一些明显用不到的特征然后我们会选择更优的特征选择方法继续削减特征数量。
相关性过滤
望选出与标签相关且有意义的特征因为这样的特征能够为我们提供大量信息。如果特征与标签无关那只会白白浪费我们的计算内存可能还会给模型带来噪音。
sklearn当中我们有三种常用的方法来评判特征与标签之间的相关性卡方F检验互信息。
卡方过滤
卡方过滤是专门针对离散型标签即分类问题的相关性过滤。卡方检验类feature_selection.chi2计算每个非负特征和标签之间的卡方统计量并依照卡方统计量由高到低为特征排名。
再结合feature_selection.SelectKBest这个可以输入”评分标准“来选出前K个分数最高的特征的类我们可以借此除去最可能独立于标签与我们分类目的无关的特征。
卡方值 X2的计算公式如下
observed是实际值expected是理论值。卡方值的目的是衡量理论和实际的差异程度。
卡方值高说明两变量之间具有相关性的可能性更大。
from sklearn.ensemble import RandomForestClassifier as RFC # 随机森林
from sklearn.model_selection import cross_val_score # 交叉验证
from sklearn.feature_selection import SelectKBest #选出前K个分数最高的特征
from sklearn.feature_selection import chi2 # 卡方
# 通过卡方=》排序=》选择300个相关性最高的特征
X_fschi = SelectKBest(chi2, k=300).fit_transform(X_fsvar, y)
# 用随机森林验证一下
cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()
如果交叉验证的结果比之前的准确率低说明删除了与模型相关且有效的特征k值设置的太小了如果模型的表现提升则说明我们的相关
性过滤是有效的是过滤掉了模型的噪音的这时候我们就保留相关性过滤的结果。
如何选择超参数k
一个一个试画学习曲线
%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()
随着K值的不断增加模型的表现不断上升这说明K越大越好数据中所有的特征都是与标签相关的。
上面学习曲线选不出k值还可以通过看p值选择k
卡方检验的本质是推测两组数据之间的差异其检验的原假设是”两组数据是相互独立的”。卡方检验返回卡方值和P值两个统计量其中卡方值很难界定有效的范围而p值我们一般使用0.01或0.05作为显著性水平即p值判断的边界具体我们可以这样来看
P值 | <=0.05或0.01 | >0.05或0.01 |
---|---|---|
数据差异 | 差异不是自然形成的 | 这些差异是很自然的样本误差 |
相关性 | 两组数据是相关的 | 两组数据是相互独立的 |
原假设 | 拒绝原假设接受备择假设 | 接受原假设 |
从特征工程的角度我们希望选取卡方值很大p值小于0.05的特征即和标签是相关联的特征。
chivalue, pvalues_chi = chi2(X_fsvar,y)
# chivalue卡方值 pvalues_chi p值
F验表
F检验又称ANOVA方差齐性检验是用来捕捉每个特征与标签之间的线性关系的过滤方法。它即可以做回归也可以做分类因此包含
feature_selection.f_classif
F检验分类和feature_selection.f_regression
F检验回归两个类。其中F检验分类用于标签是离散型变量的数据而F检验回归用于标签是连续型变量的数据。
F检验的本质是寻找两组数据之间的线性关系其原假设是”数据不存在显著的线性关系“。它返回F值和p值两个统计量。和卡方过滤一样我们希望选取p值小于0.05或0.01的特征这些特征与标签时显著线性相关的而p值大于0.05或0.01的特征则被我们认为是和标签没有显著线性关系的特征应该被删除。
from sklearn.feature_selection import f_classif
F, pvalues_f = f_classif(X_fsvar,y)
互信息法
互信息是衡量变量之间相互依赖程度它的计算公式如下
它既可以做回归也可以做分类并且包含两个类
feature_selection.mutual_info_classif
互信息分类和
feature_selection.mutual_info_regression
互信息回归。这两个类的用法和参数都和F检验一模一样不过互信息法比F检验更加强大F检验只能够找出线性关系而互信息法可以找出任意关系。
互信息法不返回p值或F值类似的统计量它返回“每个特征与目标之间的互信息量的估计”这个估计量在[0,1]之间取值为0则表示两个变量独立为1则表示两个变量完全相关。
from sklearn.feature_selection import mutual_info_classif as MIC
result = MIC(X_fsvar,y)
小结
现实中先使用方差过滤然后使用互信息法来捕捉相关性。
类 | 说明 | 超参数的选择 |
---|---|---|
VarianceThreshold | 方差过滤可输入方差阈值返回方差大于阈值的新特征矩阵 | 看具体数据究竟是含有更多噪声还是更多有效特征一般就使用0或1来筛选也可以画学习曲线或取中位数跑模型来帮助确认 |
SelectKBest | 用来选取K个统计量结果最佳的特征生成符合统计量要求的新特征矩阵 | 看配合使用的统计量 |
chi2 | 卡方检验专用于分类算法捕捉相关性 | 追求p小于显著性水平的特征 |
f_classif | F检验分类只能捕捉线性相关性要求数据服从正态分布 | 追求p小于显著性水平的特征 |
f_regression | F检验回归只能捕捉线性相关性要求数据服从正态分布 | 追求p小于显著性水平的特征 |
mutual_info_classif | 互信息分类可以捕捉任何相关性不能用于稀疏矩阵 | 追求互信息估计大于0的特征 |
mutual_info_regression | 互信息回归可以捕捉任何相关性不能用于稀疏矩阵 | 追求互信息估计大于0的特征 |
嵌入法Embedded
特征选择被嵌入进学习器训练过程中得到各个特征的权值系数根据权值系数从大到小选择特征。
SelectFromModel
是一个元变换器可以与任何在拟合后具有coef_
feature_importances_
属性或参数中可选惩罚项的评估器一起使用比如随机森林和树模型就具有属性feature_importances_逻辑回归就带有Ll和L2惩罚项线性支持向量机也支持l2惩罚项。
对于有feature_importances_
的模型来说若重要性低于提供的阈值参数则认为这些特征不重要并被移除。
feature_importances_
的取值范围是[0,1]如果设置阈值很小比如0.001就可以删除那些对标签预测完全没贡献的特征。如果设置得很接近1可能只有一两个特征能够被留下。
参数
- estimator使用的模型评估器只要是带feature_importances_或者coef_属性或带有L1和L2惩罚项的模型都可以使用。
- threshold特征重要性的阈值重要性低于这个阈值的特征都将被删除。
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)
学习曲线找阈值
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()
包装法Wrapper
将要使用的学习器的性能作为特征子集的评价准则目的是为给的学习器选择“量身定做”的特征子集。
依赖于算法自身的选择比如
coef_
属性或feature_importances_
属性来完成特征选择。我们往往使用一个目标函数作为黑盒来帮助我们选取特征而不是自己输入某个评估指标或统计量的阈值。包装法在初始特征集上训练评估器并且通过
coef_属性或通过feature_importances_属性获得每个特征的重要性。然后从当前的一组特征中修剪最不重要的特征。在修剪的集合上递归地重复该过程直到最终到达所需数量的要选择的特征。区别于过滤法和嵌入法的一次训练解决所有问题包装法要使用特征子集进行多次训练因此它所需要的计算成本是最高的。
在这个图中的“算法”指的不是我们最终用来导入数据的分类或回归算法即不是随机森林而是专业的数据挖掘算法即我们的目标函数。这些数据挖掘算法的核心功能就是选取最佳特征子集。
最典型的目标函数是递归特征消除法Recursive feature elimination, 简写为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)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |