基于xgb+lime的中文情感分析结果可解释性展示

浏览: 3106

作者:数据取经团-数据栗子

前言

喂,这位同学,这个感觉上应该是A,你的模型怎么预测的是B?

image.png

做模型的小伙伴,平时肯定少不了这样的追问;

为了模型准确率只能放弃可解释性,线性模型固然好解释,但是大家都知道现实中线性的问题还是很少,大部分都是很复杂的非线性问题,面对这样的问题,该怎么办???

image.png

下面我就带大家一块看看在R中是怎么操作的?



针对诸如:随机森林、XGB等树模型都有了相关的Explainer工具包;

randomForestExplainer:https://github.com/MI2DataLab/randomForestExplainer

xgboostExplainer:https://github.com/AppliedDataSciencePartners/xgboostExplainer

感兴趣的小伙伴可以点进去仔细瞅瞅。

当然,也有通用性比较强的解释工具,也就是今天的主角:Lime(局部可理解的与模型无关的解释),在由Marco Tulio Ribeiro,Sameer Singh和Carlos Guestrin合作发表于 ACM 知识发现和数据挖掘年会(KDD2016)上的论文《"Why Should I Trust You?": Explaining the Predictions of Any Classifier》中,我们对信任和解释的问题进行了精细地探索。我们提出了局部可理解的与模型无关的解释技术(Local Interpretable Model-Agnostic Explanations: LIME),一种用于解释任何机器学习分类器的预测的技术,并在多种与信任相关的任务中评估了它的可用性。

论文地址:https://arxiv.org/abs/1602.04938

一些中文解读:https://www.oreilly.com.cn/ideas/?p=563http://geek.csdn.net/news/detail/66259

当然最近R也有了相应的包,我们今天就以情感分析为例来试试这个包。

image.png

环境

R语言及版本信息

image.png

最终效果

image.png

  • case1模型预测结果是label=1(即:正面评价),起决定性正面作用的是“不错”、“包装”、“很快”等;

  • case2模型预测结果是label=0(即:负面评价),起决定性正面作用的是“以后”、“烂的”等,这个结果还是可以理解的,“以后”这个词说明反悔了,以后不会再买了。。。

备注:绿色标注的词对于预测结果的特征权重为正值,说明对预测结果起到正向作用;红色标注的词对于预测结果的特征权重为负值,说明对预测结果起到负向作用。




代码实现

以爬取京东某款红酒的评价数据为例,我们借助lime来解读到底为什么xgboost将“京东的物流是没得说了,很快。这次买酒水类,包装很仔细,没有出现意外。酒到手了,绝对是正品。感觉很不错哟!”这句话预测为正面的:

library(lime)
library(stringi)
library(text2vec)
library(data.table)
library(magrittr)
library(purrr)
library(xgboost)
library(jiebaR)

上面引用的包里面,比较核心的有lime、text2vec、xgboost、jiebaR,对文本分析的核心就是讲文本向量化,而text2vec包绝B是R语言玩转NLP的支柱,其具有高性能、简洁、灵活、快速等特点,详细介绍见:https://cndocr.github.io/text2vec-doc-cn/index.html

如果后面有必要可以单独对这个包进行下详细介绍(包括:tf-idf、N-grams、GloVe 词向量、LSA/LDA主题模型、基于多种距离的文档相似性等);

读入数据:

#读入爬取的评价数据
good_sentences <- fread("C:/Users/topnet/Desktop/好评.csv",stringsAsFactors = F,encoding = "UTF-8")
bad_sentences <- fread("C:/Users/topnet/Desktop/差评.csv",stringsAsFactors = F,encoding = "UTF-8")

#将正面评论的label设为1,负面的设为0
good_sentences[, label := 1]
bad_sentences[, label := 0]

#合并
all_sentences <- rbind(good_sentences,bad_sentences)

使用text2vec处理中文和英文的区别就在于分词,英文可以直接通过空格切开,中文需要借助中文分词工具先切开,本文使用的是jieba的分词包

分词:

#使用全切模式full,定义一个切词引擎
cutter <- worker(type = "full",bylines = T,stop_word = "d:/stop_words.utf8")
#对评论comment进行分词
article_words <- sapply(all_sentences$comment, function(x) cutter <= x)

构建DTM矩阵:

#定义预处理函数以及 tokenization 函数
prep_fun = tolower
tok_fun = word_tokenizer
it_token = itoken(article_words,preprocessor = prep_fun,tokenizer = tok_fun, ids = rownames(all_sentences), progressbar = T)
vocab = create_vocabulary(it_token)
bigram_vectorizer = vocab_vectorizer(vocab)
dtm_token = create_dtm(it_token, bigram_vectorizer)

构建XGBOOST二分类模型:

#对数据进行转换,整理成xgb的数据格式
dtrain <- dtm_token %>%
xgb.DMatrix(label = all_sentences$label)

#设置参数
param <- list(max_depth = 10, eta = 0.1, objective = "binary:logistic", eval_metric = "error", nthread = 2)
#训练模型
bst <- xgb.train(param, dtrain, nrounds = 500)

到此,我们已经建立了一个简单的情感分类模型,下面借助lime工具对新的数据进行预测解释。

首先需要建立一些function,可以将输入的文本直接处理,输出DTM矩阵:

#首先是分词的函数
get.jieba <- function(data) sapply(data, function(x) cutter <= x)

#其次是token的函数
get.iterator <- function(data) itoken(get.jieba(data), preprocessor = prep_fun, tokenizer = tok_fun, progressbar = T)

#再次是得到DTM矩阵的函数
get.matrix <- function(data) {
i <- get.iterator(data)
create_dtm(i, bigram_vectorizer)
}

#最后根据DTM得到xgb的数据格式
get.features.matrix <- . %>%
get.matrix() %>%
xgb.DMatrix()

好啦,万事俱备,只等检验了。

#要预测和解释的文本
test_sentences <- "卧槽,这酒也太好喝了,简直没的说,绝对的物有所值,下来再买"

#Run lime() on training set
explanation  <- lime(unlist(article_words), bst, get.features.matrix, keep_word_position = F)
#Run explain() on explainer
results <- explain(test_sentences,explanation,n_labels = 1,n_features = 10)
plot_features(results)

结果是这样:

image.png

不好,翻船了!什么,怎么预测成负面的了(明明是正面的啊)。。。。

image.png

仔细看下,发现“没”这个单词居然对结果起到了决定性的作用。别急,下面让我们回去瞅瞅原始的文本数据:

image.png

我们发现:包含“没”的这么多label为0的样本,而且居然把“没有”这个词分开了(可能是jieba分词选择full模式导致的),通过反向分析为我们优化模型指明了方向:优化分词规则,优化训练集样本。

看到了没有,看出什么没有,同学们,这样还可以用来修正你的模型!!!




推荐 0
本文由 数据取经团 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册