我正在尝试重新创建文章中的分析:“从时间序列到复杂网络:可见性图”。以下是文章的链接:https://www.pnas.org/doi/10.1073/pnas.0709247105#core-B14。我正在研究的系列是布朗运动 B(t),这是我用来生成数据的代码:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def brownian_motion(t, a=1):
dt = t[1] - t[0]
dW = np.random.normal(scale=np.sqrt(dt), size=t.shape)
W = np.cumsum(dW)
return a**(1/2) * W
t = np.linspace(0, 100, 100000)
np.random.seed(42)
W = brownian_motion(t)
plt.plot(t, W)
plt.xlabel('t')
plt.ylabel('W(t)')
plt.title('Brownian Motion')
plt.show()
df = pd.DataFrame(W, index=t, columns=['W(t)'])
df.index.name = 't'
df.to_csv('brownian_motion_data.csv')
import numpy as np
import matplotlib.pyplot as plt
from ts2vg import NaturalVG
import networkx as nx
import pandas as pd
import powerlaw
data = pd.read_csv('brownian_motion_data.csv')
dat = data['W(t)'][:500]
nodes = range(len(dat))
vg = NaturalVG()
vg.build(dat)
edges = vg.edges
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
n = nx.number_of_nodes(G)
degree_freq = nx.degree_histogram(G)
degree_dist = []
for i in degree_freq:
x = i / n
degree_dist.append(x)
degrees = range(len(degree_freq))
fit = powerlaw.Fit(np.array(degree_dist) + 10 ** (-6))
alpha = round(fit.power_law.alpha, 3)
plt.figure(figsize=(8, 6))
plt.scatter(degrees, degree_dist, marker='o', color='b', label='Data')
fit.power_law.plot_pdf(color='r', linestyle='--', label=f'Fit (alpha={alpha})')
plt.xlabel('Degree')
plt.ylabel('Frequency')
plt.legend()
plt.show()
degrees_array = np.array(degrees)
degree_dist_array = np.array(degree_dist)
coefficients = np.polyfit(degrees_array, degree_dist_array, 2)
poly_function = np.poly1d(coefficients)
degrees_fit = np.linspace(min(degrees_array), max(degrees_array), 100)
degree_dist_fit = poly_function(degrees_fit)
plt.loglog(degrees_array, degree_dist_array, label='Original Data')
plt.loglog(degrees_fit, degree_dist_fit, label=f'Polynomial Fit', color='red')
plt.xlabel('Degrees')
plt.ylabel('Degree Distribution')
plt.title('Polynomial Fitting Example for Degree Distribution')
plt.legend()
plt.show()
我的两种方法是使用
powerlaw
和 polyfit
函数。由于度数概率有 0
值,结合我的调整,我得到的结果非常令人失望。我期待一些建议,甚至其他替代方法来使幂律拟合与上述文章类似。
我对幂律包不是很熟悉,但浏览了相应的论文后,我认为您的代码中缺少的是识别幂律拟合的正确数据范围(请参阅“识别缩放范围”部分)。
您的数据显然仅部分遵循幂律。
np.polyfit 函数按预期工作,但您的数据根本不遵循二次多项式。