我正在尝试拟合一个函数,它将输入2个独立变量x,y和3个参数作为输入a,b,c。这是我的测试代码:
import numpy as np
from scipy.optimize import curve_fit
def func(x,y, a, b, c):
return a*np.exp(-b*(x+y)) + c
y= x = np.linspace(0,4,50)
z = func(x,y, 2.5, 1.3, 0.5) #works ok
#generate data to be fitted
zn = z + 0.2*np.random.normal(size=len(x))
popt, pcov = curve_fit(func, x,y, zn) #<--------Problem here!!!!!
但是我得到了错误:&#34; func()正好接受5个参数(51个给定)&#34;。怎么能正确地传递我的论证x,y?
答案 0 :(得分:7)
只需查看documentation of scipy.optimize.curve_fit()
即可。原型是
scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, **kw)
调用文档状态curve_fit()
,目标函数作为第一个参数,独立变量作为第二个参数,因变量作为第三个参数,参数的起始值作为第四个参数论点。您试图以完全不同的方式调用该函数,因此它不起作用也就不足为奇了。具体来说,您将zn
作为p0
参数传递 - 这就是使用这么多参数调用函数的原因。
该文档还描述了如何调用目标函数:
f
:可调用的 模型函数f(x, ...)
。它必须将自变量作为第一个参数,并将参数作为单独的剩余参数。
xdata
:N
- 长度序列或(k,N)
形阵列 对于具有k个预测变量的函数。测量数据的自变量。
您尝试使用来分隔因变量的参数,而它应该是一个参数数组。这是修复的代码:
def func(x, a, b, c):
return a * np.exp(-b * (x[0] + x[1])) + c
N = 50
x = np.linspace(0,4,50)
x = numpy.array([x, x]) # Combine your `x` and `y` to a single
# (2, N)-array
z = func(x, 2.5, 1.3, 0.5)
zn = z + 0.2 * np.random.normal(size=x.shape[1])
popt, pcov = curve_fit(func, x, zn)
答案 1 :(得分:0)
尝试将前两个数组参数作为元组传递给func
并修改func
以接受参数元组
通常情况下,curvefit
会接受x和y参数func(x)
作为拟合曲线的输入。奇怪的是,在您的示例中,由于x参数不是单个值而是两个值(不确定原因),您必须修改函数,使其接受x
作为单个参数并在其中展开。
一般来说,三维曲线拟合应以与您尝试实现的方式不同的方式处理。您可以查看以下SO帖子,该帖子尝试使用线条拟合三维散点图。
>>> def func((x,y), a, b, c):
return a*np.exp(-b*(x+y)) + c
>>> y= x = np.linspace(0,4,50)
>>> z = func((x,y), 2.5, 1.3, 0.5) #works ok
>>> zn = z + 0.2*np.random.normal(size=len(x))
>>> popt, pcov = curve_fit(func, (x,y), zn)