Hatena::ブログ(Diary)

西尾泰和のはてなダイアリー

2017-01-03

書評:夢見るプログラム

だいぶ前に著者の加藤博士から頂いていたもののいろいろ忙しくて紹介が遅れました。

この本は1999年に「人工無脳は考える」を立ち上げて「人と会話をするソフトウェア」(人工無脳)について研究・考察を続けてきた加藤真一さんによる本です。特に2章では21ページにわたって、Elizaに始まる人工無脳50年の歴史を俯瞰していてとても良いです。人工知能による会話フレームワークが鳴り物入りで紹介されたりしたときに、中身を見てルールベースだったりすると、僕とかは「ゅぃぼっと」かよ!とツッコみたくなるわけです。だけどゅぃぼっとは1996年だからもう20年も前なんですねぇ。

ルールベースの人工無脳が、育つにつれて「ルール追加の手間あたりの賢くなった実感」がどんどん0に近づいて、ルールの作り手のモチベーション維持ができなくなることは、その頃から既に知られていたように思います。機械学習の分野では同様に「教師データ追加の手間あたりの精度の向上」が指数的に減衰する問題が知られていて、それへの対処として能動学習(Active Learning)などのアプローチが生まれているわけです。そこら辺の知見を取り入れて昔より良くなったのかな〜と思ったら20年前と変わらないルールベースのフレームワークだったりすると「ゅぃぼっと」かよ!とツッコみたくもなるというものです。

3章4章では90ページほど使って、実際に基本のルールベース人工無脳を実装しながら解説していきます。冒頭の「舞台設定とキャラクタ設定を作る」は僕にはない発想で目から鱗でした。後半ではルールベースの人工無脳にありがちな「直前の発言だけに反応すると話題が続かない」への対処として文脈をマルコフ近似しようとするアプローチは面白かったです。

夢みるプログラム 人工無脳・チャットボットで考察する会話と心のアルゴリズム

2015-01-17

改善案を考える・人工無脳について振り返る

彼> この会話で何が起きて欲しいですか?

僕> このプログラムの改善案について話し、それについて質問されることで考えを整理し、新しいアイデアを見つけたい

彼> あなたはその改善案をどう知るのですか?

僕> ユーザの発話の中からどの部分をキーフレーズとして抽出するかについて、最初のバージョンでは直前の発話だけから抽出してランダムに選んでいて、それでは話がどんどんずれていくので次のバージョンでは過去の発話も含めてランダムで選ぶようにして、それだと直前の発話から選ばれる確率がどんどん下がってしまうのでエビングハウス忘却曲線的なのを入れて、IDFで重み付けして、スコアの高いものほど選ばれやすいようにしたのだけども、それでもイマイチなので抜本的に変更しようと思っている。

彼> その直前は、何のようですか?

僕> 直前の発話はまさに今聞いた内容で、やはりそれをきちんと聞いている風の反応をしないとユーザが手応えのなさを感じてしまう

彼> その風は、どんな種類の風ですか?

僕> 相手の発言を受け止めていることを、相手が実感できる

彼> 発話は、どんな種類の発話ですか?

僕> 質問に対するユーザの回答で、

彼> 発話は、どのあたりにありますか?

僕> 質問に対するユーザの反応で、それが長いほど傾聴がうまく言っている証拠、と書こうとしたのだが失敗した。発話は入力としてプログラムに入ってくる

彼> その発話について、他に何かありますか?

僕> 発話が長くなるように適切なキーフレーズを選んで質問することが重要。

彼> 傾聴について、他に何かありますか?

僕> 傾聴こそがこのプログラムがユーザに与える価値なので、まずは傾聴を定量的に計測する尺度を明確にして、その尺度の上で最適化を掛けるのがよいのではないかと考えている。

彼> 発話は、何のようですか?

僕> 発話はユーザという果実から搾り出されたジュースみたいなものだ。絞っているのが質問。

彼> 入力は、どんな種類の入力ですか?

僕> 現状ではキーボードを叩いてチャットのような形で入力している。音声入力が好きな人もいるけど、それは優先度の低いパスだと思う。

彼> そのキーボードは、何のようですか?

僕> 考えを綴る道具って考えるとペンのようだな。

彼> あなたはパスをどう知るのですか?

僕> まあ、音声入力ではなくキーボード入力に選択と集中するのは特に根拠の無い選択ではある。

彼> ユーザは、どこにありますか?

僕> コンピュータの前にいる。当面は僕がユーザだと思って良い。

彼> 音声入力は、どんな種類の音声入力ですか?

僕> NG そちらの話を掘り下げたいとは思っていない

彼> 傾聴は、何のようですか?

僕> ユーザの発話の中から適切なキーフレーズを見つけて、それについて問いかけることで更にたくさんの発話を促す、芋掘りみたいにつながり合っているアイデアを蔓が切れないように気をつけながら引っ張って、土から引きずり出すようなプロセス。

彼> そのキーフレーズは、どこにありますか?

僕> キーフレーズはユーザの発話の中にあって、どこがキーフレーズであるかを判定するのが目下の重要課題

彼> そのキーフレーズは、どんな種類のキーフレーズですか?

僕> 今は、形態素解析で単語を抽出した後名詞を結合してキーフレーズを作っているが、その結果IDFの辞書に登場しないものに関してはスコアが上限に張り付いてしまう。別のスコア付けの方法が必要で、そのスコアは「ユーザがどれだけ長い返答を返すか」に相関する

彼> そのキーフレーズについて、他に何かありますか?

僕> 構成単語やNグラムの特徴量からロジスティック回帰かパッシブアグレッシブみたいな方法でスコア付けする。あ、あと直前の発話の中のキーフレーズは特別扱いで高い優先度にすべき。あとこれを書いていて気づいたけど、今、名詞が連続しているとそれは全部くっつけたもの1個だけをキーフレーズにしてしまっているけど「直前発話中のキーフレーズ」だと「直前発話中」だけをキーフレーズにするんじゃなくて、部分列全部をスコア計算したい。

彼> そのキーフレーズは、何のようですか?

僕> フックのようで、そのフックで引っ掛けて引っ張りだす。

彼> キーフレーズは、どのあたりにありますか?

僕> 直接的にはユーザの入力の中にあるのだけども、過去の発話全部が共通のキーフレーズを介してネットワーク上につながっていて、キーフレーズは個々の発話をつなぐ紐であり、1つの発話の中だけに出てくるキーフレーズはそれほど重要ではない。何度も出てきて幾つもの発話で描写された側面をつなぎあわせているようなタイプのキーフレーズが重要。だから、キーフレーズは発話の中にあるって考えは適切ではないな。それは発話の間にあって、発話の上をゆるやかに覆っているイメージが適切か。

彼> あなたはそのキーフレーズをどう知るのですか?

僕> プログラムがどういう質問を返してきたかによって、プログラムが何をキーフレーズとして認識しているかがわかる。その認識が正しくない時にそれをプログラムに教える手段があればよいのか。

彼> 考えは、どこにありますか?

僕> キーフレーズは発話の中にあるって考えは、発話からキーフレーズを抽出する処理を書いたことに起因する思い込みの中にある

彼> ユーザについて、他に何かありますか?

僕> ユーザは適切な質問をされると楽しくなってさくさく返答が掛ける。だからそれを計測すると質問が適切であったかどうかが計測できるはずか。やはりターン制の対話プログラムではなくリアルタイムなチャットの形にして、入力時間なんかを特徴量として取ることが重要か。

彼> あなたはそのターン制をどう知るのですか?

僕> ターン制を選択したのは単に実装上一番楽であることが理由。必須ではないと当初から考えてた。リアルタイム化も難しくないよ、基本的には人間の発話を待てばいいだけなので。

彼> その実装上は、何のようですか?

僕> よくある間違いだな。何が顧客にとっての価値につながるかではなく、何が自分にとって楽であるかで実装を選択してしまうという間違い。

彼> スコア付けは、どこにありますか?

僕> 今の実装では、入力を受け取って形態素解析した後、その形態素列を受け取ってスコアその他の「環境」を更新する関数がある。キーフレーズのスコア付けがその関数の最初の仕事だったけど、今では拡張されて状態遷移で対話のフローを管理することも引き受けている。

彼> あなたはその状態遷移をどう知るのですか?

僕> 今はMetaphors in Mindを参考にしながらハードコーディングしている。

彼> ターン制について、他に何かありますか?

僕> 簡単な事で、今は入力欄でユーザがEnterを押したことを、即座にターンエンドの宣告として解釈しているわけだけど、現実のリアルタイムのチャットではそうではない。続きを書き始めている時、話が完了してない時はターンエンドではない。続きを書き始めているのはCUIアプリではなくHTML+JSとかのインターフェイスに変えれば簡単に取れる。

彼> ハードコーディングは、どんな種類のハードコーディングですか?

僕> 今の状態を保持する変数があって、ある状態でどういう条件を満たしたらどういう状態に遷移するかってのがコードで実装されている

彼> その条件について、他に何かありますか?

僕> 特にパラメータのあるタイプの条件では、本当にその条件が適切かどうかっていう検証がないのは問題。そこは十分なデータがあれば自動調整することもありえるかと。

彼> その条件は、どんな種類の条件ですか?

僕> 具体的には例えばキーフレーズの抽出数が一定量を超えたら、とか。

彼> その一定量は、どんな種類の一定量ですか?

僕> 今はフィーリングで決め打ちになっている。実際に、一度大きくしすぎて期待した遷移がなかなか起きないこともあった。今もそう。あー、あとはキーワード抽出だった時代に比べてキーフレーズ抽出に変えたから抽出される数が減っているのにそれに合わせてないのも原因か。今後キーフレーズの部分列もキーフレーズにするように変えたら、今度は抽出数がぐっと増えることになるな。

彼> その抽出数は、どこにありますか?

僕> 単純に、今までに出てきたキーフレーズとそのスコアを溜めている変数があって、それのサイズで見ている。

彼> 部分列は、どんな種類の部分列ですか?

僕> 複数の単語で構成されているキーフレーズに

彼> 関数について、他に何かありますか?

僕> キーボードの調子が悪い…Enterキーが2度押しになってしまうとか酷い……。複数の単語で構成されているキーフレーズに関して、その列の一部を取り出してできるフレーズもすべてキーフレーズとしよう、という意味ね。関数は環境更新の話だったか。他には…いろいろな機能を引き受けすぎの感はあるな。でもここはホットスポットなので今はグチャッとしてても仕方ないと思う。状態の更新は今はハードコードでも、最終的には行列に変わると思っている。決定論的な遷移は確率的な遷移の特殊形にすぎないわけで、内部状態が外部からの入力により確率的に遷移して、その状態によって外部へのアウトプットが確率的に決まる、というモデルを考えていて、現状前半が決定論的、後半が確率的になっている状態だけど、前半も確率的になるのが適当だし、それは遷移行列で表現されるだろう。

彼> その2度押しについて、他に何かありますか?

僕> NG その話題を掘り下げるのはやめよう。

彼> その2度押しは、何のようですか?

僕> NG やはり「それやめよう」コマンドは必要だな。直前の質問を作成するのに使われたキーフレーズのスコアを減らすコマンドとして。

彼> その確率的は、どんな種類の確率的ですか?

僕> 今のプログラムの出力を決める確率モデルは単純で、状態が決まるとその状態で出力可能な複数の質問テンプレートが決まり、質問テンプレートに埋め込むキーフレーズは別途抽出されており、その直積の集合から「既出の質問」と「NG登録された質問」を取り除いたものからのサンプリングになる。

彼> 確率的は、どこにありますか?

僕> 今は出力を返す関数の中にハードコードされている。

彼> 確率的について、他に何かありますか?

僕> これも今はハードコードされているけど、出力確率の行列になってもよいと思う。資料中の会話例から頑張って教師データを作ったら隠れマルコフモデルのパラメータ推定問題に帰着するなぁ。めんどくさいし、あんまり顧客価値の改善につながらないと思うのでやらないけど。頑張って教師データを作って学習させるよりは、普段使っているうちに徐々に賢くなる方がいい。

彼> そのハードコードは、どこにありますか?

僕> 出力を返す関数の中。

彼> 教師データは、何のようですか?

僕> 負担。性格的な問題かもしれないけど、僕にはマメさがないので、教師データを事前に頑張って整備したら性能が上がります、っていう系統の手法はあんまり好きになれない。

彼> 決定論的について、他に何かありますか?

僕> 昔の人工無脳はおおよそ決定論的だった。キーワードがマッチした時に出力される言葉が決まっていた。だけどその後、ひとつのキーワードに対して複数の出力を対応付けることができるものが出てきて、その場合、キーワードのマッチした出力の集合からランダムにサンプリングして出力されるような実装になっていた。今から考えると、あれが決定論的な対話から確率的な対話への分かれ道だったかもしれない。

彼> その人工無脳は、どんな種類の人工無脳ですか?

僕> キーワードとそれに対する出力のペアを持っていて、ユーザが入力した時に、その入力の中にキーワードが見つかればそれに対応した出力を出す。このシステムとの比較で説明すれば、キーフレーズ抽出の部分が、あらかじめ登録されているキーワードの文字列パターンマッチで置き換えられている

彼> 遷移は、どこにありますか?

僕> 今説明した範囲では昔の人工無脳に状態遷移はない。僕が中学生の時に作った人工無脳はその点がちょっと改良されていて、文字列パターンマッチの対象がプログラムの発話自体にも拡張されていて、かつ不可視なラベルを埋め込む構文を用意したため、キーワードと出力のペアっていう従来型のデータ形式の枠組みを引き継ぎつつ、内部状態の遷移を記述できた。それまでの人工無脳が刺激に対して単発で反応するだけで記憶を持たなかったのに対して、僕のフレームワークを使えば複数回の出力で構成されるようなやりとりを記述することができた。

彼> その出力は、どのあたりにありますか?

僕> データファイルの中に、キーワードと一対一対応する形で記述されていた。

彼> ハードコードについて、他に何かありますか?

僕> そういう意味では、その人工無脳はなんらの確率モデルをハードコードしていない。全部データ側に押し出されていて、システム側は状態遷移を記述出来るだけの表現能力を持った記述言語を提供することに徹していたといえるだろうなぁ。

彼> その人工無脳は、何のようですか?

僕> 子供だね。知識を与えれば与えるほど成長してより賢くなる。しかしとにかくデータ量を増やせば賢くなるはずだというアプローチは、データ追加の労力あたりの賢くなった実感が徐々に飽和しだしてしまった。アトムを作った天馬博士と同じで、自分の子供だと思っていたアトムが成長しないことに気づいて愛が失われてしまった。

彼> そのデータ量は、どんな種類のデータ量ですか?

僕> 人間が直接手作業で入力することで作られたデータの量。だからさっきの話だと学習データに相当するもので、負担なわけだ。しかし当時は汎化性能って考え方がなかったから、入力した以上に処理できる量をスケールさせる方法がわからなかったんだな。

彼> 人工無脳について、他に何かありますか?

僕> 人間と対話することを主目的とするプログラム、っていう観点から言うと、Siriだとかしゃべってコンサルだとかの形で対話経験のあるユーザはかなり増えたんじゃないのかな。Herって映画もあったし。ただ、20年前のその人工無脳ブームは「Appleが作って与えた人工の人格との会話が楽しくてブームが起きた」のではなく「個々人が自分の好きな仮想の人格を実装して、自分だけの人工無脳を作ることが出来る」というところが顧客価値になっていたと思う。お仕着せの仮想人格と話すことではなく、自分でつくり育てることの方に価値を見出すユーザがいるっていうのが重要なポイントだと思うなぁ。

彼> その人工無脳は、どのあたりにありますか?

僕> インターネット上にチャットルームがあって、まあPerlで書かれたCGIなので簡単に設置や改造ができて、そいつに人工無脳が搭載されている、という時代があったわけだよ。そうか、最近の若い人にとってチャットってのはSkypeやLINEなのか。そうだとすると人工無脳を設置するのはそう手軽ではないか。

所見:当初の目的からずれていってるなー。当初の目的に照らし合わせて有益かもしれない内容を整理すると:

  • 音声入力を避けてキーボード入力に専念していることに、特に根拠は無い
  • 「キーフレーズはユーザの発話の中にある」と考えていたが、これは根拠の無い思い込みにとらわれていた。「キーフレーズは発話の間にある」と捉え直すことで、キーフレーズの役割は複数の発話を結びつけることであり、発話をまたいだ出現回数こそが本質的に重要な尺度なのに今はそれを使ってないってことに気づいた
  • また、適切でないキーフレーズが選ばれている場合、ユーザはそれに気づくことができるので、その気づきをプログラムに教える手段を用意すべき
  • 当初考えていた「ユーザの発話の長さが長くなるように機械学習で適切なキーフレーズを選ぶためのモデルを作る」をやる上では、ユーザの入力時間とかも取れたほうが良いのではないかということで、まずはリアルタイムチャット形式へのUIの変更のほうが優先度高。

という感じか。

2007-12-02

未踏ユース最終発表会2日目

前哨戦

  • 川合さんが持ってきた小さいマシン
  • こうなってくるとマシンを携帯する上での最大の問題は液晶の大きさ・重さ・壊れやすさになってくるか。電子ペーパーになるのかなぁ。

始まった

  • 二次会に行ったOBがほとんど来ていなくて肩身が狭い
  • モニタトラブルで時間が掛かっている間に人が増えてきた

CC-Optimizer

  • キャッシュを考慮してPostgreSQLを高速化
  • Buffering Operatorを使う
  • SQLでSELECT ... WHERE ... 的なことをする場合、「条件に合うものを取ってくる」「処理する」を切り換えて繰り返すことになるが、この片方がC1キャッシュに乗らない場合入れて捨てて入れて捨ててを繰り返してもったいないので…という話?
  • 最大74%、総合で6%〜17.5%の高速化になる

しずく

  • 図書館から利用者間のコミュニケーションが失われた
    • 貸し出し履歴情報の可視化とサジェスト、ユーザクラスタリング
  • 本を介したSNS
  • 借りた本が非公開のタブ(本棚)に自動で流れ込んできて、例えば自分の公開本棚「プログラミング」にドラッグドロップすると公開される。
  • 今Amazonなんかでブックリストを作るのに比べて「借りた本が自動的に本棚に入って、それを別の棚に分類して並べる」というだけでブックリストができるので敷居をさげる効果はありそう。
  • 本をぶちまけた無限画面がブラウザ上でぐりぐりスクロールする。ズームアウトして全体を眺めたりできると面白いだろうな。
  • 友達の本棚で見つけた本を自分の本棚に入れる=[後で読む]タグ
    • そのまま予約ができたりとか、「積ん読」本棚に入ったりするといいのかな。
  • 気になるあの子の借りている本からサジェストを掛ける→先に借りる→リアル「耳をすませば」支援
  • なんか「後で借りる」「後で買う」「買った」「借りた」タグがあるといいのかもとちょっと思った。

昼休みスケジュールを書いてもらう機構

  • 「拡大するとこんなにでかい!」
    • そりゃ拡大してるから!w
  • みんなでDoS攻撃してサーバが落ちるプレゼン

Sequential Graphics

  • みなさんお待ちかねのSequential Graphics
  • PC上で紙の真似の臨場感を目指しても追いつけないのではないか。PC上でしか不可能な臨場感を作れないか。
  • Processingではタブレットの筆圧を取るのが困難だった。C++に移植した。
  • みなくても使えるメニュー。
    • メニューからマウスジェスチャーに自然につながる。
      • pieメニューという名前らしい。
      • ペンデバイスインタラクションの論文を読むといいらしい。
  • おおおお、3Dカラーピッカー、ぐりぐり!
  • 任意の画像でペン代わり
  • すごい
    • プレゼンもうまい日本昔話
  • きちんと新しいものができている。最初からかなりすごかったのだけど、単に高速にしたりとかするだけじゃなくて新しいエクスペリエンスを作り出せている。すごい。
  • マウスの移動が早すぎて拾えなかったところを補完で周囲から生成
  • 音も入った。簡易シーケンサー!これはすごい!
  • ひげの伸縮する竹内先生w
  • 「YamahaのDX7はそれじゃないと出来ない音が出たから、テクノが生まれた 」by ところてん

MPEG圧縮を考慮した大域照明

  • まっくちゅぷらんく
    • コンピュータサイエンスのまっくちゅぷらんくは辺境の地においてあるのでパソコン以外何もない
  • トイ・ストーリーはレンダリングだけで3年掛かってる
  • 頑張って綺麗にレンダリングしてもMPEGで圧縮する過程でエラーが入る。もったいない。ならばどれくらいのエラーが入りそうか調べて、その精度でレンダリングをやめてしまえば高速。
  • 「ごっつさぶいんですよ」
  • Pixerは映画を圧縮してDVDにしているのではなく、別個にパラメータを変えているらしい。

終わり

  • Social IME: http://www.social-ime.com/
  • 川合賞は欠番
    • 川合賞出すならと思って西尾賞の準備したけど…
    • 賞品が何もでない西尾賞は松原さんのホワイトボード。一般のユーザをターゲットにする場合UIはとても重要。よいUIを作るためにはきちんとユーザテストをすることが重要。ユーザテストを長期間やったことは評価できる。
      • 終わった後でユーザテストの際に作ったマニュアルを見せてもらったけど、こんなきちんとしたマニュアルを作ったのならもっとアピールすべきだと思った。
    • 超特急で発表資料を作ったせいでいまいち説明不足だったな。なにより、最後の「誰が受賞か」のところにスライドがなかったのでわかりにくかった。前に「僕は前四次元うにゃうにゃをやっていたので『四次元体感ゲーム』に賞を出す…と見せかけて実はもっとずっと前には人工無脳を作っていたので人工無脳搭載の『ブレインストーミングエンジン』に授賞したいと思います!」とかやってたのを知らない人の方が多いしなー。
  • 作業をしている時のデスクトップ状態を保存しておきたい。Aというプロジェクトをやっているときに、BというプロジェクトをやりたくなるとAやりかけの環境を取っておきたい。
    • 「それ『ユーザアカウントを作る』でOK」
      • おおお、それだ!すばらしいライフハック。
      • どう書くorgを作る自分。ActionScriptを勉強する自分。
  • ぐるプロ中
    • レイヤー合成の式をみんなで導出した。後は実装するだけ!