趋近智
嵌入 (embedding)式特征选择方法将选择过程直接融入机器学习 (machine learning)模型的构建。树模型是一种很常用且高效的内嵌技术。决策树、随机森林和梯度提升等算法在训练时会自行计算每个特征的重要性分数。
基于树的模型通过根据特征值递归地分割数据来构建一系列决策规则。这些模型中特征重要性的主旨是,那些在分割数据、提高节点纯度(用于分类)或减小方差(用于回归)方面更有效的特征被认为更重要。
以单个决策树为例。当树算法决定在哪里分割一个节点时,它会评估不同特征和阈值上的潜在分割点。选择产生最佳分割的特征和阈值(例如,分类中基尼不纯度降低最大,或回归中均方误差减少最多)。在树中更上方(靠近根部)被选作分割点或被用于更多分割的特征通常对最终预测有更大影响。
对于随机森林或梯度提升机等集成模型,它们结合了多个树的预测,特征重要性通常计算为该特征在集成中所有树上的平均重要性。这种平均过程使得重要性分数比单个决策树的更稳定。
在Scikit-learn中,训练基于树的模型后,获取特征重要性十分直接。大多数集成树估计器(如RandomForestClassifier、RandomForestRegressor、GradientBoostingClassifier、GradientBoostingRegressor、HistGradientBoostingClassifier等)在调用fit方法后会提供一个feature_importances_属性。
来看一个实际的例子。假设我们有特征矩阵X_train和目标向量 (vector)y_train。
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
# 假设X和y是预先加载的pandas DataFrame和Series
# 为了演示,我们创建合成数据:
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5,
n_redundant=2, n_classes=2, random_state=42)
feature_names = [f'feature_{i}' for i in range(X.shape[1])]
X = pd.DataFrame(X, columns=feature_names)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 初始化并训练一个RandomForestClassifier
rf_model = RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1)
rf_model.fit(X_train, y_train)
# 获取特征重要性
importances = rf_model.feature_importances_
# 创建一个DataFrame以便更好地可视化
importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': importances})
importance_df = importance_df.sort_values(by='Importance', ascending=False)
print("RandomForestClassifier的特征重要性:")
print(importance_df)
# 你可以使用柱状图可视化这些重要性
# (Plotly的可视化JSON将在下方生成)
这段代码训练了一个随机森林模型,然后提取并以降序打印出重要性分数。可视化这些分数通常能提供更清晰的认识。
随机森林模型计算的特征重要性,以水平柱状图形式展现。特征根据其对模型预测的贡献(平均不纯度下降)从最重要到最不重要进行排序。
获得重要性分数后,你可以用它们来选择特征子集。常用策略包括:
N个特征。Scikit-learn提供了SelectFromModel元转换器,它简化了这个过程。它接受一个具有feature_importances_(或线性模型的coef_)属性的估计器,并根据指定的阈值选择特征。
from sklearn.feature_selection import SelectFromModel
import numpy as np
# 将SelectFromModel与已训练的RandomForest模型一起使用
# 我们可以设置一个阈值,例如,选择重要性高于中位数重要性的特征
# 从已拟合的模型中计算中位数重要性
median_importance = np.median(rf_model.feature_importances_)
selector = SelectFromModel(estimator=rf_model, threshold=median_importance, prefit=True)
# 此外,如果希望SelectFromModel自行计算,可以使用 threshold='median'。
# selector = SelectFromModel(estimator=rf_model, threshold='median', prefit=True) # 'median' 需要字符串输入
# 'prefit=True' 是因为rf_model已经训练过了。
# 如果prefit=False,SelectFromModel将自行拟合估计器。
# 转换数据以仅保留选定的特征
X_train_selected = selector.transform(X_train)
X_test_selected = selector.transform(X_test)
# 获取选定特征的名称
selected_feature_indices = selector.get_support(indices=True)
selected_feature_names = X_train.columns[selected_feature_indices]
print(f"\n原始特征数量: {X_train.shape[1]}")
print(f"选定的特征数量 (重要性 > 中位数): {X_train_selected.shape[1]}")
print(f"选定的特征: {selected_feature_names.tolist()}")
SelectFromModel可以使用"mean"、"median"等阈值,或浮点数值(例如0.01)。你还可以指定max_features直接选择前N个特征,不过这通常需要在SelectFromModel内部重新拟合估计器,除非使用了prefit=True并且阈值能自行选定所需数量。
尽管基于树的特征重要性被广泛应用且高效,但请记住以下几点:
基于树的特征重要性提供了一种计算高效的方式,可以直接从许多数据科学家日常使用的模型中评估特征关联性。通过理解这些分数是如何获得的以及它们的潜在局限,你可以有效地将它们作为特征选择工具包的一部分,通常与SelectFromModel结合使用,以减少维度并可能提升模型性能和可解释性。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•