You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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

火山引擎 最新活动