城ヶ崎美嘉(CV:佳村はるかさん)の誕生日なので,セリフが城ヶ崎美嘉か城ヶ崎美嘉じゃないかを多層パーセプトロンで判別してみた

注意

深層学習じゃありません.

はじめに

私はPではないので知りませんでしたが,今日は「アイドルマスターシンデレラガールズ」の城ヶ崎美嘉(CV:佳村はるか)の誕生日です.twitter.com

おめでとうございます!

ちなみに佳村はるかさんといえば「SHIROBAKO」の安原絵麻を演じていたのが記憶に新しいです*1

ちょうどよい機会なので,先日 Amazon.co.jp: 深層学習 (機械学習プロフェッショナルシリーズ): 岡谷 貴之: 本 の4章誤差逆伝播法を読んで実装した多層パーセプトロンを試しましょう.
数式については鴨川ηをご覧ください.

今回のタスクは以下のとおり

セリフが城ヶ崎美嘉城ヶ崎美嘉じゃないかを判別したい


本題

タスク自体はシンプルです*2

データ

肝心のセリフデータですが,Wikiのまとめにあったセリフをスクレイピングして使っています.1.5時間位でデータを作りました.


1つのセリフはこのようなものです.

「はじめまして★城ヶ崎美嘉だよー。アイドルだろうと何だろうと、どうせやるならオンリーワンよりナンバーワンになりたい! ってことで、一緒にトップアイドル、目指そうね!」

いい話ですね.


全部で445件取れました.

城ヶ崎美嘉じゃないセリフも必要です
セリフ以外も必要なのかもしれませんが簡単のためセリフデータに限定します.

まず,城ヶ崎美嘉には妹がいるのでその方のセリフを数件にとってきました.
(補足すると,「アイドルマスターシンデレラガールズ」は,モバゲーで配信されているソーシャルゲームで,ユーザがプロデューサーとなってアイドルを育てるゲームです.
同じアイドルでもカード(?)が違うとセリフが異なります.)

次にアニメで城ヶ崎美嘉と仲の良い「赤城みりあ」というキャラ(小学生)からも数件,残りは適当なアイドル3人選び,合計で5人のセリフをとってきました.


ここで「アイドルマスターシンデレラガールズ」のキャラで偏るといけないと思い,夢野久作の「オンチ」からセリフを10件ほどとってきました.



城ヶ崎美嘉を正例,それ以外を負例としたいので,集めたセリフをMecab分かち書きた結果に対して城ヶ崎美嘉のセリフに1を,それ以外のセリフには0をつけます.

全890件です.
"#" より後ろは実際のデータにはありません.

0 すごい 星 が いっぱい だ ね ☆ カブトムシ 座っ て ない か なー # 城ヶ崎莉嘉
1 ほ ー ら 、 受け取れ ー っ ★ # 城ヶ崎美嘉
0 シッカリ 働け 。 ボーナス が 大きい ぞ # 夢野久作先生作品

各層について

今回は,2値分類なので出力層にロジスティクス関数をおきました.
最終的には,出力層の値が0.5以上なら1(城ヶ崎美嘉である確率が高い),それ以外なら0(城ヶ崎美嘉である確率が低い)で城ヶ崎美嘉かどうかを判定します.

誤差関数は対数尤度です.


中間層についても同様にロジスティクス関数をおきます.
中間層の数は任意に変更できるようにしたので,いくつか変えて実験します.

入力ですが,今回は単語の1-gramと2-gramの頻度を使いました.
なのでユニークな1-gramと2-gramの数だけ入力層のユニットがあります.
ニューラルネットのネットワークを以下の図で表すとInput leyerの丸がユニークな1-gramと2-gramの数+1だけあります.

f:id:another16javac:20151112052702p:plain


実装

ChainerとかTensorFlowは使わずに書きました.
確率的勾配法だけ組んでいて,ドロップアウトやモメンタムはまだ組んでいません.


入力層は8574ユニットです.

まずは学習回数を誕生日にちなんで1112回*3,ミニバッチの数を30とし,データの15%をテストデータ,残りを訓練データとしました.(scikit-learn最高)

まず学習率を変えてみる

隠れ層は300,150の2層で固定し,学習率を0.1,0.5.0.9の3通りで実験します.

結果

テストデータの正解率
f:id:another16javac:20151112072712p:plain
9割はあたるようです.


対数尤度
f:id:another16javac:20151112072716p:plain

確率的勾配法なので,誤差関数がなかなか安定しませんが,反復回数を増やすごとに安定していく様子がわかります.

隠れ層を変えてみる

先ほどと同様に学習回数を誕生日にちなんで1112回,ミニバッチの数を30とし,15%をテストデータ,残りを訓練データとし,学習率を0.15で固定します.


以下の4通りで試してみます.

  • 300-200-150
  • 800-400-200-100-50
  • 300-150
  • 150-300

4つ重ねると見えないので2つに分けて可視化します.

まず

  • 300-200-150
  • 800-400-200-100-50

について

テストデータの正解率
層が最も深くて2層目が最も大きい800-400-200-100-50が正解率が9割を超えました.
f:id:another16javac:20151112072330p:plain

対数尤度
ただし,対数尤度の変化が学習終了する段階でも激しいです.
f:id:another16javac:20151112072334p:plain

続いて

  • 300-150
  • 150-300

です

最初の隠れ層を150,次の隠れ層を300にするとあまり性能がよくないです.
テストデータの正解率
f:id:another16javac:20151112072339p:plain

対数尤度
f:id:another16javac:20151112072344p:plain

終わりに

改めておめでとうございます.

アニメの3話でも流れたTOKIMEKIエスカレート: 城ヶ崎美嘉(CV:佳村はるか) は,すばらしくいい曲なのでオススメします.


深層学習の方ですが,次の章の自己符号化器を実装できそうならそれで試すか,無理そうならフレームワークを使う,あるいはドロップアウトやモメンタムを試してみようかと思います.



以上です.

*1:私の人生の7割はこのアニメでできていると言っても過言ではないでしょう

*2:ちなみにアニメをよく画像でやってる方がいるので画像は?と思われますが,確か「ごちうさ」でやってる方がいたのでやっても面白くなさそうなのと自分が言語処理しかやってないのでやりません.

*3:多すぎたと後悔しています