当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python SciPy optimize.curve_fit用法及代码示例


本文简要介绍 python 语言中 scipy.optimize.curve_fit 的用法。

用法:

scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=None, bounds=(-inf, inf), method=None, jac=None, *, full_output=False, nan_policy=None, **kwargs)#

使用非线性最小二乘法将函数 f 拟合到数据。

假设 ydata = f(xdata, *params) + eps

参数

f 可调用的

模型函数 f(x, …)。它必须将自变量作为第一个参数,并将要拟合的参数作为单独的剩余参数。

xdata array_like

测量数据的自变量。对于具有 k 个预测变量的函数,通常应该是 M-length 序列或 (k,M) 形数组,并且如果每个元素是类似数组的对象,则每个元素都应该是 float 可转换的。

ydata array_like

依赖数据,一个长度为 M 的数组 - 名义上是 f(xdata, ...)

p0 数组,可选

参数的初始猜测(长度 N)。如果为 None,则初始值全部为 1(如果可以使用内省确定函数的参数数量,否则会引发 ValueError)。

sigma 无或标量或M-length序列或MxM数组,可选

确定不确定性数据.如果我们将残差定义为r = ydata - f(xdata, *popt), 那么解释西格玛取决于它的维数:

  • A scalar or 1-D sigma should contain values of standard deviations of errors in ydata. In this case, the optimized function is chisq = sum((r / sigma) ** 2).

  • A 2-D sigma should contain the covariance matrix of errors in ydata. In this case, the optimized function is chisq = r.T @ inv(sigma) @ r.

无(默认)等效于用 1 填充的一维 sigma。

absolute_sigma 布尔型,可选

如果为 True,则以绝对意义使用 sigma,估计的参数协方差 pcov 反映了这些绝对值。

如果为 False(默认),则只有西格玛值很重要。返回的参数协方差矩阵pcov基于缩放西格玛由一个常数因子。这个常数是通过要求减少的奇斯克为最优参数流行音乐使用时缩放 西格玛等于统一。换一种说法,西格玛被缩放以匹配拟合后残差的样本方差。默认为假。数学上,pcov(absolute_sigma=False) = pcov(absolute_sigma=True) * chisq(popt)/(M-N)

check_finite 布尔型,可选

如果为 True,则检查输入数组是否不包含 infs 的 nan,如果包含,则引发 ValueError。如果输入数组确实包含 nan,则将此参数设置为 False 可能会默默地产生无意义的结果。如果未明确指定nan_policy,则默认值为 True,否则为 False。

bounds 数组 或 Bounds 的 2 元组,可选

参数的下限和上限。默认为无限制。有两种方法可以指定边界:

  • Instance of Bounds class.

  • 2-tuple of array_like: Each element of the tuple must be either an array with the length equal to the number of parameters, or a scalar (in which case the bound is taken to be the same for all parameters). Use np.inf with an appropriate sign to disable bounds on all or some parameters.

method {‘lm’, ‘trf’, ‘dogbox’},可选

用于优化的方法。看scipy.optimize.least_squares更多细节。对于无约束问题,默认值为 ‘lm’,如果为 ‘trf’界限提供。当观测值数量小于变量数量时,‘lm’ 方法将不起作用,在这种情况下使用‘trf’ 或‘dogbox’。

jac 可调用,字符串或无,可选

带签名的函数jac(x, ...)它将模型函数关于参数的雅可比矩阵计算为密集的类数组结构。它将根据提供的缩放西格玛。如果无(默认),将以数字方式估计雅可比行列式。 ‘trf’ 和 ‘dogbox’ 方法的字符串关键字可用于选择有限差分方案,请参阅scipy.optimize.least_squares.

full_output 布尔值,可选

如果为 True,此函数返回附加信息:infodict、mesg 和 ier。

nan_policy {‘raise’, ‘omit’,无},可选

定义当输入包含 nan 时如何处理。可以使用以下选项(默认为“无”):

  • ‘raise’: throws an error

  • ‘omit’: performs the calculations ignoring nan values

  • None: no special handling of NaNs is performed (except what is done by check_finite); the behavior when NaNs are present is implementation-dependent and may change.

请注意,如果显式指定该值(而不是“无”),check_finite将被设置为 False。

**kwargs

关键字参数传递给 leastsq 用于 method='lm' least_squares 否则。

返回

popt 数组

参数的最佳值,使f(xdata, *popt) - ydata 的残差平方和最小化。

pcov 二维阵列

popt 的估计近似协方差。对角线提供参数估计的方差。要计算参数的一个标准差误差,请使用perr = np.sqrt(np.diag(pcov))。注意之间的关系冠状病毒参数误差估计是基于模型函数围绕最优值的线性近似得出的[1]。当这种近似变得不准确时,冠状病毒可能无法提供准确的不确定性测量。

如上所述,sigma 参数如何影响估计的协方差取决于 absolute_sigma 参数。

如果解中的雅可比矩阵没有满秩,则 ‘lm’ 方法返回一个用 np.inf 填充的矩阵,另一方面 ‘trf’ 和 ‘dogbox’ 方法使用 Moore-Penrose 伪逆来计算协方差矩阵。具有较大条件数的协方差矩阵(例如使用 numpy.linalg.cond 计算)可能表明结果不可靠。

infodict dict(仅在full_output是真的)

带有键的可选输出字典:

nfev

函数调用的次数。与‘lm’ 方法相反,方法‘trf’ 和‘dogbox’ 不计算数值雅可比近似值的函数调用。

fvec

对于一维,在解中评估的残差值西格玛这是(f(x, *popt) - ydata)/sigma.

fjac

最终近似雅可比矩阵的 QR 分解的 R 矩阵的排列,按列存储。与 ipvt 一起,可以近似估计估计的协方差。方法‘lm’ 仅提供此信息。

ipvt

一个长度为 N 的整数数组,它定义了一个置换矩阵 p,使得 fjac*p = q*r,其中 r 是具有非递增大小的对角线元素的上三角形。 p 的 j 列是单位矩阵的 ipvt(j) 列。方法‘lm’ 仅提供此信息。

qtf

向量 (transpose(q) * fvec)。方法‘lm’ 仅提供此信息。

mesg str (仅在full_output是真的)

提供有关解决方案信息的字符串消息。

ier int(仅在以下情况下返回full_output是真的)

一个整数标志。如果它等于 1、2、3 或 4,则找到了解决方案。否则,找不到解决方案。在任何一种情况下,可选的输出变量 mesg 都会提供更多信息。

抛出

ValueError

如果 ydata 或 xdata 包含 NaN,或者使用了不兼容的选项。

RuntimeError

如果最小二乘最小化失败。

OptimizeWarning

如果无法估计参数的协方差。

注意

用户应确保输入扩展数据,数据,以及输出ffloat64,否则优化可能会返回不正确的结果。

对于 method='lm' ,该算法通过 leastsq 使用 Levenberg-Marquardt 算法。请注意,该算法只能处理无约束问题。

框约束可以通过方法‘trf’和‘dogbox’处理。有关更多信息,请参阅 least_squares 的文档字符串。

参考

[1] K.Vugrin 等人。非线性置信区域估计技术

地下水流回归:三个案例研究。水资源研究,卷。 43、W03423、DOI:10.1029/2005WR004804

例子

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.optimize import curve_fit
>>> def func(x, a, b, c):
...     return a * np.exp(-b * x) + c

定义要适应一些噪声的数据:

>>> xdata = np.linspace(0, 4, 50)
>>> y = func(xdata, 2.5, 1.3, 0.5)
>>> rng = np.random.default_rng()
>>> y_noise = 0.2 * rng.normal(size=xdata.size)
>>> ydata = y + y_noise
>>> plt.plot(xdata, ydata, 'b-', label='data')

拟合函数 func 的参数 a、b、c:

>>> popt, pcov = curve_fit(func, xdata, ydata)
>>> popt
array([2.56274217, 1.37268521, 0.47427475])
>>> plt.plot(xdata, func(xdata, *popt), 'r-',
...          label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

将优化限制在 0 <= a <= 30 <= b <= 10 <= c <= 0.5 的区域:

>>> popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 1., 0.5]))
>>> popt
array([2.43736712, 1.        , 0.34463856])
>>> plt.plot(xdata, func(xdata, *popt), 'g--',
...          label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
>>> plt.xlabel('x')
>>> plt.ylabel('y')
>>> plt.legend()
>>> plt.show()
scipy-optimize-curve_fit-1_00_00.png

为了获得可靠的结果,模型函数不应过度参数化;冗余参数可能导致协方差矩阵不可靠,并且在某些情况下,拟合质量较差。为了快速检查模型是否可能过度参数化,请计算协方差矩阵的条件数:

>>> np.linalg.cond(pcov)
34.571092161547405  # may vary

该值很小,因此不会引起太大关注。但是,如果我们要添加第四个参数d函数效果与a

>>> def func(x, a, b, c, d):
...     return a * d * np.exp(-b * x) + c  # a and d are redundant
>>> popt, pcov = curve_fit(func, xdata, ydata)
>>> np.linalg.cond(pcov)
1.13250718925596e+32  # may vary

如此大的数值令人担忧。协方差矩阵的对角线元素与拟合的不确定性相关,提供了更多信息:

>>> np.diag(pcov)
array([1.48814742e+29, 3.78596560e-02, 5.39253738e-03, 2.76417220e+28])  # may vary

请注意,第一项和最后一项比其他元素大得多,这表明这些参数的最佳值不明确,并且模型中只需要其中一个参数。

相关用法


注:本文由纯净天空筛选整理自scipy.org大神的英文原创作品 scipy.optimize.curve_fit。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。