一文介绍机器学习中的三种特征选择方法

2023-11-02

38fe8ec65892c3e6d2267810bff47d47.gif

作者 | luanhz

来源 | 小数志

导读

机器学习中的一个经典理论是:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限。也正因如此,特征工程在机器学习流程中占有着重要地位。广义的特征工程一般可分为三个环节:特征提取、特征选择、特征衍生,三个环节并无明确的先手顺序之分。本文主要介绍三种常用的特征选择方法。

ed62d0b62155f49ddf087f9da48a9b69.png

机器学习中的特征需要选择,人生又何尝不是如此?

特征选择是指从众多可用的特征中选择一个子集的过程,其目的和预期效果一般有如下三方面考虑:

  • 改善模型效果,主要是通过过滤无效特征或者噪声特征来实现;

  • 加速模型训练,更为精简的特征空间自然可以实现模型训练速度的提升

  • 增强特征可解释性,这方面的作用一般不是特别明显,比如存在共线性较高的一组特征时,通过合理的特征选择可仅保留高效特征,从而提升模型的可解释性

另一方面,理解特征选择方法的不同,首先需要按照特征对训练任务的价值高低而对特征作出如下分类:

  • 高价值特征,这些特征对于模型训练非常有帮助,特征选择的目的就是尽可能精准的保留这些特征

  • 低价值特征,这些特征对模型训练帮助不大,但也属于正相关特征,在特征选择比例较低时,这些特征可以被舍弃;

  • 高相关性特征,这些特征对模型训练也非常有帮助,但特征与特征之间往往相关性较高,换言之一组特征可由另一组特征替代,所以是存在冗余的特征,在特征选择中应当将其过滤掉;

  • 噪声特征,这些特征对模型训练不但没有正向作用,反而会干扰模型的训练效果。有效的特征选择方法应当优先将其滤除。

在实际应用中,特征选择方法主要可分为如下三类:

c499634e779c7c80923289f612063d33.png

本文将围绕这三种方法分别介绍,最后以sklearn中自带的数据集为例给出简单的应用和效果对比。

01 过滤法

基于过滤法(Filter)实现特征选择是最为简单和常用的一种方法,其最大优势是不依赖于模型,仅从特征的角度来挖掘其价值高低,从而实现特征排序及选择。实际上,基于过滤法的特征选择方案,其核心在于对特征进行排序——按照特征价值高低排序后,即可实现任意比例/数量的特征选择或剔除。显然,如何评估特征的价值高低从而实现排序是这里的关键环节。

为了评估特征的价值高低,大体可分为如下3类评估标准:

  • 基于特征所含信息量的高低:这种一般就是特征基于方差法实现的特征选择,即认为方差越大对于标签的可区分性越高;否则,即低方差的特征认为其具有较低的区分度,极端情况下当一列特征所有取值均相同时,方差为0,对于模型训练也不具有任何价值。当然,实际上这里倘若直接以方差大小来度量特征所含信息量是不严谨的,例如对于[100, 110, 120]和[1, 5, 9]两组特征来说,按照方差计算公式前者更大,但从机器学习的角度来看后者可能更具有区分度。所以,在使用方差法进行特征选择前一般需要对特征做归一化

  • 基于相关性:一般是基于统计学理论,逐一计算各列与标签列的相关性系数,当某列特征与标签相关性较高时认为其对于模型训练价值更大。而度量两列数据相关性的指标则有很多,典型的包括欧式距离、卡方检验、T检验等等

  • 基于信息熵理论:与源于统计学的相关性方法类似,也可从信息论的角度来度量一列特征与标签列的相关程度,典型的方法就是计算特征列与标签列的互信息。当互信息越大时,意味着提供该列特征时对标签的信息确定程度越高。这与决策树中的分裂准则思想其实是有异曲同工之妙

当然,基于过滤法的特征选择方法其弊端也极为明显:

  • 因为不依赖于模型,所以无法有针对性的挖掘出适应模型的最佳特征体系;

  • 特征排序以及选择是独立进行(此处的独立是指特征与特征之间的独立,不包含特征与标签间的相关性计算等),对于某些特征单独使用价值低、组合使用价值高的特征无法有效发掘和保留。

02 包裹法

过滤法是从特征重要性高低的角度来加以排序,从而完成目标特征选择或者低效特征滤除的过程。如前所述,其最大的弊端之一在于因为不依赖任何模型,所以无法针对性的选择出相应模型最适合的特征体系。同时,其还存在一个隐藏的问题:即特征选择保留比例多少的问题,实际上这往往是一个超参数,一般需要人为定义或者进行超参寻优。

与之不同,包裹法将特征选择看做是一个黑盒问题:即仅需指定目标函数(这个目标函数一般就是特定模型下的评估指标),通过一定方法实现这个目标函数最大化,而不关心其内部实现的问题。进一步地,从具体实现的角度来看,给定一个含有N个特征的特征选择问题,可将其抽象为从中选择最优的K个特征子集从而实现目标函数取值最优。易见,这里的K可能是从1到N之间的任意数值,所以该问题的搜索复杂度是指数次幂:O(2^N)。

当然,对于这样一个具有如此高复杂度的算法,聪明的前辈们是不可能去直接暴力尝试的,尤其是考虑这个目标函数往往还是足够expensive的(即模型在特定的特征子集上的评估过程一般是较为耗时的过程),所以具体的实现方式一般有如下两种:

  • 序贯选择。美其名曰序贯选择,其实就是贪心算法。即将含有K个特征的最优子空间搜索问题简化为从1->K的递归式选择(Sequential Feature Selection, SFS)或者从N->K的递归式消除(Sequential Backward Selection, SBS)的过程,其中前者又称为前向选择,后者相应的称作后向选择。

    具体而言,以递归式选择为例,初始状态时特征子空间为空,尝试逐一选择每个特征加入到特征子空间中,计算相应的目标函数取值,执行这一过程N次,得到当前最优的第1个特征;如此递归,不断选择得到第2个,第3个,直至完成预期的特征数目K。这一过程的目标函数执行次数为O(K^2),相较于指数次幂的算法复杂度而言已经可以接受。当然,在实际应用过程中还衍生了很多改进算法,例如下面流程图所示:

4eacf5671982308e169014e11d1968b7.png

图源:《A survey on feature selection methods》

  • 启发式搜索。启发式搜索一般是应用了进化算法,例如在优化领域广泛使用的遗传算法。在具体实现中,需要考虑将特征子空间如何表达为种群中的一个个体(例如将含有N个特征的选择问题表达为长度为N的0/1序列,其中1表示选择该特征,0表示不选择,序列中1的个数即为特征子空间中的特征数量),进而可将模型在相应特征子空间的效果定义为对应个体在种群中的适应度;其次就是定义遗传算法中的主要操作:交叉、变异以及繁殖等进化过程。

基于包裹法的特征选择方案是面向模型的实现方案,所以理论而言具有最佳的选择效果。但实际上在上述实现过程中,其实一般也需要预先指定期望保留的特征数量,所以也就涉及到超参的问题。此外,基于包裹法的最大缺陷在于巨大的计算量,虽然序贯选择的实现方案将算法复杂度降低为平方阶,但仍然是一个很大的数字;而以遗传算法和粒子群算法为代表的启发式搜索方案,由于其均是population-based的优化实现,自然也更是涉及大量计算。

03 嵌入法

与包裹法依赖于模型进行选择的思想相似,而又与之涉及巨大的计算量不同:基于嵌入法的特征选择方案,顾名思义,是将特征选择的过程"附着"于一个模型训练任务本身,从而依赖特定算法模型完成特征选择的过程。

个人一直以为,"嵌入"(embedded)一词在机器学习领域是一个很魔性的存在,甚至在刚接触特征选择方法之初,一度将嵌入法和包裹法混淆而不能感性理解。

实际上,行文至此,基于嵌入法的特征选择方案也就呼之欲出了,最为常用的就是树模型和以树模型为基础的系列集成算法,由于模型提供了特征重要性这个重要信息,所以其可天然的实现模型价值的高低,从而根据特征重要性的高低完成特征选择或滤除的过程。另外,除了决策树系列模型外,LR和SVM等广义线性模型也可通过拟合权重系数来评估特征的重要程度。

基于嵌入法的特征选择方案简洁高效,一般被视作是集成了过滤法和包裹法两种方案的优点:既具有包裹法中面向模型特征选择的优势,又具有过滤法的低开销和速度快。但实际上,其也具有相应的短板:不能识别高相关性特征,例如特征A和特征B都具有较高的特征重要性系数,但同时二者相关性较高,甚至说特征A=特征B,此时基于嵌入法的特征选择方案是无能为力的。

04 三种特征选择方案实战对比

本小节以sklearn中的乳腺癌数据集为例,给出三种特征选择方案的基本实现,并简单对比特征选择结果。

加载数据集并引入必备包:

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectFromModel, SelectKBest, RFE
from sklearn.ensemble import RandomForestClassifier

默认数据集训练模型,通过在train_test_split中设置随机数种子确保后续切分一致:

%%time
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=3)


rf = RandomForestClassifier(max_depth=5, random_state=3)
rf.fit(X_train, y_train)
rf.score(X_test, y_test)


# 输出结果
CPU times: user 237 ms, sys: 17.5 ms, total: 254 ms
Wall time: 238 ms
0.9370629370629371

过滤法的特征选择方案,调用sklearn中的SelectKBest实现,内部默认采用F检验来度量特征与标签间相关性,选择特征维度设置为20个:

%%time
X_skb = SelectKBest(k=20).fit_transform(X, y)
X_skb_train, X_skb_test, y_train, y_test = train_test_split(X_skb, y, random_state=3)


rf = RandomForestClassifier(max_depth=5, random_state=3)
rf.fit(X_skb_train, y_train)
rf.score(X_skb_test, y_test)


# 输出结果
CPU times: user 204 ms, sys: 7.14 ms, total: 211 ms
Wall time: 208 ms
0.9300699300699301

包裹法的特征选择方案,调用sklearn中的RFE实现,传入的目标函数也就是算法模型为随机森林,特征选择维度也设置为20个:

%%time
X_rfe = RFE(RandomForestClassifier(), n_features_to_select=20).fit_transform(X, y)
X_rfe_train, X_rfe_test, y_train, y_test = train_test_split(X_rfe, y, random_state=3)


rf = RandomForestClassifier(max_depth=5, random_state=3)
rf.fit(X_rfe_train, y_train)
rf.score(X_rfe_test, y_test)


# 输出结果
CPU times: user 2.76 s, sys: 4.57 ms, total: 2.76 s
Wall time: 2.76 s
0.9370629370629371

嵌入法的特征选择方案,调用sklearn中的SelectFromModel实现,依赖的算法模型也设置为随机森林,特征选择维度仍然是20个:

%%time
X_sfm = SelectFromModel(RandomForestClassifier(), threshold=-1, max_features=20).fit_transform(X, y)
X_sfm_train, X_sfm_test, y_train, y_test = train_test_split(X_sfm, y, random_state=3)


rf = RandomForestClassifier(max_depth=5, random_state=3)
rf.fit(X_sfm_train, y_train)
rf.score(X_sfm_test, y_test)


# 输出结果
CPU times: user 455 ms, sys: 0 ns, total: 455 ms
Wall time: 453 ms
0.9370629370629371

通过以上简单的对比实验可以发现:相较于原始全量特征的方案,在仅保留20维特征的情况下,过滤法带来了一定的算法性能损失,而包裹法和嵌入法则保持了相同的模型效果,但嵌入法的耗时明显更短

137578eb60725250e2d0001b9ca62b95.gif

资讯

Meta开发AI语音助手,助力元宇宙

技术

Pandas重复数据处理大全

技术

5个短小精悍的Python趣味脚本

资讯

M2芯片终于要来了?全线换新

c74552540639bf080fa5622ada65295f.png

分享

f507ad412023637754ab253c90358005.png

点收藏

e402fc40af35afaf4e417793170b2c1a.png

点点赞

d5f9469536a0e472b7db8ea553db1a53.png

点在看

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一文介绍机器学习中的三种特征选择方法 的相关文章

  • xlrd.biffh.XLRDError:Excel xlsx 文件;不支持[重复]

    这个问题在这里已经有答案了 我正在尝试使用读取启用宏的 Excel 工作表pandas read excel与 xlrd 库 它在本地运行良好 但是当我尝试将其推送到 PCF 时 我收到此错误 2020 12 11T21 09 53 441
  • 切片稀疏(scipy)矩阵

    我将不胜感激任何帮助 以理解从 scipy sparse 包中切片 lil matrix A 时的以下行为 实际上 我想根据行和列的任意索引列表提取子矩阵 当我使用这两行代码时 x1 A list 1 x2 x1 list 2 一切都很好
  • Kivy - 文本换行工作错误

    我正在尝试在 Kivy 1 8 0 应用程序中换行文本 当没有太多文字时 一切正常 但如果文本很长并且窗口不是很大 它只是剪切文本 这是示例代码 vbox BoxLayout orientation vertical size hint y
  • 更新 Sqlalchemy 中的多个列

    我有一个在 Flask 上运行的应用程序 并使用 sqlalchemy 与数据库交互 我想用用户指定的值更新表的列 我正在使用的查询是 def update table value1 value2 value3 query update T
  • 根据开始列和结束列扩展数据框(速度)

    我有一个pandas DataFrame含有start and end列 加上几个附加列 我想将此数据框扩展为一个时间序列 从start值并结束于end值 但复制我的其他专栏 到目前为止 我想出了以下内容 import pandas as
  • numpy 使用 datetime64 进行数字化

    我似乎无法让 numpy digitize 与 datetime64 一起使用 date bins np array np datetime64 datetime datetime 2014 n 1 s for n in range 1 1
  • 动态 __init_subclass__ 方法的参数绑定

    我正在尝试让类装饰器工作 装饰器会添加一个 init subclass 方法到它所应用的类 但是 当该方法动态添加到类中时 第一个参数不会绑定到子类对象 为什么会发生这种情况 举个例子 这是可行的 下面的静态代码是我试图最终得到的示例 cl
  • 与 while 循环一样,如何跳过 for 循环中的步骤?

    我尝试像 while 循环一样跳过 for 循环中的几个步骤 在 while 循环中 步骤根据特定条件进行调整 如下面的代码所示 i 0 while i lt 10 if i 3 i 5 else print i i i 1 result
  • 如何使用 paramiko 查看(日志)文件传输进度?

    我正在使用 Paramiko 的 SFTPClient 在主机之间传输文件 我希望我的脚本打印文件传输进度 类似于使用 scp 看到的输出 scp my file user host user host password my file 1
  • 具有屏蔽无效值的 pcolormesh

    我试图将一维数组绘制为 pcolormesh 因此颜色沿 x 轴变化 但每个 x 的 y 轴保持不变 但我的数据有一些错误值 因此我使用屏蔽数组和自定义颜色图 其中屏蔽值设置为蓝色 import numpy as np import mat
  • 由于 json 字符串化 dict 键导致数据丢失

    考虑下面的例子 gt gt gt import json gt gt gt d 0 potato 0 spud gt gt gt json dumps d 0 potato 0 spud gt gt gt json loads json d
  • Python 声音(“铃声”)

    我想让一个 python 程序在完成任务时通过发出嘟嘟声来提醒我 目前 我使用import os然后使用命令行语音程序说 进程完成 我更愿意它是一个简单的 铃 我知道有一个函数可以用于Cocoa apps NSBeep 但我认为这与此没有太
  • Python]将两个文本文件合并为一个(逐行)[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我是蟒蛇新手 我想做的是将文件 a 和文件 b 逐行合并到一个文件中 例如 text file a a n b n c text fi
  • 无法在 python 3.8 上将带有 webapp 的 python 部署到 azure

    我正在尝试使用部署一个测试项目Flask使用以下方法将框架迁移到 Azure 云中Azure CLI https learn microsoft com en us azure app service containers quicksta
  • 如何使用 Keras ImageDataGenerator 预测单个图像?

    我已经训练 CNN 对图像进行 3 类分类 在训练模型时 我使用 keras 的 ImageDataGenerator 类对图像应用预处理功能并重新缩放它 现在我的网络在测试集上训练得非常准确 但我不知道如何在单图像预测上应用预处理功能 如
  • 处理大文件的最快方法?

    我有多个 3 GB 制表符分隔文件 每个文件中有 2000 万行 所有行都必须独立处理 任何两行之间没有关系 我的问题是 什么会更快 逐行阅读 with open as infile for line in infile 将文件分块读入内存
  • 如何使用 matplotlib 为圆柱体的每个单独面添加颜色

    我正在尝试为圆柱体的每个面着色 但是我不确定如何进行 我尝试了以下方法 for i in range 10 col append for i in range 10 for j in range 20 col i append plt cm
  • Django 模型:如何使用 mixin 类来覆盖 django 模型以实现 save 等功能

    我想在每次保存模型之前验证值 所以 我必须重写保存函数 代码几乎是一样的 我想把它写在 mixin 类中 但失败了 我不知道如何写 super func 我英语不好 抱歉 class SyncableMixin object def sav
  • 如何为所有用户安装 Anaconda python?

    Anaconda python 发行版 https store continuum io cshop anaconda 非常方便地部署科学计算环境 SCE 并根据需要切换python版本 默认情况下 安装会将 python 定位到 anac
  • 缓存 Flask-登录 user_loader

    我有这个 login manager user loader def load user id None return User query get id 在我引入 Flask Principal 之前它运行得很好 identity loa

随机推荐

  • 专利与论文-1:为什么要写专利?专利有什么好处?

    前言 很多人 都认为写专利没什么多大的用处 不过是个人赚一点公司申请专利的奖励而已 对个人和公司 用处都不是大 还不如做学习一些专业技能或做一些实际项目 花在专利上的实际不太值得 随着时间和知识双重积累 越来越会发现专利 无论对于个人还公司
  • 强化学习代码实战入门

    这是一个易理解的 demo 300行左右 可以作为RL的入门代码 辅助基础公式的理解 这个是我自己的学习笔记 三连留下邮箱 可以直接发送完整的代码标注文件 如有错误 麻烦指出 我已经蛮久没写博了 上一篇RL博客也快一年半了 很久没做这一块了
  • Java生成二维码并解决中文乱码问题

    Java生成二维码并解决中文乱码问题 引入依赖 JAVA代码 引入依赖 maven工程
  • ESP32+st7789/ili9341运行LVGL例程,依赖ESP-IDF编译lv_port_esp32官方Demo(1)

    LVGL是一个C语言编写的免费的开源图形库 其提供了用于嵌入式GUI的各种元素 用户可以利用丰富的图形库资源 在消耗极低内存的情况下构建视觉效果丰富多彩的GUI 只需 64kB 闪存和 8kB RAM 就足以满足简单的用户界面 LVGL 可
  • 【ObjectARX】--创建和访问图形数据库(DwgDatabase)

    1 使用ObjectARX创建新工程DwgDatabase 选择MFC支持 2 注册一个命令CreateDwg创建一个新的图形文件 并保存在AutoCAD的安装路径中 实现函数为 static void AAAMyGroupCreateDw
  • Java链式编程与Builder(建造者)设计模式

    一 链式编程 1 1 释义 链式编程 也叫级联式编程 调用对象的函数时返回一个this对象指向对象本身 达到链式效果 可以级联调用 1 2 特点 可以通过一个方法调用多个方法 将多个方法调用链接起来 形成一条 链式 从而提高代码的可读性 1
  • ASP.NET Web Pages基础知识---Razor 实例:显示图片

    假设在您的图像文件夹中有 3 张图像 您想根据用户的选择动态地显示图像 这可以通过一段简单的 Razor 代码来实现 如果在您的网站的图像文件夹中有一个名为 Photo1 jpg 的图像 您可以使用 HTML 的 img 元素来显示图像 如
  • 用于机器学习的 NumPy(ML)

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 031.PyQt5_QCommandLinkButton_命令链接按钮

    QCommandLinkButton命令链接按钮 描述 命令链接是Windows Vista引入的新控件 它的用途类似于单选按钮的用途 因为它用于在一组互斥选项之间进行选择 命令链接按钮不应单独使用 而应作为向导和对话框中单选按钮的替代选项
  • 【pytorch】微调技术

    前言 训练神经网络是一件非常耗费时间的事情 其需要大量的算力以及大量的数据 显然从头开始训练并不是明智之选 利用好已有的资源才是明智之选 微调技术 图像识别笼统地可以分为两步 提取图片的特征 此部分往往通过CNN卷积神经网络实现 根据提取的
  • Qt5学习笔记3:Qt的ui界面文件与程序源代码的生成关系及访问

    首先 按照前面章节的方法 创建一个工程demo 位于目录demo 下 然后直接编译运行 弹出一个空窗口 如下 工程项目在Qt creator的管理界面显示如下 在工程目录demo 下 生成了两个文件夹 build xxx Debug和dem
  • 5.网络爬虫——Xpath解析

    网络爬虫 Xpath解析 Xpath简介 Xpath解析 节点选择 路径表达式 谓语 未知节点 Xpath实战演示 豆果美食实战 获取数据 源代码 前言 此专栏文章是专门针对Python零基础爬虫 欢迎免费订阅 第一篇文章获得全站热搜第一
  • TensorFlow学习笔记(二)Tensorflow+VScode和Jupyter NoteBook新姿势

    TensorFlow学习笔记 二 Tensorflow VScode和Jupyter NoteBook新姿势 过了一个星期了 自己弄环境弄了两天之后 装好环境整个人就开始懒散 不想写东西 但想到既然开始了 那就坚持写下去吧 上次用Anaco
  • chatgpt赋能python:Python主成分分析(PCA)结果解读

    Python主成分分析 PCA 结果解读 主成分分析 PCA 作为一种重要的多元统计方法 可以对多个变量进行降维处理 从而提取出相关性最高的主成分作为新的维度来进行数据分析和可视化 Python是一种流行的编程语言 它提供了许多快速和灵活的
  • mysql oracle 查看数据库中有哪些数据表, 数据表中有哪些字段

    文章目录 1 查看mysql中有都有哪些数据库 2 查看数据库中都有哪些数据表 2 1 for mysql 2 2 for oracle 3 查看数据表中都有哪些字段 3 1 mysql方法1 3 2mysql方法2 推荐 3 3 for
  • java如何定义一个变长数组_如何自定义一个长度可变数组

    摘要 本文主要写了如何自定义一个长度可变数组 数组是在程序设计中 为了处理方便 把具有相同类型的若干元素按无序的形式组织起来的一种形式 在定义之初 数组的长度就被定义 新建数组有很多方式 下面两个都可以 但一般书写习惯会选择第一种 1 St
  • window VNC连接linux Unable to connect to VNC Server

    gsettings set org gnome Vino require encryption false 若不生效 可以尝试重启服务器 本人重启后生效
  • python中if的基本用法(if,else,elif,and,or,if嵌套,跟电脑猜拳)

    用实例来演示 if 要判断的条件 条件成立的时候 要做的事 1 定义一个整数变量 age 12 2 判断是否满18岁 if age gt 18 print 欢迎来酒吧 print 成年后再来哦 但是当age 18时候 就会出现问题 所以我们
  • SpringMVC进阶:常用注解、参数传递和请求响应以及页面跳转

    目录 一 常用注解 1 1 RequestMapping 1 2 RequestParam 1 3 ModelAttribute 1 4 SessionAttributes 1 5 RequestBody 1 6 RequestHeader
  • 一文介绍机器学习中的三种特征选择方法

    作者 luanhz 来源 小数志 导读 机器学习中的一个经典理论是 数据和特征决定了机器学习的上限 而模型和算法只是逼近这个上限 也正因如此 特征工程在机器学习流程中占有着重要地位 广义的特征工程一般可分为三个环节 特征提取 特征选择 特征