¿Por qué no usar las "ecuaciones normales" para encontrar coeficientes de mínimos cuadrados simples?

17

Vi esta lista aquí y no podía creer que hubiera tantas formas de resolver mínimos cuadrados. Las "ecuaciones normales" en la Wikipedia parecían ser una forma bastante

α^=y¯β^x¯,β^=i=1n(xix¯)(yiy¯)i=1n(xix¯)2

Entonces, ¿por qué no solo usarlos? Supuse que debe haber un problema de cálculo o precisión dado que en el primer enlace anterior, Mark L. Stone menciona que SVD o QR son métodos populares en software estadístico y que las ecuaciones normales son "TERRIBLES desde el punto de vista de la fiabilidad y la precisión numérica". Sin embargo , en el siguiente código, las ecuaciones normales me dan una precisión de ~ 12 lugares decimales en comparación con tres funciones populares de python: polyfit de numpy ; linregress de scipy ; y scikit-learn de LinearRegression .

Lo que es más interesante es que el método de ecuación normal es el más rápido cuando n = 100000000. Los tiempos de cálculo para mí son: 2.5s para linregress; 12.9s para polyfit; 4.2s para la regresión lineal; y 1.8s para la ecuación normal.

Código:

import numpy as np
from sklearn.linear_model import LinearRegression
from scipy.stats import linregress
import timeit

b0 = 0
b1 = 1
n = 100000000
x = np.linspace(-5, 5, n)
np.random.seed(42)
e = np.random.randn(n)
y = b0 + b1*x + e

# scipy                                                                                                                                     
start = timeit.default_timer()
print(str.format('{0:.30f}', linregress(x, y)[0]))
stop = timeit.default_timer()
print(stop - start)

# numpy                                                                                                                                      
start = timeit.default_timer()
print(str.format('{0:.30f}', np.polyfit(x, y, 1)[0]))
stop = timeit.default_timer()
print(stop - start)

# sklearn                                                                                                                                    
clf = LinearRegression()
start = timeit.default_timer()
clf.fit(x.reshape(-1, 1), y.reshape(-1, 1))
stop = timeit.default_timer()
print(str.format('{0:.30f}', clf.coef_[0, 0]))
print(stop - start)

# normal equation                                                                                                                            
start = timeit.default_timer()
slope = np.sum((x-x.mean())*(y-y.mean()))/np.sum((x-x.mean())**2)
stop = timeit.default_timer()
print(str.format('{0:.30f}', slope))
print(stop - start) 
Oliver Angelil
fuente
Las respuestas son bastante exageradas. No es tan horrible si evitas calcular explícitamente el inverso.
mathreadler
3
Algunas notas sobre la velocidad: solo está viendo una sola covariable, por lo que el costo de la inversión de la matriz es esencialmente 0. Si observa unos pocos miles de covariables, eso cambiará. En segundo lugar, debido a que solo tiene una sola covariable, la mezcla de datos es lo que realmente toma mucho tiempo en los competidores empaquetados (pero esto solo debería escalar linealmente, por lo que no es un gran problema). La solución de ecuaciones normales no combina datos, por lo que es más rápida, pero no tiene campanas y silbatos asociados con sus resultados.
Cliff AB

Respuestas:

22

AxbAATAlog10(cond)ATAATAx=ATblog10(cond(ATA))=2log10(cond(A))

1081016

A veces te sales con las ecuaciones normales, y a veces no.

Mark L. Stone
fuente
2
Una manera más simple de verlo (si no sabe / no le importan los números de condición) es que (esencialmente) está multiplicando algo por sí mismo ("cuadrándolo"), lo que significa que puede esperar perder aproximadamente la mitad de sus bits de precisión. (Esto debería ser más obvio si A es un escalar, y debería ser fácil ver que hacer que A sea una matriz realmente no cambia el problema subyacente)
User541686
Además de las diferencias de precisión, ¿existe también una gran diferencia de velocidad entre QR y ecuaciones normales? porque en el último caso podrías estar resolviendo (X'X) -1 * X'Y, que es lento debido a la inversa? Pregunto porque no estoy seguro de cómo funciona el QR, así que tal vez hay algo allí que es tan lento como invertir una matriz. ¿O es el único punto de consideración la pérdida de precisión?
Simon
44
ATAATb
8

Si solo tiene que resolver este problema variable, continúe y use la fórmula. No tiene nada de malo. Podría verte escribiendo algunas líneas de código en ASM para un dispositivo integrado, por ejemplo. De hecho, usé este tipo de solución en algunas situaciones. No es necesario arrastrar grandes bibliotecas estadísticas solo para resolver este pequeño problema, por supuesto.

La inestabilidad numérica y el rendimiento son cuestiones de problemas más grandes y de configuración general. Si resuelve mínimos cuadrados multivariados, etc. Para un problema general, no usaría esto, por supuesto.

Aksakal
fuente
0

Ningún paquete estadístico moderno resolvería una regresión lineal con las ecuaciones normales. Las ecuaciones normales existen solo en los libros de estadística.

Las ecuaciones normales no deberían usarse ya que calcular el inverso de la matriz es muy problemático.

¿Por qué usar el descenso de gradiente para la regresión lineal, cuando hay disponible una solución matemática de forma cerrada?

... aunque la ecuación normal directa está disponible. Observe que en la ecuación normal uno tiene que invertir una matriz. Ahora invertir una matriz cuesta O (N3) para el cálculo donde N es el número de filas en la matriz X, es decir, las observaciones. Además, si la X está mal condicionada, creará errores de cálculo en la estimación ...

SmallChess
fuente