这里简单探讨QA系统的几种形式
假设我们有一堆问答对(q_1, a_1, q_2, a_2, ..., q_n, a_n)
如果这个时候新来了一个问题,最朴素的想法就是去这些问答对里面搜索,找到答案(假设有的话)。
问题是,问题本身的形式可能多种多样,例如:
这些问题本身都代表一样的含义,或者说他们有相似的语义(Semantic)。
那么问题来了,如何确定答案?
假设我们有一个函数f(x, y)
,当两个问题相似的时候f(q_1, q_2)
趋近于1,当两个问题不相似的时候f(q_1, q_3)
趋近于0。
那么用户只要输入一个新问题q_user
,那么我们只要从数据库里面计算argmax{q_i} f(q_i, q_user)
就好了。也就是从数据库中找到与问题q_user
最相似的问题。
当然还有另一种类似的做法,假设一个函数g(x, y)
,当一个问题q
和答案a
是一对的时候(也就是a
是q
的正确答案),那么g(q, a)
趋近于1,如果不是一对,则趋近于0。
当用户来了新问题q_user
,那么我们只要遍历数据库里面的所有答案寻找argmax{a_i} g(q_user, a_i)
,则可以找到,最符合用户问题的答案
当然实际应用的时候,我们不可能真的遍历数据库的所有问题(可能有几百万条数据,时间性能不允许),这个时候我们可以通过其他手段。
例如我们有一个函数vec(x)
,它可以把一个问题或者答案转换成一个有限长度的实数向量。然后我们还有一个函数similarity(x, y)
,用来判断两个向量是否相似。那么当用户来了一个问题q_user
的时候,我们可以先把它向量化得到vec(q_user)
,然后再去匹配我们已经预先
向量化好的其他问题。
即argmax{vec(q_i)} similarity(vec(q_user), vec(q_i))
因为向量相似匹配的算法,可能远快于遍历所有问题(或答案)。(例如用K-neighbour相关算法如BallTree等)
用深度学习解决此类问题的论文比较多,例如:
(Ming Tan, LSTM-BASED DEEPLEARNING MODELS FOR NON-FACTOID ANSWER SELECTION, 2016)
利用搜索引擎,或者类似搜索引擎的技术
假设我们问“爱因斯坦出生于哪一年?”
然后把这个问题直接丢给搜索引擎,或者经过某种转换到某个形式(例如把问题修改为文本“爱因斯坦 出生 年份”)
假设去搜索,第一条结果可能如下:
阿尔伯特·爱因斯坦- 维基百科,自由的百科全书
https://zh.wikipedia.org/zh-hant/阿尔伯特·爱因斯坦
阿尔伯特·爱因斯坦,或譯亞伯特·爱因斯坦(德語:Albert Einstein,1879年3月14日-1955年4月18日),猶太裔理論物理學家,创立了現代物理學的兩大支柱之一的相对论 :274,也是質能等價公式(E = mc2)的發現者。他在科學哲學領域頗具影響力。因為“對理論物理的貢獻,特別是發現了光電效應的原理”,他榮獲1921年諾貝爾物理學獎 ...
而我们根据问题可以判断用户的意图是希望结果是“哪一年”,也就是问题答案很可能是(18xx年, 19xx年, 18xx-xx-xx, 19xx-xx-xx)之类的形式。
我们获得了潜在的答案类型,和潜在包含答案的数据条目。我们再从中搜索我们的答案。
这个方法的方法与条件:
当然也可以说语义网、知识图谱等based
这个角度解决QA问题首先我们需要有一堆数据库,常见使用三元组(triples)的形式保存,例如:
类似这样,一般来说三元组中间那是一个关系(relation),而两边是两个实体(entity),我们也可以写作出生于(爱因斯坦,1879)
,出生于(这篇文章的作者,2020)
,类似这样的形式
假设我们有很多这样的三元组数据,那么我们解决:“爱因斯坦出生在哪年”这样的问题方法,是把问题转换为一种逻辑形式,例如:
爱因斯坦出生在哪年 => 出生于(爱因斯坦, ?x)
中国的首都 => 首都(中国, ?y)
其中出生于
和首都
都是关系,而中国
和爱因斯坦
都是实体,而?x
和?y
都是自由变量,这里代指我们想要寻求的答案。
从这个角度解决QA问题有一套比较完整的方法论,如RDF,Semantic Web,SPARQL等技术和方法
也有一些文献使用了结合deep learning与sequence-to-sequence等技术的的Knowledge-based解决方案,具体内容我们后续会讨论。