rubyで自分のツイートデータから頻出語を見つける
ふと自分のツイートデータを使って頻出語リストを作ってみたいなと思ったのでやってみました。
必要なものをインストールする
MeCab(めかぶ)とはオープンソースの形態素解析エンジンで、これを使うと、文字列を単語ごとに区切ることができます。
(例: 「今日はいい天気ですね」→「今日 | は | いい | 天気 | です | ね」)
mecab用の辞書ファイルとともにインストールします。
$ brew install mecab-ipadic mecab
- gem 'natto'
MeCabをrubyから使うために、今回は'natto'というgemを使います。
$ gem install natto
ツイートデータをダウンロードする
Twitterの設定画面の下のほうに、全ツイート履歴のダウンロードをリクエストするボタンがあります。
https://twitter.com/settings/account
リクエストしてからしばらく経つと、ダウンロード準備完了のメールがくるので、そこに書いてあるリンクよりダウンロードしましょう。tweets.zipというファイルがダウンロードできるはずです。
tweets.zipを解答すると、いくつかファイルがあると思いますが、今回はtweets.csvを使用します。
このファイルをテキストエディタやExcel等で開いて頂くと、どんな構造をしているのかがわかると思います。
頻出語の集計方法
頻出語を集計するにあたっての順番は、
- tweets.csvにすべてのツイートデータが含まれているので、まずここからツイートのテキストだけを抽出します。
- それらテキスト一件一件に対して、形態素解析を行います。
- 形態素解析によって分解された単語ひとつひとつについて、ツイートデータ全体で何回出現したかをt_mapに格納します。
- t_mapに格納された単語データを出現回数でソートします。
- t_mapの内容をt.csvに出力します。
といった感じです。
実際にコードにする
こんな感じです。
# count.rb require 'csv' require 'natto' require 'pp' reader = CSV.open('tweets.csv', 'r') # 先頭行は不要なので、読み飛ばす reader.take 1 nm = Natto::MeCab.new t_map = {} reader.each do |row| # RTで始まるツイートはリツイートなので処理しない next if row[5].index('RT') == 0 nm.parse(row[5]) do |n| t_map[n.surface] = t_map[n.surface] ? t_map[n.surface] + 1 : 1 end end t_map = t_map.sort_by {|k, v| v} File.open('t.csv','w'){|f| t_map.each do |word, count| f.write "#{word},#{count}\n" end }
実行
count.rbと同じディレクトリにtweets.csvを置いて、実行します。ツイート数によっては多少時間がかかるかもしれません。
$ ls count.rb tweets.csv $ ruby count.rb $ ls count.rb t.csv tweets.csv
結果
自分のツイート、約3万件に対してやってみたところ、15秒くらいで処理が終わりました。
結果を出現回数の多い順からいくつか挙げると、
単語 | 出現回数 |
---|---|
, | 24657 |
の | 16085 |
。 | 13683 |
た | 12598 |
@ | 12062 |
て | 11845 |
、 | 10393 |
となります。実際にやってみてデータを眺めてみるとわかると思うのですが、上位に出てくるものの中には、単語として意味をなさない文字が多く出てきます。
これらはストップワードといい、きちんと解析をする際には、集計をする前に意味のない単語や文字を除去してから解析を行います。
事前にデータを綺麗に整理する処理を入れなければ、このように意味のない言葉が大量に出てきてしまします。
今回は簡単のため、ストップワードを除去する処理は入れませんでしたので、主観で意味のある単語を選び、その中で多い順上位10単語を挙げてみます。
単語 | 出現回数 |
---|---|
笑 | 3722 |
俺 | 920 |
今日 | 917 |
時間 | 685 |
大学 | 493 |
自分 | 469 |
先生 | 453 |
バイト | 420 |
授業 | 416 |
勉強 | 413 |
今回は、単純に出現回数の多いものから順に出力しただけですが、次は特徴語を抽出したりしてみたいと思います。