リツイート関係の視覚化

M.A.Russell, Mining the Web, pp.4-16 に掲載されている "Twitter上でのリツイート関係の視覚化" を試してみた.
ここで,ノードは Twitter ユーザ名,エッジは ツイートがretweet された関係を示している.

プログラムは以下のとおり.本に載っているまま.

#coding: utf-8

import twitter
import networkx as nx
import re

# M.A.Russell, Mining the Web, pp.4-16 に掲載されている
# Twitter からの検索およびリツイート関係の視覚化
# (注) プログラムは本に載っているとおり.

# Twitter search を利用し,Evernote を含むツイートを収集
twitter_search = twitter.Twitter(domain="search.twitter.com")
search_results = []
for page in range(1,6):
    search_results.append(twitter_search.search(q="Evernote", rpp=100, page=page))

all_tweets = [ tweet for page in search_results for tweet in page["results"]]

# retweet 関係に基づくネットワーク構築
g = nx.DiGraph()
def get_rt_sources(tweet):
    rt_patterns = re.compile(r"(RT|via)((?:\b\W*@\w+)+)", re.IGNORECASE)
    return [ source.strip()
            for tple in rt_patterns.findall(tweet)
            for source in tple
            if source not in ("RT", "via")]

for tweet in all_tweets:
    rt_sources = get_rt_sources(tweet["text"])
    if not rt_sources: continue
    for rt_source in rt_sources:
        g.add_edge(rt_source, tweet["from_user"], {"tweet_id" : tweet["id"]})

print "Number of nodes : " + str(g.number_of_nodes())
print "Number of edges : " + str(g.number_of_edges())

# 解析結果を Graphviz (DOT file) へ書き出す
OUT = "/home/muto/evernote_search_result.dot"
nx.drawing.write_dot(g, OUT)

結果は以下のとおり.EvernoteJP から発信された情報が拡散されている様子が分かる.また,同時に日本における Evernote 利用者数の多さも(間接的だが)証明している.
f:id:ymuto109:20110915170108p:image