2012-02-21 39 views
12

El método leastsq en scipy lib ajusta una curva a algunos datos. Y este método implica que en estos datos, los valores Y dependen de algún argumento X. Y calcula la distancia mínima entre la curva y el punto de datos en el eje Y (dy)Ajuste de regresión ortogonal en el método scipy de mínimos cuadrados

Pero lo que si necesito para calcular la distancia mínima en ambos ejes (dy y dx)

¿Hay algunas maneras de implementar este ¿cálculo?

Este es un ejemplo de código cuando se utiliza un cálculo eje:

import numpy as np 
from scipy.optimize import leastsq 

xData = [some data...] 
yData = [some data...] 

def mFunc(p, x, y): 
    return y - (p[0]*x**p[1]) # is takes into account only y axis 

plsq, pcov = leastsq(mFunc, [1,1], args=(xData,yData)) 
print plsq 

recientemente He probado scipy.odr biblioteca y devuelve los resultados adecuados sólo para la función lineal. Para otras funciones como y = a * x^b, devuelve resultados incorrectos. Esta es la forma en que lo uso:

def f(p, x):  
    return p[0]*x**p[1] 

myModel = Model(f) 
myData = Data(xData, yData) 
myOdr = ODR(myData, myModel , beta0=[1,1]) 
myOdr.set_job(fit_type=0) #if set fit_type=2, returns the same as leastsq 
out = myOdr.run() 
out.pprint() 

Esto devuelve resultados erróneos, no deseados, y en algunos datos de entrada ni siquiera cerca de real. Puede ser, hay algunas formas especiales de usarlo, ¿qué hago mal?

+1

Scipy tiene un módulo de "ortogonal Distancia regresión" - que es lo que necesita? http://docs.scipy.org/doc/scipy/reference/odr.html –

+0

Sí, parece que resuelve este problema, pero cuando lo intento, devuelve el mismo resultado que el método leastsq. Seguí los ejemplos, que se proporcionan en la documentación, y no funciona según sea necesario. ¿Tienes algunos ejemplos de trabajo? – Vladimir

+0

Cuando lo probé, descubrí que los resultados eran similares, pero no idénticos; supuse que solo significaba que el cálculo extra no tenía mucha importancia para el ajuste. –

Respuesta

5

que he encontrado la solución. Scipy Odrpack funciona muy bien, pero necesita una buena estimación inicial para obtener resultados correctos. Entonces dividí el proceso en dos pasos.

Primer paso: encuentre la conjetura inicial utilizando el método de mínimos cuadrados ordinaty.

Segundo paso: sustituya esta suposición inicial en ODR como parámetro beta0.

Y funciona muy bien con una velocidad aceptable.

Gracias chicos, su consejo me dirigió a la solución correcta

+1

Sé que esta es una publicación anterior, pero podría publicar su fragmento de código aquí. Estoy tratando de hacer un ODR implícito, pero no estoy seguro de cómo configurarlo en scipy. – Barbarossa

+1

@Barbarossa Puede que le guste [este fragmento de código] (http://blog.rtwilson.com/orthogonal-distance-regression-in-python/). – gerrit

+0

@gerrit Gracias por la información. – Barbarossa

0

Si puede invertir la función descrita por p, puede incluir x-pinverted (y) en mFunc, supongo que como sqrt (a^2 + b^2), así (pseudo código)

return sqrt((y - (p[0]*x**p[1]))^2 + (x - (pinverted(y))^2) 

por ejemplo para

y=kx+m p=[m,k]  
pinv=[-m/k,1/k] 

return sqrt((y - (p[0]+x*p[1]))^2 + (x - (pinv[0]+y*pinv[1]))^2) 

Pero lo que solicita es en algunos casos problemáticos. Por ejemplo, si una curva polinomial (o tu x^j) tiene un ym mínimo en y (m) y tienes un punto x, y más bajo que ym, ¿qué tipo de valor quieres devolver? No siempre hay una solución.

+0

Si el punto x, y es menor que ym, entonces debe devolver la distancia miminal a ese ym. ** sqrt ((m-x)^2 + (ym-y)^2)/2 **. ¿Por qué esto es un problema? – Vladimir

+0

si tiene una función y = f (x) eso significa que para cualquier x hay un valor para y. Bot no siempre tiene un valor de x para cualquier entrada y. No todas las funciones son invertibles. por ejemplo y = x^2 y cualquier punto con x = -2 –

+0

oh, ahora veo, sí, tienes razón. Pero cómo algunos softwares crean esta adaptación de mínimos cuadrados (regresión de Deming) para cualquier función en cualquier dato de entrada. Debe haber alguna manera de hacerlo en python – Vladimir

6

scipy.odr implementa regresión de distancia ortogonal. Ver las instrucciones de uso básico en la cadena de documentación:

https://github.com/scipy/scipy/blob/master/scipy/odr/odrpack.py#L27

+0

oh, sí, lo probé, y funciona de la misma manera que leastsq, devuelve los mismos resultados – Vladimir

+4

¿Los mismos resultados exactos? Eso me parece poco probable. ¿Puedes actualizar tu publicación para mostrar un ejemplo ejecutable con 'scipy.odr' que te da resultados incorrectos? –

Cuestiones relacionadas