2014年8月30日 星期六

[R] PTT推文文化的社群網絡分析(Social Network Analysis),帶你一窺社群網絡中的互動情況




        PTT是台灣最大的社群網站(http://zh.wikipedia.org/wiki/批踢踢),很多人介紹過我就不多費脣舌,PTT中很特別的功能就是可以推文回應作者,畢竟回文相對來說比較正式,推文感覺更加閒聊的性質.Wxxxxd版相對PTT中的其他版來說,由於有每日發文限制,版友之間更頃向利用推文的方式來互動,而且因為男多女少的緣故,通常女生的推文比較多人推,男生(例如我)可能發文都沒人鳥,然後網友之間彼此也會利用推文互動,本文就是要以圖像化的方式來展現這種推文互動關係。


        我知道大家對程式語言沒興趣,所以我先講怎樣看圖:


  1. 每個圈圈代表一個網友,圈圈的大小代表該網友被“不同人”推文的文章次數
  2. 箭頭代表的推文的方向 A -> B表示A推B的文章,而且不同大小的圈圈
從圖中來看,可以發現網友之間的互動真的非常密切和多樣,除了幾位人氣王之外,也有很多小團體和出現眾星拱月的情況.人氣王彼此之間的互動也不在少數,相信有逛過wanted版的朋友看起來會更有感觸.至於ID的部分我就隱藏起來了,雖然是這是公開資料,但是畢竟不是每個人都喜歡被別人分析XD

        以下講的是做法:本次分析包含資料截取到畫圖都是利用R軟體來實做,用的主要方法包括爬網和社群網絡分析(social network analysis),以下是原始碼:
library("XML")
library("httr")
library("stringr")
library("igraph")
library("dplyr")
##這部分是爬網,先從網頁版PTT中抓下每篇文章的聯結
rm(data)
data <- list()
for( i in 1628:2628){
url <- paste('bbs/Wanted/index', i, '.html', sep='')
html <- content(GET("https://www.ptt.cc/", path = url),as = 'parsed')
url.list <- xpathSApply(html, "//div[@class='title']/a[@href]", xmlAttrs)
data <- rbind(data, url.list[[1]])
}
##把一些空值刪掉
data = Filter(function(x) x != "www.ptt.cc",data)
##根據每篇文章代碼進去抓作者和推文的資料
popu <- function(link){
html <- content(GET('https://www.ptt.cc', path = data[[link]]), as = 'parsed')
poster <- xpathApply(html,"//div[@class='article-metaline']/span[@class='article-meta-value']",xmlValue)[[1]]
#這邊特別說明一下,因為作者這個欄位很討厭,除了ID之外還有暱稱,要把暱稱刪掉
poster <- str_split_fixed(poster, "\\(",2)[,1]
puller <- xpathApply(html,"//div[@class='push']/span[@class='f3 hl push-userid']",xmlValue)
#這個if是排除那些沒人有推文的作者(例如我)
if (length(puller) >0 ){
puller <- as.data.frame(matrix(unlist(puller),nrow = length(puller),T))
edgelist <- merge(poster,puller,all = TRUE)
return (edgelist)
}
}
##我在這個步驟卡了半天 每次抓ID和推文都很容易抓漏
##原本用sapply做但是遇到抓錯後面就全部錯,所以改用for回圈
edge = list()
for (l in 1:length(data)){
edge <- rbind(edge, popu(l))
}
#依照推文和被推者分組,計算每個pair的數量
edge2 <- group_by(edge,x,V1)
edge2 <- summarise(edge2,weight=n())
#from 表示推文者 in 表示被推文的
edge2 <- data.frame(from = edge2$V1, to = edge2$x,weight = edge2$weight)
#使用igraph套件將edge list的data轉成graph 物件,這是有方向性的
g <- graph.data.frame(edge2,directed = TRUE)
#用被推文的數量“in"來決定大小
V(g)$size <- degree(g,mode = ("in"))/2
#接下來就是畫圖輸出了
png(filename="org_network.png", height=1080, width=1080)
plot(g, layout = layout.fruchterman.reingold,
vertex.label=NA,
edge.arrow.size = 1
)
dev.off()
view raw gistfile1.r hosted with ❤ by GitHub



6 則留言:

  1. 作者已經移除這則留言。

    回覆刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 您好:
    請問一下抓網址那邊為什麼i只放數字,但實際上不是還會夾雜英文嗎?
    如:/bbs/Wanted/M.1446388368.A.CB2.html

    我剛剛也試了直接在網址(https://www.ptt.cc/bbs/Wanted/index.html)中的index後加數字
    看起來是日期的不同???

    回覆刪除