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

rubyで自分のツイートデータから頻出語を見つける

ふと自分のツイートデータを使って頻出語リストを作ってみたいなと思ったのでやってみました。

環境

必要なものをインストールする

MeCab(めかぶ)とはオープンソース形態素解析エンジンで、これを使うと、文字列を単語ごとに区切ることができます。
(例: 「今日はいい天気ですね」→「今日 | は | いい | 天気 | です | ね」)
mecab用の辞書ファイルとともにインストールします。

$ brew install mecab-ipadic mecab
  • gem 'natto'

MeCabrubyから使うために、今回は'natto'というgemを使います。

$ gem install natto

ツイートデータをダウンロードする

Twitterの設定画面の下のほうに、全ツイート履歴のダウンロードをリクエストするボタンがあります。
https://twitter.com/settings/account
リクエストしてからしばらく経つと、ダウンロード準備完了のメールがくるので、そこに書いてあるリンクよりダウンロードしましょう。tweets.zipというファイルがダウンロードできるはずです。

tweets.zipを解答すると、いくつかファイルがあると思いますが、今回はtweets.csvを使用します。
このファイルをテキストエディタExcel等で開いて頂くと、どんな構造をしているのかがわかると思います。

頻出語の集計方法

頻出語を集計するにあたっての順番は、

  1. tweets.csvにすべてのツイートデータが含まれているので、まずここからツイートのテキストだけを抽出します。
  2. それらテキスト一件一件に対して、形態素解析を行います。
  3. 形態素解析によって分解された単語ひとつひとつについて、ツイートデータ全体で何回出現したかをt_mapに格納します。
  4. t_mapに格納された単語データを出現回数でソートします。
  5. 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

今回は、単純に出現回数の多いものから順に出力しただけですが、次は特徴語を抽出したりしてみたいと思います。