Hatena::ブログ(Diary)

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

2017-01-03

書評:夢見るプログラム

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

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

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

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

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

2015-09-10

首都大学東京の「情報通信特別講義」で話してきました

首都大学東京システムデザイン学部1-2年生配当科目「情報通信特別講義」で1時間半の講義をしてきました。

講義資料はアンケート結果をもらってから加筆して公開する予定です。

今回、複数人の講師による講義でした。

小町先生が他の講師の講義も含めて #tmutalks というタグでツイートしています。首都大学東京システムデザイン学部1-2年生配当科目「情報通信特別講義」 - Togetterまとめ

自分のTweetまとめ

講義の後の質疑・雑談や他の講師の話を聞いて、僕が違和感を持ったところ(僕の講義で使った「言語」で表現するなら「現実と自分の理解のギャップ」)について後からいくつかツイートしたので転載して加筆修正しておきます。

■「コネが大事」という言葉の真意について

「一言で要約すると、コネが大事」というような話が何度か出たのですけど、僕個人は「コネ」という言葉はあまり使いません。そのギャップが何から生まれたのか考えてみました:

僕が学生の頃「コネが大事」と言うオッサンは嫌いだった。自分がオッサンになって、彼らが何を伝えたかったかがわかるようになった。当時の自分の「コネ」という言葉の解釈と、彼らの「コネ」という言葉の解釈にズレがあったのだ、と今では考えている。

当時の僕は、「コネ」を「親がすごい」みたいな「運で決まるもの」と捉えていた。しかし、学生にアドバイスをするオッサンがそんな「本人の努力でどうにもならないこと」を重要だとか言うはずがない。彼らの言っているのは「努力で作ることができるコネ」のことだ。これはどうやって作られるか?

その作り方がこれ:「人と仲良く。過去に仲良くすると助けてくれるが、過去にいじわるすると跳ね返ってくる。」 自分が困ったときに助けてもらえる「コネ」は、ヘラヘラ笑いながら名刺交換していても作れない。自分から率先して人を助けることによって作られる。 https://t.co/LToipAZb7e

(参考: ギブ&テイクはギブから始まる 焼畑農業をやめるために---新卒準備カレンダー 2011春)

というわけでオッサンの言う「コネが大事」ってのは、当時の自分にわかりやすいように噛み砕くと「周りの人を助けることで、自分が困ったときに助けてくれる人を増やそう、それが大事」ということだと思うんだ。誰もそこまで噛み砕いて教えてはくれなかったが。


■「流行りものに飛びつこう」について

たぶん id:overlast さんの講演の中で語られたのであろう「流行りものに飛びつこう」という言葉について、これも「コネ」と同様にオッサンの中の解釈と学生の中の解釈がズレそうだなと思ったのでつらつらと書いてみました:

「流行りものに飛びつこう」も、割とハイコンテキストな言い方なのではないかと懸念している。「数学が大事」「より抽象度の高い知識ほど応用範囲が広い」というテーゼが通奏低音として流れていることを前提として、アンチテーゼとしてあえての「流行りものに飛びつこう」だよね?

抽象度の高い知識の方が応用範囲が広いから、年を取るに従ってそういう知識の重要度が上がる。オッサンたちは普段の生活の中でその必要性を痛感していて、だから学生に「大学の数学とか超重要」などといったアドバイスをする。一方で抽象的知識は経験と結びつかないと応用しにくい、それを学ぶモチベーションも維持しにくい。

それを踏まえて「流行りものに飛びつこう」は若者の戦略としては有用だ。経験を積み上げているオッサンと若者の戦いは基本的に若者が不利だが、流行りものはスタートラインの差が小さいから、体力や自由にできる時間の多い若者に有利になる。有利な土俵で勝つことで、注目や実績や人脈を(オッサンに取られる前に)奪い取る戦略は若者向きだ。

一方で、その「流行りもの戦略」での成功体験に囚われるとジリ貧になる。僕が最初に出した本はJythonの本で、本を出す実績を積んだ点は成功だったが、個人的には内容の陳腐化の速度が予想以上で、題材選択の失敗と解釈している。それが二冊目の題材選択に強く影響している。

(5年経っても陳腐化しないことを目指して書かれた「コーディングを支える技術〜成り立ちから学ぶプログラミング作法」のこと)

まあ「若者がオッサンと戦う上での戦略」みたいなことを言ったけど、33歳のオッサン当時に、流行りもののword2vecの本を出す話が来た時には「飛びついて実績を作る」戦略を選んだわけだなあ、今考えると。機械学習の広いテーマの解説だと機械学習自体が本業のPFNとかの人に蓄積の量でかなわないから、流行りもの戦略を採用した、と事後的には解釈できる。

話を少し戻すと「流行りものに飛びつこう」が若者の戦略として有用なのは対オッサン戦略としてだけではない。積み上げの少ない分野だから、他人のやってないことを実現するまでの時間が短い。注目の分野だからフィードバックを貰える確率も高い。つまり学習サイクルが速く回せる。

「学習のサイクルを速く回す」というコンセプトは、実は教育関係の本ではなく、意外かもしれないがベンチャーの経営に関する本で学んだ。「リーン・スタートアップ」だ。遡るとこれは経営戦略における派閥の一つで、その話はサイボウズ式の原稿に書いたのでそのうち公開される予定。

2015-07-31

Long Short-term Memory(LSTM)の論文紹介

ラボの機械学習勉強会でLong Short-term Memoryについて発表した資料を公開しました。

http://www.slideshare.net/nishio/long-shortterm-memory

2015-05-29

実践多クラス分類 Kaggle Ottoから学んだこと

Kaggleのコンペに参加することで 色々な実践的ノウハウを学んだので、 そのノウハウをサイボウズラボの機械学習勉強会で共有するためにスライドを作りました。


目次

p.3〜53 コンペ中に自分がやったこと

p.54〜99 ハイランカーがやっていたこと

p.100〜 ハイランカーかやっていたことを 自分も実際にやってみる


スライドはこちらから: http://www.slideshare.net/nishio/kaggle-otto

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の変更のほうが優先度高。

という感じか。