RubyでTwitterのtweetを収集して、簡単な分析をしてみます。

ここでは以下を点を分析することにします。
・tweetでは、どれくらいの割合でHashタグが付けられているのか?
・tweetでは、どれくらいの割合でリンクが付けられているのか?
・tweetでは、どれくらいの割合でmentionが付けられているのか?
・どのクライアントアプリでよく使われているのか?

tweetの収集

まずtweetの収集ですが、
Twitterには「REST API」と「Streaming API」の二種類があり、
分析するために大量のtweetを取得する用途には、
「Streaming API」が向いてそうなのでそちらを使います。

RESTAPIとStreamingAPIの違いはこのスライドがわかりやすいです。

TwitterのStreamingAPIについて 概要と簡単な実演
 http://www.slideshare.net/hidenorigoto/twitterstreaming-api

TwitterのStreaming APIのマニュアル
 https://dev.twitter.com/docs/streaming-apis

Streaming APIを使用してtweetを取得してみます。
こちらのサイト参考にしました(かなりの部分そのままですww)。

Twitter Streaming APIをRubyで試してみる
 http://d.hatena.ne.jp/shibason/20090816/1250405491

先に上げた分析に必要な情報は
 ・tweetの本文
 ・クライアントアプリ名

これを取得する、以下のプログラムでtweetを収集します。
呼び出し時にコマンドライン引数で、
twitterのユーザ名・パスワードを指定します。

#!/usr/bin/env ruby
# coding: utf-8

require 'net/http'
require 'uri'
require 'rubygems'
require 'json'

# コマンドライン引数からtwitterユーザ名・パスワードを取得
if ARGV.size < 2
puts "usage: ruby get_publictweet.rb [username] [password]"
exit
end
username = ARGV[0]
password = ARGV[1]

# 取得したtweetを出力するファイルをオープン
twout = File.open('twout.csv',"w")

# streaming APIに接続
uri = URI.parse("https://stream.twitter.com/1/statuses/sample.json")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.start

# tweetの取得開始
request = Net::HTTP::Get.new(uri.request_uri)
request.basic_auth(username, password)

twcnt = 0
http.request(request) do |response|
raise 'Response is not chuncked' unless response.chunked?
response.read_body do |chunk|
# 空行は無視、JSON形式でのパースに失敗したら次へ
status = JSON.parse(chunk) rescue next
# 削除通知など、'text'パラメータを含まないものは無視して次へ
next unless status['text']
# 日本語でないtweetは無視して次へ
next unless status['user']['lang'] == 'ja'

# tweetの本文とクライアントの情報を出力
twarray = [status['text'], status['source']]
twarray.map! {|e| e.gsub(/"/, "\"\"") }
twarray.map! {|e| "\"#{e}\"" }
twout.puts twarray.join(",")
twcnt += 1

# 必要な数のtweetが収集できたら終了(ここでは40tweet)
exit if twcnt > 40

end
end

# ファイルをクローズ
twout.close

このプログラムを実行すると、
 1列目:tweetの本文
 2列目:クライアントアプリ名
が入ったCSVファイルが出力されます。

◆出力イメージ
tweet_stat1

tweetの分析

tweetの分析ですが、今回収集したもの以外に
2001年5月に収集したデータが手元にあったので比較して見ます。

tweet本文の中に
「http://」が含まれている場合 → URLのリンクを含んだtweet
「#」が含まれている場合 → hashタグのついたtweet
「@」が含まれている場合 → mentionのtweet
として集計します。
※実際の集計にはExcelを使いましたが、細かいところは省略します。

tweet本文を上記のように集計したところ以下のようになりました。

◆2011年5月と2012年8月のtweet傾向比較

2011/52012/8
URLのリンクを含んだtweet16.50%18.72%
hashタグのついたtweet6.93%6.39%
mentionのtweet8.98%41.19%

tweet_stat2

15ヶ月前と比較するとmentionの付いたtweetが、
4倍以上増加している事がわかります。
このことから、twitterの使われ方が、
 「個人のつぶやき」→「コミュニケーション」
と変化してきているのではないかと考えられます。

次にクライアントもsource部分のクライアント名で集計します。
集計結果は次のようになりました。

◆2011年のクライアント利用状況

クライアント名利用割合
web13.10%
Keitai Web12.99%
ついっぷる/twipple6.82%
Twitter for iPhone5.14%
モバツイ / www.movatwi.jp4.71%
Tween4.22%
Echofon3.73%
twicca3.41%
yubitter2.33%
ついっぷる for iPhone2.27%
TweetDeck2.16%
Twitter for Android2.00%
jigtwi1.89%
Saezuri1.46%
Tweet Button1.46%
SOICHA1.24%
TwitBird1.03%
YoruFukurou1.03%
HootSuite0.97%
TweetMe for iPhone0.81%
その他27.22%

◆2012年のクライアント利用状況

クライアント名利用割合
Twitter for iPhone14.76%
web12.33%
Twitter for Android12.11%
twittbot.net6.83%
Keitai Web5.95%
EasyBotter4.85%
ついっぷる/twipple3.08%
twicca2.86%
Echofon2.42%
SOICHA2.20%
ついっぷる for iPhone1.98%
Janetter1.54%
jigtwi1.32%
Tweet Button1.10%
Twipple for Android1.10%
twitterfeed1.10%
mixi ボイス 0.88%
BotMaker0.88%
jigtwi for Android0.88%
Tween0.88%
その他20.93%

2012年の利用率上位10位のクライアントについて、
2011年の利用率と比較してみると以下のようになりました。

tweet_stat3

15ヶ月前と比較すると
 ・Keitai Webが減少
 ・Twitter for iPhone/Androidが増加
という傾向がはっきりと見えます。
最近のスマートフォンの普及の影響でしょう。

Echofonが減少して、SOICHAが増加というのも、
スマートフォン向けtwitterクライアントの
トレンドを反映してそうですね。

結果をまとめると、twitterは、
『従来型携帯電話からスマートフォンでの利用にシフト』しており、
その使われ方は、
『個人のつぶやきよりもコミュニケーション(会話)』が増えてきている
と考えられます。

さらに「それはなぜなのか」も考えて見ると面白いかもしれませんね。

例えば考えられる仮説:
・ユーザのtwitterの利用暦が長くなり人脈が増えた結果、会話が増えた
・従来型携帯電話よりスマホの方が会話しやすいから、会話が増えた
 (専用クライアントがあるため)
・個人的なつぶやき中心のユーザが飽きてtwitterやめて、会話の割合が増えた
とか、とか。。

※情報の収集方法・期間
収集方法: public_timelineのtweetを15分後とに20件ずつ取得し、ユーザの言語がjaのものを抽出
収集期間:
 2011年5月分: 5/18(水) 10:45 ~ 5/24(水) 11:30 (日本時間)
 2012年8月分: 8/16(木) 17:15 ~ 8/17(金) 13:30 (日本時間)