1. 程式人生 > >社交網路分析演算法(SNA)

社交網路分析演算法(SNA)

近來學習聚類,發現聚類中有一個非常有趣的方向—社交網路分析,這篇只是一篇概況,並沒有太多的公式推導和程式碼,基本是用人話解釋社交網路分析中的常用的幾種演算法。詳細到每個演算法的以後有空再把詳細的公式和程式碼補上。
目錄:
1.應用場景
2.分析指標
3.社群發現演算法
3.1 GN演算法
3.2 Louvain演算法
3.3 LPA與SLPA

  1. 應用場景

社交網路分析中最常用的就是社交圈子的識別,所謂物以類聚,人以群分,一旦能對社交圈子進行分類,能做的事情就會很多。

FaceBook和微信是關於人與人之間的強關係網路,劃分社交圈有助於朋友間相互推薦。
領英是關於職業的社交的社交網路,有助於求職和商務合作交流。
微博,Twitter,豆瓣,微信公眾號是關於關注與被關注的的弱關係網路,有助於訊息和知識的傳播。

分好社交網路之後可以對人進行精準化營銷,推薦個性化的商品和服務,比如京東;
疾病傳播也是由一箇中心點向外擴散,切斷網路中的關鍵節點就可以有效阻止傳染病的傳播;
識別網際網路金融行業中的欺詐團伙,進行反欺詐預測;

這只是其中的三個方面,還有很多應用在此不作細講。

2.分析指標

圖,簡單來說就是人物(事物)關係的形象化表示。節點(node)代表一個人物,邊(edge)代表人物關係。有向圖用箭頭表示人物間的關係,無向圖用線段表示人物間的關係。
順便提供兩份圖資料集,可以自己拿來做實驗:
斯坦福大學實驗資料

這裡重點講述社交網路演算法的分析指標。

度(Degree)
連線點活躍性的度量;與點相連的邊的數目。在有向圖中,以頂點A為起點記為出度(out degree)OD(A),以頂點A為終點入度(In degree)ID(A),則頂點A的度為D(A) = OD(A) + ID(A)。
Igraph是圖計算和社交網路分析的常用工具,提供了python的介面,安裝方式參考官網:

Igraph官網點這

這裡寫圖片描述

算了,還是拿權遊的資料玩一下比較爽。
計算度:

import csv
edges = []
firstline = True
with open('/Users/huanghuaixian/desktop/stormofswords.csv','r') as f:
    for row in csv.reader(f.read().splitlines()):
        if firstline == True:
            firstline = False
            continue
        u,v,weight = [i for
i in row] edges.append((u,v,int(weight))) from igraph import Graph as IGraph g = IGraph.TupleList(edges ,directed = True ,vertex_name_attr = 'name' ,edge_attrs = None ,weights = True) print(g) for p in g.vs: print(p['name'],p.degree())

分析一下網路結構:

#角色數
g.vcount()
#143個角色
#網路直徑,網路中最長最短路徑
print(g.diameter())
#輸出7

最短路徑

print(g.shortest_paths("Sansa","Margaery"))
print([ names[x] for x in g.get_all_shortest_paths("Sansa","Margaery")[0]])
for p in g.get_all_shortest_paths('Sansa'):
    print([names[x]for x in p])
#輸出1和所有以Sansa開始的最短路徑

緊密中心性(closness centrality)
節點V到達其他節點的難易程度,也就是到其他所有節點距離的平均值的倒數。
這裡寫圖片描述
程式碼實現:

ccvs = []
for p in zip(g.vs, g.closeness()):
    ccvs.append({"name": p[0]["name"], "cc": p[1]})
sorted(ccvs, key=lambda k: k['cc'], reverse=True)[:10]

[{‘cc’: 0.5120772946859904, ‘name’: ‘Tyrion’},
{‘cc’: 0.5096153846153846, ‘name’: ‘Sansa’},
{‘cc’: 0.5, ‘name’: ‘Robert’},
{‘cc’: 0.48847926267281105, ‘name’: ‘Robb’},
{‘cc’: 0.48623853211009177, ‘name’: ‘Arya’},
{‘cc’: 0.4796380090497738, ‘name’: ‘Jaime’},
{‘cc’: 0.4796380090497738, ‘name’: ‘Jon’},
{‘cc’: 0.4796380090497738, ‘name’: ‘Stannis’},
{‘cc’: 0.4690265486725664, ‘name’: ‘Tywin’},
{‘cc’: 0.4608695652173913, ‘name’: ‘Eddard’}]

介數中心性(betweenness centrality)
核心思想是兩個非鄰接成員間的相互作用依賴於網路中的其他成員,特別是兩成員間路徑上的成員,它們對兩非鄰接成員間起著某種控制或依賴關係。如果一個成員A位於其他成員的多條最短路徑上,那麼成員A的作用就比較大,也具有較大的介數中心性。
本質:網路中包含成員B的所有最短路徑條數佔所有最短路徑條數的百分比。
計算公式如下:
這裡寫圖片描述
計算步驟:
1.計算每對節點(i,j)的最短路徑(需要得到具體的路徑)
2. 對各節點判斷v是否在最短路徑下
3. 累加經過v的最短路徑條數

#偷懶一下
btvs = []
for p in zip(g.vs, g.betweenness()):
    btvs.append({"name": p[0]["name"], "bt": p[1]})
sorted(btvs, key=lambda k: k['bt'], reverse=True)[:10]

結果:

[{‘bt’: 332.9746031746032, ‘name’: ‘Tyrion’},
{‘bt’: 244.63571428571433, ‘name’: ‘Samwell’},
{‘bt’: 226.2047619047619, ‘name’: ‘Stannis’},
{‘bt’: 208.62301587301587, ‘name’: ‘Robert’},
{‘bt’: 138.66666666666666, ‘name’: ‘Mance’},
{‘bt’: 119.99563492063493, ‘name’: ‘Jaime’},
{‘bt’: 114.33333333333334, ‘name’: ‘Sandor’},
{‘bt’: 111.26666666666665, ‘name’: ‘Jon’},
{‘bt’: 90.65, ‘name’: ‘Janos’},
{‘bt’: 64.59761904761905, ‘name’: ‘Aemon’}]

3 . 社群發現演算法

社群相當抱團,類似群的概念,同一個社群內的連線緊密,而社群間的連線非常稀疏。社群發現可以理解為在圖中發現n個社群,他們連線非常緊密。

3.1 GN 演算法

邊介數(betweenness):網路中經過該邊的最短路徑佔所有最短路徑的比例。
GN演算法計算步驟:
1. 計算網路中所有邊的介數
2. 找到介數最高的邊,並將它從網路中移除
3. 重複以上步驟,直到每個節點就是一個社群為止。
這裡寫圖片描述

3.2 Louvain 演算法
Louvain演算法是基於模組度的演算法,其優化目標就是最大化整個社群網路結構的模組度。

模組度
它的物理含義是社群內節點的連邊數與隨機情況下節點的連邊數之差,它可以衡量一個社群緊密程度的度量。因此模組度就可以作為優化函式優化社群的分類。
計算方法如下:
這裡寫圖片描述
其中Aij是節點i與節點j之間的權重,網路不是帶權圖時,所有邊的權重看作是1;ki=jAij表示所有與節點i相連的權重之和;ci表示節點i所屬的社群;
m=12ijAij表示所有邊的權重之和,取值範圍:[-1/2,1)。

演算法思想
1. 不斷遍歷網路中的節點,嘗試把單個節點加入能使模組度提升最大的社群,直到所有節點不再改變
2. 將第一階段形成的一個個小的社群併為一個節點,重新構造網路。這時邊的權重為兩個節點內所有原始節點的邊權重之和。
3. 重複以上兩步

更多請參考:點這

3.3 LPA與SLPA

LPA演算法思想:
1. 初始化每個節點,並賦予唯一標籤
2. 根據鄰居節點最常見的標籤更新每個節點的標籤
3. 最終收斂後標籤一致的節點屬於同一社群

SLPA演算法思想:
SLPA是LPA的擴充套件。
1. 給每個節點設定一個list儲存歷史標籤
2. 每個speaker節點帶概率選擇自己標籤列表中標籤傳播給listener節點。(兩個節點互為鄰居節點)
3. 節點將最熱門的標籤更新到標籤列表中
4. 使用閥值去除低頻標籤,產出標籤一致的節點為社群。