/* 版权声明:能够随意转载,转载时请标明文章原始出处和作者信息 .*/
                                                     author: 张俊林

问答社区算是一类已经比較成熟的互联网应用了,国外的比方Quora、StackOverflow。国内的比方老派的百度知道,新一代的知乎,都算是代表性的社交类问答社区。问答社区本质上就是个人肉知识库,通过一段时间的积累,会累积相当多以<问题。答案>方式存在的知识。

除了这些通用的问答社区外还有非常多垂直领域的问答社区,比方我们畅捷通的会计家园。就是拥有数百万財会人员的知识交流社区,財会人员能够在社区提出自己的一些工作和生活中的疑问,会有非常多热心网友或领域专家帮你答疑解惑,会计家园长这个样子:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

这样的问答社区往往有信息冗余的问题。就是说历史上已经有不少同样的问题以及答案,可是非常多用户并不清楚这点,往往还会问出同样的问题,当然两个问题虽然是同一个问题,可是因为语言表达的灵活性,在字面上看起来可能问题还是有区别。就比方以下两个问题:

问题A:注冊资本认缴制下实收资本的账务怎样处理?

问题B:认缴制下成立的公司。一開始的账务处理是什么样的,实收资本要做吗?求解

为了能够添加信息的复用率。我们已经使用自然语言处理、搜索技术以及一些深度学习的技术做了问题推荐系统,在用户提问的时候就将语义相关的问题推荐出来。假设用户看到类似的问题直接看答案即可,所以用户提问的时候看到的这样的交互界面:

可是我们想更进一步,是否能在用户问出问题后,直接把答案交给用户?说实话,这事实上是搜索引擎的近乎终极目标。就是用户提出疑问,直接给出答案。眼下搜索引擎的交互方式还是比較原始的,比方用户发出问题。然后人要在搜索结果里面再筛一遍,找到真正自己关心的答案。所以事实上是技术+人工的方式。将来的搜索引擎交互方式应该是用户问问题。搜索引擎直接给答案。当然详细体现形式能够有多种,比方眼下比較火的聊天机器人本质上就是在往这个目标走的一个中间形式。也就是说是这样的方式:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

将来的话,假设全息投影技术普及后,应该就是科幻电影里常见的交互模式。那时候随时随地召唤出全息天使全天候为您服务,您不用操心雾霾天他有没胆出门的问题…..比方以这样的附体方式:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
   嗯,上面是口味比較重的用户的选择,大多数用户可能会更喜欢这样的附体方式:

闲话少叙,让我们言归正传而且紧张严肃起来。形式化地说。如今我们面临的是例如以下问题:

找到与Qnew语义同样的问题Qi后,将Qi相应的答案Ai推荐给用户,就完毕了用户提出新问题后。直接告诉用户答案的任务。所以这个问题本质上是个问句Paraphrase问题。就是说推断两个句子是否语义等价的问题。

(读者小Y画外音Qi:请说人话!

作者小张回答Ai请去京东买本初中数学教材。)

我们用Word Embedding加上卷积神经网络CNN来解决问题。CNN不必说了,眼下在图像处理领域基本已经横扫,未来两年出现1000层CNN网络叠加起来解决应用问题也不必惊奇。

Word Embedding更是深度学习在文本处理领域的技术基石。假设如今做应用不用这两样东西预计你出门不太好意思跟同行打招呼吧。为了面子上挂得住,咱得掏出这两把刷子刷刷。以证明咱确实拥有这两把刷子。

一种直观的思路会用两个CNN来解决问题。其架构图例如以下:

就是说首先把两个要推断语义是否等价的句子转换为Word Embedding形式,作为整个神经网络的输入层,然后CNN1通过卷积层和池化层来抽取出一个句子的语义特征,CNN2抽取出另外一个句子的语义特征,之后两个CNN的池化层拼接起来作为兴许三层神经网络的输入层,兴许三层神经网络通过隐层对两组语义特征进行非线性变换。最后通过线性层分类输出,得出两个句子是语义同样(比方输出1)或者语义不同(比方输出0)的分类结果。

可是,我们想换种思路来做这个任务。能不能把输入层改造成真正的二维结构。就像一张图片那样。然后套上一个CNN来解决问题呢?让我们来试试,首先第一个问题是。给定两个句子SentenceA和SentenceB,怎样把CNN的输入层改造成类似图片的二维结构?

在做之前,我们假设两个句子例如以下:(说明:这个样例仅仅是为了方便绘图和举例,真实的训练和測试样例是会计家园的实际问题对,长度大约在10几个字到几十个字左右)

SentenceA:电脑多少钱?

SentenceB:计算机价格?

能够这么做:

Step1:把SentenceA分割成3-Gram表达形式,于是SentenceA变成例如以下形式

SetA={电脑多。脑多少。多少钱}

Step2:把SentenceB分割成3-Gram表达形式。于是SentenceB变成例如以下形式

SetB={计算机,算机价,机价格}

Step3:把SetA的元素作为纵坐标。SetB的元素作为横坐标,将两个输入改造成二维结构,就像以下的图形:

Step4:那么这个矩阵格子里面的值怎么填呢?用横坐标和纵坐标相应的语言片段的语义类似性填充就能够。于是新问题又产生了,给了两个语言片段。比方“多少钱”和“机价格”,怎样计算它们的语义类似性呢。请移步看Step5;

Step5:计算两个语言片段的语义类似性。

此时锣鼓点响起,我们的小杀器Word Embedding该粉墨登场了。

首先能够用Word2Vec训练出每一个汉字的Word Embedding,也就是其低维向量表示。一定程度上代表其包括的语义信息。

那么3-GRAM包括了三个汉字,这3-GRAM的语义向量Word Embedding该怎么表示?能够简单粗暴地把其三个汉字的Word Embedding相应维度上的值累加求和即可,看上去霸王硬上弓包办婚姻,可是事实上这是一种通常的做法,一般应用效果还能够。嗯,我们土豪界办事情通常就是这么任性。

这样两个3-GRAM片段相应的Word Embedding都有了,剩下的就简单了,它们两个的语义类似性直接用Cosine计算两个Word Embedding在语义空间的向量夹角就成。一般语义越类似。Cosine得分越大。

Step 6:有了Step5的锦囊妙计。就能够完形填空。填充矩阵中相应格子的值了,假设填充完图形例如以下:

那么类似图片的二维输入结构就完毕了。

这个矩阵代表什么含义呢?代表的是两个句子随意两个语言片段之间的语义类似性。

有了上面填充好的二维矩阵作为神经网络的输入层,那么后面就简单了,你就当做输入的是个图片。然后直接套上一层或者多层CNN,最后再加上一个全联接分类层就齐活了。改造完的神经网络结构例如以下:

敲定了网络结构。剩下的就是训练神经网络了。我们利用眼下已经做好的问题推荐系统。通过人工找到语义同样表达不同的句子对作为训练集的正例,把一些语义相近可是不同的句子对作为训练集的负例。然后就能够训练这个基于Word Embedding和CNN的神经网络了。

通过实验我们发现,多层CNN并不能带来性能优势。所以终于仍然採用了一层CNN结构。然后用Torch 7训练模型。调整超參数比方隐层神经元个数,卷积层filter的个数等,终于最优分类精度在90.36%左右。效果还不错。说明祭出CNN这个大杀器和Word Embedding这个小杀器还是有效的。

当然这跟负例中两个句子对的语义相关性有一定关系,非常明显负例句子对语义相关性越高。分类难度越大,后面我们还会不断添加分类难度对模型进行调整。

致谢:感谢畅捷通公司智能平台沈磊、薛会萍、桑海岩和黄通文等同事在构建模型和整理训练数据方面的工作。

扫一扫关注微信号:“布洛卡区” ,深度学习在自然语言处理等智能应用的技术研讨与科普公众号。

利用卷积神经网络(CNN)构造社区问答系统的更多相关文章

  1. 使用深度双向LSTM模型构造社区问答系统

    所看到的. 首先强调一下,这个结构也是一个解决对照两个句子类似性的通用RNN解决方式,不只能够使用在问答社区.凡是涉及到对照两个句子或者实体关系的场合全然能够套用这个模型来解决.这点希望读者注意. 首 ...

  2. 卷积神经网络(CNN)基础介绍

    本文是对卷积神经网络的基础进行介绍,主要内容包含卷积神经网络概念.卷积神经网络结构.卷积神经网络求解.卷积神经网络LeNet-5结构分析.卷积神经网络注意事项. 一.卷积神经网络概念 上世纪60年代. ...

  3. 卷积神经网络(CNN)反向传播算法

    在卷积神经网络(CNN)前向传播算法中,我们对CNN的前向传播算法做了总结,基于CNN前向传播算法的基础,我们下面就对CNN的反向传播算法做一个总结.在阅读本文前,建议先研究DNN的反向传播算法:深度 ...

  4. 卷积神经网络CNN总结

    从神经网络到卷积神经网络(CNN)我们知道神经网络的结构是这样的: 那卷积神经网络跟它是什么关系呢?其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进.比如下图 ...

  5. 深度学习之卷积神经网络(CNN)详解与代码实现(二)

    用Tensorflow实现卷积神经网络(CNN) 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/10737065. ...

  6. 深度学习之卷积神经网络(CNN)详解与代码实现(一)

    卷积神经网络(CNN)详解与代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/10430073.html 目 ...

  7. Neuromation新研究:利用卷积神经网络进行儿童骨龄评估

    近日,Neuromation 团队在 Medium 上撰文介绍其最新研究成果:利用卷积神经网络(CNN)评估儿童骨龄,这一自动骨龄评估系统可以得到与放射科专家相似或更好的结果.该团队评估了手骨不同区域 ...

  8. 卷积神经网络CNN学习笔记

    CNN的基本结构包括两层: 特征提取层:每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征.一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来: 特征映射层:网络的每个计算层由多 ...

  9. paper 162:卷积神经网络(CNN)解析

    卷积神经网络(CNN)解析: 卷积神经网络CNN解析 概揽 Layers used to build ConvNets 卷积层Convolutional layer 池化层Pooling Layer ...

随机推荐

  1. Verilog学习笔记基本语法篇(二)·········运算符

    Verilog HDL的语言的运算符的范围很广,按照其功能大概可以分为以下几类: (1)算术运算符 +,-,*,/,% 优先顺序 !~ *  /   % +    - <<    > ...

  2. FastJson生成json时,显示Null属性

    FastJson生成json时,默认不会输出null字段. 移动端,有时候,需要后端提供完整的字段说明. Map < String , Object > jsonMap = new Has ...

  3. C#上位机开发(二)—— Hello,World

    上一篇大致了解了一下单片机实际项目开发中上位机开发部分的内容以及VS下载与安装,按照编程惯例,接下来就是“Hello,World!” 1.新建C#项目工程 首先选择新建Windows窗体应用(.NET ...

  4. prometheus + mysqld_exporter + grafana 实现对mysql db的监控

    https://blog.csdn.net/hfut_wowo/article/details/78536022 1.参考这篇博文2.博主的用的是windows版本 prometheus-2.5.0- ...

  5. Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作

    3.依赖跟踪如何工作 初学者不需要知道这一点,但更高级的开发人员将想知道为我们怎么实现KO自动跟踪依赖性和自动更新UI的正确部分... 它其实相当简单优雅,跟踪算法如下: 当你定义一个计算监控,KO立 ...

  6. WCF全局异常处理

    在用wcf做为单纯的服务端的时候,发生错误是常有的事情,特别是在调用其他系统提供的接口的时候,发生的一些错误总是让人摸不着头脑,严重影响了错误的定位.做.net web开发的时候,我们可以在Globa ...

  7. soa服务治理

    SOA服务治理 文章:SOA 治理简介 文章:中小型互联网公司微服务实践-经验和教训

  8. vue 自定义日历组件

    <template> <div class=""> <div class="calendarTraffic" name=" ...

  9. hdu6060[贪心+dfs] 2017多校3

    /* hdu6060[贪心+dfs] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long L ...

  10. BZOJ 4033 [HAOI2015]树上染色 ——树形DP

    可以去UOJ看出题人的题解. 这样的合并,每一个点对只在lca处被考虑到,复杂度$O(n^2)$ #include <map> #include <ctime> #includ ...