一、DrQA系统的构成:
- DrQA系统的构成
- Document Retriever:据问题检索出维基百科中的相关文章
- Document Reader:在文章中找到相应的段落并提取出答案
- DrQA系统整体图:
二、 Document Retriever部分:
- 通过问题检索出相关的文章有很多的方法,简单的方法就是统计两者的TF-IDF得到词袋模型向量,然后通过cosine similarity等相似度度量方式进行检索。可以进一步可以将相邻词汇也考虑进去,使用n-gram的词袋模型。这篇文章中,作者使用bigram的词袋模型,为了加快效率,将bigram映射为murmur3 hash。我们通过Document Retriever检索出最相关的五篇文章返回给Document Reader
- 关于词袋模型与TF-IDF算法参考:https://blog.csdn.net/ACM_hades/article/details/93085783
三、 Document Reader部分:
- 假设给定一个问题为 q q q,由l个词组成 { q 1 , q 2 , … , q l } \{q_1,q_2,…,q_l\} {q1,q2,…,ql}。讲Document Retriever返回的五篇文章切割成段落,每个段落 p p p由 m m m个词组成 { p 1 , p 2 , … , p m } \{p_1,p_2,…,p_m\} {p1,p2,…,pm}:
- 第一步: 将段落中的每一个词用一个特征向量表示,该特征向量包含以下四个部分:
- 词向量(Word-embbedings):使用300维的Glove词向量。保留大部分预训练词向量固定,只微调的1000个最常见的问题词,因为一些关键字,比如what,how,which等等可能是QA系统的关键。公式如下: f e m b ( p i ) = E ( p i ) f_{emb} (p_i) = E(p_i) femb(pi)=E(pi)
- 精确匹配特征(Exact Match):我们用三个二元特征来表指示 p i p_i pi是否与 q q q中的一个问题词完全匹配,即是否再问句中存在。三个二元特征分别表示该token的不同形式的表达是否在问句存在:原型,小写,引用形式。公式如下: f e x a c t − m a t c h ( p i ) = I ( p i ∈ q ) . f_{exact-match} (p_i)=I(p_i∈q). fexact−match(pi)=I(pi∈q).
- 符号的特征(Token Features):我们也加入一些反映 p i p_i pi在上下文中的特性的人工特征加入到特征向量中,包括:词性标注、命名实体识别标签和归一化后的TF分数。 公式如下: f t o k e n ( p i ) = ( P O S ( p i ) , N E R ( p i ) , T F ( p i ) ) f_token (p_i) =(POS(p_i),NER(p_i),TF(p_i)) ftoken(pi)=(POS(pi),NER(pi),TF(pi))
- 引入对问题的注意力机制(Aligned question embedding):该特征和Exact Match类似,都是为了表征该 p i p_i pi和问题的关联度,不同的是,该特征考虑了整个问题与它的相似度,而非某一个具体的单词,是一种soft-alignment。具体来说,将问题每个单词 q j q_j qj的embedding和该 p i p_i pi的embedding通过点乘得到 p i p_i pi与 q i q_i qi的相似度 a i , j a_{i,j} ai,j,再对问题每个单词的embedding进行加权求和作为该特征,公式如下: f a l i g n ( p i ) = ∑ j a i , j E ( q j ) f_{align} (p_i)=∑_ja_{i,j} E(q_j) falign(pi)=j∑ai,jE(qj) a i , j = e x p ( α ( E ( p i ) ) ∗ α ( E ( q j ) ) ∑ j e x p ( α ( E ( p i ) ) ∗ α ( E ( q j ) ) a_{i,j}=\frac{exp(α(E(p_i ))*α(E(q_j))}{∑_jexp(α(E(p_i ))*α(E(q_j))} ai,j=∑jexp(α(E(pi))∗α(E(qj))exp(α(E(pi))∗α(E(qj)) 其中, α ( ∗ ) α(*) α(∗)是一个带有ReLU的非线性全连接层
- 第二步:段落编码
- 经过第一步我们就将段落中的每一个token进行了向量化,将他们表示为: { p ^ 1 , p ^ 2 , … , p ^ m } \{\hat{p}_1,\hat{p}_2,…,\hat{p}_m\} {p^1,p^2,…,p^m},接下来我们将 { p ^ 1 , p ^ 2 , … , p ^ m } \{\hat{p}_1,\hat{p}_2,…,\hat{p}_m\} {p^1,p^2,…,p^m}输入一个多层的双向LSTM,再将将所有隐层连接起来。假设层数为 a a a,隐藏层状态向量的长度为 h h h和,那么对于每个token就得到了一个长度为 a h ah ah的向量表达 P i P_i Pi。公式如下: { P 1 , P 2 , … , P m } = R N N ( { p ^ 1 , p ^ 2 , … , p ^ m } ) \{P_1,P_2,…,P_m \}=RNN(\{\hat{p}_1,\hat{p}_2,…,\hat{p}_m\}) {P1,P2,…,Pm}=RNN({p^1,p^2,…,p^m})
- P i P_i Pi编码了 p i p_i pi周围有效地上下文信息.
- 第三部:问题编码
- 接下来我们对问题进行encoding,使用采用另一个RNN对问题的中的每个词的embedding进行编码,再将每个隐层进行加权求和,这样我们就得到了一个问题的向量表达 q q q。公式如下: q = ∑ j b j q j q = ∑_jb_j q_j q=j∑bjqj b j = e x p ( w ∗ q j ) ∑ j e x p ( w ∗ q j ) b_j=\frac{exp(w*q_j)}{∑_jexp(w*q_j)} bj=∑jexp(w∗qj)exp(w∗qj)W为权重向量,学习得到,它学习了问题中每个单词的重要程度。
- 第四步:预测
- 得到了问题和段落的编码后,我们就可以进行答案区间的预测了,我们对于段落的每一个位置 i i i,都用两个双线性项去分别预测它作为答案起始位置和终止位置的概率,公式如下: P s t a r t ( i ) ∝ e x p ( p i W s q ) Pstart(i) ∝ exp (p_i W_s q) Pstart(i)∝exp(piWsq) P e n d ( i ) ∝ e x p ( p i W e q ) Pend(i) ∝ exp (p_i W_e q) Pend(i)∝exp(piWeq)
- 我们在每个段落中寻找一个最有可能是答案的区间 [ i , i ′ ] [i,i'] [i,i′],即满足 P s t a r t ( i ) × P e n d ( i ′ ) P_{start} (i)×P_{end} (i') Pstart(i)×Pend(i′)最大,且 i ≤ i ′ ≤ i + 15 i≤i'≤i+15 i≤i′≤i+15。并且将每个候选段落中最可能是答案的区间进行比较,选出最终的答案区间,这里为了能够在所有段落中进行比较,我们用指数形式替换掉归一化的Softmax。