特征选择方法

特征选择

对于模型的训练来说,当输入的数据维度过大会消耗大量的时间,而且也不是所有的属性对于模型性能的提升都是有益的,无关的属性输入反而还会降低模型的性能。在此情形下,需要对属性进行选择。

方差过滤

一些属性的值在某一常值附近波动极小,甚至就是常值,也就是说这些属性的方差值很小。这些属性对于映射关系的建立几乎是没有用的,在这些属性上没有区分度。如果提前对数据进行方差过滤,就可以筛选出这样的属性减少模型的输入维度。

在Sklearn中,方差过滤的类为VarianceThreshold。

from sklearn.feature_selection import varianceThreshold
import numpy as np
selector = VarianceThreshold()//默认方差值为0 
x_var = selector.fit_transfrom()
x_fsvar = VarianceThreshold(np.median(x.var().values).fit_transform(x)//选出一半的特征

如果特征是伯努利分布,则方差为:
p ( 1 − p ) p(1-p) p(1p)

阈值很小,被过滤的特征数较少阈值较大,被过滤的特征数较多
模型表现不会有太大影响可能变好,代表被滤掉的特征大部分是噪音;可能变坏,代表被滤掉的有一些有用信息
运行时间可能降低模型运行时间一定能够降低模型运行时间
卡方过滤

卡方过滤针对特征和离散型数据(分类)之间的相关性进行过滤,卡方统计原假设两数据之间独立不具有相关性,其要求特征非负。

在SKlearn中,卡方过滤类为ch2

from sklearn.feature_selection import Ch2
from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import cross_val_score
x_fschi = selectKBest(ch2,k=300).fit_transform(x)//k为特征选择后个数
crosss_val_score(RFC(n_estimators=10,random_state=0),x_fschi,y,cv=5).mean()

在经过卡方检验选择后,模型的性能可能会提升,说明检验滤除了特征噪音;也有可能降低,说明滤除了有用特征。此时可以利用学习曲线来确定特征个数K。

通过学习曲线寻找最佳K值:

score = [ ]
for i  in range(390,200,-10):
   x_fschi = selectKBest(chi2, k = i).fit_transform(x_fsvar,y)
  onece = cross_val_score(RFC(n_estimators=10,random_stade=0),x_fschi,y,cv=5).mean( )
  score.append(once)
plt.plot(range(350,250,-10),score)
plt.show()

卡方检验返回两个值,卡方值和P,其中卡方值难以界定有效范围,P值取0.01或0.05作为显著性边界–拒绝还是接受原假设。

chivalue,pvalues_chi = chi2(x_fsvar,y)
chivalue
pvalues_chi
k = chivalue.shape[0]-(pvalues_chi > 0.05).sum()
P<=0.05或0.01p>0.05或0.01
数据差异差异不是自然形成差异自然形成
相关性两组数据线性相关不具有线性相关
原假设拒绝原假设接收原假设
F检验

F检验捕捉每个特征与标签间的线性关系,其原假设:数据间不存在显著的线性关系。既可以应用于连续性标签(回归),也可以应用于离散型标签(分类),其对应的类分别为feature_selection.f_classify和feature_selection.f_regression。

from sklearn.feature_selection import f_classif
from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import cross_val_score
x_f = selectKBest(f_classif,k=300).fit_transform(x)//k为特征选择后个数
crosss_val_score(RFC(n_estimators=10,random_state=0),x_f,y,cv=5).mean()
F,pvalue_f = f_classif(x_fsvar,y)
print(F)
print(pvalue_f)
k = F.shape[0]-(pvalues_f > 0.05).sum()
互信息法检验

互信息的概念来自于信息熵,可以捕获特征与标签间的任意关系,包括线性与非线性,其返回特征与标签间的互信息估计值在0-1间,0表示两数据相互独立,1表示两数据完全相关。

互信息计算公式如下:
I ( X : Y ) = ∑ y ∈ Y ∑ x ∈ X p ( x , y ) l o g ( p ( x , y ) p ( x ) p ( y ) ) I(X:Y)=\sum_{y\in Y}\sum_{x\in X}p(x,y)log(\frac {p(x,y)}{p(x)p(y)}) I(X:Y)=yYxXp(x,y)log(p(x)p(y)p(x,y))
对于连续型变量:
I ( X , Y ) = ∫ y ∫ x p ( x , y ) l o g ( p ( x , y ) p ( x ) p ( y ) ) d x d y I(X,Y)=\int_y\int_xp(x,y)log(\frac{p(x,y)}{p(x){p(y)}})dxdy I(X,Y)=yxp(x,y)log(p(x)p(y)p(x,y))dxdy
对于离散型变量可以将其转化为KL散度
I ( X : Y ) = ∑ y ∈ Y ∑ x ∈ X p ( x , y ) l o g ( p ( x , y ) p ( x ) p ( y ) ) = D K L ( p ( x , y ) ∣ ∣ p ( x ) p ( y ) ) I(X:Y)=\sum_{y\in Y}\sum_{x\in X}p(x,y)log(\frac {p(x,y)}{p(x)p(y)})=D_{KL}(p(x,y)||p(x)p(y)) I(X:Y)=yYxXp(x,y)log(p(x)p(y)p(x,y))=DKL(p(x,y)p(x)p(y))
如果 x x x y y y是相互独立的随机变量,则 p ( x , y ) = p ( x ) p ( y ) p(x,y)=p(x)p(y) p(x,y)=p(x)p(y),那么 I ( X : Y ) = 0 I(X:Y)=0 I(X:Y)=0.因此, I ( X : Y ) I(X:Y) I(X:Y)越大,则两变量相关性越高。

互信息法用法和F检验类似。

from sklearn.feature_selection import mutual_info_classif
嵌入法

嵌入法让算法自己决定使用哪些特征,特征选择和算法训练同时进行,先使用机器学习算法进行训练得到各特征的权值系数,根据权值系数从大到小选择特征。
嵌入法原理图

使用如下:

from sklearn.feature_selection import selectionFromModel
RFC = RFC(n_estimators = 10,random_state=10)
x_embeded = selectionFromModel(RFC,threshold = 0.05).fit(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_embeded = selectFromModel(RFC_,threshold=i).fit_transform(x,y)
  once = cross_val_score(RFC_,x_embeded,y,cv=5).mean()
  score.append(onece)
plt.plot(threshold,score)
plt.show()
包装法

包装法和嵌入法类似,只是包装法使用目标函数进行最佳特征选择。包装法原理图

使用如下:

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)
selector.support_.sum()//返回所有特征是否被选中的布尔矩阵。
selector.ranking_

学习曲线:

score = []
for i in range(1,751,50):
   x_warper = RFE(RFC_,n_feature_to_select = i, step = 50).fit_transform(x,y)
   onece = cross_val_score(RFC_,x_warper,y cv=5).mean()
   score.append(onece)
plt.figure(figsize = [20,5])
plt.plot(range(1,751,50),score)
plt.xticks(range(1,751,50))
plt.show()
总结

在机器学习中,数据是性能的天花板,其重要性远大于算法。特征工程可以使得数据更符合算法的处理需求,在一定程度上提高算法的性能。在特征工程中可以按照缩放、缺失值处理、方差过滤等一系列检验再应用嵌入法包装法的步骤。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值