気象予報をシャロちゃんに言わせたい! (eeic Advent Calendar 2015)

eeic Advent Calendar 2015の4日目の記事。

今日はチノちゃんのお誕生日なのでチノちゃん関連の何かをしようと思ったのだが、ずっと解説しそびれていたシャロちゃんの気象情報ツイートの仕組みを取り上げることにした。

シャロちゃん(@Ishotihadus_M)は、#eeic_botthon というeeic民が集まってtwitterボットを作る会で作った僕のメイド的存在のbot。タスク管理とか天気予報とか鉄道の運行状況とか教えてくれる。チノちゃんじゃないのは、なんかシャロちゃんの方がメイドさんっぽかったから。多分フルール・ド・ラパンの制服のせいだと思う。っていうかチノちゃんはメイドさんというより嫁とか妹とかそういう家族みたいな存在が合っていそうだ。チノちゃんがメイドさんでも何も命令できないでしょ。そういうこと。シャロちゃんはちょっといじりたくなるのでメイドとして優秀。まあでも正直チノちゃんのお兄ちゃんになりたいって言ってる人たちはどうかと思うけど。

話を戻して。以前には気象庁から情報を取ってくる方法を解説したが、シャロちゃんはこれを解釈してシャロちゃんの言葉でしゃべってくれる。たとえば「今日の小笠原の天気は」とかリプライを送れば「今日の小笠原の天気はくもりで、昼前から夕方は晴れ。所によっては朝晩に雨が降るみたい。最高気温は27℃。」などと返してくれる。

もとの気象庁の文言では「くもり 昼前 から 夕方 晴れ 所により 朝晩 雨」となっていて、これを読んでシャロちゃんが上のように喋ってくれるわけだ。

見た感じ難しくないのだが、実際にやってみるとこれが結構難しい。簡単に見えるのは、人間には言葉が理解できるからだ。コンピュータは言葉が理解できない。それをまるで理解しているように見せる方法を紹介しよう。ある意味「自然言語処理」を実装していく。

動作のフロウ

動作の流れとしては、気象庁から文言を取ってくる→構文木を作る→構文木を解釈して文章を作る、というものである。実際には本当の構文木ではないのだが、天気予報の情報を表す木構造を便宜的に「構文木」と呼ぶことにする。

構文木は実際には必要なさそうなのだが、長い天気予報になるとだんだん解釈が難しくなり、そのままだと正確に変換できない可能性が高い。安全策として構文木をまず作って文章の構造だけ形にしておいて、それを選んで(できればなるべく多く情報を入れて)文章にするというのが最終目的である。

気象庁の府県天気予報で発表する文字列

これはおそらく機械的に生成している。実際に見てみれば早いのだが、全角スペース区切りでパターン的に生成されている。たとえば「北西の風 晴れ 曽於 では 夜のはじめ頃 雨 で 雷を伴う」や「北の風 晴れ 所により 夜のはじめ頃 雨 で 雷を伴い 非常に 激しく 降る」などで、地名以外は例外がほとんど出てこない。したがって、全角スペースでsplitしてしまえばそれだけで単語分けができてしまうことになる。これを元に考えていく。

(ここでの)構文木の定義

構文木のノードとその親子関係の定義をしておく。実はあまり綺麗じゃない定義なのだが、実装上コレが楽だったのでこんな感じになってしまった。この構文木の定義が腕の見せどころであって、これを自分の使いやすいように作れることが一番良い。

構文木の目的は、「元の文言を復元できる状態で、修飾関係を明らかにする」ことである。修飾関係が明らかになれば、もとの単語が並べてあるだけの文字列から複数の文をつくることも容易い。

1つのノードには自分の親と子情報以外に「単語」「付属語」「付属目的語」の3つの情報を含めることにする。「付属語」と「付属目的語」の2つはあってもなくてもよい(この2つは造語で、本来の意味ではない)。

「付属語」は「から」「まで」「では」の3通りで、「付属目的語」は「AからB」のパターンの場合のみこれにBが入る(普通は「Aから」)。たとえば「晴れ 夜遅く から 雨」の場合は、「晴れ」の子ノードは「夜遅く」で、この付属語は「から」になる。「晴れ 朝 から 昼前 雨」の場合は、「朝」のノードに付属語「から」と付属目的語「昼前」がつく。付属語が「では」の時は単語に地名が入る。

「から」「まで」「では」が後置しない単語はすべて付属語を持たない単一ノードとなる。

子と親の関係は、修飾関係にあるとき子になるのが原則。ただしルートノードはメインの天気になるので必ずしもそうならない場合もある。子が複数ある場合は、たとえば「雨 のち くもり 所によって 夜遅く から 雷を伴い 激しく 降る」などで、このときはルートの「雨」ノードの子が「のち」と「所によって」の2つになる。

例を見てみよう。文言が「晴れ」の場合はノードが1つで、そのノードの単語が「晴れ」。文言が「晴れ のち くもり」の場合は「晴れ」->「のち」->「くもり」の親子関係になっており、すべて付属語を持たない。その他にも幾つか例を挙げておくと、下のようになる(付属などの説明は省いている)。

クリップボード01

構文木の生成

といってもこれは前から順番に単語を見ていって適当に作っていけばいいだけだ。だがこれを説明しないとこのブログの意味が無いので説明しておく。

今回の実装では単語のパターンとして以下の5パターンを用意した。

  • 「では」(場所指定句)
  • 「所により」(場所句先頭帰還句)
  • 「まで」「から」(時間指定句)
  • 「未明」「夜明け」「夜遅く」など(時間句)
  • その他

実装上注意する点は以下のとおり。

  • 「では」は直前の語を場所の単語として認識させ、この場所の単語をルートノードの子にする。
  • 「所により」や時間句も同様にこの場所の単語をルートノードの子にする。
  • 「まで」「から」は、それが登場したら、自分自身はその前の単語の付属語になる。
  • 「から」は、その後に時間句がきた場合のみ「付属目的語」になることも考慮する必要がある。

これらのことを考慮しながら構文木を作っていけば良い。なお特に指定がない場合は、直前に見たノードを親としてノードを作れば良い。

実際に例を使うと下の図のような感じになる。

クリップボード01

あとはこれをプログラム的に実装すればいいだけだ。

ただしシャロちゃんは「所により昼前まで」などといったパターンも適用できるようになっている。実際に結構登場する。さらに元のデータでは先に風に関する文言が来るので、どこから天気の文言が始まるのかも調べられるようになっている。このへんは余裕で実装できるはずなので、特別な解説はしない。

構文木から文章を生成する

構文木ができたら、これを読んでいって文章を作る。子ノードの順番が解釈順に保持されていることを利用してやっていくが、まずは最終的にどんな文章にしたいのかを考えておく。シャロちゃんの場合、
「今日の天気は晴れのちくもり。所によっては夜から雨が降るみたい。」
などとなっていて、前半はそのままの内容だが、後半はかなり文言を書き換えて動詞にするなどしている。この概略を説明しよう。

まあでももちろん構文木を深さ優先で見ていってそのまま繋げればよい。シャロちゃんの場合は深さ優さん探索すらせず、ルートノードを言う+ルートノードに「のち」「ときどき」「一時」(時間経過句)などがあればそれをつなげる+ルートノードに時間句があればそれをつなげる+句点を置く……などと作っている。これはたとえば同じ「晴れ」であっても「所により」の後では動詞句になるから、などの理由による。本来であれば深さ優先探索でも問題ないだろう。

動詞化は天気を辞書にしている。たとえば「雨」なら「雨が降る」、「雪」なら「雪が降る」、「くもり」なら「くもる」、「霧」なら「霧が出る」、「雨か雪」なら「みぞれが降る」などである。「雨」の後に「で 雷を伴う」なら「雷雨になる」などとしている。辞書にない場合はそのまま「みたい。」をつなげることでそれなりに不自然でない(「夜は雪みたい。」)のでこれを採用している。

補足

時間句は気象庁で定められている17個の用語(未明、夜明け、明け方、早朝、朝、午前中、昼頃、昼前、昼過ぎ、午後、夕方、夜のはじめ頃、夜、夜遅く、朝晩、朝夕、日中)を採用している。

天気を表す用語は11個(晴れ、曇り、くもり、霧雨、雨、雪、ひょう、雷、霧、雨か雪、みぞれ)を採用している。たしか「みぞれ」が予想されるときは「雨か雪」と表現されるので必ずしもすべて登場するわけではない。ただ、シャロちゃんはこれを天気予報のフラグにしているので、これ以外の天気が登場すると解釈に失敗する。

時間経過句は「ときどき」「一時」「のち」の3種類である。

またシャロちゃんが受け付ける地点は全国予報で表示されている23地点に限っている。

まとめ

シャロちゃんめっちゃすごい自然言語処理してるぜオラ!みたいな記事にしたかったけど、実はパターンがわかりきっているからそれを適当に解釈して、辞書にあるとおりに文章を作っているだけ、という話になってしまった。「まるで言葉を理解しているよう」にするのは実は簡単なのかもしれない。パターン処理できるような文言はこんな感じにゴリ押しでも戦えるのだろう。

本当の自然言語処理は日本語など語順が曖昧でコンテクスト依存性が大きい言語では難しく、確かに係り受け解析などの技術も十分に作られているものの、それでもまだまだ発展途上な技術である。eeicで開講されている「言語音声情報処理」の授業でもこれからこの日本語の解析を扱っていく。研究室としては鶴岡研究室などが代表的である。自然言語処理、音声言語処理に興味がある人たちは、ぜひ #進振りはeeicへ 。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です