Lime vs TreeInterpreter用于解释决策树

时间:2018-02-21 15:18:33

标签: python machine-learning scikit-learn

Lime来源:https://github.com/marcotcr/lime

treeinterpreter来源:tree interpreter

我试图了解DecisionTree如何使用Lime和treeinterpreter进行预测。虽然两者都声称他们能够在他们的描述中解释决策树。似乎两者都以不同的方式解释相同的DecisionTree。也就是说,特征贡献顺序。怎么可能?如果两个人都在看同样的事情,并试图描述相同的事件,但按差异顺序分配重要性。

我们应该信任谁?特别是顶部特征在预测中起作用的地方。

树的代码

import sklearn
import sklearn.datasets
import sklearn.ensemble
import numpy as np
import lime
import lime.lime_tabular
from __future__ import print_function
np.random.seed(1)
from treeinterpreter import treeinterpreter as ti
from sklearn.tree import DecisionTreeClassifier

iris = sklearn.datasets.load_iris()

dt = DecisionTreeClassifier(random_state=42)                
dt.fit(iris.data, iris.target)

n = 100


instances =iris.data[n].reshape(1,-1)

prediction, biases, contributions = ti.predict(dt, instances)


for i in range(len(instances)):
    print ("prediction:",prediction)
    print ("-"*20) 
    print ("Feature contributions:")
    print ("-"*20) 

    for c, feature in sorted(zip(contributions[i], 
                                 iris.feature_names), 
                             key=lambda x: ~abs(x[0].any())):

        print (feature, c)

石灰代码

import sklearn
import sklearn.datasets
import sklearn.ensemble
import numpy as np
import lime
import lime.lime_tabular
from __future__ import print_function
np.random.seed(1)
from sklearn.tree import DecisionTreeClassifier

iris = sklearn.datasets.load_iris()

dt = DecisionTreeClassifier(random_state=42)                
dt.fit(iris.data, iris.target)

explainer = lime.lime_tabular.LimeTabularExplainer(iris.data, feature_names=iris.feature_names, 
                                                   class_names=iris.target_names, 
                                                   discretize_continuous=False)

n = 100


exp = explainer.explain_instance(iris.data[n], dt.predict_proba, num_features=4, top_labels=2)

exp.show_in_notebook(show_table=True,  predict_proba= True , show_predicted_value = True , show_all=False)

让我们先看一下的输出。

enter image description here

所以 a 它确实说它是 virginica 。但是通过在

中分配重要性

1)花瓣宽度(cm)然后花瓣长度(cm)

现在让我们看一下 lime

的输出

enter image description here

是的,它确实说算法预测 virginica 但是看看它是如何进行分类的,我们清楚地看到以下

1)花瓣长度(cm)>用石灰代替花瓣长度(cm)的花瓣宽度(cm)<1。花瓣宽度(cm)如树所示

2)其中萼片宽度和萼片长度预测为零,石灰声称具有一定的价值,如上传图片所示

这里发生了什么?

当功能为1000+时,问题就会增加,每个数字对于做出决定都很重要。

1 个答案:

答案 0 :(得分:12)

为什么这两种方法有可能产生不同的结果?

Lime :对其工作原理的简短说明,取自github page

  

直观地,解释是模型行为的局部线性近似。虽然模型在全局范围内可能非常复杂,但更容易在特定实例的附近进行近似。在将模型视为黑盒时,我们会扰乱我们想要解释的实例并学习围绕它的稀疏线性模型,作为解释。下图说明了此过程的直觉。模型的决策函数由蓝色/粉红色背景表示,并且显然是非线性的。明亮的红十字是正在解释的实例(让我们称之为X)。我们对X周围的实例进行采样,并根据它们与X的接近程度对它们进行加权(这里的重量用大小表示)。然后,我们学习了一个线性模型(虚线),它近似于X附近的模型,但不一定是全局的。

github页面上的各种链接中有更详细的信息。

treeinterpreter http://blog.datadive.net/interpreting-random-forests/上提供了对此工作原理的解释(这是针对回归的;可以找到分类的示例,其工作方式非常相似{{3} })。

简而言之:假设我们有一个节点将特征F与某个值进行比较,并根据该节点拆分实例。假设到达该节点的所有实例中有50%属于类C。假设我们有一个新实例,它最终被分配给该节点的左子节点,现在80%的所有实例都属于类C。然后,功能F对此决策的贡献计算为0.8 - 0.5 = 0.3(如果沿着路径还有更多节点使用功能F,则加上附加项。)

比较:需要注意的重要一点是,Lime是一种独立于模型的方法(不是特定于决策树/ RF),它基于局部线性近似。另一方面,Treeinterpreter以与决策树本身类似的方式操作,并且真正关注算法在比较中实际使用哪些特征。所以他们真的从根本上做了不同的事情。 Lime说&#34;如果我们稍稍摆动一个特征就很重要,这会产生不同的预测&#34;。 Treeinterpreter说&#34;如果将一个特征与我们的一个节点中的阈值进行比较,那么这个特征很重要,这导致我们采取分裂,大大改变了我们的预测&#34;。

值得信赖哪一个?

这很难明确回答。它们可能都以自己的方式有用。直观地说,您可能倾向于乍一看倾向于解释树,因为它是专门为决策树创建的。但是,请考虑以下示例:

  • 根节点:50%的实例0级,50%1级。如果F <= 50,请向左走,否则向右走。
  • 左孩子:48%的实例0级,52%的1级。在此之下的子树。
  • 右孩子:99%的实例0级,1%的实例级别1.低于此级别的子树。

如果大部分实例都离开了,只有一些是正确的,这种设置是可能的。现在假设我们有一个F = 49的实例被分配到左边并最终分配了类1. Treeinterpreter不关心F真的接近于等式的另一边在根节点中,并且仅分配0.48 - 0.50 = -0.02的低贡献。 Lime会注意到只更改F会完全改变赔率。

哪一个是对的?那不是很清楚。你可以说F非常重要,因为如果它只是有点不同,预测会有所不同(然后是石灰胜利)。你也可以说F对我们的最终预测没有贡献,因为我们在检查它的价值之后几乎没有接近决定,之后仍然需要调查许多其他功能。然后treeinterpreter获胜。

为了在这里获得更好的想法,实际绘制学习的决策树本身可能会有所帮助。然后,您可以手动跟随其决策路径并确定您认为哪些功能很重要和/或看看您是否能够理解为什么Lime和treeinterpreter都会说出他们所说的内容。