树模型特征重要性
不纯度重要性统计特征为树划分带来的累计改善,但不能解释因果。
学习前需要掌握
背景与问题
一棵树经常使用某个特征,不代表改变该特征会导致结果变化。高基数变量有更多尝试划分的机会,相关特征又可能互相替代。重要性分数首先解释特定模型的使用方式,而不是现实世界的因果关系。
概念定义
不纯度重要性 MDI 汇总某特征参与分裂时带来的样本加权不纯度下降,再按总量归一化。置换重要性固定已训练模型,在指定评价数据上打乱一个特征并测量分数下降,回答该模型对该特征信息的依赖程度。
直观理解
一本复习资料经常被翻阅,并不证明没有它就会考差;也可能有另一本内容相同的资料。置换像临时把一份资料的页码打乱,观察现有答题方法受多大影响,但并不是重新训练后能否适应。
核心原理
MDI 在训练分裂上计算,可能偏向连续或高基数特征,并把过拟合噪声也记作贡献。分数为零只说明当前模型没使用它,不说明该变量在任何合理模型中都无价值。
置换应在独立验证数据上使用与任务一致的 scoring,并重复计算不确定性。高相关特征互相替代会降低单列置换损失;独立打乱还可能制造不现实组合,分组置换也需要领域约定。
重要性应先建立在模型有足够预测能力的前提上。跨折比较、相关簇分析和领域干预可补充证据;若用置换结果筛选特征,就需要训练内嵌套选择与独立最终测试,不能反复消费同一测试集。
数学表达
置换引起的评分下降
模型固定不重训;若 scoring 越大越好,正下降表示置换损害该模型表现。
变量含义
变量定义与本页概念定义一致,代码中的同名变量保持相同语义。
计算步骤
- 1先固定独立验证与评分指标,训练可靠基线。
- 2读取 MDI 并检查基数、泄漏列和训练过拟合。
- 3在验证数据对各列重复置换,保留均值和波动。
- 4检查相关列是否互相替代,必要时按组分析。
代码对应位置
示例 1在验证划分计算置换重要性:完整训练模型并在保留划分置换,输出构造数据上的 MDI 与平均分数下降。
手算与场景核对
假设树的加权不纯度下降中,特征 A 贡献 0.2,B 贡献 0.1,归一化 MDI 为 2/3 和 1/3。这些比例分配的是已建成树的分裂改善,不是目标的因果解释份额。
若验证准确率为 0.90,置换 A 后平均为 0.70,则本协议的置换重要性为 0.20;换模型、换验证分布或存在相关替代特征,数值都可能改变。下方使用固定构造数据执行这一计算。
计算与实现步骤
- 先固定独立验证与评分指标,训练可靠基线。
- 读取 MDI 并检查基数、泄漏列和训练过拟合。
- 在验证数据对各列重复置换,保留均值和波动。
- 检查相关列是否互相替代,必要时按组分析。
- 仅作模型依赖解释;特征筛选与因果结论另需验证。
代码实现
示例 1
在验证划分计算置换重要性
example_01.py用途:完整训练模型并在保留划分置换,输出构造数据上的 MDI 与平均分数下降。
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.inspection import permutation_importance
from sklearn.model_selection import train_test_split
X, y = make_classification(n_samples=200, n_features=4, n_informative=2,
n_redundant=1, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.3,
stratify=y, random_state=42)
model = RandomForestClassifier(n_estimators=50, min_samples_leaf=2, random_state=42)
model.fit(X_train, y_train)
result = permutation_importance(model, X_valid, y_valid, n_repeats=5,
scoring="accuracy", random_state=42)
print(f"validation_accuracy={model.score(X_valid, y_valid):.4f}")
print("MDI=" + ",".join(f"{x:.4f}" for x in model.feature_importances_))
print("permutation=" + ",".join(f"{x:.4f}" for x in result.importances_mean))代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
完整训练模型并在保留划分置换,输出构造数据上的 MDI 与平均分数下降。
X- 完整特征矩阵,每行一个样本、每列一个特征。
y- 目标标签或连续目标值。
X_train- 训练特征,只允许它参与预处理器和模型的 fit。
y_train- 与 X_train 对齐的训练目标。
model- 组合预处理和估计器的模型对象。
Step 1 · 1–5 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.inspection import permutation_importance
from sklearn.model_selection import train_test_splitStep 2 · 7–17 行
按固定协议切分训练与测试数据;此处的数据边界决定后续哪些样本可以参与 fit。
X, y = make_classification(n_samples=200, n_features=4, n_informative=2,
n_redundant=1, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.3,
stratify=y, random_state=42)
model = RandomForestClassifier(n_estimators=50, min_samples_leaf=2, random_state=42)
model.fit(X_train, y_train)
result = permutation_importance(model, X_valid, y_valid, n_repeats=5,
scoring="accuracy", random_state=42)
print(f"validation_accuracy={model.score(X_valid, y_valid):.4f}")
print("MDI=" + ",".join(f"{x:.4f}" for x in model.feature_importances_))
print("permutation=" + ",".join(f"{x:.4f}" for x in result.importances_mean))代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
validation_accuracy=0.9000 MDI=0.2276,0.5726,0.1387,0.0611 permutation=0.0233,0.4000,0.0000,-0.0033
常见错误 · 5 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 把模型重要性写成因果效应或业务贡献比例。
- 在训练集做置换后将分数作为独立泛化证据。
- 相关特征单列置换损失小,就认定它们都没用。
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 发现模型过度依赖 ID、时间泄漏或代理特征。
- 为后续特征分析形成候选,结合跨折稳定性筛选检查重点。
常见错误
- 把模型重要性写成因果效应或业务贡献比例。
- 在训练集做置换后将分数作为独立泛化证据。
- 相关特征单列置换损失小,就认定它们都没用。
资料与假设
参见 scikit-learn:Permutation feature importance。 本页数值均为构造例;涉及模型分数时仅说明给定数据与协议下的计算。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。