Python 使用scipy曲线拟合错误

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

我想把一些数据拟合成指数截止的幂律函数。我用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
我得到的结果是:[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是的,你是对的!我注意到我的错误,删除了我的第二个提示。多谢各位