10本目! Question Generation for Question Answering

さてさてさーて。Question Generationにやってまいりました。

Question Generationといえば、傾聴とかの必須スキル。とういうか、Chatbotでの会話の継続のためにぜひとも学習したいモデルですね。

では、早速見ていきましょう。

ちなみに今回の論文はMicro Softです。Microsoft Research Aisaなので、XioIceとかのQuestion Generationとかもこれかもしれない。

まあ、Question Generationていうのは、CNNを使った検索ベースのモデルと、RNNを使った生成ベースのモデルがあるみたい。 ここ、Seq2seq大好きだからなー。(XioIceのモデルもSeq2seq)

目的としては、会話の履歴からQuestion(Open Question と Closed Question の両方)を作りたい。

Question Generation

基本的にQuestion Generationは文章Sが与えられたときに、質問のリスト{Q}を生成したいみたい。 ってことは相手の会話の履歴の7分くらいをぶち込んで、Question Listを生成できるようになれればいいってこと。

Question Generationに用いる Engineは4つの機能が必要らしい。

1.Question Pattern Mining

データセットから質問文を抜き出すstepみたい。without any human anotaion effortってことは、文章の最後に「?」がついているかのPattern Maching とか、「何故」 とかの疑問詞とかを持っている文章を抜き出すみたい。 こっから、質問文自体のデータセットQを作るのか。

疑問点としてはここで固有表現抽出とかを使ってパターンを作るのか、それとも単語の置き換えとかをせずに質問文のパターンを作るのか?どっちだろう?それとも、別のパターン?

2.Question Pattern Prediction

文章Sから質問文にふさわしいパターンをN個抜き出すらしい。このstepではGeneration-based でもRetrival-basedでも変わらないみたい。

Question Generationにおける『推測』の意味は、検索ベースにおいては質問の候補を文章Sに基づいてrankづけすることらしい。では、生成ベースにおいては文章Sを入力として、seq2seqを使って新しいQuestionパターンを作ることらしい。

疑問点としてはGeneration-baseにおいて、質問文のデータセットQをどういうふうに使っているのか? seq2seqのモデルの訓練にしか使わないのか、それとも推論時にはどうデータセットQを使うのか、それともそれ以外の方法なのか?

3.Question Topic Selsection

質問文データセットQから、推論時の質問パターンQ_pから、qution topic の Q_tを選ぶらしい。このQ_tはどっから出てきたんだ? データセットQ?

4.Question Ranking

いろいろな特徴量を用いて、生成された質問のrankづけをするらしい。まあ、文章Sにはたくさんの質問文を作るための fact があるから、どの質問が最適かを決めるのがこのstepらしい。

会話の文章なら、できるだけ最後のfactを用いて、かつ話者が以前に言及していない質問を選ぶと良いってことか?ここらへんの rankづけは文章の種類によって変化するだろうし。

ではでは、1~4までの内容について、見ていきましょう。

Question Pattern Mining

Question Pattern について、固有表現のところかわからんが、一部を「#」に置き換える。

あと、ここでFQAの定義が出てくる。FQAってQuestion Patternが一定回数以上登場したら、Frequently Question-Answeringって定義している。

んで、問題となるのがQuestionのなかで、どこを#に置き換えるのかが問題となってくる。

ここで登場するのが重要度。なんの重要度かって言うと、わからん。

数式を見て見ると、


Importance(Q_t ^m)  = \sum_{Q_k} \delta (Q_t ^m, Q_k) \dot |Q_t ^m|

よくわからん。 \delta (Q_t ^m, Q_k) っていうのが、0か1を取る関数で、 Q_t ^mっていうのが、Q_tっていう文のm番目の単語らしい。ってことは、 Q_kっていう質問文の中に Q_t ^mの単語があるかどうかってことらしい。

んで、 |Q_t ^m|っていうのが Q_t ^mの全体の出現数らしい。

っていうことは、Q_tがいっぱい出てくるほうがImportanceが大きくなってくるみたい。Importanceが最も大きい Q_tをtopicとして、他のQuestion Patternから抜き出して、#に置換するみたい。

わからんのが、 Q_tは文章なのにどうやって抜くんだろう?

単語の質問があるってこと?「Vivy?」みたいな文章が、最も重要な文と判断すれば、良いのだろうけど、こういった質問文がなかったどうすんだろう?謎が深まる。

あー、質問クラスター中での特異性を調べてんのか。データセットであるCQAでは関連した質問のリストがあるらしいし。関連した質問のリストにだけ、よく頻出する単語がQuestion Topicってことか。

あー、 Q_tの解釈が違うかも。質問のリストでn-gramかけて7文字以内のwordの組み合わせで Q_t ^ 1, Q_t ^2, ..., Q_t ^mを作るのか。そうすれば「Vivy?」みたいな文章がつくられるし。

んで、この抜き出した単語の組み合わせでどうやって質問文のtopicの境界を決めるんだろう?

Thus, we can leverage the consensus information among questions to detect the boundary of the question topic.

ってあるんだけど、consensus informationってどうやって取り出すんだよー(泣)。あー、 Q_tの隣から一定値以上のImportanceをもつ単語だけ抜き出して行けば良いのか。

Question Pattern Prediction

質問パターンが文章Sのどこの部分で引き起こされたかで、質問が作れるらしい。 「誰が歌っていますか?」っていうバターンが抽出できて、それが「がカラオケにいた」という文の一部から引き出されるらしい。

Training Data Construction

まず、QAのデータセットから<Q, A>を取り出す。このQに基づいて、Question PatternのセットであるQからQ_pを取り出す。んで、「#」にあてはまるQ_tをAから取り出す。

目標としては文章Sから、Q_pを取り出すのが目的。

方法論としては検索ベースと生成ベースがある。

Retrival-based QP Prediction

Input layer

attention付きのCNNで取り出すみたい。  v_i ^S, v_j ^{Q_p}をそれぞれ、文章Sのi番目の単語、Q_pの番目の単語として、Attentionをcosine類似度で計算する。


Atten_{i, j} = cos(v_i ^S, v_j ^{Q_p})
んで、このAtteionの大きさが最も大きい[tex: VS],  V^{Q_p}をそれぞれ選んで、これをSoftmaxをかけたやつをそれぞれのembeddingにかけて、更新する。

Convolution layer

embeddingで作られた文章Sについてのベクターから[tex: v{t-d}, ..., v{t}, ..., v{t+d}]をt= 0~|S|まで取り出して、concateして[tex: Z_S = {l_1, .., l{|S|}]を作って、Convolution layerの入力にするみたい。

こっから、[h_t ^S = tanh(W_c l_t)]で h_t ^Sを作って畳み込み終了

Pooling layer

max-poolingをかけるらしい。ここで、各 h_t ^Sについて最大のベクターを取り出すみたい。んで、 l_p ^sをつくると。

つまり、文章S中に含まれる各単語についての最大のベクターの塊。

Optput layer

 y(S) = tanh(W_s l_p ^X)で文章Sについての最終的な埋め込みベクターを作るみたい。 あとはおんなじように y(Q_p)をつくって、y(Q_p)とy(S)が最小のコサイン類似度となるように訓練すればいいらしい。

めっちゃ面倒やん(泣)。

Generation-based QP Prediction

seq2seqのBiGRUってモデルが使われているみたい。

入力をS = (x_1, x_2, .., x|S|)として、出力Q_p = (y_1, y_2, ..., y|Q_p|)となるように学習したい。ってことで、普通にモデルにぶち込んで、SDGでパラメータの調節をして完成ってことで。

推論時にはこっからBeam-searchかけて、top-Nを取り出すみたい。

問題としては、生成ベースだと「#」が生成されないかもってこと。そうする場合どうすんだろう?でも、検索ベースだと、汎用的な質問パターンしか選ばれないかもしれないし、そこは難しい。

Question Topic Selection

では、肝心のQ_tを文章Sから取り出して見ましょう。

For Q_p from retrieval-based method

Q_tはまずFreebaseの固有表現とか、Stanford parseの名詞句を用いて、取り出すらしい。

んで、 s(Q_t, Q_p) = \# \frac{1}{N} \sum_k  (Q_p ^{t_k})  dist(v _ {Q _ t}, v _ {Q _ p})って感じで、sを出力するらしい。

 #(Q_p ^{t_k})が他の質問で t _ kが出た回数で、 dist(v _ {Q _ t}, v _ {Q _ p}) っつーのが2つのベクターの距離。つまり、topicが他の質問パターンで何回も登場していて、かつそのtopicが抜けている質問パターンとはできるだけ異なるやつを選びたいらしい。

まあ、似た質問で欠けているところを探す作業と考えれば良いのか。

For Q_p from generated-based method

topicは w _ j = argmax _ {w _ j} \alpha _ {ij'}でもとめられるみたい。つまり、めちゃくちゃAttentionがかかっているところってことね(笑)。

まあ、こうすると一単語しか抜き出せないんだけど、どうすんだろう?ちなみに i が固定で i は「#」が入っているところらしい。

Question Ranking

Q_p中の「#」をQ_tに置き換えたあとの話。

Q_pのランク付けは以下の点を考慮するそうだ。

Question pattern prediction scroe Question topic selection score QA matching score Word overlap between Q and S *Question patten frequency

まあ、検索ベースと生成ベースで差をつけて、s(Q_t, Q_p)やattentionの重みが大きくて、QとSが関連してるQのクラスターから選んで、QとSに似た単語が多く登場して、Q_pがQにいっぱい含まれていると良いよね、ってことらしい。

まあ、 p(Q|S) = \sum _ i \lambda _ i h _ i (Q, S, Q _ p, Q _ t)っていう何か簡単な式でこれを最大化すればいいらしい。

うーむ。実に難しい(笑)。