京公网安备 11010802034615号
经营许可证编号:京B2-20210330
资源 | 一个Python特征选择工具,助力实现高效机器学习
鉴于特征选择在机器学习过程中的重要性,数据科学家 William Koehrsen 近日在 GitHub 上公布了一个特征选择器 Python 类,帮助研究者更高效地完成特征选择。本文是 Koehrsen 写的项目介绍及案例演示文章。
项目地址:https://github.com/WillKoehrsen/feature-selector
特征选择(feature selection)是查找和选择数据集中最有用特征的过程,是机器学习流程中的一大关键步骤。不必要的特征会降低训练速度、降低模型可解释性,并且最重要的是还会降低其在测试集上的泛化表现。
目前存在一些专用型的特征选择方法,我常常要一遍又一遍地将它们应用于机器学习问题,这实在让人心累。所以我用 Python 构建了一个特征选择类并开放在了 GitHub 上。这个 FeatureSelector 包含一些最常用的特征选择方法:
1.具有高缺失值百分比的特征
2.共线性(高度相关的)特征
3.在基于树的模型中重要度为零的特征
4.重要度较低的特征
5.具有单个唯一值(unique value)的特征
在本文中,我们将介绍在示例机器学习数据集上使用 FeatureSelector 的全过程。我们将看到如何快速实现这些方法,从而实现更高效的工作流程。
完整代码已在 GitHub 上提供,欢迎任何人贡献。这个特征选择器是一项正在进行的工作,将根据社区需求继续改进!
示例数据集
为了进行演示,我们将使用来自 Kaggle「家庭信用违约风险」机器学习竞赛的一个数据样本。了解该竞赛可参阅:https://towardsdatascience.com/machine-learning-kaggle-competition-part-one-getting-started-32fb9ff47426,完整数据集可在这里下载:https://www.kaggle.com/c/home-credit-default-risk/data。这里我们将使用部分数据样本来进行演示。
数据示例。TARGET 是分类标签
这个竞赛是一个监督分类问题,这也是一个非常合适的数据集,因为其中有很多缺失值、大量高度关联的(共线性)特征,还有一些无助于机器学习模型的无关特征。
创建实例
要创建一个 FeatureSelector 类的实例,我们需要传入一个结构化数据集,其中观察在行中,特征在列中。我们可以使用一些仅操作特征的方法,但基于重要度的方法也需要训练标签。因为这是一个监督分类任务,所以我们将使用一组特征和一组标签。
(请确保在 feature_selector.py 所在目录下运行这段代码)
fromfeature_selectorimportFeatureSelector
# Features areintrain and labels areintrain_labels
fs = FeatureSelector(data = train, labels = train_labels)
方法
这个特征选择器有 5 种用于查找待移除特征的方法。我们可以访问任何已被识别出来的特征并通过人工方式将它们移出数据,也可以使用 FeatureSelector 中的 remove 函数。
这里我们将介绍其中每种识别方法,还将展示如何同时运行这 5 种方法。此外,FeatureSelector 还有几个图表绘制功能,因为可视化地检查数据是机器学习的一大关键部分。
缺失值
查找和移除特征的第一个方法很简单:查找缺失值比例超过特定阈值的特征。下面的调用能识别缺失值比例超过 60% 的特征(粗体是输出结果)。
fs.identify_missing(missing_threshold =0.6)
17featureswithgreater than0.60missing values.
我们可以在一个 dataframe 中查看每一列的缺失值比例:
fs.missing_stats.head()
要查看待移除特征,我们可以读取 FeatureSelector 的 ops 属性,这是一个 Python 特征词典,特征会以列表的形式给出。
missing_features = fs.ops['missing']
missing_features[:5]
['OWN_CAR_AGE',
'YEARS_BUILD_AVG',
'COMMONAREA_AVG',
'FLOORSMIN_AVG',
'LIVINGAPARTMENTS_AVG']
最后,我们可以绘制一张所有特征的缺失值分布图:
fs.plot_missing()
共线性特征
共线性特征是指彼此之间高度关联的特征。在机器学习领域,高方差和较低的模型可解释性导致在测试集上的泛化能力下降。
identify_collinear 方法能基于指定的相关系数值查找共线性特征。对于每一对相关的特征,它都会标识出其中要移除的一个(因为我们只需要移除其中一个):
fs.identify_collinear(correlation_threshold =0.98)
21featureswitha correlation magnitude greater than0.98.
使用热图可以很好地可视化共线性。下图展示了所有至少有一个相关关系(correlation)超过阈值的特征:
fs.plot_collinear()
和之前一样,我们可以访问将会被移除的整个相关特征列表,或者在一个 dataframe 中查看高度相关的特征对。
# listofcollinear features to remove
collinear_features = fs.ops['collinear']
# dataframeofcollinear features
fs.record_collinear.head()
如果我们想全面了解数据集,我们还可以通过将 plot_all = True 传入该调用,绘制出数据中所有相关性的图表:
零重要度特征
前面两种方法可被应用于任何结构化的数据集并且结果是确定的——对于一个给定的阈值,每次结果都一样。接下来的方法是专为监督式机器学习问题设计的,其中我们有训练模型的标签并且是非确定性的。identify_zero_importance 函数能根据梯度提升机(GBM)学习模型查找重要度为零的特征。
我们可以使用基于树的机器学习模型(比如 boosting ensemble)求取特征重要度。这个重要度的绝对值没有相对值重要,我们可以将相对值用于确定对一个任务而言最相关的特征。我们还可以通过移除零重要度特征来在特征选择中使用特征重要度。在基于树的模型中,零重要度的特征不会被用于分割任何节点,所以我们可以移除它们而不影响模型表现。
FeatureSelector 能使用来自 LightGBM 库的梯度提升机来得到特征重要度。为了降低方差,所得到的特征重要度是在 GBM 的 10 轮训练上的平均。另外,该模型还使用早停(early stopping)进行训练(也可关闭该选项),以防止在训练数据上过拟合。
LightGBM 库:http://lightgbm.readthedocs.io/
下面的代码调用了该方法并提取出了零重要度特征:
# Passinthe appropriate parameters
fs.identify_zero_importance(task ='classification',
eval_metric ='auc',
n_iterations =10,
early_stopping = True)
# listofzero importance features
zero_importance_features = fs.ops['zero_importance']
63featureswithzero importance after one-hot encoding.
我们传入的参数解释如下:
这时候我们可以使用 plot_feature_importances 绘制两个图表:
# plot the feature importances
fs.plot_feature_importances(threshold =0.99, plot_n =12)
124features requiredfor0.99ofcumulative importance
左图给出了 plot_n 最重要的特征(重要度进行了归一化,总和为 1)。右图是对应特征数量的累积重要度。蓝色竖线标出了累积重要度为 99% 的阈值。
对于基于重要度的方法,有两点需要记住:
这应该不会有太大的影响(最重要的特征不会突然就变成最不重要的),但这会改变某些特征的排序,也会影响识别出的零重要度特征的数量。如果特征重要度每次都改变,请不要感到惊讶!
当我们到达特征移除阶段时,还有一个选项可移除任何被添加进来的 one-hot 编码的特征。但是,如果我们要在特征选择之后做机器学习,我们还是必须要 one-hot 编码这些特征。
低重要度特征
接下来的方法基于零重要度函数,使用来自模型的特征重要度来进一步选择。identify_low_importance 函数能找到重要度最低的特征,这些特征无助于指定的总重要性。
比如,下面的调用能找到最不重要的特征,即使没有这些特征也能达到 99% 的重要度。
fs.identify_low_importance(cumulative_importance =0.99)
123features requiredforcumulative importanceof0.99after one hot encoding.
116featuresdonot contribute to cumulative importanceof0.99.
根据前面的累积重要度图和这一信息,梯度提升机认为很多特征都与学习无关。重申一下,每次训练运行后该方法的结果都不一样。
我们也可以在一个 dataframe 中查看所有特征重要度:
fs.feature_importances.head(10)
low_importance 方法借鉴了主成分分析(PCA)中的一种方法,其中仅保留维持一定方差比例(比如 95%)所需的主成分是很常见的做法。要纳入考虑的总重要度百分比基于同一思想。
只有当我们要用基于树的模型来做预测时,基于特征重要度的方法才真正有用。除了结果随机之外,基于重要度的方法还是一种黑箱方法,也就是说我们并不真正清楚模型认为某些特征无关的原因。如果使用这些方法,多次运行它们看到结果的改变情况,也许可以创建具有不同参数的多个数据集来进行测试!
单个唯一值特征
最后一个方法相当基础:找出任何有单个唯一值的列。仅有单个唯一值的特征不能用于机器学习,因为这个特征的方差为 0。举个例子,如果一个特征仅有一个值,那么基于树的模型就永远不能进行区分(因为没有可做区分的依据)。
不同于其它方法,这个方法没有可选参数:
fs.identify_single_unique()
4featureswitha single unique value.
我们可以绘制每个类别唯一值数量的直方图:
fs.plot_unique()
还有一点要记住,在计算唯一值之前,NaNs 已经使用 Pandas 默认移除了。
移除特征
在确定了待移除特征之后,我们有两种移除它们的选择。所有要移除的特征都存储在 FeatureSelector 的 ops 词典中,我们可以使用这个列表来手动移除它们,当然也可使用内置的 remove 函数。
对于这一方法,我们需传入要用于移除特征的 methods。如果我们想使用所实现的所有方法,我们只需使用 methods = 'all'
# Remove the featuresfromall methods (returns a df)
train_removed = fs.remove(methods ='all')
['missing','single_unique','collinear','zero_importance','low_importance'] methods have been run
Removed140features.
这个方法会返回一个包含被移除特征的 dataframe。另外,要移除在机器学习过程中创建的 one-hot 编码的特征:
train_removed_all = fs.remove(methods ='all', keep_one_hot=False)
Removed187features including one-hot features.
在执行操作之前检查将被移除的特征可能是个好想法!原来的数据集会被存储在 FeatureSelector 的 data 属性中用作备份!
一次运行所有方法
除了单独使用各个方法之外,我们也可通过 identify_all 一次性使用所有方法。我们需要使用一个词典来设定其中每个方法的参数:
fs.identify_all(selection_params = {'missing_threshold':0.6,
'correlation_threshold':0.98,
'task':'classification',
'eval_metric':'auc',
'cumulative_importance':0.99})
151total features outof255identifiedforremoval after one-hot encoding.
注意,多次运行该模型的总特征数量可能也各不相同。之后就可以调用 remove 函数来移除这些特征了。
总结
这个特征选择器类实现了训练机器学习模型之前几种用于移除特征的常见操作。其提供了可用于识别待移除特征的函数以及可视化函数。这些方法可以单独使用,也可以一次全部应用以实现高效的工作流程。
其中 missing、collinear 和 single_unique 方法是确定性的,而基于特征重要度的方法会随每次运行而变化。与机器学习领域很相似,特征选择很大程度上是实证式的,需要测试多种组合才能找到最优解。最好的做法是在流程中尝试多种配置,并且 FeatureSelector 提供了一种用于快速评估特征选择参数的方法。
CDA学员免费下载查看报告全文:2026全球数智化人才指数报告【CDA数据科学研究院】.pdf
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在大数据技术飞速迭代、数字营销竞争日趋激烈的今天,“精准触达、高效转化、成本可控”已成为企业营销的核心诉求。传统广告投放 ...
2026-04-24在游戏行业竞争白热化的当下,用户流失已成为制约游戏生命周期、影响营收增长的核心痛点。据行业报告显示,2024年移动游戏平均次 ...
2026-04-24 很多业务负责人开会常说“我们要数据驱动”,最后却变成“看哪张报表数据多就用哪个”,往往因为缺乏一套结构性的方法去搭建 ...
2026-04-24在Power BI数据可视化分析中,切片器是连接用户与数据的核心交互工具,其核心价值在于帮助使用者快速筛选目标数据、聚焦分析重点 ...
2026-04-23以数为据,以析促优——数据分析结果指导临床技术改进的实践路径 临床技术是医疗服务的核心载体,其水平直接决定患者诊疗效果、 ...
2026-04-23很多数据分析师每天盯着GMV、DAU、转化率,但当被问到“哪些指标是所有企业都需要的”“哪些指标是因行业而异的”“北极星指标和 ...
2026-04-23近日,由 CDA 数据科学研究院重磅发布的《2026 全球数智化人才指数报告》,被中国教育科学研究院官方账号正式收录, ...
2026-04-22在数字化时代,客户每一次点击、浏览、下单、咨询等行为,都在传递其潜在需求与决策倾向——这些按时间顺序串联的行为轨迹,构成 ...
2026-04-22数据是数据分析、建模与业务决策的核心基石,而“数据清洗”作为数据预处理的核心环节,是打通数据从“原始杂乱”到“干净可用” ...
2026-04-22 很多数据分析师每天盯着GMV、转化率、DAU等数字看,但当被问到“什么是指标”“指标和维度有什么区别”“如何搭建一套完整的 ...
2026-04-22在数据分析与业务决策中,数据并非静止不变的数值,而是始终处于动态波动之中——股市收盘价的每日涨跌、企业月度销售额的起伏、 ...
2026-04-21在数据分析领域,当研究涉及多个自变量与多个因变量之间的复杂关联时,多变量一般线性分析(Multivariate General Linear Analys ...
2026-04-21很多数据分析师精通描述性统计,能熟练计算均值、中位数、标准差,但当被问到“用500个样本如何推断10万用户的真实满意度”“这 ...
2026-04-21在数据处理与分析的全流程中,日期数据是贯穿业务场景的核心维度之一——无论是业务报表统计、用户行为追踪,还是风控规则落地、 ...
2026-04-20在机器学习建模全流程中,特征工程是连接原始数据与模型效果的关键环节,而特征重要性分析则是特征工程的“灵魂”——它不仅能帮 ...
2026-04-20很多数据分析师沉迷于复杂的机器学习算法,却忽略了数据分析最基础也最核心的能力——描述性统计。事实上,80%的商业分析问题, ...
2026-04-20在数字化时代,数据已成为企业决策的核心驱动力,数据分析与数据挖掘作为解锁数据价值的关键手段,广泛应用于互联网、金融、医疗 ...
2026-04-17在数据处理、后端开发、报表生成与自动化脚本中,将 SQL 查询结果转换为字符串是一项高频且实用的操作。无论是拼接多行数据为逗 ...
2026-04-17面对一份上万行的销售明细表,要快速回答“哪个地区卖得最好”“哪款产品增长最快”“不同客户类型的购买力如何”——这些看似复 ...
2026-04-17数据分析师一天的工作,80% 的时间围绕表格结构数据展开。从一张销售明细表到一份完整的分析报告,表格结构数据贯穿始终。但你真 ...
2026-04-16