東京電機大学 工学部 情報通信工学科
ネットワークシステム研究室
指導教員 坂本直志教授
学籍番号 16EC095
氏名 橋口悠人
現在、自然言語をコンピュータに処理させるコンテンツは多くある。例えば、ワープロや検索は元よりGoogleやWeblioが提供している翻訳 [1] [2]、自然言語を音声で認識をして自然言語で返答するAppleのSiri [3]、さらには数学の問題を画像で読み取り、類似の問題を検索してくMathpressoのqanda [4]などが挙げられる。また、国立情報学研究所による2021年度に東京大学入試を突破することを目標とする、入学試験問題を題材とした取り組みもある [5]。このような自然言語処理をするために、音声認識、形態素解析、文脈解析などのコンピュータで処理するための前段階が非常に重要である。そして最近、リクルートの研究所が依存構造解析ライブラリを一般公開した [6]。本研究はこのライブラリを用いて小学一年生レベルの算数の文章題を解析し、解答するプログラムを作成した。
先行研究 [7]を参考に以下の節で示す条件の元、小学一年生レベルの文章題を入力して、その問題の正解を出力するシステムを構築する。解答する文章題は1、2文目が説明文、3文目が質問文の3文構成のものを想定する。また、解答に想定される計算は足し算と引き算のみを想定した問題を扱う。また2.1から2.4節の4種類の問題のタイプを分類してシステムを構築していたが本システムでは2-4のタイプの問題は扱わないものとする(理由は5-2に示す)。
リスト 1のように、1、2文目で対象物(例文では「画用紙」)の変化を説明し、3文目でその対象物の最終的な値を問う問題である。
リスト 2のように、1文目に対象物の1つ(例文では「赤い金魚」)の説明があり、2文目に2つの対象物を比較し、3文目にもう片方の対象物を問う問題である。
リスト 3のように、1文目と2文目でそれぞれの対象物を説明し、3文目でその差を問う問題である。
リスト 4のように、1文目で二つの対象物の和を説明し、2文目で片方の対象物の量を説明し、3文目でもう片方の対象物を問う問題である。前述のとおり本システムではこのタイプの問題は扱わない
大まかな処理の流れは図 1のようになっている。まず、文章題の平文を自然言語処理ライブラリのGiNZAで処理することで、平文が単語ごとに区切られ、その単語の品詞と主述などの単語間の関係が付与されたデータが出力される。次にそのデータからルールに基づいたPrologで処理できる論理表現に変換する。最後にその論理表現から計算結果となる情報を推論から出力するといった処理となる。
GiNZAはリクルートのAI開発機関が国立国語研究所との共同研究成果の学習モデルを用いたPython向け日本語自然言語処理オープンソースライブラリである [6]。2019年4月2日に一般公開され、7月8日に2.0.0バージョンが公開されている(本研究ではこのバージョンを利用する)。同じくオープンソースの自然言語処理ライブラリ「SpaCy」と形態素解析器「SudachiPy」を利用し、高精度なトークン化処理と依存構造が実現している。
図 2は入力の例とその出力した解析木を示す。出力情報には区切られた単語、その単語の原形、構文の注釈のフレームワークである「Universal Dependencies」に基づいた品詞と依存ラベルがある。ここで、単語の原型は活用形であれば活用の原形(例:「持っ」の原形が「持つ」)を表示するがそれ以外にも次のような特徴がある。
これらの性質を利用することで、平文中の様々な形をした単語を同一の意味の単語として認識できたり、少ない情報量で処理ができるメリットがある。次に、依存ラベルは主述や目的語、接頭辞など、単語間の関係性を表している。これを利用すれば、対象物の動作を読み取ることができる。
但し、依存ラベルが間違えるケース(矢印方向はあっているがラベルの種類が違うケース)は多々ある。実際、図2の結果も厳密には間違っており、「持っ」と「太郎」は主述の関係「nsubj」が正しく、述語と間接目的語の関係「iobj」ではない。このようなケースを対処するために、接頭辞(「case」ラベルなど)や品詞といった情報も解析木から論理表現への変換の処理に利用する。
Prolog言語とは述語論理形態に基づいたプログラミング言語である。この言語ではまずいくつかの定義をし、その定義に基づいて質問に答えるプロセスを行う。以下では、Prologをシステムに採用する利点をリスト 5~リスト 7の動作例と共に説明する。
まず、定義についてリスト 5を例に説明する。今回の定義の記述方法は「ある(A,B).」の書き方は「AにBがある。」を意味し、「含む(A,B)」は「AはBを含む。」を意味する。よって、1~4行目の意味は上から「袖ヶ浦市にドイツ村がある。」、「浦安市にディズニーランドがある。」、「千葉県は袖ヶ浦市を含む。」、「千葉県は袖ヶ浦市を含む。」である。また、「A:-B,C.」の書き方は一階述語論理の「B∧C→A」(BかつCであればA)を意味する。よって、5行目の意味は「『XはZを含む。』かつ『ZにYがある。』なら『XにYがある。』」(それぞれの「X」,「Y」,「Z」は同一のものを指す)である。具体的には「含む(X,Z).」と「ある(Z,Y).」が定義されていれば「ある(X,Y).」も定義されることになる。
次に、質問の1つ目についてリスト 6を例に説明する。この質問文の意味は「浦安市に何があるか。」であり、「浦安市にディズニーランドがある。」ため回答は「ディズニーランド」と返す。具体的には、「ある(A,B).」の「A」を「浦安市」、「B」をワイルドカード(変数)の「X」にすることで、プログラムは定義されているものの中で「ある(浦安市,X).」に当てはまるものを検索し、当てはまるものがあればその「X」に当たる部分をすべて列挙するといった処理を行う。この質問に対しての結果は定義の2文目が当てはまるため、「X=ディズニーランド」といった出力をする。
次に質問の2つ目についてリスト7を例に説明する。この質問文の意味は「千葉県」に何があるかを意味する。今回の質問は直接的な「ある(千葉県,X).」の定義は存在しないが、定義の5文目によってこの質問に回答が存在する。まず、定義の1文目に「ある(袖ヶ浦市,ドイツ村).」、3文目に「含む(千葉県,袖ヶ浦市).」があるから、5文目によって「ある(千葉県,ドイツ村).」が定義されているから、これが質問に当てはまる定義となる。2文目と4文目の定義からも同様に「ある(千葉県,ディズニーランド).」の質問に当てはまる定義になる。よって、回答は「X=ドイツ村」と「X=ディズニーランド」となる。
このように今回の定義文では「含む(千葉県,袖ヶ浦市).」のような書き方で、簡単に千葉県の市を定義して活用できる。これによって、システムの辞書の作成、検索の実装も簡単にできる。
AZ-Prolog [8]はこのPrologの言語処理系の一つである。また、C言語のインターフェースがサポートされているため、今回ベースとなるPythonプログラムに簡単に組み込むことができる。
3-1の図 1の順に処理と手法を説明する。
3-2で紹介したようにGiNZAはこの変換を可能とするため、この処理は主にライブラリに依存するものとする。GiNZAは入力した文の数と同じ数の木を出力するため、今回の3文で構成されている文章題を入力すると3本の木を出力する。また、図 3のように変換先が曖昧であったり、明らかな変換ミスの対処法は考慮しないものとする。但し、3-2の最後にあるような依存ラベルのミスは次の4-3で補正する処理をするものとする。
先行研究では字句解析した問題の単語成分から必要な情報のみを入手し、それを論理表現で定義してPrologで処理させる手法をとっていた。具体的にはタイプAの問題の一文目は主語(対象物とその修飾語)、述語、数、助数詞の情報を与えた論理表現にして処理をさせていた。本研究でもこれを参考に論理表現を定義していく手法をとるが、異なる点がある。先行研究では問題のタイプごと、文番号ごとに別の論理表現を使用する方法をとっていた。しかし、今後のシステムの発展において、新しい問題のタイプを実装する場合や4文以上の文章題を解答できるシステムを実装する場合に新しく論理表現が考慮する必要がある。そのため、定義する論理表現は一種類で実装し、問題のタイプをprologが判断をする方法を用いる。
定義する論理表現は以下のものになる。
sen(文番号,形容詞,動詞,主語,直接目的語(比較対象), 数).
本研究では入力する文は3文であるため、この論理表現を3つ定義することになる。以下に具体的な要件と定義例を記す。
①文番号は何文目の文章かを示す。
②主語、直接目的語(比較対象)は「object(修飾語,名詞)」の形になる。
③形容詞が比較を表す場合、直接目的語は代わりに比較対象となる対象物が入る。
④すべて原形を使用する。
⑤形容詞と動詞は存在しない場合は「n」(存在しないシンボル)にする。
⑥主語と直接目的語は存在しない修飾語、または名詞を無名変数「_」にする。
⑦数が存在しないことはない。
リスト 8の定義の例より、1文目だから文番号には「1」になる。形容詞は存在しないため「n」になる。動詞は「あり」だからその原形の「有る」になる。主語の名詞は「本」、修飾語は存在しないため「object(_,_)」になる。直接目的語は存在しないため「object(_,_)」になる。数は「4冊」だから「4」になる。
リスト 9の定義の例では比較の文を例にしている。形容詞は「少ない」だからその原形の「少ない」になる。比較文で比較対象は「赤い金魚」だから、直接目的語の位置には「object(赤い,金魚)」になる(③の例)。
リスト 10の定義では3文目を例にしている。今回のシステムは「この」のような連体詞は修飾語に加えないものとする。重要な点は「何」が数として読み取れることである。その手法を次の項目で解説する。
GiNZAから出力した木を4-3-2で示した論理表現に変換する方法を紹介する。初めは各文に一つだけ存在する依存ラベルが「ROOT」の要素から処理していく。
このシステムでは、処理の簡略化やGiNZAの誤差を補うためにいくつかの依存ラベルをグループ化する。ただし、一種類のラベルが複数グループに属する場合もある。依存グループと属する依存ラベルは表 2に表記する。
依存ラベルが「ROOT」の要素とは木の根に当たる要素(図 2.GiNZAの入出力例なら「持っ」)を指す。この要素から品詞ラベルによって以下の論理表現を生成する。
ここで処理する要素は「形容詞」であることを示し、比較形容詞の場合の比較対象を見つけることを目的とする。すべての子要素をチェックし、依存ラベルが「修飾グループ」に属する要素であったら要素ごとに4-3-3-4の処理をする。
ここで処理する要素は「主語」・「目的語」となる可能性のあることを示し、格助詞の種類によって論理表現の位置を決定し、その修飾語を見つけることを目的としている。すべての子要素をチェックし、依存ラベルが「格助詞グループ」に属す要素は以下のように論理表現の位置が決定する。
また、依存ラベルが「修飾グループ」に属する要素の原形が各「object」の「修飾語」になる。
ここで処理する要素は数詞の可能性があることを示し、子要素に含む数を見つけることを目的としている。すべての子要素をチェックし、品詞タグが「NUM」である要素の原形が論理表現の「数」になる。
論理表現から問題の答えを導きだす論理推論を行う。ここでは各問題タイプの論理推論の定義を述べていく。
3-3のようにAZ-PrologではC言語インターフェースが用意されている。しかし、静的ライブラリしか用意されてないため、これだけではPythonでは利用できない(Pythonでは動的ライブラリで利用可能)。そのため、Visual Studioで作成した動的ライブラリをこのシステムで利用している。
問題の特徴より、2文目に形容詞があればタイプBである。そうでなければ3文目に形容詞があればタイプC、なければタイプAであることが分かる。ここで形容詞とはどんな形容詞でもよいわけではなく、定量的な比較できる形容詞のみをさす。つまり、「多い」、「長い」、「高い」は定量的な比較ができるが、「甘い」、「赤い」、「嬉しい」は定量的な比較ができない。4-4では以後、形容詞とは前者のもののみを指すものとする。
タイプAは1文目と2文目から対象物の変化を推論し、最終的な数を解答する。先行研究では動詞によって対象物の増加・減少を決めている(例えば、「○○が居る」なら増加、「○○を使う」なら減少など)。今回はこの手法を参考にし、さらに自動詞か他動詞かによって主語を対象物とするか、直接目的語を対象物とするかを判定させるように推論させる。そのため、表 3のような動詞の辞書を作成する。
この辞書からどの部分を対象物にして、それを増やすか減らすかの解釈を行い。具体的な推論方法はリスト 11を例にとる。
1文目をみると動詞が「有る」である。辞書から正負は「正」、対象物は「主語」だから、この文から「object(_,画用紙)」が6個増えると推論できる。2文目では動詞が「使う」である。辞書から正負は「負」、対象物は「直接目的語」だから、この分から「object(_,画用紙)」が2個減っていると推論できる。3文目では動詞が「残る」である。表3の辞書には載っていないが対象物は「主語」だから、「object(_,画用紙)」の数を聞かれていることを推論できる。よって、「object(_,画用紙)」の増減を適用した絶対値は4になり、これが答えになる。
タイプBは1文目から一つ目の対象物の変化を決推論し、2文目で二つ目の対象物の数を一つ目の対象物の変化と比較して決定する。比較を行う際は表 4のような形容詞辞書を用意する。
この表から比較対象より数が大きいか小さいかを判別する。例えば、「えんぴつは消しゴムより5個多い。」であれば比較対象である「消しゴム」より「えんぴつ」の数は大きく、「北海道は東京より10度低い。」であれば比較対象である「東京」より「北海道」の数が小さいことが判別できる。この方法を用いて、リスト 12を例に推論方法を説明する。
1文目はタイプAのときと同様に処理することで「object(赤い,金魚)」が15個増えると推論できる。2文目を見ると形容詞は「少ない」である。そのため、「object(黒い,金魚)」は比較対象の「object(赤い,金魚)」より数が少ないことが分かる。よって「黒い金魚」は(+15)-(6)個増えると推論できる(評価して9にしても可)。3文目もタイプAのときと同様に「object(黒い,金魚)」の数を聞かれているから、評価した絶対値の9が答えになる。ここで注意する点は2文目の評価でも動詞の正負は考慮する必要がある。例えば、2文目「赤い金魚は黒い金魚より5匹多く渡した。」という文では「渡す」の正負は「負」である。この時、1文目から「object(黒い,金魚)」は7個減っているのような推論になるため、最終的な答えが2という答えが出てきてしまうからである。
タイプCは1文目で出てくる対象物と2文目で出てくる対象物の差を求める。つまり、タイプAの対象物が1文目と2文目で異なるだけであり、これまでの手法を用いて実現できる。リスト 13を例に推論方法を説明する。
まず、1文目はこれまでの手法から「object(_,男の子)」が34個増えると推論できる。2文目も同様に「object(_,女の子)」が20個増えると推論できる。3文目では文章に関係なく、これまでの推論から異なる2つの対象物の差の絶対値の14が答えとなる。
まず、1文目はこれまでの手法から「object(_,男の子)」が34個増えると推論できる。2文目も同様に「object(_,女の子)」が20個増えると推論できる。3文目では文章に関係なく、これまでの推論から異なる2つの対象物の差の絶対値の14が答えとなる。
2-2で紹介した文章題ではタイプAとタイプBは正確な解答を出力できた。タイプCの問題は4-2で紹介したような変換先が曖昧な文章のため、GiNZAの処理で理想的な木を出力してくれないことが原因となっている。この場合は文章題の単位を「人」から「匹」に変えることで正確な解答の出力が確認できた。また、リスト 14のような一見複雑な文章でも正確な答えを出力できることを確認した。この文章題では「ゆうかさん」や「あと、」などの余分な語が多いが、依存ラベルと品詞ラベルを利用して、必要な情報のみを使って処理できていることが分かる。さらにどのタイプにも属さないがリスト 15とリスト 16のような問題を解くことができる。リスト 15ではタイプAのような問題だが、一文目と二文目の対象物が異なる問題である。しかし、最後の文章では修飾語がない「金魚」の数を聞かれるため、ユニフィケーションによって、「赤い金魚」と「黒い金魚」を「金魚」に属する解釈をして正しく解答できる。リスト 16では2つの対象物の数を説明し、最後に片方の数を問う問題である。これもタイプAの処理の通り処理しても、「ウサギ」の数を取り出すことができるため正しく解答できる。このようにGiNZAから出力する木が理想的なものであれば、特定の問題は正しく解答できる。
論理表現の構造とその扱い方によって解くことのできない問題のパターンがある。まず、リスト 17のような問題である。この文章題は先行研究においてタイプD(条件文1に2つの対象物のある問題)として取り扱っていた。しかし、本システムの論理表現では1文目の表現が不可能であるため断念した。また、表現が可能な論理表現を用いても、続く論理推論において2つの対象物の和を保持しておくことが難しい課題となる。
リスト 18では最後の文で対象物の名詞が省略され、修飾語のみで表されている。この場合、最終文の「黒い」とそれ以外の「黒い金魚」が同じものである解釈をする必要があるため、実装していない本システムで解くことができない。リスト 19とリスト 20はシステム上、望んでいない部分を対象物として読み取ってしまう例である。リスト 19は1文目の「長さ」、リスト 20は3文目の「残り」を対象物として読み取ってしまい、いずれも論理推論で失敗してしまう。このように、本システムでは様々な課題があることがわかった。
本システムは先行研究で考慮されていた問題パターンを解くことを目的として、より簡潔なものに構築した。
本システムでは形態素解析と依存構造解析はGiNZAで処理をさせ、その木から計算結果を導く提案をして処理をした。各文に対象物と数が存在することを前提として、木の動詞から対象物とする部分と増減を判定、形容詞から比較方法の判定、依存・品詞ラベルから数を取得して計算させるシステムを構築した。
評価より、解けない問題のパターンがいくつかあるが、想定していたよりも多くのパターンの問題を正しく解答できるシステムになった。これにより、文の構造情報と動詞辞書と形容詞辞書から文章題を解くことができることが分かった。また、Prologを活用することによって過去の対象物の判定を簡潔に書くことができる。
また、このシステムは論理表現を一種類しか用意していない。さらに、対象物の変化量を登録する仕組みになっているため、さらに長い問題文や別のタイプの問題を実装することもできる。
しかし、解けない問題で紹介したパターンはこのシステムで用いている論理表現では不十分であるといえる。特に修飾語の表現力は大変不足しておりで、「赤いひもの長さ」、「佐藤さんが使った画用紙」、「赤と黒の金魚」などは今回のシステムでは表現できない。また、「赤と青の色紙が合わせて16枚ある。」は赤と青の色紙の合計が16枚あるという情報を保持する必要があるが今回のシステムでは扱うことができない。そのため、複雑な修飾語を取得できる論理表現と合計値を情報として持てることが今後の課題といえる。また、今回は形態素解析と依存構造解析はGiNZAライブラリを用いたが、先行研究のように文章題を考慮した解析器を用意することも改善の一つである。しかし、既存の解析器の出力を文章題を解くために補完することでもさらに改善すると考える。
本システムで使用したコード、作成ライブラリを以下から一式をダウンロードできる。また、表 5に重要ファイル、コードの簡単な説明を示す。
表 5.ソースコードの種類と説明
ソースコード | 説明 |
---|---|
solver.py | ベースとなるプログラム問題文の入力から解答の出力まで一貫して行う。 |
labelClasses.py | 依存グループの情報が記述されているファイル。 |
op.prolog | Prolog処理のベースとなるプログラム。 |
verb.prolog | 動詞辞書。 |
adv.prolog | 形容詞辞書。 |
AzProlog.dll | AzPrologの機能を利用できるダイナミックリンクライブラリ。 |