将参数传递给一个用于拟合的函数

3

我正在尝试拟合一个函数,该函数以两个独立变量x和y以及三个待定参数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!!!!!

但是我遇到了错误:"func()接受了5个精确的参数,但给出了51个"。如何正确地传递我的参数x和y?

curve_fit 的文档对 func 参数有何说明?显然它试图使用 51 个参数调用它,所以您可能应该重新阅读文档。 - Wes
2个回答

7
看一眼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)

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接