如何判断两段文本说的是「同一件事情」?
刚刚被邱锡鹏大神赞了。。好激动。。这两天正好在看相关方向的论文,在原回答后面又补充回答一下attention based method, 怎样的siamese architecture, 不同的distance metrics,甚至怎样利用unsupervised pretraining在数据量有限的情况下尽量地generalize model达到最佳效果。欢迎吐嘈
----------------------
虽然问题放出来才七天,但感觉有种要歪楼的趋势,逼得不研究这个的工业狗来强答一波真的好吗。
首先先反对说这事做不了的,Paraphrase Identification即使是短文本的我感觉做的已经很不错了。微软的Microsoft Research Paraphrase Corpus (MSRP)数据集就是来搞这个事情的。这里贴一下地址 Paraphrase Identification (State of the art) 所有引用这个数据集的最高的F score已经到85.9%了,还是在training data只有4000+句子的基础上啊。这么小的数据自然需要加很多额外的feature才能跑得好,所以dependency tree啊wordnet啊的方法表现都很不错。SRL (Semantic Role Labelling)的结果也可以加进来当作feature啊,但纯用information extraction来做的方法我是不支持的,能作用到的句子范围太窄了
而如果你的数据量本身比较大的话完全可以尝试end-to-end的方法啊,省时省力迁移性也好。Quora作为一个国外知乎前些时间放出了一个公共数据集,用于检测问题是否是duplicated (下载地址 First Quora Dataset Release: Question Pairs ).
这里面有很多干扰项,比如有些相关而非意思相同的问题。对这个问题Quora自家放出一个benchmark,是基于LSTM的,请看这里 Semantic Question Matching with Deep Learning
结构非常简单,就是把一对问题Embedding了以后想办法用LSTM encode成representation再计算距离。端到端计算简直完美,然后他们好像并没有放code。但是不贴代码对初学者而言帮助并不大,于是我查了reddit,还真有人用类似的方法实现了,并将代码放在了github上,请移步 这里 lampts/my_dl_solutions 据作者称其F1达到了79%,auc达到了92%。数据集本身比较大嘛,并不稀奇。
这显然并不是最优的解法,加了attention的做法效果至少要再好5个百分点,然而我本人并没有实验过,坐等大神们来答state of the art的方法。因为类似的方法拿来做information retrieval based Question Answering基本连代码都不用改,最近也是相当火啊。抱歉中文有没有类似的数据集我不清楚但是方法应该是类似的。
最后顶一下2PiR的答案,希望他能详细说说
---------------------
暂时还没有大神登陆,所以我再自力更生贡献一点干货。我在之前的答案里说了,paraphrase identification和information retrieval based QA很像,为什么呢?因为一个问题的答案(e.g. 天空是蓝色的)从某种角度来看,可以看作是这个问题的paraphrase (e.g.天空是什么颜色的?)然后,假设我有一堆备选答案,有一些干扰项是相关但并不准确的(e.g.天空下的大地是绿色的),这时搜索引擎如何能排除干扰选项而找到最准确的答案呢?用paraphrase identification的模型一个个去比对备选答案呗,比对相似度最高的那个作为答案(基本是这个思路,当然实际当中不可能遍历去比如)
大家试想如果这个模型训练的好,对于用户的每一个问题,你都能从维基百科里找出最符合答案的一句话来作为回答,这样的成果是不是很诱人?基本上一个问答机器人的雏形就浮出水面了呀。确实不错,所以这一块现在也非常的火。有两个数据集提一下,一个叫insuranceQA,一个叫wikiQA,大家都在这上面跑benchmark。
我前面说了,Quora这个模型显然不是最优的。我下面会列举一些文章,谈谈它们的架构为什么有良好的表现,有代码的也贴贴代码,造福一下大家。
先介绍一下这一篇,APPLYING DEEP LEARNING TO ANSWER SELECTION: A STUDY AND AN OPEN TASK,真是业界良心。说它有良心倒真不是因为它的模型好,而是因为它做了很多实验,把我能想到的结构都试了一遍,这样我就不需要自己去试了,很费时间的。
它最终表示这个框架最好,全连接层和CNN层用的是共享权重(Siamese 结构),而这个P+T是指pooling和tanh层是Q和A分开的,说是这样的结构效果最佳。至于最终他们模型建议用的是GESD距离,而不是cosine similarity距离,CNN的filter加到4000之后模型在insuranceQA上表现最好能到0.65
然后下一篇是Attentive Pooling Networks,创新点在于用Q和A的representation构造了一个矩阵G,分别对这个G的row和column做max pooling, 这样就能分别能得到Q和A的attention vector。作为比较简单的attention实现,在wikiQA上表现大概是0.68几
说到这里要吐槽一下不用attention的模型,比如说Quora的模型,单凭一个cosine distance想把error BP传回去,这个也太理想了吧。真正句子之前相似度的比较是多个维度的比较,有word level, syntax level, semantic level,每个level都很微妙而难以捕捉,这时要通过attention机制把能匹配上的先匹配上再来看high-level层面的相似度,这样的模型才make sense不是吗。
还有三篇我想讲,但今天讲不动了。分别是Attentive CNN (Yin and Schütze, 2015) , L.D.C. (Wang et al., 2016) 和 Key-Value Memory Networks for Directly Reading Documents, 他们中间最好的在wikiQA上达到了0.70几,虽然就那么两个百分点,但是启示性是不一样的。所以等我有机会还要好好说说。
接下来要放代码了,这个博客用了keras的实现,是比较简单的Siamese结构用于insuranceQA的,也配有代码 Deep Language Modeling for Question Answering using Keras 但是该博主的代码效果并不理想,我觉得有几个原因,一来它Embedding用了fixed的word2vec,大家都知道fixed embedding会挺伤的,二来它cnn filter设太少,三来它Q和A的pooling并没有分开,所以效果真的还好。另外一个github, 效果是不错基本实现了论文中宣称的准确率,但是注释比较少,新手学习曲线有点小高,在这里也贴一下 white127/insuranceQA-cnn-lstm
key-value memory network的实现也很多啦,这里贴两个 https://github.com/facebook/MemNN/tree/master/KVmemnn 和 https://github.com/siyuanzhao/key-value-memory-networks Tensorflow
这里留了一个悬念,怎么用pretrained rnnlm来克服小数据不够用的问题还没说,过两天再来。。。