思考ノイズ

無い知恵を絞りだす。無理はしない。

Chainerをつかった助詞の学習システムを作る

久しぶりにPythonでちょっとおおネタ。複数回にまたがりそうなうえ、個別項目の備忘録も必要になってくるかもしれないですが、見切り発車でGoです。

モチベーション

Chainerによる実践深層学習

Chainerによる実践深層学習

この本のお勉強の続きで、7章Recurrent Neural Network, 8章で実用のケースとして翻訳モデルの実装方法について記載しています。せっかく得たこの知識を使ってなにか作れないか探していたところ、以下の記事を見つけました。

www.atmarkit.co.jp

助詞の訂正かー、これ実装できたら面白うだし、課題としてはちょうどよいかもしれない。ということでコーディングを始めてみました。ちなみにですが、コーディングにつきましては以下のエントリをがっつり参照させてもらっています。この方も助詞検出を機械学習してコードを公開していらっしゃいます。こちらのコードをだいぶお手本として参照させていただきました。

catindog.hatenablog.com

今回作るものはChainer本とこちらのエントリのミクスチャーとなります。id:catindog さんはKarasというPythonライブラリでの実装を行っていますが、私が持っている武器は現在本に記載されているChainerだけなので、Chainerでの実装をめざしてみようと思います。

助詞の検出のための学習

学習のアイデア id:catindog さんの方法を丸々使わせてもらいました。*1

今回の助詞の検出モデルを作成するにあたり、何を学習させる必要があるのかを考えてみます。

f:id:bython-chogo:20171008031513p:plain

助詞は前後の文節の流れで決まります。上の例で、私は/野球、に続く助詞を考えたときに、この後にくる助詞は、「が」、「を」、「も」など、一意に決まりません。しかし後に続く、好き、です、により「が」が適していることが分かります。つまり学習のプロセスは、1. 学習(検出)する文章の助詞をさがす。2.その助詞の前後の文章を入力値、助詞自身が正解の出力値として複数の文章を学習させる。 となります。

学習文章のサンプル取得方法

某地上波のWeb記事を抽出しました。その文章を文節ごとにスペースを空ける「分かち書き」をおこない、その文章の中で助詞にあたる文字を抽出して、その前後の文節を一定数、入力値として登録します。お手本に習い、助詞の前後10ワードずつとしました。

文章の抜き出し方法はそのまま公開するといろいろ問題がありそうなのでしませんが、Beautiful Soupを使っています。また分かち書きMeCabPythonモジュールを使いました。正直、ここの分かち書きが難所だと思ったのですが、こんなライブラリが用意されているとはほんとにインターネット時代様様です。

ちなみに、Mecabを使うと以下のような変換が行われます。(わかりやすく間に / を入れています。通常はスペース。)

せっかく得たこの知識を使ってなにか作れないか探していたところ、以下の記事を見つけました。
せっかく/得/た/この/知識/を/使っ/て/なにか/作れ/ない/か/探し/て/い/た/ところ/、/以下/の/記事/を/見つけ/まし/た/。 

素敵。これをそのまま別の文節として学習できちゃう。 この例の場合、今回の学習の入力値と出力値は次のようになります。

  • 入力1:/得/た/この/知識/を/使っ/て/なにか/作れ/ない//探し/て/い/た/ところ/、/以下/の/記事/を/
  • 出力1:か
  • 入力2:/この/知識/を/使っ/て/なにか/作れ/ない/か/探し//い/た/ところ/、/以下/の/記事/を/見つけ/まし/
  • 出力2:て

学習文章と検証文章について

先ほどのWeb記事の10月1日の記事を学習サンプルとして、10月6日の記事を検証サンプルとしてみました。10月1日のデータ数は以下になりました。*2 学習の繰り返し回数は50にしてみました。根拠なくChainer本の値をそのまま入れただけです。

  • 学習するUnit: 7154
  • 学習において出てきた単語数: 5241

ちなみに検証の記事については2つ以上の助詞があっても1文章につき、1サンプルとしました。類似の検証用記事が偏ること避けるためなのですが、意味があるかはわかりません。

成功例と失敗例

今回のテストで学習させた結果、以下の例のように助詞を提案してくれます。正解の例と、失敗の例を示します。

正解例

ことし 7月 1 日 から 9月 1 0 日 まで  [ の ]  夏山 シーズン の 登山 者 は 合わせ て 2 
    の 0.999983
    に 1.62042e-05
    と 4.91623e-07
    や 9.80575e-08
    で 8.98966e-08

失敗例

 の 繁華 街 で は 悪質 な 客引き 行為 など  [ が ]  相次ぎ 、 日本語 が わから ない 外国 人 観光 
    は 0.804192
    の 0.0810047
    を 0.0239791
    が 0.0194065
    に 0.00046254

正解率と損失率

今回の学習と検証では以下のような結果となりました。横軸は損失数を減らすようにアジャストした学習の反復回数です。 f:id:bython-chogo:20171008205752p:plain

いえることとして、 - およそ 0.55 ~ 0.60 の正解率。微妙w - 10回の反復で損失数はほぼ0に張り付いてます。この学習では50も繰り返す必要はなさそうですね。

次のステップ

さて、今回のパターンでは微妙な正解率となってしまいました。次回からはこの学習率を高めるにはどうするかを実験してみたいと思います。あと、コードはぐちゃぐちゃになってしまったので、整理してからきちんと公開したいと思います。

追記

最初に間違ったスペルでIDコールを飛ばしてしまいました。お詫びして訂正いたします。

*1:すいません、例題分もまるまる同じものを使って説明しております。

*2:ちなみに、Web記事は記事の抽出コードを実行したときにWebに掲載されている新着記事となります。同じ日でも別の時間に実行すると抽出する記事は変わります。