百万个冷知识百万个冷知识

百万个冷知识
一起学习百万个冷知识

使用NetworkX对社交网络进行系统的分析:Facebook网络分析案例

前言:下期给我们撷取NetworkX非官方得出的SNSABM事例:FacebookABM[1],以更进一步增进对繁杂互联网基本知识的认知。

那个笔记本电脑包涵了三个SNSABM,主要就是用NetworkX的库继续执行的。简而言之,将对10对个人的facebook圈子里(挚友条目)展开检查审核,以抽取各式各样有用的重要信息。统计数据集能在麻省理工学院的中文网站上[2]找出。除此之外,不可否认,facebook互联网是无向的,没权重股,因为三个采用者可能将只与另三个采用者正式成为一场挚友。从图象预测的视角上看统计数据集:

★ 每一结点代表者三个非官方的facebook采用者,他归属于这六个挚友条目中的三个。

★ 每一边都相关联着归属于那个互联网的三个facebook采用者的情谊。换言之,三个采用者要在facebook上正式成为挚友就能在某一的互联网中相连。

上面得出非官方的jupyter notebook实例标识符:

具体来说,引入必要性的库:

import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt from random import randint

从统计数据配置文件读取Minervois统计数据,每一边都是三个LX1,每一边都有三个start_node和三个end_node列:

facebook = pd.read_csv( "data/facebook_combined.txt.gz", compression="gzip", sep=" ", names=["start_node", "end_node"], )

创建互联网:

G = nx.from_pandas_edgelist(facebook, "start_node", "end_node")

可视化互联网:即使我们对统计数据的结构没任何真正的感觉,所以让我们从采用random_layout查看互联网,这是最快的布局函数之一。

fig, ax = plt.subplots(figsize=(15, 9)) ax.axis("off") plot_options = {"node_size": 10, "with_labels": False, "width": 0.15}nx.draw_networkx(G, pos=nx.random_layout(G), ax=ax, **plot_options)

生成的图不是很有用,这种图可视化有时被通俗地称为“毛球”,即使重叠的边会导致纠缠的混乱。

很明显,如果我们想要获得统计数据的感觉,我们需要在定位上施加更多的结构。为此,我们能采用spring_layout函数,它是networkx绘图模块的默认布局函数。spring_layout函数的优点是它考虑了结点和边来计算结点的位置。然而,缺点是那个过程的计算成本要高得多,而且对于有100个结点和1000个边的图来说会非常慢。

由于我们的数据集有超过80k条边,我们将限制spring_layout函数中采用的迭代次数,以减少计算时间。我们还将保存计算出来的布局,以便在将来的可视化中采用它。

pos = nx.spring_layout(G, iterations=15, seed=1721) fig, ax = plt.subplots(figsize=(15, 9)) ax.axis("off") nx.draw_networkx(G, pos=pos, ax=ax, **plot_options)

★ 获取互联网的基本拓扑属性:

# 结点数量 G.number_of_nodes() 4039 # Minervois数量 G.number_of_edges() 88234 np.mean([d for _, d in G.degree()]) 43.69101262688784 shortest_path_lengths = dict(nx.all_pairs_shortest_path_length(G)) # Length of shortest path between nodes 0 and 42 shortest_path_lengths[0][42] 1 diameter = max(nx.eccentricity(G, sp=shortest_path_lengths).values()) diameter 8 # Compute the average shortest path length for each node average_path_lengths = [ np.mean(list(spl.values())) for spl in shortest_path_lengths.values() ] # The average over all nodes np.mean(average_path_lengths)3.691592636562027

上述结果代表者了所有结点对最短路径长度的平均值:为了从三个结点到达另三个结点,平均大约要遍历3.6条边。

上面的度量捕获了关于互联网的有用重要信息,但是像平均值这样的度量只代表者了分布的三个时刻。我们能通过预先计算的dict-of-dicts构建三个最短路径长度分布的可视化:

# We know the maximum shortest path length (the diameter), so create an array # to store values from 0 up to (and including) diameter path_lengths = np.zeros(diameter + 1, dtype=int) # Extract the frequency of shortest path lengths between two nodes for pls in shortest_path_lengths.values(): pl, cnts = np.unique(list(pls.values()), return_counts=True) path_lengths[pl] += cnts # Express frequency distribution as a percentage (ignoring path lengths of 0) freq_percent = 100 * path_lengths[1:] / path_lengths[1:].sum() # Plot the frequency distribution (ignoring path lengths of 0) as a percentage fig, ax = plt.subplots(figsize=(15, 8)) ax.bar(np.arange(1, diameter + 1), height=freq_percent) ax.set_title( "Distribution of shortest path length in G", fontdict={"size": 35}, loc="center" ) ax.set_xlabel("Shortest Path Length", fontdict={"size": 22}) ax.set_ylabel("Frequency (%)", fontdict={"size": 22})

大多数最短路径的长度是从2条边到5条边的长度。除此之外,对于一对结点来说,其最短路径长度为8(直径长度)的可能将性非常小,即使其可能将性小于0.1%。

计算图的密度,显然,这是三个非常稀疏的图。以及图包涵组件的数量,正如预期的那样,那个互联网由三个巨大的组件组成:

nx.density(G) 0.010819963503439287 nx.number_connected_components(G)1

接下来,对facebook互联网的中心性指标展开研究:

★ 度中心性:度中心性简单地根据每一结点所拥有的链接数量分配三个重要分数。在那个预测中,这意味着三个结点的中心性程度越高,相连到该结点的边越多,因此该结点的邻居结点(facebook挚友)也越多。事实上,三个结点的中心性程度就是它所相连的结点的分数。换言之,它是互联网中某一结点与交友关系的百分比。

具体来说,我们找出中心度最高的结点。其中,8个度中心性最高的结点及其度中心性如下图所示:

degree_centrality = nx.centrality.degree_centrality(G) # save results in a variable to use again (sorted(degree_centrality.items(), key=lambda item: item[1], reverse=True))[:8] [(107, 0.258791480931154), (1684, 0.1961367013372957), (1912, 0.18697374938088163), (3437, 0.13546310054482416), (0, 0.08593363051015354), (2543, 0.07280832095096582), (2347, 0.07206537890044576), (1888, 0.0629024269440317)]

现在我们还能看到中心度最高的结点的邻居数量:

(sorted(G.degree, key=lambda item: item[1], reverse=True))[:8] [(107, 1045), (1684, 792), (1912, 755), (3437, 547), (0, 347), (2543, 294), (2347, 291), (1888, 254)] 绘制出程度中心性的分布: plt.figure(figsize=(15, 8)) plt.hist(degree_centrality.values(), bins=25) plt.xticks(ticks=[0, 0.025, 0.05, 0.1, 0.15, 0.2]) # set the x axis ticks plt.title("Degree Centrality Histogram ", fontdict={"size": 35}, loc="center") plt.xlabel("Degree Centrality", fontdict={"size": 20}) plt.ylabel("Counts", fontdict={"size": 20})

现在让我们根据结点的大小来检查中心度最高的采用者:

node_size = [ v * 1000 for v in degree_centrality.values() ] # set up nodes size for a nice graph representation plt.figure(figsize=(15, 8)) nx.draw_networkx(G, pos=pos, node_size=node_size, with_labels=False, width=0.15) plt.axis("off")
★ 介数中心性: betweenness_centrality = nx.centrality.betweenness_centrality( G ) # save results in a variable to use again (sorted(betweenness_centrality.items(), key=lambda item: item[1], reverse=True))[:8] [(107, 0.4805180785560152), (1684, 0.3377974497301992), (3437, 0.23611535735892905), (1912, 0.2292953395868782), (1085, 0.14901509211665306), (0, 0.14630592147442917), (698, 0.11533045020560802), (567, 0.09631033121856215)] plt.figure(figsize=(15, 8)) plt.hist(betweenness_centrality.values(), bins=100) plt.xticks(ticks=[0, 0.02, 0.1, 0.2, 0.3, 0.4, 0.5]) # set the x axis ticks plt.title("Betweenness Centrality Histogram ", fontdict={"size": 35}, loc="center") plt.xlabel("Betweenness Centrality", fontdict={"size": 20}) plt.ylabel("Counts", fontdict={"size": 20})
按照介数值的大小展开互联网可视化: node_size = [ v * 1200 for v in betweenness_centrality.values() ] # set up nodes size for a nice graph representation plt.figure(figsize=(15, 8)) nx.draw_networkx(G, pos=pos, node_size=node_size, with_labels=False, width=0.15) plt.axis("off")
★ 接近度中心性: closeness_centrality = nx.centrality.closeness_centrality( G ) # save results in a variable to use again (sorted(closeness_centrality.items(), key=lambda item: item[1], reverse=True))[:8] [(107, 0.45969945355191255), (58, 0.3974018305284913), (428, 0.3948371956585509), (563, 0.3939127889961955), (1684, 0.39360561458231796), (171, 0.37049270575282134), (348, 0.36991572004397216), (483, 0.3698479575013739)] # 除此之外,三个某一结点v到任何其他结点的平均距离也能很容易地用公式求出:1 / closeness_centrality[107]2.1753343239227343 plt.figure(figsize=(15, 8)) plt.hist(closeness_centrality.values(), bins=60) plt.title("Closeness Centrality Histogram ", fontdict={"size": 35}, loc="center") plt.xlabel("Closeness Centrality", fontdict={"size": 20}) plt.ylabel("Counts", fontdict={"size": 20})
node_size = [ v * 50 for v in closeness_centrality.values() ] # set up nodes size for a nice graph representation plt.figure(figsize=(15, 8)) nx.draw_networkx(G, pos=pos, node_size=node_size, with_labels=False, width=0.15) plt.axis("off")
以及特征向量中心性等中心性指标,用类似的方式即可获取上述图象。 ★ 集聚系数: # 平均集聚系数 nx.average_clustering(G) 0.6055467186200876 plt.figure(figsize=(15, 8)) plt.hist(nx.clustering(G).values(), bins=50) plt.title("Clustering Coefficient Histogram ", fontdict={"size": 35}, loc="center") plt.xlabel("Clustering Coefficient", fontdict={"size": 20}) plzt.ylabel("Counts", fontdict={"size": 20})
★ 桥: nx.has_bridges(G) True # 输出桥的数量 bridges = list(nx.bridges(G))len(bridges) 75 plt.figure(figsize=(15, 8))nx.draw_networkx(G, pos=pos, node_size=10, with_labels=False, width=0.15)nx.draw_networkx_edges( G, pos, edgelist=local_bridges, width=0.5, edge_color="lawngreen") # green color for local bridgesnx.draw_networkx_edges( G, pos, edgelist=bridges, width=0.5, edge_color="r") # red color for bridgesplt.axis("off") ★ 互联网关联系数: nx.degree_assortativity_coefficient(G)0.06357722918564943nx.degree_pearson_correlation_coefficient(G) 0.06357722918564918 ★ 互联网社区:社区是一组结点,因此组内的结点相连 的边要比组间相连的边多得多。该互联网将采用两种不 同的算法展开社区检测。 具体来说,采用半同步标签传播方法检测社区: 该函数自行确定将检测到的社区数量。现在将遍历社 区,并创建三个颜色条目,为归属于同三个社区的结点 包涵相同的颜色。除此之外,社区的数量也被打印出来: colors = ["" for x in range(G.number_of_nodes())] # initialize colors listcounter = 0for com in nx.community.label_propagation_communities(G): color = "#X" % randint(0, 0xFFFFFF) # creates random RGB color counter += 1 for node in list( com ): # fill colors list with the particular color for the community nodes colors[node] = colorcounter44plt.figure(figsize=(15, 9))plt.axis("off")nx.draw_networkx( G, pos=pos, node_size=10, with_labels=False, width=0.15, node_color=colors) 其次,采用异步流体团体算法: colors = ["" for x in range(G.number_of_nodes())]for com in nx.community.asyn_fluidc(G, 8, seed=0): color = "#X" % randint(0, 0xFFFFFF) # creates random RGB color for node in list(com): colors[node] = colorplt.figure(figsize=(15, 9))plt.axis("off")nx.draw_networkx( G, pos=pos, node_size=10, with_labels=False, width=0.15, node_color=colors)[1] https://networkx.org/nx-guides/content/exploratory_notebooks/facebook_notebook.html#id2[2] http://snap.stanford.edu/data/ego-Facebook.html
本文采用 文章同步助手 同步
未经允许不得转载:百万个冷知识 » 使用NetworkX对社交网络进行系统的分析:Facebook网络分析案例
分享到: 更多 (0)

百万个冷知识 带给你想要内容

联系我们