如何知道 RandomForest 中特定样本的特征及其贡献

Posted

技术标签:

【中文标题】如何知道 RandomForest 中特定样本的特征及其贡献【英文标题】:How to know the features and their contributions of a specific sample in RandomForest 【发布时间】:2018-07-26 07:30:31 【问题描述】:

如何找到影响特定样本预测的特征及其贡献,例如第 5 行

更新

感谢@FatihAkici

我现在可以应用 TreeInterpreter

from treeinterpreter import treeinterpreter as ti

instances = X_train.loc[[1,2]]
print(rf.predict(instances))
prediction, biases, contributions = ti.predict(rf, instances)

for i in range(len(instances)):
    print ("Instance", i)
    print ("Bias (trainset mean)", biases[i])
    print ("Feature contributions:")
    for c, feature in sorted(zip(contributions[i], 
                                 rf.feature_importances_), 
                             key=lambda x: ~abs(x[0].any())):
        print (feature, np.round(c, 2))
    print ("-"*20 )

print (prediction)
print (biases + np.sum(contributions, axis=1))

我的问题是为什么[ 0.12 -0.12] 有两个似乎是正面和负面的值,而不是那个特征的一个值。这是我的输出

【问题讨论】:

首先,feature_importances_ 是 RandomForestClassifier 的属性,而不是预测数据的属性。所以不适用于y_pred。其次,获取测试数据的特征重要性没有意义。该模型只能在它所看到的数据中找到特征的重要性(经过训练)。三、第二个问题是什么? @Vivek Kumar,你的第二点是我的问题(我会修改问题以反映你的想法),然后我可以训练整个数据集,然后提取该特定点的特征重要性。我正在制定我的第二个问题 那么您是说您想知道影响特定样本分类的特征吗? @Victor 每个样本没有一个路径,而是n_estimators 不同的路径 - 每个决策树都有一个路径。据我所知,没有重量。如果这是您想要的,您可以尝试计算每个特征在路径上的分割中使用的频率。 (我不确定这是否可以被视为重要性度量。)Sklearn 不公开此类功能,因此您必须自己实现decision_path 功能。 你也可以看看lime 【参考方案1】:

是的,您可以了解影响特定观察预测的特征及其贡献(权重不是正确的术语)。这实际上构成了它如何根据特定观察做出决定的决策路径。你要找的是TreeInterpreter。

第二个问题是:为什么每个变量和实例总是有两个值(比如[0.12 -0.12]代表第一个特征和第一个实例)似乎是正负,而不是该功能的一个价值?

所以我的答案是:这些列表中的每一个(例如[0.12 -0.12])只代表一个特征对实例属于第 1 类和第 2 类的最终概率的贡献。请记住,特性从不规定实例必须属于哪个类,而是增加或减少实例的最终类概率。所以 0.12 意味着特征 1 将实例 0 属于类 1 的概率增加了 0.12,并将其属于类 2 的概率降低了 0.12。这些值始终是对称的,这意味着无论使实例更有可能属于第 1 类的情况,都会使其不太可能属于第 2 类。

同样,特征 2 将实例 1 成为 1 类的概率降低了 0.05,并将其作为 2 类的概率增加了 0.05。

因此,每个特性对属于类 1 的实例 1 的贡献(增加或减少):0.12、-0.05、0.22、0.14、0.07、0.01。现在将这些全部加到属于第 1 类的偏差 (0.49854),您得到 1,即该实例属于第 1 类的最终概率,如模型输出所示。

类似地,将每个列表的所有第二个值相加,并加上属于第 2 类的偏差 (0.50146),得到 0,即该实例属于第 2 类的最终概率,如模型所示上面的输出。

最后对实例 1 重复完全相同的练习,即在 0.49854 的偏差上加上 -0.03、-0.11、0.06、0、-0.06、-0.04,得到 0.32,即Pinstance1 = class1。将 0.03, 0.11, -0.06, 0, 0.06, 0.04 添加到 0.50146 的偏差上,得到 0.68,即Pinstance1 = class2。因此,这些数字构成了一个完整的贡献轨迹,从一个实例的初始偏差到最终分类概率。

我在 datascience.stackexchange.com 上在概念层面回答了一个非常相似的问题,请随时查看by clicking here。

【讨论】:

Akici 我已经编辑了代码以打印功能名称而不是标题,你知道为什么它打印 2 个值而不是 1 个吗? @Victor 你已经完美地想通了,恭喜!关于 2 个值,这是非常典型的。我在 Python 和 R 建模期间都遇到过这种情况,它只代表因变量 (Y) 的两个类别。模型的每个特征都会增加或减少分类模型的最终结果(类概率)。第一个值是对第 1 类的特征贡献,其次是对第 2 类的贡献。它们始终是对称的,这意味着无论使观察更有可能属于第 1 类的情况,都会使其不太可能属于第 2 类。 @Victor 抱歉编辑晚了;我添加了关于输出中这两个对称值如何工作的解释。如果有任何不清楚的地方请告诉我,我们会进一步讨论。 @Victor 刚刚加了一句:“特征从不规定实例必须在哪个类中,相反,它们会增加或减少实例的最终类概率。”我猜这应该澄清你的困惑。每个特征只是略微提高或降低类概率。 非常感谢您详细而深入的解释。看了这么多网站和原文章,你的解释我最明白了。

以上是关于如何知道 RandomForest 中特定样本的特征及其贡献的主要内容,如果未能解决你的问题,请参考以下文章

r语言randomforest包下载不了

Weka 3.7 中 RandomForest 的精确实现

如何找出标准误差与正态分布的特定量相关的概率?

R语言 | randomForest包的随机森林回归模型以及对重要变量的选择

当给定特定类的 0 个样本时,如何对不平衡的数据集进行分类?

RandomForest随机森林