机器学习特征选择的四种实用方法
在机器学习项目中,特征选择(Feature Selection)往往容易被忽视,但事实上,它却是决定模型成败的核心环节之一。本文梳理了四种经典的特征选择方法,并附上基于Scikit-learn的实战代码,帮助您快速掌握并应用于实际项目。 注:本文节选自Ankit Dixit所著的《集成机器学习》(E
在机器学习项目中,特征选择(Feature Selection)往往容易被忽视,但事实上,它却是决定模型成败的核心环节之一。本文梳理了四种经典的特征选择方法,并附上基于Scikit-learn的实战代码,帮助您快速掌握并应用于实际项目。

注:本文节选自Ankit Dixit所著的《集成机器学习》(Ensemble Machine Learning)一书。该书专注于讲解如何组合多种强大的机器学习算法来构建优化模型,非常适合作为初学者入门的实践指南。
下面我们详细讨论的方法包括:单变量特征选择、递归特征消除(RFE)、主成分分析(PCA)以及基于特征重要度的筛选。前三种方法将简要介绍,最后一种在数据科学社区中应用最为广泛,因此会展开深入讲解。
单变量特征选择
统计检验可以帮助我们找出与输出变量关联最强的特征。Scikit-learn的SelectKBest类正是为此设计的——你可以搭配不同的统计检验方法,直接指定要保留的特征数量。
下面的示例采用了卡方检验(适用于非负特征),从皮马印第安人糖尿病数据集中选取四个最佳特征:
# Feature Extraction with Univariate Statistical Tests (Chi-squared for classification) # Import the required packages import pandas import numpy from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = pandas.read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] test = SelectKBest(score_func=chi2, k=4) fit = test.fit(X, Y) numpy.set_printoptions(precision=3) print(fit.scores_) features = fit.transform(X) print(features[0:5,:])
运行后,你会看到每个特征的得分,以及被选中的四个参数——plas、test、mass和age。具体分数如下:
[111.52 1411.887 17.605 53.108 2175.565 127.669 5.393 181.304]
最终选出的特征矩阵:
[[148. 0. 33.6 50. ] [85. 0. 26.6 31. ] [183. 0. 23.3 32. ] [89. 94. 28.1 21. ] [137. 168. 43.1 33. ]]
递归特征消除(RFE)
RFE的思路非常直观:反复删除特征,在剩余特征上训练模型,然后根据模型精度判断哪些特征(或特征组合)对预测目标贡献最大。你可以使用任何稳定的模型,例如逻辑回归。下面的例子借助RFE搭配逻辑回归选出前三个重要特征:
import pandas
import numpy
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = pandas.read_csv(url, names=names)
array = dataframe.values
X = array[:,0:8]
Y = array[:,8]
model = LogisticRegression()
rfe = RFE(model, 3)
fit = rfe.fit(X, Y)
print("Num Features: %d"% fit.n_features_)
print("Selected Features: %s"% fit.support_)
print("Feature Ranking: %s"% fit.ranking_)
输出结果:
Num Features: 3 Selected Features: [ True False False False False True True False] Feature Ranking: [1 2 3 5 6 1 1 4]
可以看到,RFE最终选出了preg、mass和pedi这三个特征,它们在support_数组中被标记为True,在ranking_中排名第一(标记为1)。
主成分分析(PCA)
PCA通过线性代数将数据压缩为更紧凑的形式,通常被视为一种降维技术。它有一个自然的属性:你可以指定要保留的主成分数量。下面我们使用PCA从原始数据中提取三个主成分:
import pandas
import numpy
from sklearn.decomposition import PCA
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = pandas.read_csv(url, names=names)
array = dataframe.values
X = array[:,0:8]
Y = array[:,8]
pca = PCA(n_components=3)
fit = pca.fit(X)
print("Explained Variance: %s") % fit.explained_variance_ratio_
print(fit.components_)
转换后的三个主成分虽然与原始特征几乎没有直接可比性,但它们解释了数据中绝大部分方差:
Explained Variance: [ 0.88854663 0.06159078 0.02579012]
[[ -2.02176587e-03 9.78115765e-02 1.60930503e-02 6.07566861e-02
9.93110844e-01 1.40108085e-02 5.37167919e-04 -3.56474430e-03]
[ -2.26488861e-02 -9.72210040e-01 -1.41909330e-01 5.78614699e-02
9.46266913e-02 -4.69729766e-02 -8.16804621e-04 -1.40168181e-01]
[ -2.24649003e-02 1.43428710e-01 -9.22467192e-01 -3.07013055e-01
2.09773019e-02 -1.32444542e-01 -6.39983017e-04 -1.25454310e-01]]
基于特征重要度的选择
这种方法思路非常直接:利用训练好的有监督分类器(比如随机森林)来评估每个特征的重要性。当决策树在训练时,每个节点都会选择一个特征来分割数据,而衡量这个分割效果的指标(如基尼系数、信息增益或方差)就可以作为特征重要度的打分依据。随机森林汇集了多棵树的判断,平均后给出每个特征的最终得分。
接下来我们用一个实际案例来演示:使用随机森林做特征选择,并比较选择前后分类器的性能。这里使用Kaggle上的Otto数据集(需要注册下载),该数据集包含超过61000个产品、93个模糊特征,目标是将产品分成10个类别(如时尚、电子等)。评价指标是多类对数损失。
首先导入必要的工具库:
from pandas import read_csv import numpy as np from sklearn.ensemble import RandomForestClassifier from sklearn.feature_selection import SelectFromModel np.random.seed(1)
定义拆分训练集和测试集的函数:
def getTrainTestData(dataset, split):
np.random.seed(0)
training = []
testing = []
np.random.shuffle(dataset)
shape = np.shape(dataset)
trainlength = np.uint16(np.floor(split * shape[0]))
for i in range(trainlength):
training.append(dataset[i])
for i in range(trainlength, shape[0]):
testing.append(dataset[i])
training = np.array(training)
testing = np.array(testing)
return training, testing
定义评估准确率的函数:
def getAccuracy(pre, ytest):
count = 0
for i in range(len(ytest)):
if ytest[i] == pre[i]:
count += 1
acc = float(count) / len(ytest)
return acc
加载数据集,取前50000个实例,其中70%用于训练,30%用于测试:
data = read_csv('train.csv')
feat = data.keys()
feat_labels = feat.get_values()
dataset = data.values
np.random.shuffle(dataset)
inst = 50000
dataset = dataset[0:inst, :]
train, test = getTrainTestData(dataset, 0.7)
Xtrain = train[:, 0:94]
ytrain = train[:, 94]
shape = np.shape(Xtrain)
print("Shape of the dataset ", shape)
print("Size of Data set before feature selection: %.2f MB" % (Xtrain.nbytes / 1e6))
输出:
Shape of the dataset (35000, 94) Size of Data set before feature selection: 26.32 MB
接下来构建随机森林分类器:250棵树,最大深度30,每次分裂随机选择7个特征,其余参数保持默认。
Xtest = test[:, 0:94]
ytest = test[:, 94]
trees = 250
max_feat = 7
max_depth = 30
min_sample = 2
clf = RandomForestClassifier(n_estimators=trees,
max_features=max_feat,
max_depth=max_depth,
min_samples_split=min_sample,
random_state=0,
n_jobs=-1)
import time
start = time.time()
clf.fit(Xtrain, ytrain)
end = time.time()
print("Execution time for building the Tree is: %f" % (float(end) - float(start)))
pre = clf.predict(Xtest)
acc = getAccuracy(pre, ytest)
print("Accuracy of model before feature selection is %.2f" % (100 * acc))
输出:
Execution time for building the Tree is: 2.913641 Accuracy of model before feature selection is 98.82
准确率已经高达98.82%,但在特征选择后还能进一步提升。我们来看看每个特征的重要度:
print(feature)
('id', 0.33346650420175183)
('feat_1', 0.0036186958628801214)
('feat_2', 0.0037243050888530957)
('feat_3', 0.011579217472062748)
('feat_4', 0.010297382675187445)
('feat_5', 0.0010359139416194116)
('feat_6', 0.00038171336038056165)
('feat_7', 0.0024867672489765021)
('feat_8', 0.0096689721610546085)
('feat_9', 0.007906150362995093)
('feat_10', 0.0022342480802130366)
...
可以看到,每个特征的重要度差异很大。我们设定阈值0.01,只保留重要度高于该值的特征:
sfm = SelectFromModel(clf, threshold=0.01)
sfm.fit(Xtrain, ytrain)
Xtrain_1 = sfm.transform(Xtrain)
Xtest_1 = sfm.transform(Xtest)
print("Size of Data set before feature selection: %.2f MB" % (Xtrain_1.nbytes / 1e6))
shape = np.shape(Xtrain_1)
print("Shape of the dataset ", shape)
输出:
Size of Data set before feature selection: 5.60 MB Shape of the dataset (35000, 20)
特征从94个锐减到20个,数据集大小从26.32MB降到5.60MB,缩减了约80%。
接下来用同样的超参数在缩减后的数据集上训练并测试:
start = time.time()
clf.fit(Xtrain_1, ytrain)
end = time.time()
print("Execution time for building the Tree is: %f" % (float(end) - float(start)))
pre = clf.predict(Xtest_1)
acc2 = getAccuracy(pre, ytest)
print("Accuracy after feature selection %.2f" % (100 * acc2))
输出:
Execution time for building the Tree is: 1.711518 Accuracy after feature selection 99.97
结果令人振奋:准确率提升到99.97%,训练时间从2.91秒缩短到1.71秒,模型更轻、更快、更准。
| 评估标准 | 特征选择前 | 特征选择后 |
| 特征数量 | 94 | 20 |
| 数据集大小 | 26.32MB | 5.60MB |
| 训练时间 | 2.91 s | 1.71 s |
| 精确度 | 98.82% | 99.97% |
上表直观地展现了特征选择的实际价值:减少特征数量,降低模型复杂度,缩短训练时间,最终还能提升准确率。本文共介绍了四种经典的机器学习特征选择方法,从统计检验到递归消除,从主成分分析到基于模型重要度的筛选,各有适用场景。在实际项目中,具体选择哪种方法取决于数据规模、任务类型以及对可解释性的需求。
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:机器学习特征选择的四种实用方法要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点在企业内部跑一个 LLM 工作流的时候,几乎所有失败都是廉价的:重试、回退,甚至直接忽略都行。可一旦把这个工作流挂到客户的 API 或 MCP 服务器后面,容错空间就瞬间归零。此时唯一重要的事情是:客户拿到正确、可用的结果了吗?他们的流程依赖于你交付的结果。由他们——而不是你——来决定什么算“交付”
每周都感觉自己像陈平安,在浩瀚的信息海洋里打捞那些优美的句子。他是一笔一画刻在竹简上,我是一字一句收藏在备忘录里。然后挑个晴日,翻出来重新翻阅品味、细细朗读。 这就是“读”。心中有话忍不住对这个世界倾诉,那就是“说”。 读 机器正在学习我们的语言,因此我们不再需要学习它们的语言。 从本质上讲,世界是
从“唯模型论”到“数据说了算” 面对一个新问题,很多人会不假思索地选择眼下表现最好的模型。这是人之常情。在当下这个节点,极限梯度提升几乎成了“靠谱”的代名词,而它也确实在许多任务中战功赫赫。 所以,当你看到我拿五个分类器在同一个任务上做对比,而那个只有一行代码的线性模型居然赢了Kaggle冠军时——
这篇内容源自 Iliad Fellowship 项目,由 Dmitry Vaintrob 指导完成。 太长不看版: 幂律(即“重尾”)分布与正态分布类似,背后同样存在某种“通用性定理”作为支撑。在机器学习领域,诸多现象都遵循幂律分布,其中权重矩阵的谱分布最为稳健、也最值得深入探讨。本文的核心观点是:
- 日榜
- 周榜
- 月榜
热点快看
