鉴于无向网络X图graph
,我想检查它是否无标度。
为此,据我所知,我需要找到每个节点的k
度,以及整个网络中该度P(k)
的频率。由于度数的频率与度数本身之间的关系,这应该代表幂律曲线。
绘制P(k)和k的计算结果会显示预期的功率曲线,但是当我对其进行双重记录时,不会绘制直线。
以1000个节点获得以下图表。
代码如下:
k = []
Pk = []
for node in list(graph.nodes()):
degree = graph.degree(nbunch=node)
try:
pos = k.index(degree)
except ValueError as e:
k.append(degree)
Pk.append(1)
else:
Pk[pos] += 1
# get a double log representation
for i in range(len(k)):
logk.append(math.log10(k[i]))
logPk.append(math.log10(Pk[i]))
order = np.argsort(logk)
logk_array = np.array(logk)[order]
logPk_array = np.array(logPk)[order]
plt.plot(logk_array, logPk_array, ".")
m, c = np.polyfit(logk_array, logPk_array, 1)
plt.plot(logk_array, m*logk_array + c, "-")
m
应该表示缩放系数,如果它在2到3之间,那么网络应该是无标度的。
通过调用NetworkX的scale_free_graph方法获取图形,然后将其用作Graph构造函数的输入。
根据@Joel的要求,下面是10000个节点的图
此外,生成图表的确切代码如下:
graph = networkx.Graph(networkx.scale_free_graph(num_of_nodes))
正如我们所看到的,大量值似乎形成一条直线,但网络似乎在其双重日志形式中有一个奇怪的尾部。
答案 0 :(得分:1)
您是否在python中尝试过powerlaw模块? 非常简单。
首先,从您的网络中创建一个学位分布变量:
degree_sequence = sorted([d for n, d in G.degree()], reverse=True) # used for degree distribution and powerlaw test
然后将数据拟合到幂律和其他分布:
import powerlaw # Power laws are probability distributions with the form:p(x)∝x−α
fit = powerlaw.Fit(degree_sequence)
要考虑到幂律,它会通过从数据集中的每个唯一值开始创建幂律拟合来自动找到xmin的最佳alpha值,然后选择一个导致数据之间最小Kolmogorov-Smirnov距离D的幂律。和适合。如果要包含所有数据,则可以如下定义xmin值:
fit = powerlaw.Fit(degree_sequence, xmin=1)
然后您可以绘制:
fig2 = fit.plot_pdf(color='b', linewidth=2)
fit.power_law.plot_pdf(color='g', linestyle='--', ax=fig2)
这将产生如下输出:
另一方面,它可能不是幂律分布,而是任何其他分布,例如对数线性等,您也可以检查powerlaw.distribution_compare:
R, p = fit.distribution_compare('power_law', 'exponential', normalized_ratio=True)
print (R, p)
其中,R是两个候选分布之间的似然比。如果第一次发布中的数据可能性更大,则此数字为正,但您还应检查p <0.05
最后,一旦您选择了xmin作为分布,就可以在社交网络的一些常规学位分布之间进行比较:
plt.figure(figsize=(10, 6))
fit.distribution_compare('power_law', 'lognormal')
fig4 = fit.plot_ccdf(linewidth=3, color='black')
fit.power_law.plot_ccdf(ax=fig4, color='r', linestyle='--') #powerlaw
fit.lognormal.plot_ccdf(ax=fig4, color='g', linestyle='--') #lognormal
fit.stretched_exponential.plot_ccdf(ax=fig4, color='b', linestyle='--') #stretched_exponential
lognornal vs powerlaw vs stretched exponential
最后,考虑到网络中的幂律分布正在讨论中,因此从经验上讲,高度无标度的网络似乎很少见
答案 1 :(得分:0)
你的一部分问题是,你不能包括缺少适合你的生产线的学位。有一小部分大学位节点,你可以在你的队伍中包含这些节点,但是你忽略了许多大学位不存在的事实。你的最大学位在1000-2000范围内,但只有2个观察。实际上,对于如此大的值,我期待随机节点具有如此大的2 /(1000 * N)的概率(或者实际上,它甚至可能甚至小于该值)。但是,在你的情况下,你将它们视为两个特定度数的概率是2 / N,并且你忽略了其他度数。
简单的解决方法是仅使用较小的度数。
更健壮的方法是适应互补的累积分布。不是绘制P(K=k)
,而是绘制P(K>=k)
并尝试拟合(注意如果P(K = k)是概率的概率,那么P(K> = k)的概率也是,但使用不同的指数 - 检查它。
答案 2 :(得分:0)
尝试使一条直线适合这些点是错误的,因为这些点在x轴上不是线性分布的。线的拟合函数将更加重视包含更多点的区域部分。
您应该像这样使用函数np.interp
在x轴上重新分配观测值。
logk_interp = np.linspace(np.min(logk_array),np.max(logk_array),1000)
logPk_interp = np.interp(logk_interp, logk_array, logPk_array)
plt.plot(logk_array, logPk_array,".")
m, c = np.polyfit(logk_interp, logPk_interp, 1)
plt.plot(logk_interp, m*logk_interp + c, "-")