淺談社會網絡分析(Social Network Analysis)

in #cn7 years ago

早前試過用Steemit的數據玩過文本分析,現在就打算用數據試一下別的。想了想就覺得社會網絡分析應該會挺有趣,所以先開個帖子跟大家說一下這是一種什麼分析,還有怎樣用Python去實現這個東西。

什麼是社會網絡分析


社會網絡就是把有關係的人連起來而成的一個組織,大概就像下面圖示這樣:

(圖片來源: https://goo.gl/LkkGCp)

那麼社會網絡分析就是運用圖論(Graph theory)從這些連結去研究整個結構,比如看看一個群體能分成多少個圈子(Clustering)、誰是每一個圈裏的軸心個體(Key Person)或是把每個人之間的關係緊密程度圖像化等等。

舉一個實際例子,社會網絡分析對於Facebook就有很大作用,比如它可以用於向用戶建議一些他們可能會認識的朋友。但像這種比較深入的分析會需要用到一些數學模型,今天就淺談一點,說說怎樣把數據圖像化以了解一個群體的結構。

在說明怎樣用Python寫編碼之前,我們先來看看一些例子:

用一個比較簡單的情況,比如有18個人(A – R),有以下的關係:

A-B, A-C, A-D, A-E, A-F, A-G, A-H,
H-I, H-J, H-K, H-M, H-N, H-O,
P-Q, P-R, P-H, B-C, D-F, B-G

那麼把它們畫出來就是這個樣子 (圖1):
P2.png

這裏大概就能看到三個群組,分別以H、A跟P為軸心。在這裏我們是沒有考慮人與人之間的親密度,假設我們已用某種方法把人跟人之間的親密度量化,就能製作一個加權的版本。

假設關係不變,且除了H跟P比較疏離、A跟H比較親近之外其他人的親密度是一樣的,那麼結果如下 (圖2):
P3.png
上圖所用的加權為:

個體1個體2加權(Weight)個體1個體2加權(Weight)
AH3HK1
PH0.5HM1
AB1HN1
AC1HO1
AD1PQ1
AE1PR1
AF1BC1
AG1DF1
HI1BG1
HJ1

這裏我用了線的粗幼來區分親密度,所以你能看到P跟H中間的線明顯是比其他線要幼很多的,而A跟H中間的線明顯比較粗。除了線的粗幼,還可以用顏色、長短這些來反映關係的程度,但在這就不一一做出來了,讓大家自己發掘一下。

以上看到的都是沒有方向關係(Undirected Graph),但有些社會網絡中的關係可以是單向或是雙向的,例如在Facebook上誰向誰發出交友邀請(單向)、誰向誰點讚(單向/雙向)等等,這時候我們需要製作有向圖(Directed Graph / Digraph) (圖3):

P4.png

如上圖,比較粗的一邊就等同箭頭,所以舉A跟H作例子,方向是從A指向H的。有向圖就能讓你發現原來H是一個接受者,假如圖中的方向是發出交友邀請的方向,那麼就等於H是一個不會主動發交友邀請的人,都是其他人主動加他為朋友的。

怎樣用Python去實現結果

我用的是Python裡面一個叫Networkx的library,其實用的編碼都很簡單 ( //後的是我的備註):

import networkx as nx
G=nx.Graph() // 定義G為一個網絡圖

G.add_edge('A', 'B') // 在G裡面把A跟B兩個個體連上
G.add_edge('A', 'C') // 這裡我就只保留了其中兩句,要製作上面的網絡你需要自己繼續連上其他個體

pos=nx.spring_layout(G) // 定義pos為G的佈圖 (layout),除了spring以外還有其他如circular, random, spectral等等的佈圖可以選擇

nx.draw_networkx_nodes(G,pos,node_size=1500, alpha=0.5) // 把G裡面的個體(node)畫出來,alpha是透明度

nx.draw_networkx_edges(G,pos,alpha=0.5, edge_color ='b') // 把G裡面個體間的線(edge)畫出來

nx.draw_networkx_labels(G,pos,font_size=13,font_color='w') // 把G裡面個體的名稱顯示出來

如果需要加入個體間的關係程度作加權的話 (如圖2),就需要改以下編碼:

  • G.add_edge裡面的函數中加上weight:

G.add_edge('A', 'H', weight = 3)
G.add_edge('A', 'B', weight = 1) // 同樣地,這裡只用了其中2句作例子

  • 然後加上一句代碼:

edgewidth = [d['weight'] for (u,v,d) in G.edges(data=True)]

  • 再在nx.draw_networkx_edges裡面的函數中加上width = edgewidth

nx.draw_networkx_edges(G,pos,alpha=0.5, edge_color ='b', width=edgewidth)

如果需要製作有向圖 (如圖3),則把

G=nx.graph()

改成

G=nx.Digraph()

就可以了,Digraph就是Directed graph的意思。
大家可以試試動手做,也不妨用Steemit的數據玩一下~ 過一兩天我會用Steemit的數據跑一下結果,再跟大家分享 :)


其實單純用Python去做的話結果圖是不太美觀的,而且當數據量巨大的時候結果會很難看,所以我個人會用Python把結果導出成graphml的格式,再用Gephi(一個專門把網絡圖像化的程式)去處理,下圖就是一個用Gephi製作的網絡圖的例子,但這個如果大家有興趣的話我晚一點再談吧。

P5.jpg
(圖片來源: https://goo.gl/Qur35C)

謝謝收看~ 希望大家發現數據分析其實也可以很有趣啦


歡迎Follow我 @rayccy :)

Sort:  

我真的很喜欢你分享这篇文章,我觉得你是在挑选东西,你会希望在讨论非常有创意,你总能成功

非常受启发!我正在用R语言做类似的工作。谢谢分享!

不客氣,我以前也用過R去跑,用visnetwork跑出來的結果也挺好看的,也可以互動

Look forward to your work. Followed. You may consider using upvotes, follow, comments as variables to construct relationships.

Thanks. Haha that's actually my idea to do so too!

好玩呀。。。 social networking model!!! 十年前我寫論文的題目,現在變得很流行呢!

你也是唸數據分析的嗎? 十年前我還是剛進中學不久的小薯 XD 師兄請指教

的確在大數據的時代這種分析就挺流行了,但我也是只懂皮毛啦 哈哈

你也是唸數據分析的嗎 > 我也想,只是讀大學的時候被迫寫這題目 :(

沒想到十年前你寫的這個題目十年後也挺有用吧? 哈哈

現在開始學數據分析也不遲啊~