人工無脳は考える
心のモデル化

機嫌の変わる辞書型人工無脳

記述できない心を記述する(その2) 2016/3/17

辞書型人工無脳

前回、plutchikの感情と行動のモデルを雑談にあてはめようとすると(1)イベントへの分類困難、(2)画一的対応、(3)意図の不在といった問題があることを明らかにした。次に人間同士のコミュニケーションであっても我々は相手の気持ちが分かっているようで分かっていないのであるが、それが人との付き合いを豊かなものにする一面があることも明らかにした。これらを踏まえ、周期的に変動する1つのパラメータを用い、ユーザの感情や反応と無関係に人工無脳の挙動が変わるというモデルを考えた。そこで今回は辞書型人工無脳自体について簡単に説明し、前述のモデルを組込む方法を検討する。

辞書型人工無脳は、おはようと言われたらおはようございますと返事する、というオウムや九官鳥のような方法で会話する。辞書にないことを言われたら~って何?と聞き返して返事を記憶し、次に同じことを言われたときは覚えた言葉で返事する。

返答を生成する部分の実装は例えば以下のようになる。

  1. キーワードと返答のペアを集めた辞書を用意しておく。
  2. ユーザのセリフの中にキーワードが含まれるか検査し、見つけた場合はそのキーワードのペアになっている返答を人工無脳の返事として使う
  3. 複数の返答候補があったら、その中からランダムに一つを選んで使う
  4. 返答に$weather$のように$~$で囲まれた文字列が含まれていたら、それをキーワードとして辞書を検査し、その返答で$~$の部分を置き換える

4番目の動作は返答のバリエーションを簡単に増やすための工夫で、タグと呼ぶ。

例1 人工無脳の辞書
キーワード返答
おはようおはようございます
こんちはこんにちは!,元気ですか?,ようこそ!,今日は$weather$だね
$weather$雨,晴れ,雪,くもり,くもり

例1の辞書の場合、ユーザが「こんちは!」と入力すると、辞書のキーワード「こんちは」が含まれるため、これのペアになっている返答のうち一つを出力する。ここで「今日は$weather$だね」を用いることにした場合、$weather$の部分は雨、晴れ、雪、くもりの中からランダムに選んだひとつに置き換えられ、例えば「きょうは雪だね」が実際の返答文字列となる。

変動する機嫌を組込む

さて、まず考えられるのは体調が良いときと悪いときで返答を変えることである。前回考えた変数conditionを使って、値の中に%Condition%という文字列を見つけたらcondition値に置換するという方法が考えられる。conditionは実数であるが、四捨五入して整数にキャストすれば1か0として扱える。例2の$hello%condition%$は、0≦condition<0.5の時は$hello0$、0.5≦condition≦1の時は$hello1$に変換され、体調によって異なる返答が生成できる。

例2 タグ展開を使った返答のバリエーション
キー
おはよう$hello%condition%$
$hello1$機嫌がよいときの返事
$hello0$機嫌が悪いときの返事

この方式は分かりやすいが、辞書が非常に読みにくくなるし0.3と0.4での違いなどは表現していない。また、画一的な反応を避けるために体調の変動を取り入れていながら、結局返答が偏る点もよろしくない。機嫌が悪いとき、まれに「絶好調ですよ!」と言われると言外にいろいろなメッセージを感じることができる。これはぜひ取り入れたい要素である。加えて、従来の人工無脳からのアップグレードを考えたとき、この方法では辞書を書きなおさなければ体調による変動が表現できない。人工無脳ではシステム以上に辞書を作りこむところで製作者の負担を減らすことが重要で、従来の書式でも体調の変動が生じるような方法が望ましい。

そこで、前述の方法はやめて分布のある乱数を導入する。

通常の乱数は一様な乱数と呼ばれ、どの値が現れる確率も同じになることが理想とされる。分布のある乱数は、それが特定の確率分布に従う。シミュレーションなど乱数の品質が求められる場合は正規分布、t分布、ベータ分布などが使われるが、人工無脳の場合はあまり精度が要求されないので図1のような直線を組み合わせた確率密度分布で考えよう。図1のグラフは高さfのすそがありcを頂点とした三角分布で、面積は常に1になる。fが1になると均一分布になり、fが0に近いほど分布のコントラストが強くなる。

図1 すそのある三角型の確率分布 (f=0.3, c=0.7)

これを積分し、逆関数を求めると次のようになる。

図2 累積確率分布とその逆関数

図2(a)の逆累積分布関数(b)をFINV(x)とすると、一様な乱数rand()から図1の確率分布を持つ乱数FINV(rand())が得られる。確率分布(a)を直線の組み合わせにしておくことで、逆関数の計算で使う数学関数は実数値を返すsqrt()だけにできる。すなわちMathモジュールが不要になる。

次にconditionを0~1の範囲で変動させるのに、もっとも簡単な方法としてsin()を用いる。図3の例ではcを7日周期で変動させ、乱数を生成した。cのラインの近くは点の密度が多く、離れたところはまばらになっている様子がわかるだろう。

図3Conditionの変動と乱数の出力例(f=0.25,cの周期=7日)

こうして生成した分布のある乱数FINV(rand())を辞書と組み合わせると、例3のように羅列した複数の候補を元気のないときほど左側、元気な時ほど右側になるように並べることで、体調に応じた反応ができる。

例3 体調変動が組み込まれた辞書
キー
おはよう・・・うん,おはよう,おはようございます。,おはよう!,おっはよーございます!Userさん元気ですか?!私は超元気ですよ!
左側ほど元気のない返事← →右側ほど元気な返事

次回はこのシステムを使った変動型人工無脳を試作しよう。

HOME ◀ 1 NEXT 3 ▶

人工無脳は考える by 加藤真一 2016