前回の記事、gensimによるニュース記事のトピック分類 〜前編〜では、livedoorのニュースコーパスをトピック分類するための前処理とgensimのLDAモデルで扱えるようにするための辞書とコーパス作成の手順について、クラス内の関数という形で説明してきました。
今回の後編では、実際にそのクラスを使ってlivedoorのニュースコーパスに適切な処理を施し、gensimのLDAモデルを使ってトピック分類を行ってみようと思います。
辞書とコーパスの作成
前回説明したユーザー辞書は、/usr/local/lib/mecab/dic内にuserdicというディレクトリを作り、その下にignores.dicとして保存しています。
tt = TextTransform(texts, ignores_path='./data/ignores.txt', userdic='/usr/local/lib/mecab/dic/userdic/ignores.dic')
no_below = 5
no_above = 0.3
dictionary = tt.make_dict(no_below, no_above, output='./data/livedoor_r.dict')
corpus = tt.make_corpus(no_below, no_above, output='./data/livedoor_r.mm')
全体で5語以下しか出現しない単語と、全体で3割以上出現する単語は除去しています。
作成した辞書とコーパスはそれぞれ、dataディレクトリ内に"livedoor_r.dict", "livedoor_r.mm"として保存しました。
gensimのLDAモデルを使ってみる
モデルの評価方法はTISさんの技術ブログを参考にさせてもらいました。(ほとんど丸パクリなのでコードは載っけません)
もとのニュースコーパスが9つのニュースサイトの記事をまとめたものだったので、トピック数を7~11で動かし、最もパープレキシティが低かったものを選ぶようにしています。下が評価結果になります。
dataset: training/test = 5894/1473
7: perplexity is 5285.368135530054/13766.419075459813
8: perplexity is 5212.197972249593/13639.0306219986
9: perplexity is 5271.528346984613/14298.020126937266
10: perplexity is 5074.945883706681/14187.125353601654
11: perplexity is 5258.119732076605/15066.916716609201
Best model: topics=8, perplexity=13639.0306219986
パープレキシティがめちゃくちゃ悪いので、(丸パクリの過程で)どこか間違っていたのかもしれないですが原因がわかりません...もしくは前処理がまだまだ足りないだけかもしれないです。
ですが、トピック数8の各トピックで重みの大きい単語を表示してみると意外といい感じの結果が得られました。
from gensim import models
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=8, iterations=500, passes=5)
lda.print_topics(8)
[(0,
'0.020*"ON" + 0.014*"写真" + 0.009*"氏" + 0.009*"撮影" + 0.008*"シャープ" + 0.006*"ゴルフ" + 0.006*"内蔵" + 0.005*"日本" + 0.005*"発表会" + 0.005*"IS"'),
(1,
'0.010*"女性" + 0.006*"男性" + 0.006*"仕事" + 0.005*"結婚" + 0.004*"いく" + 0.004*"聞く" + 0.004*"女子" + 0.004*"考える" + 0.003*"しれる" + 0.003*"行く"'),
(2,
'0.020*"D" + 0.016*"smartphone" + 0.015*"対応" + 0.015*"搭載" + 0.013*"Android" + 0.013*"モデル" + 0.011*"発表" + 0.011*"NTTドコモ" + 0.010*"発売" + 0.009*"S"'),
(3,
'0.009*"話題" + 0.006*"情報" + 0.005*"日本" + 0.005*"Twitter" + 0.004*"イベント" + 0.004*"声" + 0.003*"人気" + 0.003*"行う" + 0.003*"ネット掲示板" + 0.003*"登場"'),
(4,
'0.012*"ネット掲示板" + 0.012*"声" + 0.010*"韓国" + 0.008*"氏" + 0.008*"話題" + 0.007*"日本" + 0.007*"批判" + 0.006*"放送" + 0.006*"番組" + 0.005*"報じる"'),
(5,
'0.021*"アプリ" + 0.017*"画面" + 0.012*"表示" + 0.012*"機能" + 0.010*"設定" + 0.008*"使う" + 0.008*"smartphone" + 0.008*"利用" + 0.008*"紹介" + 0.007*"Twitter"'),
(6,
'0.021*"映画" + 0.010*"公開" + 0.009*"作品" + 0.006*"監督" + 0.005*"世界" + 0.005*"本作" + 0.005*"演じる" + 0.005*"登場" + 0.004*"日本" + 0.004*"描く"'),
(7,
'0.021*"更新" + 0.021*"MAX" + 0.016*"ソフトウェア" + 0.011*"S" + 0.008*"利用" + 0.008*"ソフトバンク" + 0.007*"Xi" + 0.007*"製" + 0.006*"本体" + 0.006*"行う"')]
トピック1は恋愛関係っぽいので、おそらく毒女通信の記事の単語が多く含まれていると思われます。トピック2,5,7あたりは最新ガジェットに関係するような単語が多いのでエスマックス、家電チャンネル、ITライフハックなどの記事の単語が多く含まれているのでしょう。トピック6は映画関連っぽいので、MOVIE ENTERだと思われます。トピック4は政治関連でしょうか。スイーツや美容関係の記事が多いPeachyのニュースサイト内で出てきそうな単語は見当たりませんでした(T_T)
まとめ
livedoorのニュースコーパスを使って、前処理からモデル構築までを一通りやってきました。まだまだ改善の余地はありそうですが、自然言語処理の基本的な処理やトピックモデルについてなんとなくでも雰囲気を掴めた気がします。
今回のコード全文はこちら