Tokyo.Webmining#5で使うコード

明日のデータマイニング+WEB 勉強会@東京 (Tokyo.Webmining)の発表で使っているコードです。

発表資料はこちら→ http://bit.ly/bupfT1

Twitterをしている現役国会議員をネットワーク分析してクラスタリング
無駄に長いです。

library(twitteR)
library(igraph)
library(Cairo)

# TwitterのAPI制限回数は公式には150回/時。
# 取得できるのは最新100人分。
# なのでフォロー先が100未満の人に絞る。
# 現役国会議員50アカウント。(広報含む)
ACCOUNT <- c("jimin_koho", # 自民党広報
  "komei_koho", # 公明党広報
  "your_party", # みんなの党広報
  "Tanigaki_S", # 谷垣禎一 (自民)
  "tadamori_oshima", # 大島理森(自民)
  "TAIRAMASAAKI", # 平将明(自民)
  "AkiraNishino", # 西野陽(自民)
  "junmatsumoto411", # 松本純(自民)
  "akibakenya", # 秋葉賢也(自民)
  "ohmura_hideaki", # 大村秀章(自民)
  "akimoto_tsukasa", # 秋元司(自民)
  "SatoMasahisa", # 佐藤正久(自民)
  "kandorishinobu", # 神取忍(自民)
  "maruyamakun", # 丸山和也(自民)
  "shiba_masa", #柴山昌彦(自民)
  "abetoshiko", # 阿部俊子(自民)
  "kushibuchi", # 櫛渕万里(民主)
  "yokokume", # 横粂勝仁(民主)
  "miekondotcom", # 中林美恵子(民主)
  "oniken0024", # 大西健介(民主)
  "yo_ishida", # 石田芳弘(民主)
  "yamanoikazunori", # 山井和則(民主)
  "takashinagao", # 長尾敬(民主)
  "Kumaatsu", # 熊田篤嗣(民主)
  "otaninobumori", # 大谷信盛(民主)
  "okadayasuhiro", # 岡田康裕(民主)
  "takasho624", # 高橋昭一(民主)
  "toshiro141", # 石井登志郎(民主)
  "Sakaguchi_Naoto", # 阪口直人(民主)
  "yunoki_m", # 柚木道義(民主)
  "tamakiyuichiro", # 玉木雄一郎(民主)
  "nagaetakako", # 永江孝子(民主)
  "fukken01", # 福嶋健一郎(民主)
  "grazie4812", # 磯谷香代子(民主)
  "imai_masato", # 今井雅人(民主)
  "fujitadaisuke", # 藤田大助(民主)
  "GOGOdai5", # 松浦大悟(民主)
  "Y_Kaneko", # 金子洋一(民主)
  "fujimoto_yuuji", # 藤本祐司(民主)
  "kunivoice", # 谷岡郁子(民主)
  "k_maekawa", # 前川清成(民主)
  "inuzuka2010", # 犬塚直史(民主)
  "izki_toyama", # 外山斎(民主)
  "odachi_moto", # 尾立源幸(民主)
  "hirayamamakoto", # 平山誠(新党日本)
  "HideoYoshiizumi", # 吉泉秀男(社民)
  "hattori_ryoichi", # 服部良一(社民)
  "edaoffice", # 江田憲司(みんな)
  "kiyohiko_toyama", # 遠山清彦(公明)
  "Noriko_Furuya") # 古屋 範子(公明)

INIT <- initSession("bob3bob3", "**********")

# エッジリストを作る
EDGE <- NULL
for (i in ACCOUNT){
 FRIENDS <- userFriends(i, INIT)
 FRIENDS.NAME <- sapply(FRIENDS, screenName)
 DF <- data.frame(FROM=i, TO=FRIENDS.NAME)
 EDGE <- rbind(EDGE, DF)
}

G <- graph.data.frame(EDGE)  # エッジリストをgraphオブジェクトに変換

V(G)$label <- V(G)$name # ノードにラベルをつける

#描画
Cairo(1920, 1920, file="zu1.png", type="png", bg="white")
par(mar=c(0, 0, 0, 0))
plot(G, layout=layout.kamada.kawai, edge.arrow.size=0.5)
dev.off()


# 次数が2以下のノードを削る
DG <- degree(G)  # 次数(ノードごとのエッジの数)を算出
VL <- rownames(get.adjacency(G))  # ノードの名前
EL <- get.edgelist(G)  # エッジリスト
CUT <- VL[DG < 3]
for (k in CUT) EL <- EL[EL[, 1]!=k, ]
for (l in CUT) EL <- EL[EL[, 2]!=l, ]
G2 <- graph.data.frame(EL)
V(G2)$label <- V(G2)$name

Cairo(1920, 1920, file="zu2.png", type="png", bg="white")
par(mar=c(0, 0, 0, 0))
plot(G2, layout=layout.kamada.kawai, edge.arrow.size=0.5)
dev.off()


# ページランクを算出し、ノードの大きさに使う
PR <- page.rank(G2)$vector
Cairo(1920, 1920, file="zu3.png", type="png", bg="white")
par(mar=c(0, 0, 0, 0))
plot(G2, layout=layout.kamada.kawai, vertex.size=10*PR/max(PR),
     edge.arrow.size=0.5)
dev.off()


# modularity Q でクラスタリング
MERGES <- walktrap.community(G2)$merges
Q.SIZE <- nrow(MERGES)
Q <- numeric(Q.SIZE)
STEPS <- 1:Q.SIZE
for (i in STEPS) {
 MENBER <- community.to.membership(G2, MERGES, steps=i)
 Q[i] <- modularity(G2, MENBER$membership)
 }
plot(STEPS, Q, type="b", pch=21, bg="green", main="modularity Q",
     xlab="Steps", ylab="Q")
# modularity Q が最大になるstepでクラスタを分割
CLUSTERS <- community.to.membership(G2, MERGES, steps=which.max(Q))
MEMBERSHIP <- CLUSTERS$membership
table(MEMBERSHIP)
# クラスターごとに色を付ける
V(G2)$color <- c("#ffbcbc", "#ddbcff", "#bcddff", "#bcffbc",
                 "#ffddbc")[MEMBERSHIP+1]
Cairo(1920, 1920, file="zu5.png", type="png", bg="white")
par(mar=c(0, 0, 0, 0))
plot(G2, layout=layout.kamada.kawai, vertex.label.family="mono",
     vertex.size=10*PR/max(PR), edge.arrow.size=0.5)
dev.off()


以上です。