问题
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