![]()
人工無脳は考える |
掲示板 |
資料 |
アーカイブ
2005/02/12,19 人工無脳のアーキテクチャ |
next:解析ブロック入門編 >> Next Session:人工無脳の条件
現在色々な環境で稼動している人工無脳たちには特に決まった構造のルールや共通のライブラリなどは無く、個々の製作者の趣味に基づいて作られている。それでも目的や考えは大体同じなので、大雑把にとらえれば共通する構造のようなものがある。本章ではそれをできるだけ一般的な形で機能ごとに整理しよう。
Table 1に、典型的な人工無脳の形式を示す。ハッシュ型は入力文字列の中に辞書のキーにヒットするものがあるかどうかを検索し、ヒットした場合、その辞書記憶の内容を出力する。キー文字列が短いと色々な入力にヒットするようになってしまって命中精度が低くなり、キー文字列が長いといつまでたってもヒットしない。ログ型はチャットのログをそのまま辞書に転用し、入力文字列と辞書の記憶が似ていればヒットする。マルコフ連鎖型はチャットのログからランダムに文書らしきものを生成する辞書を起こしておき、辞書のキーにヒットするものを選んでから文書を生成させる。もちろんこれは人工無脳入門編というべきシステムで、人工無脳製作者はそれぞれに工夫を凝らして面白いやり取りができるように独自拡張を施すのが普通である。それでもこれらの例でわかるように、返答アルゴリズムと辞書の形式は密接に連携している場合が多い。
| Table 1. 人工無脳の分類 | ||
| 人工無脳のタイプ | 返答アルゴリズム | 辞書の形式 |
| ハッシュ型 | 辞書の逆引き | 連想配列 |
| ログ型 | 文字列の相関係数+辞書の時系列 | タグ置換したログ |
| マルコフ連鎖型 | 返答へのポインタ? | マルコフ連鎖 |
ここで、人工無脳全体の構造を理解しやすくするために、独断と推測でシステムをブロック図にしてみた。人工無脳は入力文字列を利用しやすくするための前処理である解析、辞書への追記である学習、次の発言を決定するルールである計画、辞書から日本語を組み立てる生成などから構成されていると考えられる(Fig. 1)。
![]() |
ただし、前述のように稼動中の人工無脳はこのような機能の区分をあまり明確にしていないものが多い。また、多くの人工無脳は「次の返事の生成」についてのアルゴリズムは持っているが、長期間に渡る会話を考慮していないために、人間が脊髄反射的にボケやつっこみの発言を行なうように単発の入力に単発の返事を返す場合が多い。これは図中の計画ブロックが状態を持たないということを意味し、またフィードバックも効果的に機能していない可能性が高い。人工無脳が人間とより自然な会話をするためにはボケ-突っ込みだけでは不足であることは明らかなので、まず人工無脳の基幹となる解析-学習-計画-生成の各ブロックについてできるだけ機能ごとに独立するようにまとめ、それらに何を付け足したらよりよい人工無脳ができるのかを考えていこう。
解析ブロックの主な目的は、人工無脳にとって必要な情報を入力文字列から取り出すことである。必要な情報とは、例えば人の特定のために「私」という単語を検出したいと思っても、単純に検索をかけると「私立高校」や「私の車」などにヒットしてしまう。すなわち、ここで問題となるのは日本語の場合、英語と違って単語の区切りを機械的に解釈できないということである。そのためのツールとして、近年は形態素解析器と呼ばれるモジュールがよく使われる。形態素解析器は巨大な日本語辞書を要するため昔は人工無脳ごとに工夫を凝らした擬似的な日本語解析が行なわれていたが、今ではフリーの形態素解析器11茶筌、MeCab、KAKASIなどが代表的。が利用可能である。形態素解析は、日本語の文字列を
| ひぐらしの合唱を聞いているだけで、日中の暑さを忘れられるようだった。 |
| ひ ぐらし の 合唱 を 聞い て いる だけ で 、 日中 の 暑 さ を 忘れ ら れる よう だっ た 。 |
というように品詞ごとに切り分ける。むろん形態素解析器は万能でなく、上の例でも分かるように、「ひぐらし」→「ひ+ぐらし」と間違った解析をする場合もある。
学習ブロックは入力文字列を人工無脳の辞書に追加する機能を持つ。辞書の構造は様々であるが、連想配列とかハッシュと呼ばれる仕掛けが利用される。これらは通常の配列と異なり、$hash["key"] = "value"
というように文字列を使って配列の内容を取り出すことができる。PerlやRubyなどのスクリプト系言語はハッシュが始めから組み込まれているので、人工無脳を作るのに適している。
人工無脳には常に自動的に学習を行なうものと、明示的な指令によって学習するものがある。前者の利点はチャットサービスに人工無脳を設置しておくだけで次第に辞書が増強されることであり、自然とそのチャットに要する知識を吸収できる。しかし、人工無脳は不特定多数の人間の発言を詰め込んだ辞書を作るためキャラクタ付けには向いていない。後者の利点はなんと言っても台詞を覚えさせるのに労力がかかりすぎて往々にして人工無脳製作者が途中放棄することである。
人工無脳の返答を決定する。この部分が人工無脳のネタの根幹とも言えるが、ソース上ではたったの一行で表現されてしまうことも多く、人工無脳プログラムを読むときの難関のひとつである。我々自身、会話の中ではどういうアルゴリズムで返答しているのだろうか。何気ない話題を振る、質問に答える、冗談で相手を笑わせる、連想したことを述べる、などいくつも考えられるだろう。計画ブロックを考える第一歩は、そういった日常を、電車の中で誰かと誰かが会話しているのを横から聞くように、少し引いた立場で観察することにあるのかもしれない。
繰り返しになるが、よく知られた返答のアルゴリズムとしては辞書の逆引きとログの再生がある。
「こんにちは」と言われたとき「こんにちは。お元気ですか」と返事することができる。この入力と出力の組み合わせを辞書として記憶しておき、入力文字列の中に「こんにちは」があるかどうかを調べる。大きな辞書を用意すれば、様々なシチュエーションに対応できるようになる。なお、辞書に載っている言葉がひとつもなかった場合はどうとでも取れる返事を適当に返す。この適当な返事にバリエーションを持たせることで何とか単調にならないようにする。このシステムの欠点は、辞書を充実させればさせるほど個々の項目にヒットする確率が低下し、適当な返事が多用されすぎることにある。
チャットのログを読めば、会話の中で行なわれたやり取りを後から追跡できる。すなわち、質問の次の行には返事が記録されている確率が高いことになる。そこで入力文字列とログの文字列を比較し、何らかの方法で相関係数を計算してそれが最も高い行の次の行を返答とする。ここで「デイジー(←人工無脳の名前)はどう思ってるの?」という返事の行を利用することになったとして、人工無脳が自分自身にそれを尋ねるのはおかしいので「あなたはどう思ってるの?」という具合に置き換えたい。この人称代名詞の置き換え処理は通常解析ブロックで行なわれる。
返答アルゴリズムが決定した返答は、実際の表現としては文の先頭ノードへのアドレスだったり、何かのコードである。それを日本語に展開するのが生成ブロックの機能である。もっとも単純にはただハッシュを引いて得られた内容を返すだけだが、乱数を使って文章を作ったり、タグの展開などを行なう場合もある。
以降のページで、プログラムを作りながら各ブロックを構築し、スターター的な人工無脳を作ってみる。