我有以下代码:
import numpy as np
from scipy.optimize import curve_fit
def func(x, p): return p[0] + p[1] + x
popt, pcov = curve_fit(func, np.arange(10), np.arange(10), p0=(0, 0))
它会引发 TypeError:func()只需要2个参数(给定3个)。嗯,这听起来很公平 - curve_fit使(0,0)不是两个标量输入。所以我尝试了这个:
popt, pcov = curve_fit(func, np.arange(10), np.arange(10), p0=((0, 0),))
同样,它说: ValueError:对象太深,不适合所需的数组
如果我将其保留为默认值(不指定p0):
popt, pcov = curve_fit(func, np.arange(10), np.arange(10))
它会引发 IndexError:标量变量的无效索引。显然,它只为函数提供了标量p。
我可以使def func(x,p1,p2):返回p1 + p2 + x以使其正常工作,但是在更复杂的情况下,代码看起来会变得冗长和混乱。如果有一个更清洁的解决方案,我真的很喜欢它。
谢谢!
答案 0 :(得分:5)
不确定这是否更干净,但至少现在更容易向拟合功能添加更多参数。也许甚至可以从中做出更好的解决方案。
import numpy as np
from scipy.optimize import curve_fit
def func(x, p): return p[0] + p[1] * x
def func2(*args):
return func(args[0],args[1:])
popt, pcov = curve_fit(func2, np.arange(10), np.arange(10), p0=(0, 0))
print popt,pcov
编辑:这对我有用
import numpy as np
from scipy.optimize import curve_fit
def func(x, *p): return p[0] + p[1] * x
popt, pcov = curve_fit(func, np.arange(10), np.arange(10), p0=(0, 0))
print popt,pcov
答案 1 :(得分:2)
使用curve_fit
时,您必须明确说出适合参数的数量。做类似的事情:
def f(x, *p):
return sum( [p[i]*x**i for i in range(len(p))] )
会很棒,因为它将是一个通用的n阶多项式拟合函数,但不幸的是,在我的SciPy 0.12.0中,它提出了:
ValueError: Unable to determine number of fit parameters.
所以你应该这样做:
def f_1(x, p0, p1):
return p0 + p1*x
def f_2(x, p0, p1, p2):
return p0 + p1*x + p2*x**2
依此类推......
然后你可以使用p0
参数调用:
curve_fit(f_1, xdata, ydata, p0=(0,0))
答案 2 :(得分:1)
<强> scipy.optimize.curve_fit 强>
scipy.optimize.curve_fit(f,xdata,ydata,p0 = None,sigma = None,** kw)
Use non-linear least squares to fit a function, f, to data. Assumes ydata = f(xdata, *params) + eps
要安装的功能应采用仅标量(不:*p0
)。
请记住,拟合的结果取决于初始化参数。
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def func(x, a0, a1):
return a0 + a1 * x
x, y = np.arange(10), np.arange(10) + np.random.randn(10)/10
popt, pcov = curve_fit(func, x, y, p0=(1, 1))
# Plot the results
plt.title('Fit parameters:\n a0=%.2e a1=%.2e' % (popt[0], popt[1]))
# Data
plt.plot(x, y, 'rx')
# Fitted function
x_fine = np.linspace(x[0], x[-1], 100)
plt.plot(x_fine, func(x_fine, popt[0], popt[1]), 'b-')
plt.savefig('Linear_fit.png')
plt.show()
答案 3 :(得分:1)
您可以定义返回其他功能的函数(请参阅Passing additional arguments using scipy.optimize.curve_fit?)
工作示例:
import numpy as np
import random
from scipy.optimize import curve_fit
from matplotlib import pyplot as plt
import math
def funToFit(x):
return 0.5+2*x-3*x*x+0.2*x*x*x+0.1*x*x*x*x
xx=[random.uniform(1,5) for i in range(30)]
yy=[funToFit(xx[i])+random.uniform(-1,1) for i in range(len(xx))]
a=np.zeros(5)
def make_func(numarg):
def func(x,*a):
ng=numarg
v=0
for i in range(ng):
v+=a[i]*np.power(x,i)
return v
return func
leastsq, covar = curve_fit(make_func(len(a)),xx,yy,tuple(a))
print leastsq
def fFited(x):
v=0
for i in range(len(leastsq)):
v+=leastsq[i]*np.power(x,i)
return v
xfine=np.linspace(1,5,200)
plt.plot(xx,yy,".")
plt.plot(xfine,fFited(xfine))
plt.show()