cedro-blog

Keras MLPの文章カテゴリー分類を日本語のデータセットでやってみる

今回は、Keras MLPの文章カテゴリー分類プログラムを使って、livedoor ニュースコーパスを分類してみます。

こんにちは cedro です。

先回、サンプルプログラムにある、ロイター・ニュースのカテゴリー分類を紐解いてみました。その結果、ポイントとなるデータセットの構造が分かったので、今度は別のデータセットでやってみたくなりました。

Webで色々探してみると、livedoor ニュースコーパスというのが手頃な大きさで扱い易そうなことが分かりました。やっぱりデータセットは英語ではなく、日本語じゃないとピンと来ませんからね。

というわけで、今回は、Keras MLPの文章カテゴリー分類プログラムを使って、livedoor ニュースコーパスを分類してみます。

 

livedoor ニュースコーパスとは

livedoor ニュースコーパスとは、livedoor が発信するニュース 7,367個9つのカテゴリーに分類したもので、約40MBと手頃なサイズです。まず、このリンクから、idcc-20140209.tar.gz をダウンロードします。解凍すると、text フォルダーが出来ますので、これから作るプログラムと同じフォルダーに保存します。

 

text フォルダーの下に、9つのフォルダーがありますので、そのフオルダー名を0〜8に変更します。これは、この後作るプログラムで、フォルダー名をそのまま分類ラベルに使うためです。

 

これは、独女通信のニュースの一部です。1行目がURL 、2行目が発信日時、3行目が題名、4行目以降が内容になっています。

 

プログラムを作成します

英文は単語と単語がスペースで区切られているので、スペース区切りで文字を読み込んで数字を割り振れば良いわけですが、日本語はそういうわけにはいきません。まず、適切な区切りで、分かち書きをする必要があります。例えば、

もうすぐジューン・ブライドと呼ばれる6月。→ もうすぐ_ジューン_・_ブライド_と_呼ば_れる_6月_。という感じ。そして、分かち書きした単語の1つ1つの品詞を調べて、適当なものだけを選ぶ必要があるのです。だって、「・」とか「と」とか「れる」とか「。」は、わざわざ数字にしてもノイズになるだけですよね。

こういう時に活躍するのが、形態素解析のライブラリーです。形態素解析のライブラリーで一番有名なのは、MeCabですが、今回は、 janome を使います。janome は、windows でも、mac でも一発でインストールできるので便利です。まだインストールしてなければ、「pip janome install」 でインストールして下さい。

 

janome がどういう働きをしてくれるのか、このプログラムを実行して見てみます。 単語を名詞、動詞、副詞、助詞、記号など品詞別に分類してくれ、様々な情報を提供してくれます。後は、ここから必要な情報だけ取得すれば良いわけです。

 

テキストデータを読み込んで、janome を使って分かち書きし、狙いの品詞を抽出するプログラムです。wakati.py で保存します。抽出する品詞は名詞、動詞、形容詞など色々考えられますが、今回はシンプルに名詞のみにします。

28行目で、text フォルダー以下にある全ての txt ファイル名を読み込んでから、ファイルを1つづつ処理します。9行目に定義した関数を使って、ファイルの最初の3行は、URL+発信日時+タイトルなので捨てます。そして、分かち書きして名詞のみを残します。そして、結果を txt ファイル名の最後に wakati を加えた名前で、保存します。具体的には、下記の様な感じです。

 

 

分かち書きしたファイルを使って、データセットを作る部分です。9行目で text フォルダー以下にある、wakati ファイル名を全て読み込んでから、ファイルを1つづつ処理して行きます。

新たに出てくる単語には順番に数字を割り振ると共に辞書に登録します。既に辞書に登録されている単語が再び出て来たら、辞書に登録されている数字を割り振ります配列 x には名詞を数字化したリストが順次アペンドされ、配列 y にはフォルダー名が順次アペンドされて行きます。

ちなみに、配列 x は、こんなイメージ x = [ [ 10, 11, 12, 3, 8, 13,  … 38 ] , [ 39, 40, 12, 16, 19, … ,56 ] , ….  ,  [ 1200, 1504, 3, 15, … 3300 ] ]配列 y は、こんなイメージ y = [ 0, 0, 0, 0, … ,8, 8, 8, 8 ]

全てのファイルを処理した後、30行目でデータセットを学習80%評価20%に分割します。

 

 reuters_mlp.py を改造したプログラム全体を載せておきます。90行目からは、おなじみの acc の推移グラフを保存する部分。103行目からは、これもおなじみの Confusion Matrix を保存する部分です。

 

プログラムを動かしてみます

python wakati.py でプログラムを実行すると、該当するテキストファイルを次々にスクリーンに表示しながら、処理を進めます。終了すると、txt ファイルと同じ場所に、wakati ファイルが保存されます。

 

続いて、python reuters_mlp.py でプログラムを実行します。作成した wakati ファイルを読み込んで、データセットを作ります。辞書に登録された数字と単語が、スクリーンに次々に表示されます。今回、登録された単語は、全部で 61,600個でした。

 

データセットが完成すると、データセットを学習用:評価用=8:2に分けて、学習を開始します。学習完了後、学習に使わなかった評価データ1474個を分類した時の精度Test accuracy)は 87.72%で、いわゆる Bag of Words という簡単な手法でもまずまずの分類精度が得られました。

 

Validation acc の推移グラフです。3epoch 以降はあまり変化なく横ばいという感じです。

 

Confusion Matrix です。まずまずバランス良くカテゴリー分類が出来ている様です。

 

さらに分類精度を上げるために、max_word1000から辞書登録単語数の61,600に変更してプログラムを実行した結果がこれです。学習時間は約40倍になりますが、分類精度Test accuracy)は 94.98%+7.26 ポイント大幅に向上しました。ロイターニュースがほとんど変わらなかったことに対してこれだけ変化が大きいのは、単語に数字を割り振る時に、出現頻度を考慮していないことが要因だと思われます。

今回は、分類するテキストが手頃なサイズなので処理時間が40倍になっても実質問題になりませんが、テキストサイズ大規模になると、単語に数字を割り振る時に出現頻度を考慮することが、システムのパフォーマンス向上有効な手法になると思われます。そう考えると、ロイターニュースのデータセットは良く考えられていますね。

では、また。