iva*_*rre 6 python numpy curve-fitting scipy
我试图将一些数据拟合到具有指数切断的幂律函数.我用numpy生成一些数据,我试图用scipy.optimization来适应这些数据.这是我的代码:
import numpy as np
from scipy.optimize import curve_fit
def func(x, A, B, alpha):
return A * x**alpha * np.exp(B * x)
xdata = np.linspace(1, 10**8, 1000)
ydata = func(xdata, 0.004, -2*10**-8, -0.75)
popt, pcov = curve_fit(func, xdata, ydata)
print popt
Run Code Online (Sandbox Code Playgroud)
我得到的结果是:[1,1,1],这与数据不符.难道我做错了什么?
尽管xnx为您提供了为什么curve_fit失败的答案,但我想我会建议采用另一种方法来解决不依赖于梯度下降的函数形式的问题(因此可以进行合理的初始猜测)
请注意,如果获取适合的功能的日志,则会获得表格
在每个未知参数(对数A,α,B)中线性关系
因此,我们可以通过将线性方程代写为矩阵形式来使用线性代数机制来解决该问题
对数y = M p
其中log y是ydata点的对数的列向量,p是未知参数的列向量,M是矩阵 [[1], [log x], [x]]
或明确地
然后可以通过使用来有效地找到最佳拟合参数向量 np.linalg.lstsq
您在代码中的示例问题可以写成
import numpy as np
def func(x, A, B, alpha):
return A * x**alpha * np.exp(B * x)
A_true = 0.004
alpha_true = -0.75
B_true = -2*10**-8
xdata = np.linspace(1, 10**8, 1000)
ydata = func(xdata, A_true, B_true, alpha_true)
M = np.vstack([np.ones(len(xdata)), np.log(xdata), xdata]).T
logA, alpha, B = np.linalg.lstsq(M, np.log(ydata))[0]
print "A =", np.exp(logA)
print "alpha =", alpha
print "B =", B
Run Code Online (Sandbox Code Playgroud)
可以很好地恢复初始参数:
A = 0.00400000003736
alpha = -0.750000000928
B = -1.9999999934e-08
Run Code Online (Sandbox Code Playgroud)
另请注意,此方法比curve_fit解决当前问题快20倍左右
In [8]: %timeit np.linalg.lstsq(np.vstack([np.ones(len(xdata)), np.log(xdata), xdata]).T, np.log(ydata))
10000 loops, best of 3: 169 µs per loop
In [2]: %timeit curve_fit(func, xdata, ydata, [0.01, -5e-7, -0.4])
100 loops, best of 3: 4.44 ms per loop
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1512 次 |
| 最近记录: |