昨天把这个教程的目录给理出来了,然后今天就想趁着这满腔热情(
无心搬砖)把剩下的教程也写了。 对于整个系统,不管具体细节是怎么实现的,是逻辑一定要理清楚,于是这一节主要介绍各个模块的逻辑,为什么要这么做。
首先我简单的画了一个示意图(这叫啥图我也还给软件工程老师了,肯定不规范,帮老师画了一上午的图,心都累了,将就着看吧)
从第一部分的目录和上面的示意图我们我们都可以了解到,实际上要处理的就是那几个蓝色实线框,在实现那几个蓝色实线框之前还需要做一些准备,也就是蓝色圆角虚线框,下面我将对各个部分简单的啰嗦下。
- 问题预处理
问题预处理要做些什么事呢,这就要看看我们想要从问题中获取点什么东西了,首先我们想获取问题中的询问对象是什么,也就是主语,是人还是电影,这就涉及到自然语言处理中的命名实体识别;接着我们还想从问题中了解到用户想问什么,也就是用户的意图,要了解用户意图,这就涉及到文本表示问题,最最基本的文本表示方法是one-hot形式,在试验中使用的是sklearn中的tfidf工具。
- 抽取关键信息
对于关键信息抽取中的命名实体识别,在实验过程中,在这一部分我们其实用的词性标注,因为我发现,词性标注工具可以把人民标注出来,如下:
nr 人名 名词代码 n和“人(ren)”的声母并在一起。
所以,只要我们把问题词性标注后,找到对应的nr对应的单词,那就是人名啦,电影名称的识别和这个差不多,在下一篇实验准备的博文中将具体介绍怎么提高识别率。
- 训练问题分类器
我们要想搞清楚用户到底想问啥,是问某某演了那些电影嘛,还是某某电影什么时候上映呢?想想我们在思考这个疑问的过程中是不是把问题在脑海里面进行的分类处理,其实在自然语言处理中很多问题都可以抽象成分类问题。好,我们现在把用户想问啥抽象成了分类问题,那用户问题主要涉及到哪些方面,可以分成多少类呢?以及我们怎么识别这个用户问题属于那一类呢?一种最直接的方法就是把用户会问到的各个方面都列出来,然后分门别类,这样就解决了前两个问题。对于怎么识别用户的问题属于那一类呢?当然选择分类器啦,但是等等,训练分类器需要数据咋办。解决办法就是前面不是把用户问题分成了很多类嘛,对于每一类问题,想想用户会以什么样的方式来提问,然后我们把这些提问方式记录下来,这样得到了该类别问题所对应的训练数据。是不是感觉很麻烦,我也觉得有点麻烦,这么麻烦的事其实没必要重复去造轮子(亲自去构建这些数据也不是不可以),这里需要想搞明白的这个思路是怎么来的(该教程针对的像我一样的小白,大佬请自动忽略,囧~~),这部分的数据在下一篇博文中会给出链接,github目录下也有。(感觉有点啰嗦了),部分数据样例如下:
nnt演了什么电影
nnt出演了什么电影
nnt演过什么电影
nnt演过哪些电影
nnt过去演过哪些电影
nnt以前演过哪些电影
nnt演过的电影有什么
nnt有哪些电影
nnt演过那些电影作品
nnt的电影作品有哪些
- 问题模板
在前面训练问题分类器中,我们把用户的问题归纳成了很多类,在这个模块下,我们要做的事就是对各个类别进行抽象,比如对于用户询问某某演过哪些电影等一系列问题,我们可以把它抽象成:
nr 电影作品
n r nr nr前面介绍过了,代表人名,在模板中我们使用nnt来表示的。于是我们得到了用户各种问题的模板( n m nm nm代表电影名称, n g ng ng代表电影类型):
0:nm 评分
1:nm 上映时间
2:nm 类型
3:nm 简介
4:nm 演员列表
5:nnt 介绍
6:nnt ng 电影作品
7:nnt 电影作品
8:nnt 参演评分 大于 x
9:nnt 参演评分 小于 x
10:nnt 电影类型
11:nnt nnr 合作 电影列表
12:nnt 电影数量
13:nnt 出生日期
- 查询答案
在知道用户想问啥的时候,我们就可以根据用户的要求来查询,得到答案返回,这部分主要是如何对图数据库进行操作。
好了,到了现在,你对主要的模块都了解了,然后最后我来串一哈,首先得到用户的问题,从用户的问题中得到问题的关键信息,主要是人名、电影名称等信息,接着是对问题进行分类,看问题想问什么,预测出问题模板,在得到问题模板后,使用人名或电影名等具体信息来替换模板中的抽象信息,得到一个新的问题,下面是一个实际的例子:
刘德华演过哪些电影呀?
获取关键信息:
刘
德
华
刘德华
刘德华
问题分类得到问题模板:
7
:
n
n
t
电
影
作
品
7:nnt 电影作品
7:nnt电影作品
进行替换得到新的问题:
刘德华 电影作品
然后就根据这个新的问题来查询,获得答案返回。
这个系统逻辑介绍就啰嗦到这里吧,废话挺多的,至于每个模块怎么实现的,那就接着看后续文章吧