minimos - regresion lineal python paso a paso
Ajuste de regresión ortogonal en el método scipy de mínimos cuadrados (3)
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)
Pero, ¿y si necesito calcular la distancia mínima en ambos ejes (dy y dx)?
¿Hay alguna forma de implementar este cálculo?
Aquí hay una muestra de código cuando se usa un cálculo de 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 probé la biblioteca scipy.odr y devuelve los resultados adecuados solo para la función lineal. Para otras funciones como y = a * x ^ b, devuelve resultados incorrectos. Así es como 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 arroja resultados incorrectos, no deseados, y en algunos datos de entrada ni siquiera cerca de lo real. Puede ser, hay algunas formas especiales de usarlo, ¿qué hago mal?
Si / cuando puede invertir la función descrita por p, puede incluir x-pinverted (y) en mFunc, supongo que como sqrt (a ^ 2 + b ^ 2), entonces (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 pides es en algunos casos problemático. 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.
scipy.odr
implementa regresión de distancia ortogonal. Vea las instrucciones para uso básico en la docstring:
https://github.com/scipy/scipy/blob/master/scipy/odr/odrpack.py#L27
Encontré 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: encuentra la conjetura inicial usando el método de ordination de mínimos cuadrados.
Segundo paso: sustituya esta suposición inicial en ODR como parámetro beta0.
Y funciona muy bien con una velocidad aceptable.
Gracias amigos, su consejo me dirigió a la solución correcta