数据处理和特征工程(二)

4. 特征选择

一般有四种方法用来选择特征:过滤法、嵌入法、包装法、降维算法

4.1 Filter过滤法**

根据统计检验的分数和相关性指标来选择特征,完全独立于各种机器学习算法

4.1.1 方差过滤VarianceThreshold

通过特征本身的方差来筛选类,如果一个特征的方差很小,说明样本在这个特征上基本没有差异,可能大多数值都一样。
VarianceThreshold有重要参数Threshold,表示舍弃所有方差小于threshold的特征,不填默认为0,删除所有记录相同的特征。
过滤法的主要对象是:需要遍历特征或者升维的算法,而过滤法的主要目的是,在维持算法表现得前提下,帮助算法们降低计算成本
现实中,我们只会使用阈值为0或者阈值很小得方差过滤,消除一些明显用不到得特征,然后会选择更优得特征选择方法继续削减特征数量

4.1.2 代码示例

from sklearn.feature_selection import VarianceThreshold
import numpy as np

x_var0 = VarianceThreshold.fit_transform(x)
x_fsvar = VarianceThreshold().fit_trainsform(x)
x_fsvar.shape

4.2 相关性过滤【卡方过滤】

4.2.1 相关性过滤

卡方过滤是专门针对离散型标签得过滤方法。计算每个非负特征和标签之间得卡方统计,并依照卡方统计量由高到低为特征排名,再依据排名选出前k个分数最高得特征得类
如果卡方检验检测到某个特征中所有值都相同,会提示我们先进行方差过滤

4.2.2 代码示例

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  # 卡方检验统计量

# 假设我们需要选出前200个分数最高得特征
# x_fvar为使用方差过滤后的x特征矩阵
x_fschi = SelectKBest(chi2,k=200).fit_transform(x_fvar,y)
x_fschi

这里得k如果使模型得效果降低了,就说明k值设得太小了,我们需要重新调整k值,或者放弃卡方过滤。 卡方检验得本质是推测两组数据之间得差异,其检验得原假设是“两组数据是相互独立得”,卡方检验返回卡方值和P值,其中卡方值很难界定有效得范围,而P值,我们一般使用0.01或0.05作为显著性水平,就是p值得判断边界。当p<0.05或0.01时,两组数据是相关得,反之,两组数据相互独立

chivalue,pvalues_chi = chi2(x_fvar,y)  # 结果返回卡方值和p值

# 我们想要消除所有p值大于设定值得特征
k = chivalue.shape[0] - (pvalues_chi > 0.05).sum()

4.3 F检验过滤

F检验过滤是通过捕捉每个特征与标签之间的线性关系的过滤方法,F检验既可以做回归也可以做分类。

  • feature_selection.f_classif F检验分类
  • feature_selection.f_regression F检验回归

F检验在数据服从正态分布时效果会比较稳定,因此需要先将数据转换成服从正态分布的方式
和卡方过滤一样,我们希望选取p值小于0.05或0.01的特征,这些特征与标签是显著线性相关的,p>0.05或者0.01的特征则被我们认为没有线性相关关系,应该被删除

from sklearn.feature_selection import f_classif

# 返回F值和P值
F,pvalues_f = f_classif(x_fsvar,y)
k = F.shape[0] - (pvalues_f > 0.05).sum()

4.4 互信息法

互信息法是用来捕捉每个特征与标签之间的任意关系(线性和非线性)的过滤方法,既可以做回归,也可以做分类

  • feature_selection.mutual_info_classif
  • feature_selection.mutual_info_regression
from sklearn.feature_selection import mutual_info_classif as MIC

result = MIC(x_fsvar,y)
k = result.shape[0] - sum(result <= 0)

4.5 嵌入法**

让算法自己决定使用哪些特征的方法,即特征选择和算法训练同时进行。
用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据权值系数从大到小选择特征。比如决策树返回的feature_importances。
嵌入法的计算速度和计算量会基于所选择的算法
在sklearn中使用SelectFromModel来完成嵌入法的使用,其含有estimator和threshold两个参数

  • estimator : 使用的模型评估器
  • threshold :特征重要性的阈值,重要性低于这个阈值的特征都将被删除
# 使用随机森林作为示例
from sklearn.feature_selection import SelectFromModel   # 导入SelectFromModel
from sklearn.ensemble import RandomForestClassifier as RFC
import numpy as np
import matplotlib.pyplot as plt

RFC_ = RFC(n_estimators=10,random_state=0)  # 随机森林的实例化
x_embedded = SelectFromModel(RFC_,threshold=0.005).fit_transform(x,y)   
x_embedded.shape

# 使用学习曲线来考察最佳阈值
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 = SelectFormModel(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.6 包装法

与嵌入法十分相似,也是特征选择和算法训练同时进行的方法。它会帮我们选择一个目标函数来选取特征【不用我们自己选择】 包装法每次递归都会删除一些特征,因此计算成本要低于嵌入法
在sklearn中实现包装法使用RFE

  • n_features_to_select:想要选择的特征个数
  • .support_:返回所有特征中的布尔矩阵【查看被选中和没有被选中的特征】
  • .ranking_: 返回特征的按数次迭代中综合重要性的排名
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)  # 选择340个特征

selector.support_.sum()  # 返回所有特征中的布尔矩阵【查看被选中和没有被选中的特征】
selector.ranking_        # 返回特征的按数次迭代中综合重要性的排名
x_wrapper = selector.transform(x)

# 使用学习曲线选择最好的n_features_to_select
score = []
for i in range(1,751,50):
   x_wrapper = RFE(RFC_,n_features_to_select=i,step=50).fit(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()
  • 数据量很大时,优先使用方差法过滤和互信息法调整,再上其他特征选择方法
  • 使用逻辑回归时,优先使用嵌入法
  • 使用支持向量机时,优先使用包装法

5. 降维算法PCA

算法中的降维指的是降低特征的数目,降维的目的是为了让算法运算更快,效果更好

5.1 主成分分析PCA

在降维中,PCA使用的信息衡量指标就是样本方差,又称可解释性方差,方差越大,特征所带的信息越多,让数据能够压缩到少数特征上并且总信息量不损失太多的技术就是矩阵分解,PCA找到的每个新特征向量就叫做“主成分”,而被丢弃的特征向量很有可能就是噪音

PCA和特征选择的区别?
特征选择是从已存在的特征中选取携带信息最多的,选完之后的特征依然具有可解释性。而PCA是对已存在的特征进行压缩,降维完毕后的特征不是原本特征的任何一个。新特征矩阵不具有可解释性。因此PCA一般不适用于探索特征和标签之间关系的模型【线性回归】,在线性回归中使用特征选择

5.1.1 PCA基本参数

  • n_components:降维后的维度。只是需要人为设定的超参数,并且设定的数字会影响模型的表现,n_componnents需要设定一个合理的值,不能太大也不能太小
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import numpy as np

# 导入数据
iris = load_iris()
x = iris.data
y = iris.target

pca = PCA(n_components=2)  # 降到2维
x_ = pca.fit_transform(x)
x_  # 降维后的特征矩阵

# explained_variance_ 查看降维后每个新特征向量上所带的信息量大小【可解释性反差的大小】
pca.explained_variance_

# explained_variance_ratio_ 查看降维后每个新特征所占的信息占原始数据总信息的百分比【可解释性方差贡献率】
pca.explained_variance_ratio_
pca.explained_variance_ratio_.sum()

# 可视化
pca_line = PCA().fit(x)
plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks([1,2,3,4])
plt.xlabel('number of components after dimension reduction')
plt.ylabel('cumulative explained variance')
plt.show()
  • n_components:按信息量占比选参数,输入[0,1]之间的浮点数,让参数svd_solver=='full',表示希望降维后的总解释性方差占比大于指定的百分比。比如,输入n_components = .97,PCA会自动选出能够保留的信息超过97%的特征数量
pca_f = PCA(n_components=.99,svd_solver='full')
pca_f = pca_f.fit(x)

5.1.2 PCA中的SVD

SVD是奇异值分解器的意思
SVD有一种非常简便的计算过程,不计算协方差矩阵,直接找到新特征向量组成的n维空间。简单来说,SVD在矩阵分解的过程中比PCA简单快速。SVD中衡量特征的指标是奇异值。在PCA中,使用SVD的性值来减少计算量,并让信息的评估指标是方差
重要参数

  • svd_solver:用来控制矩阵分解的一些细节的参数,有四种模式可以选择'auto','full','arpack','randomized',默认值是auto
    • auto:基于x.shape和n_components的默认策略来选择分解器。如果数据维度太高,则会选择效率更高的randomized,如果数据维度适中,则会使用full
    • full:会生成完整的SVD,适合数据量适中且计算时间充足的情况
    • arpack:可以加快运算速度,适合特征矩阵很大的时候,但一般用于特征矩阵为稀疏矩阵的情况
    • randomized:适合特征矩阵巨大,计算量庞大的情况
  • random_state:random_state 在参数svd_solver 为randomized或arpark时生效,选“auto”即可
pca_f = PCA(n_components=.99,svd_solver='full')
pca_f = pca_f.fit(x)
pca_f.explained_variance_ratio_.sum()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容