scipy.optimize.curvefit: Asymmetric error in fit

。_饼干妹妹 提交于 2019-12-18 08:57:26

问题


I try to fit a function to my data using scipy.optimize.curvefit.

Q=optimization.curve_fit(func,X,Y, x0,ERR)

and it works well.

However, now I am trying to use an asymmetric error and I have no idea how to do that - or even if it is possible.

By asymmetric error I mean that the error is not for example: 3+-0.5 but 3 +0.6 -0.2. So that ERR is an array with two columns.

It would be great if somebody had an idea how to do that - or could me point to a different Python routine which might be able to do it.

That a snippet of the code I am using - but I am not sure it makes it clearer:

A=numpy.genfromtxt('WF.dat')
cc=A[:,4]
def func(A,a1,b1,c1):
    N=numpy.zeros(len(x))
    for i in range(len(x)):
        N[i]=1.0*erf(a1*(A[i,1]-c1*A[i,0]**b1))

return N


x0   = numpy.array([2.5  , -0.07 ,-5.0])
Q=optimization.curve_fit(func,A,cc, x0, Error)

And Error=[ErP,ErM] (2 columns)


回答1:


Least squares algorithm like curve_fit or scipy.optimize.leastsq will not be able to do this because the loss function is quadratic, and so symmetric for positive and negative error.

I haven't seen any models for this and maybe PAIDA can handle it, as DanHickstein mentioned.

Otherwise, you could use the nonlinear optimizers like optimize.fmin and construct your own asymmetric loss function.

def loss_function(params, ...):
    error = (y - func(x, params))
    error_neg = (error < 0)
    error_squared = error**2 / (error_neg * sigma_low + (1 - error_neg) * sigma_upp))
    return error_squared.sum()

and minimize this with fmin or fmin_bfgs.

(I never tried this.)




回答2:


In the current version, I am afraid it is not doable. curve_fit is a wrap around the popular Fortran library minipack. Check the source code of \scipy_install_path\optimize\minipack.py, you will see: (line 498-509):

if sigma is None:
    func = _general_function
else:
    func = _weighted_general_function
    args += (1.0/asarray(sigma),)

Basically what it means is that of sigma is not provided, then the unweighted Levenberg-Marquardt method in minipack will be called. If sigma is provided, then the weighted LM will be called. That implies, if sigma is to be provided, it must be provided as a array of the same length of X or Y.

That means if you want to have asymmetric error residue on Y, you have to come up with some modification to your target function, as @Jaime suggested.




回答3:


I'm not 100% sure, but it looks like the PAIDA package might do fits with asymmetric errors:

http://paida.sourceforge.net/documentation/fitter/index.html




回答4:


A solution, which I've used frequently, is to draw realisations (say 100-1000) from a split-normal distribution, and run your fitting algorithm on each of these realisations with the error set to 0.0. You'll then have 100-1000 best-fitting parameters, from which you can simply take the median, along with any error estimate you want to use.



来源:https://stackoverflow.com/questions/19116519/scipy-optimize-curvefit-asymmetric-error-in-fit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!