読者です 読者をやめる 読者になる 読者になる

Rによるtwitterテキストマイニング 〜テキストに対する学習とは〜

自分のtweetがウケるか滑るかをpostする前にrandomForestで判別してみよう!


LTは制限時間10分だったため、詳細は意図的に省きました。
本記事では皆さんにも実践頂けるよう、学習データの作り方についてスライドより詳しく説明したいと思います。


●そもそも「学習する」とは?
今回の目的は、自分のツイートがfav(面白い), non(普通)のどちらになるか分類することです。
そのためには「favになるツイートはどのような特徴を持っているか?」を明らかにしなければなりません。
特徴が明らかになっていれば、
・このツイートはfavの特徴を強く持っている→favに分類
・このツイートはfavの特徴を殆ど持っていない→nonに分類
というモデルを作成可能です。
つまり、「学習する」とは、「分類に適した特徴(量)を抽出する」ことです。


一般的な学習するの意味は分かりました。
では、「テキストデータの学習」とは何なのか考えてみましょう。
分類に適した特徴には何が該当するでしょうか?
(※解析手法よりも、この特徴選択がテキストマイニングでは一番重要です。しっかり考えましょう)
テキストの長さや投稿日時等も一つの特徴だと考えることは出来ます。
しっかり調べれば、「朝5時に投稿されたツイートよりも夜22時頃のツイートの方がfavになりやすい」
等といったことも抽出可能でしょう。
実際、ショッピングサイト等でこういったアクセス解析をよく利用します。
でももっとテキストデータならではの有効な特徴はないでしょうか?
例えば「どんな単語がどの程度用いられるか?」は非常に重要な特徴であると考えられます(他にも色々ありますが)。
具体例として、「もてない」という単語を含むツイートが、favはnonより異常に多かったため
「『もてない』を含むツイートはウケやすいのでは?」というモデルを立てることが出来ます。
というわけで、ここではfavツイートに含まれる単語とその出現頻度を得るために、
形態素解析にかけて頻度を調べてみましょう。


●学習データの作り方
favツイートを何らかのクローラー(Webページから目的としたデータを自動で収集するアプリ)を用いてfavstar等から取得します。
nonツイートは拙作さくさくツイートマイニング(http://d.hatena.ne.jp/AntiBayesian/20110702)をご利用下さい。
集めたツイートを、発表スライド12ページのように、
Excel等で1列目にfav, nonというタグ情報を手動で書込み、2列目にツイートを貼り付け、それをCSV形式で保存します。
CSVファイルをttmにかけて、下図にあるように、ttm6を出力します。

ttm(http://mtmr.jp/ttm/)というフリーソフトを利用すれば、
プログラミング要らずで簡単に形態素解析+頻度情報を得ることが可能です。
ttm6にかけた実際のファイルが以下になります。
http://www24.atpages.jp/antibayesian/up/src/up0018.bin
(※他人のツイートそのものを配布するのは問題がありそうなので、
原文が判明しないような解析結果だけを公開)


皆さんが独自で収集したツイートをそのままttmにかけると、恐らく多数のゴミが混入しているでしょう。
ゴミとして頻出なのが
1.URL
2.顔文字
3.MeCabの標準辞書では対応していない新語、未知語
4.誤字脱字
です。
本来ならMeCabの辞書を整備して頂くのが一番良いと思いますが(他にも活かせるから)、
ttmには不要語や類義語を定義する便利機能があるため、そちらを利用した方がずっと手軽です。
下の方で書いていますが、私は1時間半程度しか辞書整備作業しませんでした。
もっと時間かけてすべき作業です。
Rでごちゃごちゃやるより、辞書整備した方が余程精度上がります。


以上です。



●おまけ:経緯と実際の流れ
懇親会で「どれくらいの時間で実データ解析とかモデル立てたりとかしたの?」
と聞かれたため「私だとこんな感じですよ〜」と説明したのを、つらつらと書き連ねることにしました。


TokyoR当日の0時頃、主催者のyokkunsに突然LTを振られ、急遽やることに。
当然何やるかも決めておらず、「Rを使い10分で、それでいて面白可笑しいLTを」
という無茶振りだけが手元にありました。


0時から20分くらい掛けて「twitterで自分のツイートがウケルかどうかの判定をしよう」と決め、
「favstar(twitterの人気ツイートを収集するサイト)を正例、普通のツイートを負例とし、
自分のツイートが正例(ウケる)負例(ウケない)のどちらに二値分類されるか」
という大雑把なモデルを立てる。


PHPを用い、5分くらいで、favstar等から正例として6/1〜6/30までの約1500ツイートを獲得☆順に取得。
2分くらいで負例は常時Twitter Streaming APIから取得しているツイートから適当にサンプリング。
これでデータは揃った。
データをttmに放り込んで、Rで分析しやすいようにデータを加工。
1時間半かけて、不要語ファイルなど整備。


この時点で既に二時である…。


さて、分類フェーズに入ろう。
まずは簡単なナイーブベイズ
説明も楽だし、単純な実装で済むため、大規模データでも比較的高速で便利。
と思ったが、精度が全然出ない…。
学習データからモデルを立て、そのモデルで学習データを分類することによって、
学習データに対するモデルの説明力を見ようとしたのだが、
こいつがF値で6割ちょっとしかでなくて全く使い物にならない、当たるも八卦当たらぬも八卦状態。
辞書整備し直したり色々やってたら1時間半くらい経過して、それでも精度7割ちょっと…。
恐るべき眠さが訪れたのでナイーブベイズを投げ捨てた。


主に精度面、そして汚いデータにも強いという頑健さ、実行速度などを勘案し、
結局randomForestを用いることに。
始めからrandomForest使えば良いのでは???
とも思わなくもないですが、猫も杓子もrandomForestという現状は如何なものかという思いから、
あまり頼りたくはなかったが、時間もないし何より眠い、背に腹は代えられない。
randomForestに放り込んだらあっさり8割後半。
ちょこちょこ整備したらF値0.9を叩き出したので満足して寝る。
寝る前に時計を見たら4時半であった…。


スライドは会場到着してから作成。
気付いている方もいるとは思いますが、slideshareに上げたスライドと発表スライド、実は全然違います。
発表スライドはネタ画像を入れまくり。
スライド自体は1時間半くらいで作成、ネタ画像探しに30分程度。
スライド眺めながら脳内プレゼンシミュレーションを2回程行い、発表時間調整。これに20分程度かけた。


と言うわけで、実質7時間程度ですね、今回の発表の作業時間。
発表はそこそこ笑いを取れて良かったです。
twitter上でNLPerからも面白がって貰えたようで何より。
短時間で実践して一応それなりの結果が出せて良かったなーっと一安心です。
簡単なことしかしていません。
スライド見て頂ければソースも載っているため、
興味があれば是非皆さんにも実践して頂ければなーと思います。
皆もテキストマイニング、やってみましょう!!!