特征重要性评估

机器学习中,了解哪些特征对模型的预测能力贡献最大是非常重要的。这不仅可以帮助优化模型,还可以提高对数据的理解。本文将介绍如何使用随机森林模型来评估特征在分类任务中的重要性,并比较了基于不纯度减少(MDI)和排列重要性两种方法。

数据生成与模型拟合

首先,生成一个包含10个特征的合成数据集,其中只有3个特征是信息性的。特意不打乱数据集,以确保信息性特征对应于数据矩阵X的前三个列。此外,将数据集分为训练集和测试集。

from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split # 生成数据集 X, y = make_classification(n_samples=1000, n_features=10, n_informative=3, n_redundant=0, n_repeated=0, n_classes=2, random_state=0, shuffle=False) # 分割数据集 X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)

接下来,将使用随机森林分类器来计算特征重要性。

from sklearn.ensemble import RandomForestClassifier # 初始化随机森林分类器 forest = RandomForestClassifier(random_state=0) forest.fit(X_train, y_train)

在Jupyter环境中,可以重新运行此单元格以显示HTML表示,或在nbviewer.org上加载此页面以查看。在GitHub上,HTML表示无法渲染。

基于不纯度减少的特征重要性

特征重要性是通过拟合属性feature_importances_提供的,它们是每个树中不纯度减少的累积的平均值和标准差。需要注意的是,基于不纯度的特征重要性可能对高基数特征(许多唯一值)具有误导性。作为替代方案,可以查看下面的排列特征重要性。

import time import numpy as np # 计算特征重要性 start_time = time.time() importances = forest.feature_importances_ std = np.std([tree.feature_importances_ for tree in forest.estimators_], axis=0) elapsed_time = time.time() - start_time print(f"计算特征重要性所需的时间:{elapsed_time:.3f}秒")

可以绘制基于不纯度的重要性。

import pandas as pd import matplotlib.pyplot as plt # 绘制特征重要性 forest_importances = pd.Series(importances, index=[f"feature {i}" for i in range(X.shape[1])]) fig, ax = plt.subplots() forest_importances.plot.bar(yerr=std, ax=ax) ax.set_title("使用MDI的特征重要性") ax.set_ylabel("不纯度的平均减少") fig.tight_layout()

正如预期的那样,观察到前三个特征被认定为重要。

基于排列的特征重要性

排列特征重要性克服了基于不纯度的特征重要性的局限性:它们不会对高基数特征有偏见,并且可以在留出的测试集上计算。

from sklearn.inspection import permutation_importance # 计算排列特征重要性 start_time = time.time() result = permutation_importance(forest, X_test, y_test, n_repeats=10, random_state=42, n_jobs=2) elapsed_time = time.time() - start_time forest_importances = pd.Series(result.importances_mean, index=[f"feature {i}" for i in range(X.shape[1])]) print(f"计算特征重要性所需的时间:{elapsed_time:.3f}秒")

完整的排列重要性的计算成本更高。特征被n次打乱,模型被重新拟合以估计其重要性。

# 绘制排列特征重要性 fig, ax = plt.subplots() forest_importances.plot.bar(yerr=result.importances_std, ax=ax) ax.set_title("使用排列在完整模型上的特征重要性") ax.set_ylabel("平均准确度下降") fig.tight_layout() plt.show()

使用这两种方法都检测到了相同的最重要的特征,尽管相对重要性有所不同。正如图表所示,MDI不太可能完全忽略一个特征。

脚本的总运行时间

(0分钟0.941秒)

以下是一些相关的例子:

  • 使用并行森林树的像素重要性
  • 排列重要性与随机森林特征重要性(MDI)的比较
  • 具有多重共线性或相关特征的排列重要性
  • 梯度提升回归
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485