【iPhone5S vs iPhone5C 】RによるTwitterテキストマイニング

 
RによるTwitterテキストマイニング第2弾ということで、今回はiPhone5SとiPhone5Cについてつぶやかれている内容に差異があるか比較してみたいと思います。
 
まずはiPhone5sとiPhone5cについてTwitterからsearchAPIを使って情報を取得します。

Twitter APIクライアントの設定等については前回の記事をご覧ください

  
#iPhone5sに関するつぶやき
iPhone5s = ""
Twitter.search("iPhone5s -rt" ,:lang => "ja" ,:count => 100, :result_type => "recent").results.map do |result|
	iPhone5s << result.text
end

iPhone5s.gsub!(/[!-\/:-@\[-`{-~]/, "")

output = File.open("data/iPhone5s.txt", "w")
output.write(iPhone5s)
output.close
  

#iPhone5cに関するつぶやき
iPhone5c = ""
Twitter.search("iPhone5c -rt" ,:lang => "ja" ,:count => 100, :result_type => "recent").results.map do |result|
	iPhone5c << result.text
end

iPhone5c.gsub!(/[!-\/:-@\[-`{-~]/, "")

output = File.open("data/iPhone5c.txt", "w")
output.write(iPhone5c)
output.close

http://e-words.jp/p/r-ascii.html を見つつ、先にgsubで要らない半角記号を削除しておきます。

Twitter.searchの引数部分では、
:lang => “ja”で言語を日本語、
-rt を付けることでリツイートされたものは除く(重複してカウントされてしまうため)ようにしています。

 
 

また、今回はN-gramを使ってみます。
N-gramモデルとは、「ある文字列の中で、N個の文字列または単語の組み合わせが、どの程度出現するか」を調査する言語モデルです。
N=2で指定します。
Nがあまりに大きくなりすぎるとモデルの精度が落ちます。
 
その後、出現頻度が2回以上あるものに絞った上で、頻度が多い順に並び替えています。

> sNgram <- Ngram("path/iPhone5s.txt", type=1, pos="名詞", N=2)
> sNgram <- sNgram[(sNgram$Freq > 2),]
> sNgram[rev(order(sNgram$Freq)),]

 
以下がiPhone5sについての結果です。Freqが出現頻度です。

                   Ngram Freq
364             [iPhone-5]   97
94                   [5-s]   74
86                   [5-S]   27
371             [iphone-5]   21
99              [5-ケース]   11
88                   [5-c]   10
425             [s-ケース]    9
1179     [iPhone-5]    7
1166             [5-分解]    6
600        [ケース-iPhone]    6
1123           [部品-実装]    5
1110           [送料-無料]    5
1010               [月-04]    5

5sに関しては、ケースに関する関心が高いことが伺えます。
実際に「CLANNAD x ギルドデザイン iPhone5sケース 高っwwwwwwwwwwwwwwwwww」などという文章が見受けられます。
 
5sは値段が高いからか、ケースもしっかりしようと思っている人が多いのかもしれません。
 
 
以下は同じ処理を行ったiPhone5cについての結果です。

> cNgram <- Ngram("Path/iPhone5c.txt", type=1, pos="名詞", N=2)
> cNgram <- cNgram[(cNgram$Freq > 2),]
> cNgram[rev(order(cNgram$Freq)),]
                            Ngram Freq
481                    [iPhone-5]   98
132                         [5-c]   76
816                      [一括-0]   35
8                          [0-円]   35
127                         [5-C]   31
496                    [iphone-5]   29
655           [キャッシュ-バック]   21
68                        [16-GB]   17
918                       [円-CB]   16
140                         [5-s]   16
1334                      [0-円]   14
928               [円-キャッシュ]   14
1220              [相互-フォロー]   12
1151                  [期間-限定]   12

 
一方で、iPhone5cの方は値段が安いからか既に背面全体に色がついているからか分かりませんが、ケースという語はでてきませんでした。
また、キャッシュバック、0円、16GBなど価格やスペックに関することが多くつぶやかれていることが分かります。これは各携帯ショップが販促のためのつぶやきをしているためです。
 

故ジョブズ氏は正しかった… 低価格「iPhone5c」にそっぽ
 
にもあるように、5cは5sに比べて売れ行きが良くないようですので、価格を下げて売りにきているようです。

Twitterの投稿からiPhone5sとiPhone5c間での差異が分かったところで今回は以上です!
コメントもどしどしお待ちしております。
 

RによるTwitterユーザーのクラスター分析

 
 
今後web上に落ちているテキストデータを元に知見を生み出すということをやっていくことになりそうなので、
試しに自分のTwitterのフォロワーをクラスター分析でグループ分けしてみました。
 

つぶやきデータの収集

 
Twitterからの情報取得の方法として、RではTwitteRというパッケージがあります。
http://cran.r-project.org/web/packages/twitteR/index.html
 
しかし、TwitteRは自分のRのバージョンではnot availableと言われて使えないようだったので、
今回はこちらのRuby用のTwitter APIクライアントを使用することにしました。
https://github.com/sferik/twitter

 


require "twitter"

Twitter.configure do |config|
 config.consumer_key = "xxx"
 config.consumer_secret = "xxx"
 config.oauth_token = "xxx"
 config.oauth_token_secret = "xxx"
end

事前にhttps://dev.twitter.com/よりアプリケーションを登録し、consumer_keyなどを取得しておく必要があります。そしてconfigに値をセット。

 


timeline = Twitter.home_timeline({:count => 20})

users = []

timeline.each do |timeline|
	tweet = "";
	user_id = timeline[:user][:id]

	unless users.include?(user_id)
		user_timeline = Twitter.user_timeline(user_id, {:count => 100})

		user_timeline.each do |user_timeline|
			tweet << user_timeline[:text]
			tweet << " "
		end	

		output = File.open("data/#{timeline[:user][:id]}.txt", "w")
		output.write(tweet)
		output.close

  		users.push(user_id)
	end	
end

自分のタイムラインに流れているユーザーを上から20人分取得し、そこから各ユーザーごとに最新のつぶやきを100件取得します。
今回はつぶやき間の分析などは行わないつもりでしたので、あらかじめユーザーごとの全てのつぶやきをつなげて保存することにしました。

また、後ほどターム・文書行列を作るために、指定のフォルダ下にユーザーごとのつぶやきのテキストファイルを作成します。

 

クラスター分析

 
ここから先はRを使用します
 
事前にMeCabとRからMeCabを使うためのライブラリであるRMeCabをインストールしておく必要があります
http://rmecab.jp/wiki/index.php?RMeCab
 

library(RMeCab)
DM <- docMatrix("data", pos = c("名詞"))

docMatrix関数を使って、ターム・文書行列を作成します。この関数は、列にTwitterユーザー名、行に一度でも出現した語が並んであり、その升目に語の出現頻度が書かれてある行列を作成します。
 
今回は業界や興味分野などでクラスタリングできたら良いなと思い、名詞のみを抽出しました。pos引数に指定すれば動詞なども抜き出せます。

“愛”, “握手”, “以外”, “伊藤”, “意見”, “異彩”, “移住”, “一員”, “一覧”, “運用”, “英”, “英国”, “横尾”, “欧州”・・・などの単語がつぶやかれています。
 

plot(hclust(dist(t(DM)), "ward"))

個体間の距離の計測・クラスター作成・プロットまで一気にやっています。
今回はウォード法を使用しました。これはクラスター内の分散が最も小さくなるようにクラスタを作成する方法です。クラスタリングの階層的手法としては、他にも最長距離法や群平均法などがあります。
 
 
その結果がこんな感じ(各枝はTwitterのユーザーID)

ward

右側は「民主主義」とか「理想」とか「自尊心」とか社会科学系のガチなことをつぶやいている方々で、左側は「巨人はクソ」とか「クリパ10人連れて来る」とか「フットサルたのぴーー」とかユルい感じでつぶやいている方々に分かれているっぽい(と自分は解釈した)
 
今回は17人のみですが、より多くのユーザーについて分析するときに、自分のフォロワーにどのようなジャンルの人がいるのかを要約的に把握するのには良いんじゃないかと思います。

 
次回は具体的にどんな単語が出てきたか・その傾向等調べたいと思います。
 
【参考】

Rを用いたTwitterテキストマイニング

Twitter Ruby Gemを使って、RubyでTwitterキーワード検索を試す

 

Clustter クラスタ判定ツール
これによると自分は「池澤あやか」クラスタらしい(なんだそりゃ)