我正在尝试将幂律与噪声幂律拟合,以对数刻度显示:
与 scipy curve_fit 的拟合是橙色线,红线是无噪声幂律。
这是代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def powerFit(x, A, B):
return A * x**(-B)
x = np.logspace(np.log10(1),np.log10(1e5),30)
A = 1
B = 2
np.random.seed(1)
y_noise = np.random.normal(1, 0.2, size=x.size)
y = powerFit(x, A, B) * y_noise
plt.plot(x, y, 'o')
plt.xscale('log')
plt.yscale('log')
popt, pcov = curve_fit(powerFit, x, y, p0 = [A, B])
perr = np.sqrt(np.diag(pcov))
residuals = y - powerFit(x, *popt)
ss_res = np.sum(residuals**2)
ss_tot = np.sum((y-np.mean(y))**2)
r_squared = 1 - (ss_res / ss_tot)
plt.plot(x, powerFit(x, *popt),
label = 'fit: A*x**(-B)\n A=%.1e +- %.0e\n B=%.1e +- %.0e\n R2 = %.2f' %tuple(np.concatenate(( np.array([popt, perr]).T.flatten(), [r_squared]) )))
plt.plot(x, powerFit(x, A, B), 'r--', label = 'A = %d, B = %d'%(A,B))
plt.legend()
plt.savefig("fig.png", dpi = 300)
我不明白拟合幂律发生了什么。为什么看起来不对?我怎么能解决这个问题?
注意:我知道你也可以拟合幂律绘制 log(y) vs log(x)。但是根据这个答案,似乎 curve_fit 也应该直接做到这一点。所以我的问题是,如果没有对数转换,是否可以在对数对数刻度中进行幂律。我有兴趣避免对数对数转换,因为它不可能应用于任何拟合(例如,考虑对 y = A*x**(-Bx) 的拟合)。