最近、日本では国会が色々と荒れていますが、それを受けてTwitterでは安倍首相に関してどんなことが話題になっているのか気になるところです。そこで今日は安倍首相に言及しているTweetデータを使ってテキスト分析してみようと思います。

ここで一つチャレンジなのは、日本語のテキスト分析になると、英語などの言語と違い、単語と単語の間にスペースがないので、トークナイズ(単語ごとに分ける)するのが難しいという点です。ただ、知ってる人も多いかと思いますが、オープンソースで、MeCabという、Google 日本語入力開発者の一人である工藤拓さん等によって開発されたライブラリを使うと日本語をトークナイズするのが簡単にできます。さらに都合のいいことに、RでMeCabが使えるように、石田基広さんが作られたRMeCabというRパッケージがあるので、それを使うと簡単にRで、つまりはExploratoryの中でテキスト・データをトークナイズしていくことができます。

今日は、そのMeCabのインストール、さらにそれをExploratoryの中で使うためのセットアップ、そしてTweetデータに対するテキスト分析を順を追って説明していきたいと思います。

セットアップ

Mecabと辞書をインストール

Mecabと辞書のインストールはこちらを参照してください。

RMeCabにある機能を、Exploratoryで使いやすくするように、関数を定義する

RMeCabのトークナイズの関数をExploratoryの中で使いやすくするように関数を定義しましょう。

プロジェクトの中で、左側にある、スクリプトの隣にあるプラスボタンを押します。

名前をつけて、作成します。

スクリプトを入力して、右上の保存ボタンをクリックします。

スクリプトの中身は以下の通りです。この mecab_tokenize という関数は、データフレームを入力として受け取り、指定された列に入っているテキストを、RMeCabCという関数を使って形態素解析します。そして結果を .token という列としてデータフレームに足します。

mecab_tokenize <- function(tbl, text_col, .drop=TRUE){
 loadNamespace("RMeCab")
 loadNamespace("tidyr")
 text_cname <- as.character(substitute(text_col))
 text <- tbl[[text_cname]]
 tokenize <- function(text){
   tokens <- unlist(RMeCab::RMeCabC(text))
   data.frame(.token = tokens, .pos = names(tokens))
 }
 if(.drop){
   tbl[[text_cname]] <- lapply(text, tokenize)
   token_col <- text_cname
 } else {
   tbl$.token <- lapply(text, tokenize)
   token_col <- ".token"
 }
 tidyr::unnest_(tbl, token_col)
}

WindowsでMecabをインストール時に文字コードをSjisで使用するように指定した場合は、以下のスクリプトを使います。

mecab_tokenize <- function(tbl, text_col, .drop=TRUE){
 loadNamespace("RMeCab")
 loadNamespace("tidyr")
 text_cname <- as.character(substitute(text_col))
 text <- tbl[[text_cname]]
 tokenize <- function(text){
     # WindowsでMecabをインストール時に文字コードをShift JISで使う場合
  # 文字コードをUTF8からcp932に変換しておく
   textSjis <- iconv(text, from="UTF8", to="cp932")
     if(is.na(textSjis)) {
        # 変換に失敗したものは空文字だとRMeCabCが動かないので空白にしておく。
        textSjis = " "
     }
   tokens <- unlist(RMeCab::RMeCabC(textSjis))
   #UTF8に戻す
   tokensUTF8 <- iconv(tokens, from="cp932", to="UTF8") 
   data.frame(.token = tokensUTF8, .pos = names(tokensUTF8))
 }
 if(.drop){
   tbl[[text_cname]] <- lapply(text, tokenize)
   token_col <- text_cname
 } else {
   tbl$.token <- lapply(text, tokenize)
   token_col <- ".token"
 }
 tidyr::unnest_(tbl, token_col)
}

これで、前準備は完了です。

安倍首相に言及しているTweetをTwitterからインポートする。

それではまず、安倍首相に言及しているTweetをTwitterからインポートしましょう。

Tweetをインポート

プロジェクトを開き、画面左側のデータフレームの隣にあるプラスボタンをクリックして、クラウドアプリケーションデータを選択します。

Twitter Searchをリストから選択します。

インポートのダイアログで以下のパラメタを指定します。

  • 取得するtweetの件数:2000件
  • 言語:日本語
  • 最近:7日分
  • リツイート:含まない
  • センチメント:スコアしない

データの取得ボタン をクリックします。無事Tweetが表示されたら、次に インポート をクリックします。

約2000件のTweetがインポートできました。

テキスト分析をする

では早速Tweetデータを分析してみましょう。

トークナイズする

Tweetテキストのデータを分析する最初のステップとして、さきほど登録したmecab_tokenizeという関数を使ってテキストをトークナイズします。この関数はデータフレームをインプットにとり、トークナイズした結果をアウトプットとして出力するので、カスタムコマンド・モードにして、この関数を呼びます。

緑色のプラスボタンを押すと、メニューが出て来るのでカスタム・コマンド入力を選びます。

以下のコマンドを入力します。引数にはtext列を指定します。

mecab_tokenize(text)

すると、Tweetのテキストのトークナイズが行われ、品詞ごとに分割されます。

ストップ・ワード(stopwords)を取り除く

下の赤く囲った部分のように、どこにでもよく出てくる単語なので、テキスト分析する上では特徴のない単語が多く含まれているのが分かります。こうした単語はストップ・ワード(stopwords)と呼ばれます。

さっそく、これらの単語を取り除きましょう。

こちらに日本語のストップ・ワードのデータがあるので、これをExploratoryにインポートします。そして、このデータを基に、アンチ結合というテクニックを使ってストップ・ワードを取り除きます。

画面左側のデータフレームの隣にあるプラスボタンをクリックします。

リモートタブを選択し、テキストファイルを選びます。

URLにhttps://raw.githubusercontent.com/exploratory-io/public/master/stopwords/twitter_stopwords.csv を指定します。

OKボタンを押します。

保存ボタンを押して、Japanese_Stop_Words として保存します。

次に、anti_joinという関数を使って、このJapanese_Stop_Wordsデータ・フレームに入っていないデータだけを残すオペレーションを行います。anti_joinはデータのフィルターと似た動きをします。具体的には、相手先のデータフレームの、指定された列に該当しないデータだけを残せます。この例では、相手先はストップ・ワードなので、ストップ・ワードでないデータだけを残すことができます。

.token列のメニューから結合(Join)を選びます。

結合の種類でアンチ結合を選び、相手として、ストップ・ワードのデータフレームを指定します。

これでストップ・ワードが取り除かれました。

さらに不要なデータを取り除く

次に、データを見ていくと下の図のように記号がいくつか入っていることに気が付きます。また、助詞や助動詞や副詞や接頭詞なども不要です。名詞と動詞だけにフィルタリングしましょう。

列のメニューからフィルタ -> どれかに等しいを選びます。

条件を確認して、OKを押します。

安倍首相と言った単語も自明すぎるので合わせて取り除きます。

どれにも等しくないというフィルタの条件が使えます。

次に、文字数が1文字以下のテキストデータも意味がないので取り除きましょう。

これで不要な単語はほとんど取り除くことができました。

頻出単語を調べる

それではまず、最もよく頻出している単語を見てみましょう。Vizのビューに行って、ピボットテーブルを作ります。行に.token列を割り当てて、ソートに.token列を割り当てて頻度の降順をセットして頻度の多い順にデータを並べます。すると、支持、拉致、横田などの単語が多く使われていることがわかります。

バーチャートで同じく頻出順に並べると、次のようになります。

ワードクラウド

上記のような頻出単語のようなテキストをもっと見やすくするために使われる可視化の手法として、ワードクラウドというのがあります。Exploratoryではこのタイプのチャートはデフォルトではサポートされていないのですが、いわゆる、RMarkdownであるノートの中でRのwordcloudというパッケージを使うことで実現することができます。

ちなみに、wordcloudを使って可視化をするには単語とその頻出件数を事前に計算しておく必要があります。

単語の頻出回数を集計

.token列のメニューからグループ化を選択します。

続いて、.token列のメニューから集計(Summarize) -> n(カウント)を選択します。

新規列名を入力して、実行ボタンを押します。すると、単語と頻出回数が計算されます。

これで準備ができました。

ノートの作成

次に、ノート上にワードクラウドを表示して、単語の頻出度を視覚的にとらえてみましょう。画面左手のドキュメントの横にあるプラスボタンを押して、ノートを選びます。

名前を入力して、作成をクリックします。

次にノートに以下のように記述します。頭と終わりにバックティックを```を3つ付けます。バックティックの後に改行は入れないように注意してください。

{r echo=FALSE, cache=FALSE, warning=FALSE, message=FALSE}
library( wordcloud )
library( RColorBrewer )
par(family = "HiraKakuProN-W3")
wordcloud(tweet_abe$.token,tweet_abe$token_freq, 
colors = brewer.pal( 8, "Dark2" ),
scale = c( 6, 1 ), min.freq = 8, random.order = FALSE, rot.per = .05)

rtweet_abe.token * * < ><トークンの列名>なので、作成されたデータフレームと列名に適宜変えて実行してください。tweet_abetokenfreq * *、<><頻度の列名>なので、作成されたデータフレームと列名に適宜変えて実行してください

scaleパラメータで文字サイズを変更したり、rot.perパラメータで縦横比率を変更できます。色はRColorBrewer というパッケージを使って、数量に応じて5つ(緑の濃淡)の色になるように指定しています。この例では、文字の大きさも色の頻出回数に基づくため、どちらも同じ情報の可視化になっています。

出力結果は以下のようになります。支持、拉致といった頻出回数の多い単語が大きめのフォントサイズで表示されていることが確認できます。

長くなってきたのでは、Part 1はここまでにして、Part 2ではトークンからNグラムを作成し、TF-IDF、クラスタリングとさらにテキスト分析をしてみます。

まとめ

今日はTwitterから安倍首相に言及されたTweetをインポートし、RMeCabでトークナイズして、ストップ・ワード等を取り除き、頻出する単語が何かを確認するところまで見てきました。

まだExploratory Desktopをお持ちでない場合は、こちらから30日間無料でお試しいただけます。

データサイエンスを本格的に学んでみたいという方へ

6月の中旬に、Exploratory社がシリコンバレーで行っているトレーニングプログラムを日本向けにした、データサイエンス・ブートキャンプが東京で行われます。データサイエンスの手法を基礎から体系的に、プログラミングなしで学んでみたい方、そういった手法を日々のビジネスに活かしてみたい方はぜひこの機会に、参加を検討してみてください。