一次性完成scipy的'curve_fit`的多次迭代

时间:2017-06-30 02:41:00

标签: python numpy scipy

考虑以下MWE

import numpy as np
from scipy.optimize import curve_fit
X=np.arange(1,10,1)
Y=abs(X+np.random.randn(15,9))

def linear(x, a, b):
    return (x/b)**a

coeffs=[]
for ix in range(Y.shape[0]):
    print(ix)
    c0, pcov = curve_fit(linear, X, Y[ix])
    coeffs.append(c0)


XX=np.tile(X, Y.shape[0])
c0, pcov = curve_fit(linear, XX, Y.flatten())

我有一个问题,我必须基本上做到这一点,但不是15次迭代,而是成千上万,而且它很慢。

有没有办法用curve_fit一次完成所有这些迭代?我知道函数的结果应该是1D数组,所以只需传递这样的args

c0, pcov = curve_fit(nlinear, X, Y)

无法运作。另外我认为答案必须是扁平Y,所以我可以得到一个扁平的结果,但我无法得到任何工作。

修改

我知道如果我这样做

XX=np.tile(X, Y.shape[0])
c0, pcov = curve_fit(nlinear, XX, Y.flatten())
然后我得到一个"意思是"系数的值,但这不是我想要的。

编辑2

为了记录,我使用Jacques Kvam的设置解决了问题但是使用Numpy实现了(因为有限制)

lX = np.log(X)
lY = np.log(Y)
A = np.vstack([lX, np.ones(len(lX))]).T
m, c=np.linalg.lstsq(A, lY.T)[0]

然后ma并获得b

b=np.exp(-c/m)

1 个答案:

答案 0 :(得分:1)

最小二乘法不会给出相同的结果,因为在这种情况下,噪声会被日志转换。如果噪声为零,则两种方法都会产生相同的结果。

import numpy as np
from numpy import random as rng
from scipy.optimize import curve_fit
rng.seed(0)
X=np.arange(1,7)
Y = np.zeros((4, 6))
for i in range(4):
    b = a = i + 1
    Y[i] = (X/b)**a + 0.01 * randn(6)

def linear(x, a, b):
    return (x/b)**a

coeffs=[]
for ix in range(Y.shape[0]):
    print(ix)
    c0, pcov = curve_fit(linear, X, Y[ix])
    coeffs.append(c0)

coefs

[array([ 0.99309127,  0.98742861]),
 array([ 2.00197613,  2.00082722]),
 array([ 2.99130237,  2.99390585]),
 array([ 3.99644048,  3.9992937 ])]

我会使用scikit-learn的线性回归实现,因为我相信它可以很好地扩展。

from sklearn.linear_model import LinearRegression
lr = LinearRegression()

记录XY

的日志
lX = np.log(X)[None, :]
lY = np.log(Y)

现在适合并检查系数是否与以前相同。

lr.fit(lX.T, lY.T)
lr.coef_

给出类似的指数。

array([ 0.98613517,  1.98643974,  2.96602892,  4.01718514])

现在检查除数。

np.exp(-lr.intercept_ / lr.coef_.ravel())

这给出了类似的系数,你可以看到方法在他们的答案中有些分歧。

array([ 0.99199406,  1.98234916,  2.90677142,  3.73416501])