机器学习特征选择方法全面总结与实战指南
为什么要费劲做特征选择?道理很简单:特征太多,模型反而可能变差。看看图1就能明白,每个任务都有一个“最佳特征数量”——太少欠拟合,太多则引入噪声,过拟合、精度下降、训练变慢,各种问题接踵而至。真正的挑战在于,如何找到那个甜点。这正是特征选择技术发挥威力的地方。 图1:分类器性能与特征维度的关系 特征
为什么要费劲做特征选择?道理很简单:特征太多,模型反而可能变差。看看图1就能明白,每个任务都有一个“最佳特征数量”——太少欠拟合,太多则引入噪声,过拟合、精度下降、训练变慢,各种问题接踵而至。真正的挑战在于,如何找到那个甜点。这正是特征选择技术发挥威力的地方。
图1:分类器性能与特征维度的关系
特征选择的主流方法
特征选择的方法大致分三类,各有利弊:
1. 过滤方法(Filter Methods):最直观,用统计指标(比如皮尔逊相关系数)给特征打分,然后取前几名。速度快,但跟模型无关。
2. 包装方法(Wrapper Methods):把特征子集丢给机器学习模型,根据模型表现决定增删特征。精度高,但计算成本高,比如递归特征消除(RFE)。
3. 嵌入方法(Embedded Methods):在模型训练过程中自动筛选特征,比如用树模型的特征重要性、Lasso回归的系数收索。兼顾效率和效果。
图2:过滤器、包装器和嵌入方法的对比示意
动手实践:以蘑菇分类数据集为例
我们拿经典的Kaggle蘑菇分类数据集来走一遍流程——目标是预测蘑菇是否有毒。一边试,一边看看不同特征选择方法对训练时间和精度的影响。先导入必要的库。
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, LabelEncoder from sklearn.ensemble import RandomForestClassifier from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn.feature_selection import RFE, SelectFromModel, SelectKBest, chi2 from sklearn.linear_model import LassoCV from sklearn.metrics import confusion_matrix, classification_report import graphviz import time
数据长什么样?图3展示了部分。
图3:Mushroom Classification数据集样例
数据全是分类变量,先用one-hot编码,再拆分特征和标签,最后标准化、划分训练测试集。
X = df.drop(['class'], axis=1) Y = df['class'] X = pd.get_dummies(X, prefix_sep='_') Y = LabelEncoder().fit_transform(Y) X2 = StandardScaler().fit_transform(X) X_Train, X_Test, Y_Train, Y_Test = train_test_split(X2, Y, test_size=0.30, random_state=101)
特征重要性:随机森林告诉你的关键特征
基于树的集成模型天然能输出特征重要性。用全部特征训练一个随机森林(700棵树),先看看基准表现。
start = time.process_time() trainedforest = RandomForestClassifier(n_estimators=700).fit(X_Train,Y_Train) print(time.process_time() - start) predictionforest = trainedforest.predict(X_Test) print(confusion_matrix(Y_Test,predictionforest)) print(classification_report(Y_Test,predictionforest))
结果:训练时间约2.2秒,准确率100%。图4展示了前7个最重要的特征——一眼就能看出哪些特征对分类贡献最大。
feat_importances = pd.Series(trainedforest.feature_importances_, index=X.columns) feat_importances.nlargest(7).plot(kind='barh')
图4:特征重要性排名(前7个)
既然前几个特征这么重要,那用它们训练模型会怎样?试试只取odor_n、odor_f、gill-size_n、gill-size_b这4个特征。
X_Reduced = X[['odor_n','odor_f', 'gill-size_n','gill-size_b']] X_Reduced = StandardScaler().fit_transform(X_Reduced) X_Train2, X_Test2, Y_Train2, Y_Test2 = train_test_split(X_Reduced, Y, test_size=0.30, random_state=101) start = time.process_time() trainedforest = RandomForestClassifier(n_estimators=700).fit(X_Train2,Y_Train2) print(time.process_time() - start) predictionforest = trainedforest.predict(X_Test2) print(confusion_matrix(Y_Test2,predictionforest)) print(classification_report(Y_Test2,predictionforest))
结果呢?只用了4个特征,准确率仅下降0.03%——从100%掉到99.97%,训练时间却砍掉了将近一半。这就是特征选择的力量。
另外,直接可视化一棵简单的决策树(深度限制为2层),也能直观看到哪些特征被树优先用来分裂(图5)。树顶的特征就是最重要的。
trainedtree = tree.DecisionTreeClassifier().fit(X_Train, Y_Train)
data = export_graphviz(trainedtree, out_file=None,
feature_names=X.columns,
class_names=['edible','poisonous'],
filled=True, rounded=True,
max_depth=2,
special_characters=True)
graph = graphviz.Source(data)
graph
图5:决策树可视化(深度2)
递归特征消除(RFE)
RFE是一种包装方法,它反复训练模型,每次剔除最不重要的特征,直到达到指定的特征数目。我们可以用循环扫描不同特征数量下模型的精度,找到最佳数目。
model = RandomForestClassifier(n_estimators=700)
rfe = RFE(model, 4)
start = time.process_time()
RFE_X_Train = rfe.fit_transform(X_Train, Y_Train)
RFE_X_Test = rfe.transform(X_Test)
rfe = rfe.fit(RFE_X_Train, Y_Train)
print(time.process_time() - start)
print("Overall Accuracy using RFE: ", rfe.score(RFE_X_Test, Y_Test))
SelectFromModel:更轻量的嵌入法
SelectFromModel是另一种快速筛选办法,它基于模型的特征重要性(或系数)设定阈值,直接砍掉低于阈值的特征。这里我们用ExtraTreesClassifier(极端随机树)代替随机森林,它方差更小、过拟合风险更低。
from sklearn.ensemble import ExtraTreesClassifier model = ExtraTreesClassifier() start = time.process_time() model = model.fit(X_Train, Y_Train) model = SelectFromModel(model, prefit=True) print(time.process_time() - start) Selected_X = model.transform(X_Train) start = time.process_time() trainedforest = RandomForestClassifier(n_estimators=700).fit(Selected_X, Y_Train) print(time.process_time() - start) Selected_X_Test = model.transform(X_Test) predictionforest = trainedforest.predict(Selected_X_Test) print(confusion_matrix(Y_Test, predictionforest)) print(classification_report(Y_Test, predictionforest))
相关矩阵分析:从标签相关性出发
老方法,但有效。计算每个特征与标签的皮尔逊相关系数,只保留与标签相关性绝对值大于0.5的特征。这些特征就是“最关心标签变化”的那一批。
Numeric_df = pd.DataFrame(X) Numeric_df['Y'] = Y corr = Numeric_df.corr() corr_y = abs(corr["Y"]) highest_corr = corr_y[corr_y > 0.5] highest_corr.sort_values(ascending=True)
当然,还要检查这些特征之间是否高度相关——冗余特征要剔除。下面画出保留特征的相关矩阵热力图(图6),一目了然。
corr2 = Numeric_df[['bruises_f','bruises_t','gill-color_b','gill-size_b',
'gill-size_n','ring-type_p','stalk-surface-below-ring_k',
'stalk-surface-above-ring_k','odor_f','odor_n']].corr()
sns.heatmap(corr2, annot=True, fmt=".2g")
图6:高相关特征之间的相关系数矩阵
最后,用这些与标签高度相关的特征训练一个支持向量机(SVM),看看效果。
单变量选择:用统计检验说话
另一种经典路径:用卡方检验(chi2)计算每个特征与标签的依赖性,只保留得分最高的k个特征。注意卡方要求非负输入,需要提前归一化到[0,1]区间。
from sklearn.feature_selection import SelectKBest, chi2 min_max_scaler = preprocessing.MinMaxScaler() Scaled_X = min_max_scaler.fit_transform(X2) X_new = SelectKBest(chi2, k=2).fit_transform(Scaled_X, Y) X_Train3, X_Test3, Y_Train3, Y_Test3 = train_test_split(X_new, Y, test_size=0.30, random_state=101) start = time.process_time() trainedforest = RandomForestClassifier(n_estimators=700).fit(X_Train3, Y_Train3) print(time.process_time() - start) predictionforest = trainedforest.predict(X_Test3) print(confusion_matrix(Y_Test3, predictionforest)) print(classification_report(Y_Test3, predictionforest))
图7:卡方检验公式
套索回归:自动淘汰无用特征
最后介绍套索回归(Lasso),它把L1正则化加入线性模型,使得不重要的系数被压缩到零,从而自动完成特征选择。用交叉验证选择最佳惩罚系数α。
from sklearn.linear_model import LassoCV
regr = LassoCV(cv=5, random_state=101)
regr.fit(X_Train, Y_Train)
print("LassoCV Best Alpha Scored: ", regr.alpha_)
print("LassoCV Model Accuracy: ", regr.score(X_Test, Y_Test))
model_coef = pd.Series(regr.coef_, index=list(X.columns[:-1]))
print("Variables Eliminated: ", str(sum(model_coef == 0)))
print("Variables Kept: ", str(sum(model_coef != 0)))
训练完成后,可以再次绘制特征重要性图(图8),看看Lasso认为哪些特征值得保留。这对模型解释非常有帮助。
top_coef = model_coef.sort_values()
top_coef[top_coef != 0].plot(kind="barh")
plt.title("Most Important Features Identified using Lasso")
图8:套索回归识别的最重要特征
以上几种方法,各有适用场景。没有最好的方法,只有最合适的。但在实际项目中,多试几种、交叉验证,总能找到那个既能提升精度、又能让模型更轻便的特征子集。特征选择不是花架子,而是真正能让你的模型“用更少的力气,做更好的事”。
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:机器学习特征选择方法全面总结与实战指南要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点Qwen3通过全谱系模型(0 6B至235B)、混合推理与真开源策略,满足从端侧到云端多样化部署需求,支持Agent开发与低代码构建。其技术突破与产业验证提振了AI应用投资信心,成为开发者与企业的理想基座模型。
对于绝大多数个人、企业乃至整个社会来说,最重要的资产是什么?答案可能会让人有些意外——是知识。 今天,知识这种无形的智力资产,已经在财富创造中占据了主导地位。它不仅能直接带来收益,比如技能、专利、许可、品牌等创新成果,还能融入文化、体系和业务流程,帮企业构建持久的竞争优势。 正因如此,有学者指出,工
先聊几句背景。建筑行业一直是一个“慢变量”的领域——项目周期长、参与方众多、信息碎片化问题严重。但随着AI大模型的爆发,越来越多的人开始认真思考:这个传统行业究竟能否真正实现“智能化”?答案是肯定的,但关键要走对路径。今天,我们以知识图谱这一技术基石为切入点,探讨它如何在建筑垂直领域助力大模型真正落
清华大学提出集成衍射光子神经网络芯片,利用亚波长结构突破集成度瓶颈,实现计算单元大规模片上拓展。该芯片计算吞吐量达1 38×10⁴TOPS,算力密度10¹⁶FLOPS mm²,能耗仅10⁻¹⁷J FLOP,具有完全自主知识产权并与CMOS工艺兼容。
- 日榜
- 周榜
- 月榜
热点快看
