特征选择(Feature Selection)

article/2025/10/14 16:02:07

主要内容:

  1. 为什么要进行特征选择?
  2. 什么是特征选择?
  3. 怎么进行特征选择

特征选择:

    在现实生活中,一个对象往往具有很多属性(以下称为特征),这些特征大致可以被分成三种主要的类型:

  1. 相关特征:对于学习任务(例如分类问题)有帮助,可以提升学习算法的效果;
  2. 无关特征:对于我们的算法没有任何帮助,不会给算法的效果带来任何提升;
  3. 冗余特征:不会对我们的算法带来新的信息,或者这种特征的信息可以由其他的特征推断出;

    但是对于一个特定的学习算法来说,哪一个特征是有效的是未知的。因此,需要从所有特征中选择出对于学习算法有益的相关特征。而且在实际应用中,经常会出现维度灾难问题,尤其是在文本处理中。例如,可以把一篇文档表示成一个词向量,但是往往会使用所有的单词作为字典,因此对于一篇可能仅仅包含100或者200个单词的文档,可能需要上万的维度(也就是特征)。如果可以从中选择一部分相关特征构建模型,这个问题就可以得到一定程度的解决。所以,特征选择和降维有一定的相似之处。另外,从上面的例子中可以发现,如果只选择所有特征中的部分特征构建模型,那么可以大大减少学习算法的运行时间,也可以增加模型的可解释性。

    因此,进行特征选择的主要目的:

  1. 降维
  2. 降低学习任务的难度
  3. 提升模型的效率

定义:

    从N个特征中选择其中M(M<N)个子特征,并且在M个子特征中,准则函数可以达到最优解。

    特征选择想要做的是:选择尽可能少的子特征,模型的效果不会显著下降,并且结果的类别分布尽可能的接近真实的类别分别。机器学习

特征选择的过程:

    对于一个有N个特征的对象,可以产生2^N个特征子集,特征选择就是从这些子集中选出对于特定任务最好的子集。特征选择主要包括四个过程:

  1. 生成过程:生成候选的特征子集;
  2. 评价函数:评价特征子集的好坏;
  3. 停止条件:决定什么时候该停止;
  4. 验证过程:特征子集是否有效;

    生成过程其实是一个搜索过程,这个过程可以从以下几种情况开始:1.没有特征;2.所有特征;3.随机特征子集。在前两种情况下,每次迭代可以增加、删除特征;但是在最后一种情况下,每次迭代随机增加或者删除特征。

    评价函数用来评价生成过程中生成的特征子集,产生一个值用来比较当前特征子集和当前最优特征子集,如果这个特征子集更好,那么就取代当前最优子集。

    停止条件用来决定迭代过程什么时候停止,生成过程和评价函数可能会对于怎么选择停止条件产生影响。停止条件有以下四种选择:

  1. 达到预定义的最大迭代次数;
  2. 达到预定义的最大特征数;
  3. 增加(删除)任何特征不会产生更好的特征子集;
  4. 根据评价函数,产生最优特征子集;

    验证过程并不是特征选择本身的一部分,但是选择出的特征必须是有效。因此,需要使用不同的测试集、学习方法验证选择出来的特征子集,然后比较这些验证结果。

生成过程:

    生成过程是一个搜索过程,这个过程主要有以下三个策略:

  1. 完全搜索:根据评价函数做完全搜索。完全搜索主要有两种:穷举搜索和非穷举搜索;
  2. 启发式搜索:根据一些启发式规则在每次迭代时,决定剩下的特征是应该被选择还是被拒绝。这种方法很简单并且速度很快,因为它的搜索空间是O(n^2);
  3. 随机搜索:每次迭代时会设置一些参数,参数的选择会影响特征选择的效果。由于会设置一些参数(例如最大迭代次数),所以搜索空间也远远小于O(2^n);

评价函数:

    评价函数主要用来评价选出的特征子集的好坏,一个特征子集是最优的往往指相对于特定的评价函数来说的。评价函数主要用来度量一个特征(或者特征子集)可以区分不同类别的能力。根据具体的评价方法主要有三类:

  1. 过滤式(filter): 先进行特征选择,然后去训练学习器,所以特征选择的过程与学习器无关。相当于先对于特征进行过滤操作,然后用特征子集来训练分类器。
  2. 包裹式(wrapper):直接把最后要使用的分类器作为特征选择的评价函数,对于特定的分类器选择最优的特征子集
  3. Filter和Wrapper组合式算法:先使用Filter进行特征选择,去掉不相关的特征,降低特征维度;然后利用Wrapper进行特征选择。
  4. 嵌入式(embedding):把特征选择的过程与分类器学习的过程融合一起,在学习的过程中进行特征选择。最常见的使用L1正则化进行特征选择。

    一般有5种比较常见的评价函数:

  1. 距离度量:如果 X 在不同类别中能产生比 Y 大的差异,那么就说明 X 要好于 Y;
  2. 信息度量:主要是计算一个特征的信息增益(度量先验不确定性和期望后验不确定性之间的差异);
  3. 依赖度量:主要用来度量从一个变量的值预测另一个变量值的能力。最常见的是相关系数:用来发现一个特征和一个类别的相关性。如果 X 和类别的相关性高于 Y与类别的相关性,那么X优于Y。对相关系数做一点改变,用来计算两个特征之间的依赖性,值代表着两个特征之间的冗余度。
  4. 一致性度量:对于两个样本,如果它们的类别不同,但是特征值是相同的,那么它们是不一致的;否则是一致的。找到与全集具有同样区分能力的最小子集。严重依赖于特定的训练集和 最小特征偏见(Min-Feature bias)的用法;找到满足可接受的不一致率(用户指定的参数)的最小规模的特征子集。
  5. 误分类率度量:主要用于Wrapper式的评价方法中。使用特定的分类器,利用选择的特征子集来预测测试集的类别,用分类器的准确率来作为指标。这种方法准确率很高,但是计算开销较大。

特征选择算法:

    根据上面的三种不同的搜索策略和五种不同的评价函数,会有很多具体的特征选择算法。以下是主要的分类:

    按照三种不同的搜索策略,简单介绍几种具体的算法:

完全搜索:

 

广度优先搜索(Breadth First Search)

    主要采用完全搜索策略和距离度量评价函数。使用广度优先算法遍历所有可能的特征子集,选择出最优的特征子集。

分支界限搜索(Branch & Bound)

    主要采用完全搜索和距离度量。B&B从所有的特征上开始搜索,每次迭代从中去掉一个特征,每次给评价函数的值一个限制条件。因为评价函数满足单调性原理(一个特征子集不会好于所有包含这个特征子集的更大的特征子集),所以如果一个特征使得评价函数的值小于这个限制,那么就删除这个特征。类似于在穷举搜索中进行剪枝。

定向搜索(Beam Search)

    主要采用完全搜索策略和误分类率作为评价函数。选择得分最高的特征作为特征子集,把它加入到一个有长度限制的队列中,从头到尾依次是性能最优到最差的特征子集。每次从队列总取得分最高的子集,然后穷举向该子集中加入一个特征后所有的特征集,按照得分把这些子集加入到队列中。

最优优先搜索(Best First Search)

和定位搜索类似,不同点在于不限制队列的长度。

启发式搜索

序列前向选择(SFS , Sequential Forward Selection)

    使用误分类率作为评价函数。从空集开始搜索,每次把一个特征加入到这个特征子集中,使得评价函数达到最优值。如果候选的特征子集不如上一轮的特征子集,那么停止迭代,并将上一轮的特征子集作为最优的特征选择结果。

广义序列前向选择(GSFS ,Generalized Sequential Forward Selection)

    该方法是SFS算法的加速算法,它可以一次性向特征集合中加入r个特征。在候选特征中选择一个规模为r的特征子集,使得评价函数取得最优值。

序列后向选择(SBS , Sequential Backward Selection)

    把误分类率作为评价函数。从特征的全集开始搜索,每次从特征子集中去掉一个特征,使得评价函数达到最优值。

    SFS和SBS都属于贪心算法,它们仅考虑使本轮选定集最优,因此容易陷入局部最优。

广义序列后向选择(GSBS,Generalized Sequential Backward Selection)

    该方法是SBS的加速,可以一次性的从特征子集中去除一定数量的特征。是实际应用中的快速特征选择算法,性能相对较好。但是有可能消除操作太快,去除掉重要的信息,导致很难找到最优特征子集。

双向搜索(BDS , Bi-directional Search)

    分别使用SFS和SBS同时进行搜索,只有当两者达到一个相同的特征子集时才停止搜索。为了保证能够达到一个相同的特征子集,需要满足两个条件:

  1. 被SFS选中的特征不能被SBS去除;
  2. 被SBS去除的特征就不能SFS选择;

增L去R选择算法(LRS , Plus L Minus R Selection)

    采用误分类率作为评价函数。允许特征选择的过程中进行回溯,这种算法主要有两种形式:

  1. 当L>R时,是一种自下而上的方法,从空集开始搜索,每次使用SFS增加L个特征,然后用SBS从中去掉R个特征;
  2. 当L<R时,是一种自上而下的算法,从特征的全集开始搜索,每次使用SBS去除其中的R个特征,使用SFS增加L个特征;

序列浮动选择(Sequential Floating Selection)

    和增L去R算法类似,只不过序列浮动算法的L和R不是固定的,每次会产生变化,这种算法有两种形式:

  1. 序列浮动前向选择(SFFS , Sequential Floating Forward Selection):从空集开始搜索,每次选择一个特征子集,使得评价函数可以达到最优,然后在选择一个特征子集的子集,把它去掉使得评价函数达到最优;
  2. 序列浮动后向选择(SFBS , Sequential Floating Backward Selection):从特征全集开始搜索,每次先去除一个子集,然后在加入一个特征子集。

决策树算法(DTM , Decision Tree Method)

    采用信息增益作为评价函数。在训练集中使用C4.5算法,等到决策树充分增长,利用评价函数对决策树进行剪枝。最后,出现在任意一个叶子节点的路径上的所有特征子集的并集就是特征选择的结果。

Relief算法

    采用距离度量作为评价函数。首先,用户设置一个参数(实例的数量),并且初始化每个特征的权重为0;然后随机从训练集中选择一个实例,根据欧式距离计算得到它的猜中近邻(同类别实例中具有欧式距离最小的实例)和猜错近邻(不同类别的实例中具有最小欧式距离的实例);然后利用猜中近邻和猜错近邻更新每个特征的权重(如果一个特征可以区分实例和它的猜错近邻,这个特征就有更大的相关性,如果它可以区分实例和猜对近邻,那它的相关性比较低);在计算完所有的特征权重之后,选择权重大于某个阈值(大于0)的所有特征。

    它可以在连续性的数据和名词性的数据中,可以用来去除噪声和不相关的特征,并且它的运行时间是线性的。但是对于冗余的特征,它可能得不到最优解。因此有另一个算法可以解决这个不足:Relief-F

随机搜索

LVF(Las Vegas Filter)

    使用一致性度量作为评价函数。使用拉斯维加斯算法随机搜索子集空间,这样可以很快达到最优解。对于每一个候选子集,计算它的不一致性,如果大于阈值,则去除这个子集。否则,如果这个候选子集中的特征数量小于之前最优子集的数量,则该子集作为最优子集。这个方法在有噪声的数据集达到最优解,它是很简单被实现而且保证产生比较好的特征子集。但是在一些特定问题上,它会花费比启发式搜索更多的时间,因为它没有利用到先验知识。

LVW(Las Vegas Wrapper)

    使用误分类率作为评价函数。使用拉斯维加斯算法随机产生子集,然后计算在这个子集上的评价指标(计算学习器上的误差);如果评价函数的值相当,并且这个子集中的特征数量小于之前的特征子集,那么将该子集作为最优特征子集。每次特征评价都需要训练分类器,计算开销很大,因此设置停止条件参数。因此如果有时间限制,可能该算法给不出最优解。

随机产生序列选择算法(RGSS , Random Generation plus Sequential Selection)

    使用误分类率作为评价函数。随机产生一个特征子集,然后在该子集上执行SFS和SBS算法,用于跳出局部最优值。

模拟退火算法(SA , Simulated Annealing)

    使用误分类率作为评价函数。模拟退火是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。因此,一定程度上克服了序列搜索算法容易陷入局部最优值的缺点,但是若最优值区域太小,则模拟退火难以求解。模拟退火过程如下:

  1. 初始化迭代起点(初始解)S,每个T值的迭代次数 L;
  2. 对于K=1,2,……,L;迭代 3 到 6;
  3. 产生新解 S_new;
  4. 计算增量:t=C(S_new)-C(S); 其中C(S)为评价函数;
  5. t<0,则接受新解为当前解;否则以 exp(-t/T) 的概率接受新解为当前解;
  6. 如果满足终止条件,则当前解为最优解,终止程序;终止条件通常为联系若干个新解都没有被接受,则终止程序;
  7. T逐渐减少,且T>0,然后转向第 2 步;

遗传算法(GA , Genetic Algorithms)

    使用误分类率作为评价函数。随机产生一批特征子集,然后使用评价函数对于子集进行评分,通过选择、交叉、突变操作产生下一代特征子集,并且得分越高的子集被选中产生下一代的几率越高。经过N代迭代之后,种群中就会形成评价函数值最高的特征子集。它比较依赖于随机性,因为选择、交叉、突变都由一定的几率控制,所以很难复现结果。遗传算法的过程如下:

  1. 随机产生初始种群;
  2. 在非支配排序后,通过遗传算法的三个算子(选择算子,交叉算子,变异算子)进行变更操作得到第一代种群;
  3. 将父代种群与子代种群合并得到大小为N的初始化种群;
  4.   对包括N个个体的种群进行快速非支配排序;
  5. 对每个非支配层中的个体进行拥挤度计算;
  6. 根据非支配关系及个体的拥挤度选取合适的个体组成新的父代种群;
  7. 通过遗传算法的基本变更操作产生新的子代种群;
  8. 重复 3 到 7 直到满足程序结束的条件(即遗传进化代数);

参考文献

 

  1. M. Dash, H. Liu, Feature Selection for Classification. In:Intelligent Data Analysis 1 (1997) 131–156.
  2. 《机器学习》 周志华 著 清华大学出版社
  3. Ricardo Gutierrez-Osuna, Introduction to Pattern Analysis 

http://chatgpt.dhexx.cn/article/R4G5dxDU.shtml

相关文章

特征选择常用算法综述

1 综述 (1) 什么是特征选择 特征选择 ( Feature Selection )也称特征子集选择( Feature Subset Selection , FSS ) ,或属性选择( Attribute Selection ) ,是指从全部特征中选取一个特征子集,使构造出来的模型更好。 (2) 为什么要做特征选择 在机器学习的实际应用…

浅谈五种常用的特征选择方法

&#x1f446;点击关注&#xff5c;设为星标&#xff5c;干货速递&#x1f446; 在许多机器学习相关的书里&#xff0c;很难找到关于特征选择的内容&#xff0c;因为特征选择要解决的问题往往被视为机器学习的一个子模块&#xff0c;一般不会单独拿出来讨论。 但特征选择是一个…

Python-编码规范

学习内容&#xff1a;Python基础入门知识-代码编写规范 专栏作者&#xff1a;不渴望力量的哈士奇不渴望力量的哈士奇擅长Python全栈白宝书[更新中],⑤ - 数据库开发实战篇,网安之路,等方面的知识,不渴望力量的哈士奇关注云原生,算法,python,集成测试,去中心化,web安全,智能合约…

前端编码规范

最近整理了一份HTML/CSS/JS编码规范&#xff0c;供大家参考。 目录&#xff1a; 一、HTML编码规范 二、CSS编码规范 三、JS编码规范 一、HTML编码规范 1. img标签要写alt属性 根据W3C标准&#xff0c;img标签要写alt属性&#xff0c;如果没有就写一个空的。但是一般要写一个…

C语言编码规范

C语言编码规范 1、代码总体规则 2、代码规范之头文件 3、代码规范之函数 4、标识符命名与定义 5、代码规范之变量 6、宏、常量

【代码规范】常见编码规范

文章来源&#xff1a;公众号-智能化IT系统。 1.明确方法功能&#xff0c;精确&#xff08;而不是近似&#xff09;地实现方法设计。如果一个功能将在多处实现&#xff0c;即使只有两行代码&#xff0c;也应该编写方法实现。 说明&#xff1a; 虽然为仅用一两行就可完成的功能…

Python的编码规范(超详细)

目录 一、前言二、编写规范三、命名规范四、结语 一、前言 编码的规范性对代码的整体展现有着较大的影响。 先让我们看两张规范与不规范的代码截图来感受下。 先让我们看看不规范的吧。 看完有什么感觉吗&#xff1f;或许你会没有感觉&#xff0c;在让我们来看看我自认为很规…

标准的Java编码规范手册

编码规范体现出一个开发者的基本素质&#xff0c;良好的编码规范可以提高团队编码的效率&#xff0c;避免很多不必要的问题。今天分享一个标准的Java编码规范给大家&#xff0c;希望对于大家今后的开发工作带来帮助。 编码规范的意义 在项目开发维护中&#xff0c;编码…

Java编码规范总结(参考腾讯编码规范)

一、java文件组织 文件组织规则&#xff1a;由于超过2000行的程序难以阅读&#xff0c;应该尽量避免出现超过2000行的程序。一个Java源文件都包含一个单一的公共类或接口。若私有类和接口与一个公共类相关联&#xff0c;可以将它们和公共类放入同一个源文件。公共类必须是这个…

编码体系与规范

编码体系与规范 网页编码是指网页中字符的编码方式。目前国内常见的网页字符编码主要有utf-8、gbk、gb2312&#xff0c;其中 utf-8为国际化编码&#xff0c;在各国各地区的网站中都很常见&#xff0c;可以说是最通用的字符编码。此外&#xff0c;有些日本网页会使用EUC-JP、SH…

python编码规范

PE8基本规范&#xff1a; 建议修改在使用的 IDE 中修改 PEP8 的每行字数不超79字符规范&#xff0c;可修改为 Django 建议的 119 字符 一、python编码规范&#xff1a; (一)代码编码&#xff1a; 1、国际惯例&#xff0c;文件编码和 Python 编码格式全部为 utf-8 &#xff0c;…

JAVA编码规范

命名风格 代码命名不能以下划线或者美元符号开头或者结尾代码命名不能以中文拼音或者中文拼音与英文混合方式类名使用UpperCamCamelCase风格&#xff0c;但DO、PO、DTO、VO、BO等除外方法名、参数名、变量名统一使用lowerCamelCase&#xff0c;必须遵守驼峰命名常量名全部大写…

【编码规范篇】| C#编码规范 代码规范总结,包括命名规范,代码规范 注释规范等

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity精品学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作分享 &…

编码的一些基本规范

1. 数据库表设计 Rule 1. 【强制】表名小写&#xff0c;多个word之间用英文下横线_分隔Rule 2. 【强制】表名普通表前缀t_;临时表tmp_;备份表bak_;视图v_;主键pk_;外键fk_;唯一索引uix_;普通索引idx_Rule 3. 【强制】关系表统一用relation结尾Rule 4. 【强制】表名和业务字段必…

编码规范汇总【持续更新】

目录 前言规范标准C规范C#规范 规范记录命名硬编码单例类【线程安全】Qt定义类【隐式内存共享】 前言 作为软件工程师&#xff0c;出产物就应该具备工程的健壮性和美观性。因此代码规范是作为软件工程师的职业素养。但总所周知&#xff0c;程序员的工作基本就是在维护一座屎山…

51单片机串口波特率

SCON SCON 0X50工作方式1 波特率需要使用定时器1 波特率 ((2^SMOD)/32) * (定时器溢出率) 定时器溢出率 系统时钟/指令周期/装载数 SMOD 1 &#xff0c;波特率加倍 TH1 TL1 -(FOSC / INSTRU_CYCLE / 32 / BAUD); //Set auto-reload vaule TR1 1;

关于51单片机串口1发送完整的数据包

关于51单片机串口1发送完整的数据包 在参考这样的协议的条件下我们想发送一套完整的数据包该如何发送呢&#xff1f;可以设计这样的程序。 1. 串行口1接收特定包头数据包函数。 参数: Uart_Rec_Data&#xff1a;串口接收到的数据 &#xff1b; USER_Get_DataPacket: 数据存储目…

51单片机串口收发

#include<reg52.h>#define uint unsigned int #define uchar unsigned char/*本代码实现串口的收发功能&#xff0c;PC发送什么单片机就接收什么&#xff0c; 然后单片机又把接收的发出去&#xff0c;本次编写了在发送单个字符串 函数上添加了字符串函数&#xff0c;方便…

学习51单片机串口工作方式及应用

1.串口控制寄存器SCON SM2:多机通信控制位 REN:允许接收控制位 TB8:发送第九位数据 RB8:接收第九位数据 TI:发送中断标志位 RI:接收中断标志位 2.电源控制寄存器PCON 当SMOD位为1&#xff0c;则串行口方式1、方式2、方式3的波特率加倍。 3.串口的工作方式 &#xff08;1…

关于51单片机串口通信的相关知识(寄存器)

一、51单片机串口概念 1、51单片机的串行口 51单片机的串行口是一个可编程全双工的通信接口&#xff0c;具有UART&#xff08;通用异步收发器&#xff09;的全部功能。 2、51单片机的硬件连接 简单双向串口通信有两根数据通信线&#xff1a; 发送端TXD&#xff08;Transmit Da…