特征选择

特征工程:
1、特征提取 :从文字,图像等数据中提取信息作为特征
2、特征创造 :把现有特征进行组合,或仙湖计算,得到新的特征
3、特征选择 :从所有的特征种,选择出有意义的,对模型有帮助的特征,避免所有特征都导图模型取训练的情况。在特征选择之前,跟数据提供者开会。

下面案例所用到的数据获取地址——>这里下载

1.过滤法

首先导入数据

import pandas as pd
data = pd.read_csv("../数据/digit recognizor.csv")
data.head()

这个数据亮较大,如果使用支持向量机和神经网络,可能会直接跑不出来,使用KNN跑一次大概需要半个小时,用这个数据更能体现特征工程的重要性。

过滤法:

全部特征—> 最佳特征子集->算法->模型评估

方差过滤

无论接下来的特征工程要做什么,都要优先消除方差为0的特征。

from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold()#实例化,默认方差为0
x_var0 = selector.fit_transform(x)
x_var0.shape#查看数据维度
pd.DataFrame(x_var0).head()#查看数据前五行

删除了方差为0的特征,但是还剩下708个特征,明显还需要进一步选择,可以设置方差阈值

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(0.8*(1-0.8)).fit_transform(x)
x_bvar.shape


差过滤对模块的影响

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)

**KNN 方差过滤前 **


35分钟才能运行完cross_val_score(KNN(),x,y,cv=5).mean()

4小时才能运行完
%%timeit   可以用来计算运行这个cell种代码所需的时间,一般是运行7次取平均值cross_val_score(KNN(),x,y,cv=5).mean()

方差过滤后

20分钟
cross_val_score(KNN(),x_fsvar,y,cv=5).mean()


%%timeit
cross_val_score(KNN(),x_fsvar,y,cv=5).mean()

可以看出,对于KNN,过滤后的效果十分明显:准确率稍微有提升
但是平均运行时间减少了10分钟,算法效率上升了1/3

随机森林: 方差过滤前

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

%%timeit
cross_val_score(RFC(n_estimators=10,random_state=0),x,y,cv=5).mean()


方差过滤后

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

%%timeit
cross_val_score(RFC(n_estimators=10,random_state=0),x_fsvar,y,cv=5).mean()

可以观察到,随机森林的准确率略逊于KNN,但运行时间连KNN的1%都不到,只需要十几秒,方差过滤后,随机森林的准确率也微弱上升,但是运行时间却几乎没有什么变化,依然是10秒左右。

所以过滤法:
主要对象是:需要遍历或升维的算法们
主要目的是:在维持算法表现的前提下,帮助算法们降低计算成本

方差过滤的影响:

阈值很小或被过滤掉的特征比较少:
模型表现:不会有太大影响,
运行时间:可能降低模型的运行时间,基于方差很小的特征有多少,当方差很小的特征不多时,对模型没有太大的影响

阈值比较大:
模型表现:可能变更好,代表被滤掉的特征大部分是噪音,也可能变糟糕,代表被滤掉的特征都是有效特征
运行时间:一定能降低模型的运行时间,算法在便利特征时的计算越复杂,运行时间下降的越多

选取超参数threshold
每个数据集都不一样,只能自己去尝试,在现实中我们会使用阈值为0或阈值很小的方差过滤,来为我们消除一些明显用不到的特征,然后我们会选择更优的特征选择方法继续消减特征数量。

卡方过滤(不能计算负数)

导入库

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

获得特征

x_fschi = SelectKBest(chi2,k = 300).fit_transform(x_fsvar,y)  #chi2以来的统计量,k=300为需要前300个特征
x_fschi.shape


查看模型效果

#查看模型效果
cross_val_score(RFC(n_estimators=10,random_state=0),x_fschi,y,cv=10).mean()#交叉验证


模型效果降低了说明删除了与模型有关的且有效的特征

使用学习曲线,获得合适的参数

%matplotlib inline
import matplotlib.pyplot as pltscore = []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(390,200,-10),score)
plt.show()

依照学习曲线选取效果好的那个数量值。

获得卡方值和P值
P值的影响

chivalue,pvalues_chi = chi2(x_fsvar,y)
chivalue#卡方值
pvalues_chi#P值

k取多少?我们想要消除所有P值大于设定值。

chivalue.shape[0] - (pvalues_chi > 0.05 ).sum()

可以看到方差验证已经把和标签无关的特征都删除了。

F 检验

from sklearn.feature_selection import f_classif
F, pvalues_f = f_classif(x_fsvar,y)
F.shape
pvalues_f.shape

我们希望选取p值小于0.05或0.01的特征,这些特征与标签显著相关的

K = F.shape[0] - (pvalues_f > 0.05).sum()


查看模型效果

x_fsF = SelectKBest(f_classif,k=300).fit_transform(x_fsvar,y)
cross_val_score(RFC(n_estimators=10,random_state=0),x_fsF,y,cv = 5).mean()


得到的结论和我们用卡方过滤得到的结论一摸一样:没有任何特征的P值大于0.01,所有的特征都是和标签相关的,因此我们不需要相关性过滤

互信息法

用来捕捉每个特征与标签之间的任意关系

from sklearn.feature_selection import mutual_info_classif as MIC
result = MIC(x_fsvar,y)
result


查看小于=0的个数

k = result.shape[0]-sum(result <= 0)
k

查看模型效果

x_fsmic = SelectKBest(MIC,k=300).fit_transform(x_fsvar,y)
cross_val_score(RFC(n_estimators = 10,random_state = 0),x_fsmic,y,cv = 5).mean()

所有特征的互信息量估计都大于0,因此所有特征都与标签相关

2.嵌入法 Embedded

导入库

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)
x_embedded.shape

模型的维度明显降低了。

查看最佳阈值,也可以画学习曲线

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


当阈值越来越大,模型的效果越来越低。可以选择前半段作为阈值。
从中挑选一个数值,验证一下模型的效果。

选取其中的值0.00067,查看模型效果

x_embedded = SelectFromModel(RFC_,threshold=0.00067).fit_transform(x,y)
cross_val_score(RFC_,x_embedded,y,cv=5).mean()


由于嵌入法比方差过滤更具体到模型的表现的缘故。
和其他调参一样,选定一个范围,使用细化的学习曲线来找到最佳的值。

进一步画学习曲线,找到更详细的值

score2 = []
for i in np.linspace(0,0.00134,20):x_embedded = SelectFromModel(RFC_,threshold=i).fit_transform(x,y)once = cross_val_score(RFC_,x_embedded,y,cv=5).mean()score2.append(once)plt.figure(figsize = [20,5])
plt.plot(np.linspace(0,0.00134,20),score2)
plt.xticks(np.linspace(0,0.00134,20))
plt.show()


查看模型效果

x_embedded = SelectFromModel(RFC_,threshold=0.000564).fit_transform(x,y)
cross_val_score(RFC_,x_embedded,y,cv=5).mean()


查看使用嵌入法后随机森林的模型效果

cross_val_score(RFC(n_estimators=100,random_state=0),x_embedded,y,cv=5).mean()

可以看到模型的效果达到了0.963,效果明显增加,但是运行的时间过于长。
所以数据量大的时候选择过滤法,因为嵌入法耗时长。

3.包装法

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)#50代表每迭代一次帮我删除50个特征
selector.support_.sum()#返回所有的特征是否被选中的布尔矩阵
selector.ranking_#返回特征的按数次迭代中综合重要性的排名

得到特征矩阵,算出模型效果

x_wrapper = selector.transform(x)#得到使用包装法的到的特征矩阵
cross_val_score(RFC_,x_wrapper,y,cv=5).mean()

对包装法画学习曲线
大概需要15分钟,很漫长。

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%以上。

小结

过滤法快速,但更粗糙。

包装法和嵌入法准确,比较适合具体到算法去调整,但计算量比较大,运行时间长。

当数据量很大的时候,优先考虑使用方差过滤和互信息法调整,再上其他特征选择方法。

使用逻辑回归时,优先使用嵌入法

使用支持向量机时,优先使用包装法

迷茫的时候,过滤法。看具体数据具体分析

------------------------------------------------------------------------------------------
python编码实战
安利一门Python超级好课!
扫码下单输优惠码【csdnfxzs】再减5元,比官网还便宜!

python机器学习之特征选择(过滤法、嵌入法、包装法案例详解)相关推荐

  1. python代码案例详解-我用Python抓取了7000 多本电子书案例详解

    安装 安装很简单,只要执行: pip install requests-html 就可以了. 分析页面结构 通过浏览器审查元素可以发现这个电子书网站是用 WordPress 搭建的,首页列表元素很简单 ...

  2. 特征选择(过滤法、包装法、嵌入法)

    文章目录 Filter过滤式方法 方差选择法 相关系数法 卡方检验 互信息法和最大信息系数Mutual information and maximal information coefficient ...

  3. R︱mlr包挑选最适机器学习模型+变量评估与选择(案例详解)

    一.R语言的mlr packages选择最适机器学习模型 install.packages("mlr")之后就可以看到R里面有哪些机器学习算法.在哪个包里面. a<-list ...

  4. python 面向对象的封装_Python面向对象封装操作案例详解

    本文实例讲述了Python面向对象封装操作.分享给大家供大家参考,具体如下: 目标 封装 小明爱跑步 存放家具 01. 封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 ―― 将 属性 和 ...

  5. 【地理建模】现代地理学中的数学方法:主成分分析法案例详解

  6. 代码检查规则:Python语言案例详解

    在之前的文章中代码检查规则:Java语言案例详解学习了Java的检查规则.我们今天将学习<代码检查规则:Python语言案例详解>,内容主要分为两个部分:Python的代码检查规则和Pyt ...

  7. python数据挖掘课程】二十一.朴素贝叶斯分类器详解及中文文本舆情分析

    #2018-04-06 13:52:30 April Friday the 14 week, the 096 day SZ SSMR python数据挖掘课程]二十一.朴素贝叶斯分类器详解及中文文本舆 ...

  8. python编程入门与案例详解-quot;Python小屋”免费资源汇总(截至2018年11月28日)...

    原标题:"Python小屋"免费资源汇总(截至2018年11月28日) 为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋"开通29 ...

  9. python数据挖掘笔记】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取

    #2018-04-06 07:57:00 April Friday the 14 week, the 096 day SZ SSMR python数据挖掘笔记]二十.KNN最近邻分类算法分析详解及平衡 ...

  10. python编程入门与案例详解-干货|| 清华大佬推荐的python400集入门资料

    �大家好!我又来了~之前我写了两篇笔记,分享了我是如何从一个0基础的小白自学python的❗️ - 今天再给大家分享一些学习python的干货❗️ - �首先, 在学python之前你要明确为什么要学 ...

最新文章

  1. 自动驾驶LiDAR点云深度学习综述
  2. 《剑指offer》旋转数组的最小数字
  3. c++十进制转二进制_二进制与十进制如何互相转换?
  4. table偏见和HTML仇外心理
  5. python笔记之单行json数据组成的json文件按行解析:read_json()
  6. 在建立与服务器的连接时出错。provider: TCP 提供程序, error: 0 - 由于目标机器积极拒绝,无法连接。)...
  7. 倡议书格式范文_倡议书写作格式及范文(共9篇)
  8. chromium thirt_party skia编译shared_liberary
  9. sap abap开发从入门到精通_云端的ABAP Restful服务开发
  10. 使用RDPWrapper实现多用户远程登录并限制IP
  11. BIOS开启了VT,但是CPU-V显示未开启
  12. python等额本息和等额本金_房贷利率有没有套路?这是我见过最透彻的Python版解读!...
  13. flutter 仿微信朋友圈发布图片
  14. 心力哲学——艰难多变环境下快乐、自由与生存力的源泉(二)
  15. 批量修改RTX腾讯通用户密码
  16. html5条件筛选jquery,jQuery实现多条件筛选
  17. 努力和勤奋是一对反义词
  18. 华硕打开桌面计算机没有反应,华硕window10电脑打开就这样,进不去桌面,怎么处理...
  19. IDL语法基础(01)
  20. es6通过Map对象对数组去重

热门文章

  1. 详解几个基本概念“标准差标准误差,方差均方差”
  2. JavaScript,实现这样的情景:阅读协议,阅读完毕后就可以点击同意复选框。
  3. 关于shp图层文件解析
  4. MATLAB运行程序后workspace是空的
  5. 在进行github相关操作的时候一直被要求Enter passphrase for key. 如何避免每次操作都重新填写一遍passphrase?
  6. SWUST OJ 492: The Dutch flag problem
  7. 计算机存储换算 2GB等于多少MB,一gb等于多少mb 1gb等于多少mb?存储单位的含义和换算【详解】...
  8. sqlmap之tamper绕过
  9. macos复制粘贴快捷键 快速_苹果MAC系统复制粘贴快捷键是什么?
  10. 提取整数的各个位数 (Separating the Digits in an Integer)