使用Python和NetworkX求概率密度函数并绘制Facebook数据幂律图
嘿,我来帮你搞定这两个问题!我之前处理社交网络数据的时候也遇到过类似的需求,咱们一步步来:
第一步:将度直方图的Y轴转换为概率
要把Y轴改成概率,核心思路就是每个度数的出现次数除以总节点数,这样得到的就是该度数对应的概率值——也就是随机选一个节点,它的度数为k的概率。下面是具体的实现代码:
首先导入需要的库:
import networkx as nx import matplotlib.pyplot as plt from collections import Counter import numpy as np
加载你的Facebook数据(假设你是用边列表文件加载的,根据实际情况调整路径):
# 替换成你的数据文件路径 G = nx.read_edgelist("facebook_combined.txt")
计算度序列和总节点数:
# 获取所有节点的度数列表 degree_sequence = [d for n, d in G.degree()] # 网络的总节点数 total_nodes = len(G.nodes())
接下来有两种常见的绘图方式,你可以根据需求选择:
方式1:概率直方图(条形区间式)
用numpy的直方图函数自动划分区间,再将计数转换为概率:
# 自动计算合适的区间(bins) counts, bins = np.histogram(degree_sequence, bins='auto') # 将每个区间的计数转换为概率 probabilities = counts / total_nodes # 计算每个区间的中点,用作x轴标签 bin_centers = (bins[:-1] + bins[1:]) / 2 # 绘制概率直方图 plt.bar(bin_centers, probabilities, width=np.diff(bins)) plt.xlabel("Degree") plt.ylabel("Probability") plt.title("Facebook Network Degree Distribution (Probability)") plt.show()
方式2:离散概率散点图(每个度数对应一个点)
这种方式更适合观察幂律分布的细节,用Counter统计每个度数的精确出现次数:
# 统计每个度数出现的次数 degree_counts = Counter(degree_sequence) # 按度数从小到大排序 sorted_degrees = sorted(degree_counts.keys()) # 计算每个度数对应的概率 probabilities = [count / total_nodes for count in degree_counts.values()] # 绘制离散概率散点图 plt.scatter(sorted_degrees, probabilities, alpha=0.6) plt.xlabel("Degree") plt.ylabel("Probability") plt.title("Facebook Network Degree Probability Distribution") plt.show()
第二步:绘制双对数图验证幂律
幂律分布的核心特征是双对数坐标系下呈现直线,因为幂律的表达式是 $P(k) \propto k^\gamma$,取对数后变为 $\log(P(k)) = \gamma \log(k) + C$,这就是标准的直线方程。
直接在之前的散点图基础上改成双对数刻度,还可以添加拟合直线来直观验证:
# 绘制双对数散点图 plt.loglog(sorted_degrees, probabilities, 'o', alpha=0.6, label='Actual Distribution') # 添加拟合直线(验证幂律特征) log_degrees = np.log10(sorted_degrees) log_probs = np.log10(probabilities) # 拟合一次多项式(直线) coefficients = np.polyfit(log_degrees, log_probs, 1) fit_line = np.poly1d(coefficients) # 转换回原刻度绘制拟合线 plt.plot(sorted_degrees, 10**fit_line(log_degrees), 'r--', label=f'Fit: $\log(P) = {coefficients[0]:.2f}\log(k) + {coefficients[1]:.2f}$') plt.xlabel("Degree (Log Scale)") plt.ylabel("Probability (Log Scale)") plt.title("Facebook Network Degree Distribution (Log-Log Plot)") plt.legend() plt.show()
如果图中的点大致沿着红色拟合直线分布,就说明你的Facebook网络符合幂律特征啦!
内容的提问来源于stack exchange,提问作者Michael




