简介:本文深入探讨如何使用scikit-learn(sklearn)库进行特征选择,涵盖过滤法、包装法、嵌入法三大方法,结合代码示例与实际应用场景,帮助开发者提升模型性能与可解释性。
特征选择是机器学习流程中的关键环节,直接影响模型性能、训练效率与可解释性。scikit-learn(sklearn)作为Python生态中最成熟的机器学习库,提供了多样化的特征选择工具,覆盖过滤法、包装法、嵌入法三大类方法。本文将系统梳理sklearn中特征选择的核心技术,结合代码示例与实际应用场景,帮助开发者高效完成特征筛选。
| 方法类型 | 原理 | 适用场景 | sklearn实现类 |
|---|---|---|---|
| 过滤法 | 独立评估每个特征与目标变量的相关性 | 数据量大、计算资源有限 | SelectKBest, VarianceThreshold |
| 包装法 | 通过模型性能反馈迭代选择特征 | 追求最优特征子集,计算成本高 | RFE, RFECV |
| 嵌入法 | 结合模型训练过程选择特征 | 模型本身支持特征重要性评估 | SelectFromModel(基于L1/树模型) |
适用于移除低方差特征(如所有样本取值相同的特征)。
from sklearn.feature_selection import VarianceThresholdimport numpy as np# 生成示例数据:最后一列方差为0X = np.array([[0, 2, 0], [1, 2, 0], [2, 2, 0]])selector = VarianceThreshold(threshold=0.1) # 移除方差<0.1的特征X_new = selector.fit_transform(X)print(X_new) # 输出: [[0 2], [1 2], [2 2]]
关键参数:
threshold:方差阈值,默认0,建议通过数据分布调整。支持多种统计指标评估特征与目标变量的相关性:
f_classif(ANOVA F值)、chi2(卡方检验)f_regression(F检验)、mutual_info_regression(互信息)
from sklearn.feature_selection import SelectKBest, f_classiffrom sklearn.datasets import load_irisX, y = load_iris(return_X_y=True)selector = SelectKBest(score_func=f_classif, k=2) # 选择得分最高的2个特征X_new = selector.fit_transform(X, y)print("Selected features indices:", selector.get_support(indices=True))
注意事项:
通过迭代训练模型并移除最不重要的特征,逐步缩小特征集。
from sklearn.feature_selection import RFEfrom sklearn.ensemble import RandomForestClassifiermodel = RandomForestClassifier(n_estimators=100)rfe = RFE(estimator=model, n_features_to_select=2) # 最终保留2个特征X_new = rfe.fit_transform(X, y)print("Ranking of features:", rfe.ranking_) # 1表示选中,其他表示淘汰顺序
进阶用法:
RFECV可自动确定最优特征数量:
from sklearn.feature_selection import RFECVrfecv = RFECV(estimator=model, step=1, cv=5) # 5折交叉验证rfecv.fit(X, y)print("Optimal number of features:", rfecv.n_features_)
与RFE相反,SFS从空集开始逐步添加特征,适用于特征间存在交互作用的场景。需借助mlxtend库实现:
from mlxtend.feature_selection import SequentialFeatureSelector as SFSsfs = SFS(model, k_features=3, forward=True, scoring='accuracy', cv=5)sfs.fit(X, y)print("Selected features:", sfs.k_feature_names_)
线性模型(如逻辑回归、线性SVM)通过L1正则化可自动稀疏化系数,实现特征选择。
from sklearn.linear_model import LogisticRegressionfrom sklearn.feature_selection import SelectFromModelmodel = LogisticRegression(penalty='l1', solver='liblinear', C=0.1)selector = SelectFromModel(model, prefit=False) # prefit=True需先拟合模型selector.fit(X, y)print("Non-zero coefficients features:", selector.get_support())
参数调优建议:
C值(正则化强度的倒数)控制稀疏程度,较小的C值会选择更少特征。决策树及其集成方法(如随机森林、XGBoost)可输出特征重要性评分。
from sklearn.ensemble import RandomForestClassifiermodel = RandomForestClassifier(n_estimators=100)model.fit(X, y)importances = model.feature_importances_indices = np.argsort(importances)[::-1] # 按重要性降序排列print("Feature ranking:", [load_iris().feature_names[i] for i in indices])
可视化建议:
import matplotlib.pyplot as pltplt.bar(range(X.shape[1]), importances[indices])plt.xticks(range(X.shape[1]), [load_iris().feature_names[i] for i in indices])plt.title("Feature Importances")plt.show()
场景:某银行信用卡交易数据包含28个行为特征与1个标签(是否欺诈),正负样本比例1:500。
解决方案:
SelectKBest+f_classif保留前10个特征,缓解类别不平衡影响。代码片段:
import xgboost as xgbfrom sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)model = xgb.XGBClassifier(scale_pos_weight=500) # 处理类别不平衡model.fit(X_train, y_train)# 基于重要性选择特征selector = SelectFromModel(model, threshold="median") # 保留重要性高于中位数的特征X_train_new = selector.fit_transform(X_train, y_train)X_test_new = selector.transform(X_test)
VarianceThreshold+SelectKBest可快速完成初步筛选。RFECV计算成本高,适合对模型性能要求苛刻的场景。通过合理组合sklearn中的特征选择工具,开发者可在保证模型性能的同时,显著提升训练效率与可解释性,为业务决策提供更可靠的支持。