石灰来源:https://github.com/marcotcr/lime
树解释器来源:tree interpreter
我试图了解 DecisionTree 如何使用 Lime 和 treeinterpreter 进行预测。虽然两者都声称他们能够在他们的描述中解释决策树。似乎两者都以不同的方式解释相同的 DecisionTree。即特征贡献order。这怎么可能?如果两者都在看同一件事,并试图描述同一事件,但按不同顺序分配重要性。
我们应该信任谁?尤其是最重要的特征在预测中很重要的地方。
树的代码
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)
让我们先看看树的输出。
所以 a 它确实正确地说它是 virginica。但是,通过在
中分配重要性1) 花瓣宽度 (cm) 然后花瓣长度 (cm)
现在让我们看看 lime
的输出是的,它确实说算法预测了 virginica,但是看看它是如何进行分类的,我们清楚地看到以下内容
1)花瓣长度(cm)>花瓣宽度(cm)以石灰代替花瓣长度(cm)<>
2) 其中萼片宽度和萼片长度预测为零,石灰声称具有一定的值(value),如上传的图片所示
这里发生了什么?
当特征达到 1000+ 时,问题就越来越大,每个数字都对做出决定很重要。
最佳答案
Lime:对其工作原理的简短说明,摘自他们的github page :
Intuitively, an explanation is a local linear approximation of the model's behaviour. While the model may be very complex globally, it is easier to approximate it around the vicinity of a particular instance. While treating the model as a black box, we perturb the instance we want to explain and learn a sparse linear model around it, as an explanation. The figure below illustrates the intuition for this procedure. The model's decision function is represented by the blue/pink background, and is clearly nonlinear. The bright red cross is the instance being explained (let's call it X). We sample instances around X, and weight them according to their proximity to X (weight here is indicated by size). We then learn a linear model (dashed line) that approximates the model well in the vicinity of X, but not necessarily globally.
在 github 页面上的各个链接中有更详细的信息。
treeinterpreter:http://blog.datadive.net/interpreting-random-forests/ 上提供了有关其工作原理的说明(这是用于回归;可以找到一个非常相似的分类示例,可以找到 here)。
简而言之:假设我们有一个比较特征的节点 F到某个值并基于此拆分实例。假设到达该节点的所有实例中有 50% 属于类 C .假设我们有一个新实例,它最终被分配给该节点的左子节点,现在所有实例的 80% 属于类 C .然后,特征的贡献F因为这个决定被计算为 0.8 - 0.5 = 0.3 (如果沿叶路径有更多节点也使用特征 F,则加上附加条款。
比较:需要注意的重要一点是,Lime 是一种独立于模型的方法(并非特定于决策树/RFs),它基于局部线性逼近。另一方面,Treeinterpreter 具体以与决策树本身类似的方式运行,并真正查看算法在比较中实际使用了哪些特征。所以他们实际上在做完全不同的事情。 Lime 说“一个特征很重要,如果我们稍微调整一下它就会产生不同的预测”。 Treeinterpreter 说“如果将某个特征与我们的一个节点中的阈值进行比较,它就会很重要,这会导致我们进行拆分,从而彻底改变了我们的预测”。
这很难明确回答。它们可能都以自己的方式有用。直觉上,你可能第一眼就倾向于 treeinterpreter,因为它是专门为决策树创建的。但是,请考虑以下示例:
F <= 50 , 向左走,否则向右走。如果大多数实例向左移动,只有一些向右移动,则这种设置是可能的。现在假设我们有一个带有 F = 49 的实例被分配到左侧并最终分配到第 1 类。Treeinterpreter 不会关心 F真的很接近在根节点中等式的另一边结束,并且只分配了 0.48 - 0.50 = -0.02 的低贡献. Lime 会注意到 F 的变化只需一点点就会完全改变赔率。
哪一个是对的?这还不是很清楚。你可以说F非常重要,因为如果它只有一点点不同,预测就会不同(然后石灰获胜)。你也可以争辩说F对我们的最终预测没有贡献,因为在检查了它的值(value)之后我们几乎没有接近一个决定,并且之后仍然需要研究许多其他特征。然后 treeinterpreter 获胜。
为了在此处获得更好的想法,实际绘制学习到的决策树本身也可能会有所帮助。然后,您可以手动遵循它的决策路径,并决定您认为哪些功能很重要和/或看看您是否可以理解为什么 Lime 和 treeinterpreter 会说他们所说的。
关于python - Lime vs TreeInterpreter 用于解释决策树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48909418/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决