用Python拟合总和 [英] Fitting a sum to data in Python

查看:92
本文介绍了用Python拟合总和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于拟合函数的类型为:

Given that the fitting function is of type:

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

I intend to fit such function to the experimental data (x,y=f(x)) that I have. But then I have some doubts:


  • 当涉及求和时,如何定义拟合函数?

  • How do I define my fitting function when there's a summation involved?

一旦定义了函数,即 def func(..)return ... 是否仍然可以使用从scipy.optimize?因为与通常的只有一个参数很少的拟合情况相比,现在有一组参数s_i和r_i涉及。

Once the function defined, i.e. def func(..) return ... is it still possible to use curve_fit from scipy.optimize? Because now there's a set of parameters s_i and r_i involved compared to the usual fitting cases where one has few single parameters.

最后,这样的情况被完全不同地对待吗?

Finally are such cases treated completely differently?

这里有点迷失了,谢谢您的帮助。

Feel a bit lost here, thanks for any help.

推荐答案

这非常容易达到 scipy.optimize.curve_fit (或者只是 scipy.optimize .leastsqr )。涉及总和的事实根本没有关系,也没有参数数组。唯一需要注意的是, curve_fit 希望为fit函数提供参数作为单独的参数,而 leastsqr 给出一个单个向量。

This is very well within reach of scipy.optimize.curve_fit (or just scipy.optimize.leastsqr). The fact that a sum is involved does not matter at all, nor that you have arrays of parameters. The only thing to note is that curve_fit wants to give your fit function the parameters as individual arguments, while leastsqr gives a single vector.

这里是一个解决方案:

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:]

一些注意事项:


  • 开始时,我们需要一维数组 X Y 的尺寸适合一维数组 R0 S0 作为初始猜测,而 N 这两个数组的长度。

  • 我分离了实际模型的实现 f 来自提供给钳工的目标函数。我使用lambda函数实现的代码。当然,也可以具有普通的 def ... 函数并将其组合为一个。

  • 模型函数 f 使用numpy的广播同时对一组参数(沿最后一个轴)求和,并为许多 x (沿最后一个轴之前的任何轴,但是如果有多个轴,则这两个拟合函数都会抱怨... .ravel()在那里帮助

  • 我们使用numpy的速记 np.r_ [R,S] 将拟合参数R和S连接到单个参数向量中。

  • curve_fit 将每个参数作为目标函数的不同参数提供。我们希望将它们作为向量,因此我们使用 * params :它将所有剩余的参数捕获到一个列表中。

  • leastsq 给出单个参数向量。但是,它既不提供 x ,也不将其与 y 进行比较。这些直接绑定到目标函数中。

  • Upon start, we need the 1d arrays X and Y of measurements to fit to, the 1d arrays R0 and S0 as initial guesses and Nthe length of those two arrays.
  • I separated the implementation of the actual model f from the objective functions supplied to the fitters. Those I implemented using lambda functions. Of course, one could also have ordinary def ... functions and combine them into one.
  • The model function f uses numpy's broadcasting to simultaneously sum over a set of parameters (along the last axis), and calculate in parallel for many x (along any axes before the last, though both fit functions would complain if there is more than one... .ravel() to help there)
  • We concatenate the fit parameters R and S into a single parameter vector using numpy's shorthand np.r_[R,S].
  • curve_fit supplies every single parameter as a distinct parameter to the objective function. We want them as a vector, so we use *params: It catches all remaining parameters in a single list.
  • leastsq gives a single params vector. However, it neither supplies x, nor does it compare it to y. Those are directly bound into the objective function.

这篇关于用Python拟合总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆