Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何检查网络是否无标度?_Python_Numpy_Matplotlib_Networkx_Complex Networks - Fatal编程技术网

Python 如何检查网络是否无标度?

Python 如何检查网络是否无标度?,python,numpy,matplotlib,networkx,complex-networks,Python,Numpy,Matplotlib,Networkx,Complex Networks,给定一个无向NetworkX图形Graph,我想检查它是否无标度 为此,据我所知,我需要找到每个节点的度k,以及该度p(k)在整个网络中的频率。由于度数频率和度数本身之间的关系,这应表示幂律曲线 绘制p(k)和k的计算结果时,会按预期显示功率曲线,但当我对其进行双重记录时,不会绘制一条直线 以下是1000个节点的图 代码如下: k = [] Pk = [] for node in list(graph.nodes()): degree = graph.degree(nbunch=n

给定一个无向NetworkX图形
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\u free\u graph方法获得的,然后将其用作图构造函数的输入

更新 根据@Joel的请求,下面是10000个节点的图。
此外,生成图形的确切代码如下:
graph=networkx.graph(networkx.scale\u free\u图(节点数))

正如我们所看到的,大量的值似乎形成了一条直线,但网络似乎有一个奇怪的双对数形式的尾巴


问题的一部分在于,在装配线时没有包括缺失的度数。有少量的大度数节点,您将其包含在行中,但忽略了许多大度数节点不存在的事实。你的最大度数在1000-2000之间,但只有2次观测。所以实际上,对于如此大的值,我期望随机节点的概率有如此大的阶数2/(1000*N)(或者实际上,它甚至可能小于这个)。但在你的拟合中,你把它们当作这两个特定度数的概率是2/N,而忽略其他度数

简单的解决方法是只使用较小的度数


更稳健的方法是拟合互补累积分布。绘制
P(K=K)
,而不是绘制
P(K>=K)
,并尝试拟合(注意,如果P(K=K)的概率是幂律,那么P(K>=K)的概率也是幂律,但具有不同的指数-检查它)。

尝试将线拟合到这些点是错误的,因为这些点在x轴上不是线性分布的。线的拟合函数将更加重视域中包含更多点的部分

您应该使用函数
np.interp
在x轴上重新分布观测值,如下所示

logk_interp=np.linspace(np.min(logk_数组),np.max(logk_数组),1000)
logPk_interp=np.interp(logk_interp,logk_数组,logPk_数组)
plt.plot(logk_数组,logPk_数组,“.”)
m、 c=np.polyfit(logk_interp,logPk_interp,1)
plt.绘图(logk_interp,m*logk_interp+c,“-”)

您尝试过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) 
考虑到通过从数据集中的每个唯一值开始创建幂律拟合,然后选择导致数据和拟合之间最小Kolmogorov-Smirnov距离D的幂律拟合,幂律自动找到xmin的最佳alpha值。如果要包含所有数据,可以按如下方式定义xmin值:

fit=powerlaw.fit(度序列,xmin=1)

然后可以绘制:

fig2 = fit.plot_pdf(color='b', linewidth=2)
fit.power_law.plot_pdf(color='g', linestyle='--', ax=fig2)
这将产生如下输出:

另一方面,它可能不是幂律分布,而是任何其他分布,如对数线性等,您也可以检查powerlaw.distribution\u 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

最后,考虑到目前正在讨论网络中的幂律分布,强无标度网络在经验上似乎很少


尝试更大的网络。我想那会更明显。另外,您能提供用于创建图的代码吗?@Joel如问题底部所述,该图是通过以下方式获得的:graph=networkx.(networkx.(num_of_nodes))。我遇到的确切问题是,日志值不是我想要的值expect@Joel照你说的做。一条直线似乎是形成的,但随着到达更高的
k
s,它变得更模糊,这毒害了我的绘图,因此也毒害了缩放系数的计算。。。