文章をprolog化するJAVAプログラム(1)

この間の記事で示してきた、文章情報のprolog化を、cabochaによるフレーズ化された情報を参考に、私が書いたものだった。ただし、cabochaの係り受け解析は用いず、ただ、フレーズの区分だけを用いている。

大量の文書情報をいちいち手動でprolog化したのでは意味がない。元々の予定である、prolog化のためのJAVAプログラムを作成した。ただし、まだ、接続詞の適切な処理、構文のツリー化における最適化などを十分行えていない。現時点でのパフォーマンス報告にとどまる。

まず、この間の記事で用いた「国境の長いトンネルを抜けると雪国であった」をprolog化させてみた。以下のようになった。

%%--------------------------------
%% 「国境の長いトンネルを抜けると雪国であった」のprolog化
%% ルート句: No.1 助詞/動詞:を 語:[[長い], トンネル] 接続詞: 原型:
%%--------------------------------
pl0000(
    node(を,
        node(の,
            国境,
            [[長い], トンネル]
        ),
        node(と,
            抜ける,
            node(であった,
                雪国,
            []
            )
        )
    )
).

少し解析ルールを変えたが、問題なくswi-prologが受け止める。pl0000 は文章の識別子で特に意味は持たない。ポイントをいくつか書いておこう。上記の文書には出ていないものも含めて書いておく。(次の記事で、メインのJAVAクラスを公開しているので、そちらを参照していただきたい。)

(1)ルート句の設定である。ルート句については、先の記事で「を、に、が、は」の助詞の強さについては書いたが、実はそれは、http://www.ibot.co.jp/wpibot/?p=2121の中で示した、wikipediaの助詞の頻度分析の上位にほぼ一致しているのである。ただし、一番上位には「の」があり、群を抜いているが、「の」の助詞の句は、さほど重要な役割を果たさない場合もあるので、基本、「の」を除いた先の頻度分析の上位のものがある句をルート句にしてツリーを作ることにしている。もし、どれもなければ「の」のある句をルートにしている。

(2)後の末尾に、右の葉が無い場合は、そこを [ ] の空リストにする場合がある。大した問題では無いのだが。

(3)連体詞は形容詞と同様の扱いをする(以前の記事で書いた)。形容詞や連体詞がひとつのフレーズの中で連続する場合は、リスト化する。

(4)助詞、助動詞、名詞、動詞、がひとつのフレーズの中で連続する場合は、ただ、繋げる。

(5)ひとつのフレーズの中で、名詞や動詞が単独で存在して、助詞、助動詞が無い場合は、暫定的に、擬似的な助詞、助動詞として、"[ところの,という]"というprologリストを付け加えておく。英語で言えば、関係代名詞みたいなものである。もちろん、単に [ ] と空リストにしたほうがいい場合もある。大した問題では無い。prologプログラム上のERRORを回避することが最大の目的である。

(6)フレーズの中に、「する」など、非自立の動詞が挟まれている時がある。例えば「職業とする人のことを指す」の中の「する」は非自立の動詞である。意味的に重要ではなく、実際に何かをするわけでも無いので、これも助詞、助動詞扱いにしてしまう。

今後、さらに細かいルールを入れてどのような文章にも対応するようにしたいが、さしあたって、上記のルールのもとに、先の芸人の定義もこのJAVAプログラムでprolog化した。結果は以下のようになった。

%%--------------------------------
%% 「芸人とは、なんらかの技芸や芸能の道に通じている人、または身に備わった技芸や芸能をもって職業とする人のことを指す日本特有の概念である」のprolog化
%% ルート句: No.9 助詞/動詞:を 語:芸能 接続詞: 原型:
%%--------------------------------
pl0000(
    node(を,
        node(や,
            node(た,
                node(に,
                    node(または,
                        node(ている,
                            node(に,
                                node(の,
                                    node(や,
                                        node(とは,
                                            芸人,
                                            [[なんらかの], 技芸]
                                        ),
                                        芸能
                                    ),
                                    道
                                ),
                                通じ
                            ),
                            人
                        ),
                        身
                    ),
                    備わっ
                ),
                技芸
            ),
            芸能
        ),
        node(て,
            もっ,
            node(と,
                職業,
                node([ところの,という],
                    する,
                    node(の,
                        人,
                        node(を,
                            こと,
                            node([ところの,という],
                                指す,
                                node(の,
                                    日本特有,
                                    node(である,
                                        概念,
                                    []
                                    )
                                )
                            )
                        )
                    )
                )
            )
        )
    )
).

これもswi-prologが正常に読み込めるprologの宣言文となっている。swi-prologに読み込むと、インデントのない次のような宣言文になっている。(:- listing.で表示させた)

pl0000(node(を, node(や, node(た, node(に, node(または, node(ている, node(に, node(の, node(や, node(とは, 芸人, [[なんらかの], 技芸]), 芸能), 道), 通じ), 人), 身), 備わっ), 技芸), 芸能), node(て, もっ, node(と, 職業, node([ところの, という], する, node(の, 人, node(を, こと, node([ところの, という], 指す, node(の, 日本特有, node(である, 概念, [])))))))))).

ルート句を「を」にしたので、その右と左をそれぞれprolog化している。私のprolog化の場合とは、「芸人とは」をルートにしていることと「または」を接続詞として生かしているところが異なっているが、全体としてさほど深刻な違いがあるとも思えない。

接続詞「または」をもっと生かせば、最終目標である、部分知識を拾い出すという点でも、遜色ないものになるはずである。