mpls工作原理通俗解释_用这两种方法向最终用户解释NLP模型的工作原理还是不错的...

点击上方关注,All in AI中国

上周,我看了一个关于“NLP的实践特性工程”的演讲。主要是关于LIME和SHAP在文本分类可解释性方面是如何工作的。

我决定写一篇关于它们的文章,因为它们很有趣、易于使用,而且视觉上很吸引人。

所有的机器学习模型都是在更高的维度上运行的,而不是在人脑可以直接看到的维度上运行的,这些机器学习模型都可以被称为黑盒模型,它可以归结为模型的可解释性。特别是在NLP领域中,特征的维数往往很大,说明特征的重要性变得越来越复杂。

LIME & SHAP不仅帮助我们向最终用户解释NLP模型的工作原理,而且帮助我们自己解释NLP模型是如何工作的。

利用 Stack Overflow 问题标签分类数据集,我们将构建一个多类文本分类模型,然后分别应用LIME和SHAP对模型进行解释。由于我们之前已经做过多次文本分类,所以我们将快速构建NLP模型,并着重于模型的可解释性。

数据预处理、特征工程和逻辑回归

 import pandas as pdimport numpy as npimport sklearnimport sklearn.ensembleimport sklearn.metricsfrom sklearn.utils import shufflefrom __future__ import print_functionfrom io import StringIOimport refrom bs4 import BeautifulSoupfrom nltk.corpus import stopwordsfrom sklearn.model_selection import train_test_splitfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score, f1_score, precision_score, recall_scoreimport limefrom lime import lime_textfrom lime.lime_text import LimeTextExplainerfrom sklearn.pipeline import make_pipelinedf = pd.read_csv('stack-overflow-data.csv')df = df[pd.notnull(df['tags'])]df = df.sample(frac=0.5, random_state=99).reset_index(drop=True)df = shuffle(df, random_state=22)df = df.reset_index(drop=True)df['class_label'] = df['tags'].factorize()[0]class_label_df = df[['tags', 'class_label']].drop_duplicates().sort_values('class_label')label_to_id = dict(class_label_df.values)id_to_label = dict(class_label_df[['class_label', 'tags']].values)REPLACE_BY_SPACE_RE = re.compile('[/(){}[]|@,;]')BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')# STOPWORDS = set(stopwords.words('english'))def clean_text(text): """ text: a string  return: modified initial string """text = BeautifulSoup(text, "lxml").text # HTML decoding. BeautifulSoup's text attribute will return a string stripped of any HTML tags and metadata. text = text.lower() # lowercase text text = REPLACE_BY_SPACE_RE.sub(' ', text) # replace REPLACE_BY_SPACE_RE symbols by space in text. substitute the matched string in REPLACE_BY_SPACE_RE with space. text = BAD_SYMBOLS_RE.sub('', text) # remove symbols which are in BAD_SYMBOLS_RE from text. substitute the matched string in BAD_SYMBOLS_RE with nothing. # text = ' '.join(word for word in text.split() if word not in STOPWORDS) # remove stopwors from text return textdf['post'] = df['post'].apply(clean_text)list_corpus = df["post"].tolist()list_labels = df["class_label"].tolist()X_train, X_test, y_train, y_test = train_test_split(list_corpus, list_labels, test_size=0.2, random_state=40)vectorizer = CountVectorizer(analyzer='word',token_pattern=r'w{1,}', ngram_range=(1, 3), stop_words = 'english', binary=True)train_vectors = vectorizer.fit_transform(X_train)test_vectors = vectorizer.transform(X_test)logreg = LogisticRegression(n_jobs=1, C=1e5)logreg.fit(train_vectors, y_train)pred = logreg.predict(test_vectors)accuracy = accuracy_score(y_test, pred)precision = precision_score(y_test, pred, average='weighted')recall = recall_score(y_test, pred, average='weighted')f1 = f1_score(y_test, pred, average='weighted')print("accuracy = %.3f, precision = %.3f, recall = %.3f, f1 = %.3f" % (accuracy, precision, recall, f1))
802c936e40d3a1c301bcbe62946cddd8.png

我们现在目标并不是产生最好的结果。我想尽快进入LIME & SHAP,这就是接下来发生的事情。

用LIME解释文本预测

从现在开始,这是有趣的部分。下面的代码片段主要是从LIME教程中借来的。

c = make_pipeline(vectorizer, logreg)class_names=list(df.tags.unique())explainer = LimeTextExplainer(class_names=class_names)idx = 1877exp = explainer.explain_instance(X_test[idx], c.predict_proba, num_features=6, labels=[4, 8])print('Document id: %d' % idx)print('Predicted class =', class_names[logreg.predict(test_vectors[idx]).reshape(1,-1)[0,0]])print('True class: %s' % class_names[y_test[idx]])
6219ec5a5a805ef5f801cb1659472929.png

我们在测试集中随机选择一个文档,它恰好是一个标记为sql的文档,我们的模型也预测它是sql。使用这个文档,我们为标签4 (sql)和标签8 (python)生成解释。

print ('Explanation for class %s' % class_names[4])print (''.join(map(str, exp.as_list(label=4))))
a529ebb31f6abb1d24b4ee20eb2a1c7e.png
print ('Explanation for class %s' % class_names[8])print (''.join(map(str, exp.as_list(label=8))))
d9856a627bb952b9b7b86b26f484c38a.png

很明显,这个文档对标签sql有最高的解释。我们还注意到正负号与特定的标签有关,例如单词"sql"对类sql是正的,而对类python是负的,反之亦然。

我们要为这个文档生成2类标签顶部。

exp = explainer.explain_instance(X_test[idx], c.predict_proba, num_features=6, top_labels=2)print(exp.available_labels())
ee064dfcc066d4dfb66402dbbbc7758b.png

它给出了sql和python。

exp.show_in_notebook(text=False)
dc44007bb735dd8cc1d4e09efb4c2281.png

让我来解释一下这种可视化:

1. 对于本文档,词 "sql"对于类sql具有最高的正分数。

2. 我们的模型预测该文档应该标记为sql,其概率为100%。

3. 如果我们从文档中删除word"sql",我们期望模型预测label sql的概率为100% - 65% = 35%。

4. 另一方面,单词"sql"对于类python是负面的,我们的模型已经了解到单词"range"对于类python有一个小的正面得分。

我们可能想放大并研究类sql的解释,以及文档本身。

exp.show_in_notebook(text=y_test[idx], labels=(4,))
63d6c08fa688480d89a9862af59f469f.png

使用SHAP解释文本预测

以下过程是从本教程中学到的。「链接」

from sklearn.preprocessing import MultiLabelBinarizerimport tensorflow as tffrom tensorflow.keras.preprocessing import textimport keras.backend.tensorflow_backend as KK.set_sessionimport shaptags_split = [tags.split(',') for tags in df['tags'].values]tag_encoder = MultiLabelBinarizer()tags_encoded = tag_encoder.fit_transform(tags_split)num_tags = len(tags_encoded[0])train_size = int(len(df) * .8)y_train = tags_encoded[: train_size]y_test = tags_encoded[train_size:]class TextPreprocessor(object): def __init__(self, vocab_size): self._vocab_size = vocab_size self._tokenizer = None def create_tokenizer(self, text_list): tokenizer = text.Tokenizer(num_words = self._vocab_size) tokenizer.fit_on_texts(text_list) self._tokenizer = tokenizer def transform_text(self, text_list): text_matrix = self._tokenizer.texts_to_matrix(text_list) return text_matrixVOCAB_SIZE = 500train_post = df['post'].values[: train_size]test_post = df['post'].values[train_size: ]processor = TextPreprocessor(VOCAB_SIZE)processor.create_tokenizer(train_post)X_train = processor.transform_text(train_post)X_test = processor.transform_text(test_post)def create_model(vocab_size, num_tags): model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(50, input_shape = (VOCAB_SIZE,), activation='relu')) model.add(tf.keras.layers.Dense(25, activation='relu'))model.add(tf.keras.layers.Dense(num_tags, activation='sigmoid')) model.compile(loss = 'binary_crossentropy', optimizer='adam', metrics = ['accuracy']) return model model = create_model(VOCAB_SIZE, num_tags)model.fit(X_train, y_train, epochs = 2, batch_size=128, validation_split=0.1) print('Eval loss/accuracy:{}'.format(model.evaluate(X_test, y_test, batch_size = 128)))
  • 模型训练完成后,我们使用前200个训练文档作为背景数据集进行集成,并创建一个SHAP explainer对象。
  • 我们在测试集的子集上获得各个预测的属性值。
  • 将索引转换为单词。
  • 使用SHAP的summary_plot方法来显示影响模型预测的主要特性。
attrib_data = X_train[:200]explainer = shap.DeepExplainer(model, attrib_data)num_explanations = 20shap_vals = explainer.shap_values(X_test[:num_explanations])words = processor._tokenizer.word_indexword_lookup = list()for i in words.keys(): word_lookup.append(i)word_lookup = [''] + word_lookupshap.summary_plot(shap_vals, feature_names=word_lookup, class_names=tag_encoder.classes_)
ae8b75f5173caf9fd415ae913aa7aa25.png
  • 单词"want"是我们模型使用的最大信号词,对类jquery预测贡献最大。
  • 单词"php"是我们模型使用的第四大信号词,当然对PHP类贡献最大。
  • 另一方面,单词"php"可能对另一个类有负面信号,因为它不太可能在python文档中看到单词"php"。

关于LIME & SHAP的机器学习可解释性,还有很多需要学习的地方。我只介绍了一小部分NLP。其余的可以在Github上找到。NLP-with-Python/LIME_SHAP_StackOverflow.ipynb at master · susanli2016/NLP-with-Python · GitHub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258932.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

向往2的年代

1. JDBC 对插入大量数据如何处理? 2. JAVA反射的使用,如何获取一个java类的某个方法? 3. 数据库连接池(优化) 4. 分布式事务管理转载于:https://www.cnblogs.com/dragonflyyi/p/3564843.html

C++ limits头文件的用法(numeric_limits)

初学C的时候,对这个模板很陌生,不知道它到底是做什么用的,今天拿起《C标准程序库》,出现了它的讨论,所以决定好好研究一番。 1. numeric_limits是什么? (A)《C标准程序库》&#xff…

三层架构——配置文件

1、配置文件是什么? 配置文件是随安装程序一起被安装到计算机上的文件,里面存放着安装好的应用程序执行时所须要的參数。 应用程序配置文件是标准的XML文件,XML标记和属性是区分大写和小写的。它能够按须要更改,开发者可使用配置文…

《嵌入式系统开发之道——菜鸟成长日志与项目经理的私房菜》——02-04项目范围(Scope)管理...

本节书摘来异步社区《嵌入式系统开发之道——菜鸟成长日志与项目经理的私房菜》一书中的第2章,第2.4节,作者:邱毅凌,更多章节内容可以访问云栖社区“异步社区”公众号查看 02-04项目范围(Scope)管理 嵌入式…

flex(入门)之timer的使用,键盘,鼠标的监听

package {import flash.display.Shape;import flash.display.Sprite;import flash.events.Event;import flash.events.KeyboardEvent;import flash.events.MouseEvent;import flash.events.TimerEvent;import flash.utils.Timer;import mx.controls.Label;//窗体大小&#xff0…

python 线程超时设置_python 条件变量Condition(36)

文章首发微信公众号,微信搜索:猿说python对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition.一.线程条件变量Condition相关函数介绍acquire() — 线程…

MsWord 操作总结

转自(http://www.cnblogs.com/eye-like/p/4121219.html) Msdn上的word操作api(不过只有英文版,英文差的先闪过) Word2007的API:http://msdn.microsoft.com/en-us/library/bb257531(voffice.12).aspxWord201…

fwrite,fread and fprintf,fscanf的一些使用体会

这周一直在完成一个任务,就是将训练出的多个model写成一个model。其中我们使用了c语言的读写方法,搞了一星期, 挖了很多坑,最终都铲平了。下面列举出若干有用的知识。 1.fwrite,fread VS fprintf,fscanf的区别 fwrite,fread 读写…

《第一桶金怎么赚——淘宝开店创业致富一册通》一一1.4 淘宝开店创业的流程...

本节书摘来自异步社区出版社《第一桶金怎么赚——淘宝开店创业致富一册通》一书中的第1章,第1.4节,作者:葛存山,更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.4 淘宝开店创业的流程 第一桶金怎么赚——淘宝开店创业致…

检测虚拟机代码总汇(更新中)

检测虚拟机代码 1 004092D0 /. 55 push ebp2 004092D1 |. 8BEC mov ebp,esp3 004092D3 |. 51 push ecx4 004092D4 |. 53 push ebx5 004092D5 |. 68 1D934000 push 0040931D 6 004092DA |. 64:FF35…

两数之和 python_同一屏幕播放两个视频 视频左右两个画面或视频上下两个画面如何制作...

咱们在网上经常可以看到一些视频画面是可以在同一屏幕播放两个视频,有的是视频左右两个画面或视频上下两个画面这些是如何制作的呢,其实熟悉视频编辑软件的网友应该会比较了解这些操作,好嘞,来,现在就让小编来演示一下…

dlib人脸特征点对齐

前面我们介绍了使用dlib进行人脸检测&#xff0c;下面我们给出如何使用dlib进行人脸特征点检测。我们直接贴出代码。我们的代码包括如下几部分功能&#xff1a; 检测单张图片检测一个视频检测一个camera 先给出代码&#xff1a; #include <dlib/image_processing/frontal_…

IOS开发基础知识--碎片13

1:运行程序报the file couldnt be opened because you dont have permission to view it 解决办法&#xff1a;项目—>targets->build settings->build options->changed the value of the "Compiler for C/C/Objective-C" to Default Compiler. 2:百度…

《LoadRunner 12七天速成宝典》—第2章2.6节第二个性能测试案例

本节书摘来自异步社区《LoadRunner 12七天速成宝典》一书中的第2章&#xff0c;第2.6节第二个性能测试案例&#xff0c;作者陈霁&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.6 第二个性能测试案例云云&#xff1a;烤鱼吃得很爽。 恋恋&#xff1a;就…

MongoDB_1

突然想去看下MongoDB的东西&#xff0c;于是有了这篇文章。其实很早以前就看过一些关于NoSql的文章&#xff0c;还记得当时里面有介绍MongoDB的&#xff0c;多瞅了2眼&#xff0c;并且在Window下安装了MongoDB的驱动&#xff0c;小玩了会。今天重新翻出来&#xff0c;没成想在命…

牛顿法与拟牛顿法,SDM方法的一些注记

SDM方法 考虑一般额NLS问题&#xff1a; f(x)minx||h(x)−y||2这里x为优化参数&#xff0c;h为非线性函数&#xff0c;y是已知变量&#xff0c;如下是基于梯度的迭代公式&#xff1a; ΔxαAJTh(h(x)−y)这里α是步长&#xff0c;A是缩放因子&#xff0c;Jh是h在当前参数x下的…

pyqt5从子目录加载qrc文件_实战PyQt5: 045-添加资源文件

添加资源文件在使用PyQt进行图形界面开发的时候不免要用到一些外部资源&#xff0c;比如图片&#xff0c;qss配置文件等。在前面代码中&#xff0c;遇到这类问题&#xff0c;我们使用绝对路径的方式来解决&#xff0c;这种方式&#xff0c;本身有其不方便之处(比如&#xff0c;…

《 Python树莓派编程》——2.7 总结

本节书摘来自华章出版社《Python树莓派编程》一书中的第2章&#xff0c;第2.7节&#xff0c;作者&#xff1a;[美]沃尔弗拉姆多纳特&#xff08;Wolfram Donat&#xff09;著 韩德强 等译&#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看。 2.7 总结 本章简…

ACM的输入输出总结

关于ACM的输入输出&#xff08;一&#xff09; 一般来说ACM的现场赛会规定输入输出 或者是文件输入标准输出 也可能是文件输入文件输出 如果没有规定的话那么一般就是标准的输入输出了 那说一下输入输出的重定向 一般用下面两种方法 c常用: #include <fstream.h>ifstream…

hdu 2064汉诺塔III 递推

汉诺塔递推题&#xff0c;比汉诺塔多了一个限制条件&#xff0c;盘子只允许在相邻的柱子之间移动。 分析&#xff1a; 第1步:初始状态&#xff1b; 第2步:把上面的n-1个盘移到第3号杆上&#xff1b; 第3步:把第n个盘从1移到2&#xff1b; 第4步:把前n-1个从3移到1&#xff0c;给…