Python 使用scipy曲线拟合错误
我想把一些数据拟合成指数截止的幂律函数。我用numpy生成了一些数据,并试图用scipy.optimization来拟合这些数据。 这是我的密码:Python 使用scipy曲线拟合错误,python,numpy,scipy,curve-fitting,Python,Numpy,Scipy,Curve Fitting,我想把一些数据拟合成指数截止的幂律函数。我用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(xda
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
我得到的结果是:[1,1,1],这与数据不符。
?我做错了什么吗?显然,您最初的猜测(默认为
[1,1,1]
,因为您没有给出一个--see)与实际参数相差太远,无法让算法收敛。主要的问题可能是B
的问题,如果为正,它会将您提供的扩展数据的指数函数发送到非常大的值
尝试提供一些更接近实际参数的内容,它会起作用:
p0 = 0.01, -5e-7, -0.4 # Initial guess for the parameters
popt, pcov = curve_fit(func, xdata, ydata, p0)
print popt
输出:
[ 4.00000000e-03 -2.00000000e-08 -7.50000000e-01]
虽然xnx给出了为什么curve\u fit
在这里失败的答案,但我认为我应该建议一种不同的方法来解决函数形式的拟合问题,它不依赖于梯度下降(因此是一个合理的初始猜测)
请注意,如果您记录了要安装的函数的日志,则会得到表单
在每个未知参数(对数A、α、B)中都是线性的
因此,我们可以使用线性代数的机制,通过将方程写成矩阵的形式来解决这个问题
对数y=mp
其中,logy是ydata点的log的列向量,p是未知参数的列向量,M是矩阵[[1],[logx],[x]]
或者明确地
然后,使用该方法可以有效地找到最佳拟合参数向量
代码中的示例问题可以写成
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
可以很好地恢复初始参数:
A = 0.00400000003736
alpha = -0.750000000928
B = -1.9999999934e-08
还要注意,对于手头的问题,此方法比使用曲线拟合
快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
我的方法中断,因为最终数据点(655642210处)的值为0。当你把它的日志,你得到一个南。我已经使用排除该点的方法计算了拟合度,得到了看起来合理的A=0.00326,alpha=-0.767,B=-1.88e-8是的,你是对的!我注意到我的错误,删除了我的第二个提示。多谢各位