本文是对 https://scikit-learn.org/stable/modules/feature_selection.html 翻译加个人思考笔记。

1.13.1 移除低方差的特征

VarianceThreshold是特征选择包中的一个方法。引用的方式是from sklearn.feature_selection import VarianceThreshold

它可以过滤掉不满足一定方差门槛值的特征。默认情况下,它会移除所有0方差的特征,0方差意味着什么呢?在所有样本中都是一样的值。

你看,特征选择首先从没有什么变动的值动手,这类值意义不大,所有特征都是一个值,那还指望学习器学到什么东西吗?不太现实。

比如说,假定我们有个数据集,取值都是布尔值,也即0或者1,我们想移除这些取值为0或者1占比80%以上的样本。布尔值的取值是伯努利速记分布,那么它的方差计算公式为:

Var[X]=p(1−p)Var[X] = p(1-p) Var[X]=p(1−p)

所以我们可以使用0.8 * (1-0.8)来做过滤的门槛值。

from sklearn.feature_selection import VarianceThresholdX = [[0,0,1],[0,1,0],[1,0,0],[0,1,1],[0,1,0],[0,1,1]]
sel = VarianceThreshold(threshold=(0.8*(1-0.8)))sel.fit_transform(X)# 输出
'''
array([[0, 1],[1, 0],[0, 0],[1, 1],[1, 0],[1, 1]])
'''

可以看到第一列被过滤没了,因为第一列6个值,5个0,0的占比大于80%,所以被过滤掉了。

注意到这种用法的逻辑,其次才是如何使用。知其然知其所以然,二者并重,但是认知有先后。

这应该是最简单的特征选择方法了:假设某特征的特征值只有0和1,并且在所有输入样本中,95%的实例的该特征取值都是1,那就可以认为这个特征作用不大。如果100%都是1,那这个特征就没意义了。当特征值都是离散型变量的时候这种方法才能用,如果是连续型变量,就需要将连续变量离散化之后才能用,而且实际当中,一般不太会有95%以上都取某个值的特征存在,所以这种方法虽然简单但是不太好用。可以把它作为特征选择的预处理,先去掉那些取值变化小的特征,然后再从接下来提到的的特征选择方法中选择合适的进行进一步的特征选择。 来自:https://www.cnblogs.com/hhh5460/p/5186226.html

1.13.2 单变量特征选择

单变量特征选择工作模式是基于单变量统计特征测试来选择出最优的特征集合。可以将这个步骤看作是学习器的预处理步骤。Scikit-Learn将特征选择作为实现了transform方法的对象暴露出来。

  • SelectKBest 只保留最高分数的K个特征
  • SelectPercentile 只保留用户指定的最高百分比分数的特征
  • 基于单变量统计测试来选择每个特征:
    • SelectFpr False positive rate
    • SelectFdr False discovery rate
    • SelectFwe Family wise error
  • GenericUnivariateSelect 可以以配置策略的形式执行单变量特征选择

比如我们可以执行卡方测试,以获得最好的两个特征。

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2 # 卡方检验
iris = load_iris()
X,y = iris.data, iris.targetX.shape # (150, 4)
# 基于卡方并选出两个最优特征
X_new = SelectKBest(chi2, k=2).fit_transform(X,y)
X_new.shape # (150, 2)

可以看出,选择完成后只留下2个特征。注意,在选择特征时fit_transform需要附上X和y,不像预处理阶段,只用给X即可fit,判定特征是否符合要求,是要知道特征 + 目标值才好判定的。

了解原理,再看代码的执行就很清晰。

这些对象会接收一个估分函数作为参数,这些估分函数会返回一个单变量分数和一个p值,对于SelectKBestSelectPercentile只需要单变量分数。

对于回归,需要的是:

  • f_regression, mutual_info_regression

对于分类则需要的是:

  • chi2, f_classif, mutual_info_classif

这些方法都是基于F检验(可以参考这篇文章:

https://blog.csdn.net/zijinmu69/article/details/80564566

来细致研究一下F检验和p值)来估计两个随机变量之间的线性依赖关系。另一方面说,互信息方法捕捉的是任意的统计依赖性,相关性。互信息I(X;Y)I(X;Y)I(X;Y)是在知道了YYY的值后XXX的不确定性的减少量。即:YYY的值透露了多少关于XXX的信息量。

但是互信息是非参数的,它们需要更多的样本来估计准确的值。

稀疏数据的特征选择

如果是处理稀疏数据,使用chi2, mutual_info_regression, mutual_info_classif不会将数据变得密集,即不会破坏数据本身的稀疏性。

单变量特征选择能够对每一个特征进行测试,衡量该特征和响应变量之间的关系,根据得分扔掉不好的特征。对于回归和分类问题可以采用卡方检验等方式对特征进行测试。这种方法比较简单,易于运行,易于理解,通常对于理解数据有较好的效果(但对特征优化、提高泛化能力来说不一定有效);这种方法有许多改进的版本、变种。来自:https://www.cnblogs.com/hhh5460/p/5186226.html

1.13.3 递归特征消除 RFE

RFE是通过学习器返回的coef_属性或者feature_importances_属性来判定每个特征的重要程度,然后从当前的特征集合中移除最不重要的特征,直到最后达到所需要的特征数量为止。
RFECV中的CV指代的是交叉验证,原始的RFE是通过两个属性判定,这里是通过交叉验证来寻找最优的特征数量。即,如果减少特征会降低性能,那么就不会移除任何特征。 来自:https://blog.csdn.net/fontthrone/article/details/79004874

给定一个外部学习器,它能够为特征指定权重,比如线性模型的变量系数参数,RFE可以通过递归选择最后相对更重要的特征。

首先,学习器会在初始的特征集合上训练,每个特征的重要性依据coef_属性或者feature_importances_属性判定。然后,最不重要的特征就会从当前的特征集合中减除。这个过程是递归执行,直到达到我们需要的特征数量为止。

而RFECV则是通过交叉验证,循环执行直到发现最优数量的特征为止。

具体案例:

# 以Pima数据为例,使用RFE
from pandas import read_csv
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)array = data.values
X = array[:, 0:8]
y = array[:, 8]
array.shape # (768, 9)
# 特征选定
model = LogisticRegression()
rfe = RFE(model, 3)
fit = rfe.fit(X,y)
print("特征个数:")
print(fit.n_features_)
print("被选定的特征:")
print(fit.support_)
print("特征排名:")
print(fit.ranking_)
'''
特征个数:
3
被选定的特征:
[ True False False False False  True  True False]
特征排名:
[1 2 3 5 6 1 1 4]
'''

在定义RFE实例时,我们手动指定选择的特征个数为3,且用逻辑斯蒂模型去选。support_属性得出的是个布尔数组,被选中的特征被标记为True,排名属性ranking_中,选到的属性值为1.

1.13.4 使用SelectFromModel进行特征选择

SelectFromModel是个元转换器,对于任何执行完拟合fit之后有coef_feature_importances_属性的学习器上使用。

如果特征对应的coef_feature_importances_值小于threshold参数,那么这个特征就会被认为不重要,就会被移除。除了特意指定threshold参数值以外,它们也是启发式的,我们可以指定字符串参数来寻找合适的阈值threshold。可用的选项有:

  • mean均值
  • median中位数

使用起来也很简单:0.1 * mean这种形式。

基于L1正则化的特征选择

线性模型带L1正则化项可以得到稀疏解,即很多估计参数都为0。

当我们的目标是对数据进行维度归约以用在其他分类器中时,可以用feature_selection.SelectFromModel来选择非零系数。稀疏学习器对完成这个目标是有利的,对于回归可以采用linear_model.Lasso,分类可以用linear_model.LogisticRegression以及svm.LinearSVC等。

from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel # 导入SelectFromModeliris = load_iris()
X,y = iris.data, iris.targetX.shape
# 输出
'''
(150, 4)
'''lsvc = LinearSVC(C=0.01, penalty='l1', dual=False).fit(X,y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape
# 输出
'''
(150, 3)
'''

使用SVM和逻辑斯蒂回归,参数C控制的是稀疏性:C越小则越少特征被选择。使用Lasso,alpha参数值越大,则越少特征被选择。

这部分还有两个案例可以研究:

Classification of text documents using sparse features

http://users.isr.ist.utl.pt/~aguiar/CS_notes.pdf

1.13.4.2 基于树的特征选择

基于树的学习器可以用来计算特征的重要性,反过来可以用来去除无关的特征(结合SelectFromModel)。

# 基于树的特征选择
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModeliris = load_iris()
X,y = iris.data, iris.targetX.shape
# 输出
'''
(150, 4)
'''clf = ExtraTreesClassifier(n_estimators=50)
clf.fit(X,y)
clf.feature_importances_
# 输出
'''
array([0.10069852, 0.05203702, 0.39963124, 0.44763322])
'''
model = SelectFromModel(clf, prefit=True)
X_new = model.transform(X)
X_new.shape
# 输出
'''
(150, 2)
'''

1.13.5 特征选择作为管道的一部分

特征选择通常作为实际学习之前数据预处理的关键步骤。在Scikit-Learn中的推荐使用方式是:sklearn.pipeline.Pipeline

# 管道
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifierclf = Pipeline([('feature_selection', SelectFromModel(LinearSVC(penalty='l1'))),('classification', RandomForestClassifier())
])clf.fit(X, y)

关于管道的使用,后面再专门针对 https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline写一篇文章,本篇到此为止。

END.

【机器学习】sklearn文档学习之特征选择相关推荐

  1. Spring文档学习

    Spring文档学习 参考Spring Framework Documentation学习 1. IoC 容器 1.1 容器实例化 <beans><import resource=& ...

  2. EasyUI文档学习心得

    概述 jQuery EasyUI 是一组基于jQuery 的UI 插件集合,它可以让开发者在几乎完全不需要CSS以及复杂的JS代码情况下完成美观且功能强大的Web界面. 本文主要说明一些如何利用Eas ...

  3. UHS-II文档学习

    #UHS-II文档学习 UHS-II 引脚分配 SD4.0与SD3.0相比多了底下一排引脚[10-17],UHS-II Mode使用的是三组差分信号分别为:D0.D1和RCLK差分信号.RCLK差分信 ...

  4. python文档学习

    文章目录 python文档学习 python解释器 传入参数 交互模式的提示符 帮助信息 基础知识 python保留字 注释 多行语句 缩进 python数据类型与运算符 变量与基本类型 数字类型 集 ...

  5. Django 4.0文档学习(一)

    本系列文章基于Django4.0版本官方网站文档学习 使用开发工具为pycharm > python -m django --version 4.0 文章目录 编写你的第一个 Django 应用 ...

  6. Spring Framework 5.3文档学习(一)

    Spring Framework 5.3文档学习(一) Overview 1.What We Mean by "Spring" 2. History of Spring and t ...

  7. sklearn文档 — 1.6. 最近邻

    sklearn.neighbors 提供了一些在无监督和有监督学习中基于近邻的学习方法.无监督近邻是许多其他学习方法的基石,特别是在流学习和光谱聚类方面.有监督的基于近邻的学习有两个方面:对带有离散标 ...

  8. 《Get Started with WebRTC》文档学习

    学习资料:https://www.html5rocks.com/en/tutorials/webrtc/basics/#toc-disruptive 学习计划:2021.05.09之前,计划时长为两天 ...

  9. 【ember zigbee】序章:协议栈相关文档学习笔记

    原文地址:https://blog.csdn.net/tainjau/article/details/90648114 文章目录 写在前面 一.材料出处 二.文档解析 2.1.EZSP Protoco ...

最新文章

  1. 查看mysql日志文件大小和数据库大小
  2. python元类、反射及双线方法
  3. Android 高级Drawable资源---复合Drawable----状态列表Drawable
  4. SpringBoot 配置环境属性
  5. 工作308:uni-设置请求参数
  6. Tomcat 改BUG之 localhost:8080 404
  7. python调用win32_python调用win32接口进行截图
  8. Myeclipse 操作技巧
  9. android studio升级到3.0之后布局视图_升级到AndroidStudio3.0 之后的遇到问题的处理(新建、方法数限制等)...
  10. 无连续整数的子集数问题
  11. linux常用命令之压缩打包
  12. 虚拟目录下apache点击报The requested URL* was not found on this server.
  13. 解析极限编程--Kent Beck, Cynthia Andres读后感
  14. python中int占几个字节_小白学python第1问: int 占几个字节?
  15. MariaDB的延迟开源模式及其BSL许可证介绍(一)
  16. 音频直播,这里面到底有多少坑
  17. 浩辰3D软件新手入门攻略:草图绘制功能全解析!
  18. Unirech:阿里云国际云服务器ecs建站流程
  19. 闽高校计算机等级考试试题,闽高校计算机等级考试信息技术选择题含答案确定书中页码版...
  20. 【以史为鉴】《饱食穷民》读后感

热门文章

  1. 数据结构笔记(十八)-- 树的定义和基本术语
  2. Linux文件内容查阅
  3. android 字体淡入淡出,如何让文字在Android中淡入淡出?
  4. rocketmq 顺序消费_RocketMQ核心概念扫盲
  5. 计算机硬盘哪里找到相关信息,获取计算机的信息(IP地址、MAC地址、CUP序列号、硬盘序列号、主板信息等等)...
  6. 计算机课程设计评分表,课程设计的评分标准.doc
  7. python的ide怎么安装_python安装以及IDE的配置教程
  8. java 异常处理发生异常_Java中的异常处理
  9. scala运算符_Scala运算符–算术,关系,逻辑,按位,赋值
  10. Python写数据结构:二叉树的创建和遍历