用Python拟合总和 [英] Fitting a sum to data in 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
andY
of measurements to fit to, the 1d arraysR0
andS0
as initial guesses andN
the 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 ordinarydef ...
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 manyx
(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 suppliesx
, nor does it compare it toy
. Those are directly bound into the objective function.
这篇关于用Python拟合总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!