将总和拟合到 Python 中的数据

Fitting a sum to data in Python

鉴于拟合函数的类型:

我打算将这样的函数拟合到我拥有的实验数据 (x,y=f(x)) 中。但是后来我有些疑惑:

感觉有点迷茫,感谢大家的帮助。

为了使用scipy.optimize.leastsq估计多个参数,您需要将它们打包到一个数组中并在您的函数中解包。然后你可以用它们做任何你想做的事。例如,如果您的 s_i 是数组 p 中的前 3 个,而您的 r_i 是接下来的三个参数,您只需设置 ssum=p[:3].sum()rsum=p[3:6].sum() .但是同样,你的参数没有被识别(根据你的评论),所以估计是没有意义的。

有关使用 leastsq 的示例,请参阅 Cookbook 的 Fitting Data example

这在 scipy.optimize.curve_fit(或只是 scipy.optimize.leastsqr)的范围内非常好。涉及总和的事实根本不重要,也不重要的是你有参数数组。唯一需要注意的是,curve_fit 想要将参数作为单独的参数提供给拟合函数,而 leastsqr 给出单个向量。

这是一个解决方案:

import numpy as np
from scipy.optimize import curve_fit, leastsq

def f(x,r,s):
    """ The fit function, applied to every x_k for the vectors r_i and s_i. """
    x = x[...,np.newaxis]  # add an axis for the summation
    # by virtue of numpy's fantastic broadcasting rules,
    # the following will be evaluated for every combination of k and i.
    x2s2 = (x*s)**2
    return np.sum(r * x2s2 / (1 + x2s2), axis=-1)

# fit using curve_fit
popt,pcov = curve_fit(
    lambda x,*params: f(x,params[:N],params[N:]),
    X,Y,
    np.r_[R0,S0],
)
R = popt[:N]
S = popt[N:]

# fit using leastsq
popt,ier = leastsq(
    lambda params: f(X,params[:N],params[N:]) - Y,
    np.r_[R0,S0],
)
R = popt[:N]
S = popt[N:]

注意几点:

  • 开始时,我们需要一维数组 XY 的测量值,一维数组 R0S0 作为初始猜测和 N这两个数组的长度。
  • 我将实际模型 f 的实现与提供给安装人员的 objective 函数分开。我使用 lambda 函数实现的那些。当然也可以把普通的def ...功能合二为一
  • 模型函数f使用numpy的广播同时对一组参数求和(沿着最后一个轴),并并行计算许多x(沿着最后一个之前的任何轴,尽管如果有多个 fit 函数都会抱怨... .ravel() 帮助那里)
  • 我们使用 numpy 的 shorthand np.r_[R,S].
  • 将拟合参数 R 和 S 连接成一个参数向量
  • curve_fit 将每个参数作为不同的参数提供给 objective 函数。我们希望它们作为向量,所以我们使用 *params:它将所有剩余参数捕获在一个列表中。
  • leastsq 给出单个参数向量。但是,它既不提供 x,也不与 y 进行比较。这些直接绑定到 objective 函数中。