scipy.optimize.curvefit: error asimétrico de ajuste

Intento ajustar una función a mis datos usando scipy.optimize.curvefit .

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

y funciona bien.

Sin embargo, ahora estoy intentando usar un error asimétrico y no tengo idea de cómo hacerlo, o incluso si es posible.

Por error asimétrico quiero decir que el error no es por ejemplo: 3+-0.5 sino 3 +0.6 -0.2 . De modo que ERR es una matriz con dos columnas.

Sería genial si alguien tuviera una idea de cómo hacerlo, o podría señalar una rutina diferente de Python que pudiera hacerlo.

Eso es un fragmento del código que estoy usando, pero no estoy seguro de que lo aclare:

 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) 

Y Error = [ErP, ErM] (2 columnas)

El algoritmo de mínimos cuadrados como curve_fit o scipy.optimize.leastsq no podrá hacer esto porque la función de pérdida es cuadrática, por lo que es simétrica para el error positivo y negativo.

No he visto ningún modelo para esto y quizás PAIDA pueda manejarlo, como lo mencionó DanHickstein.

De lo contrario, podría usar los optimizadores no lineales como optimize.fmin y construir su propia función de pérdida asimétrica.

 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() 

y minimiza esto con fmin_bfgs o fmin_bfgs .

(Nunca intenté esto).

En la versión actual, me temo que no es factible. curve_fit es una envoltura alrededor de la popular minipack biblioteca Fortran. Verifique el código fuente de \scipy_install_path\optimize\minipack.py , verá: (línea 498-509):

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

Básicamente, lo que significa es que no se proporciona sigma , entonces se minipack método no ponderado de Levenberg-Marquardt en el minipack . Si se proporciona sigma , se llamará al LM ponderado. Eso implica que, si se va a proporcionar sigma , se debe proporcionar como una matriz de la misma longitud de X o Y

Eso significa que si desea tener un residuo de error asimétrico en Y , tiene que encontrar alguna modificación en su función de destino, como sugirió @Jaime.

No estoy 100% seguro, pero parece que el paquete PAIDA podría ajustarse a los errores asimétricos:

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

Una solución, que he usado con frecuencia, es extraer realizaciones (por ejemplo, 100-1000) de una distribución dividida-normal, y ejecutar su algoritmo de adaptación en cada una de estas realizaciones con el error establecido en 0.0. Luego tendrá 100-1000 parámetros de mejor ajuste, de los cuales simplemente puede tomar la mediana, junto con cualquier estimación de error que desee utilizar.