Por que não usar as "equações normais" para encontrar coeficientes simples de mínimos quadrados?

17

Eu vi essa lista aqui e não podia acreditar que havia tantas maneiras de resolver mínimos quadrados. As "equações normais" na Wikipedia pareciam ser um caminho bastante direto:

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

Então, por que não usá-los? Eu assumi que deve haver um problema computacional ou de precisão, dado que no primeiro link acima, Mark L. Stone menciona que SVD ou QR são métodos populares em software estatístico e que as equações normais são "TERRÍVEIS do ponto de vista da confiabilidade e da precisão numérica". No entanto , no código a seguir, as equações normais estão fornecendo precisão de ~ 12 casas decimais quando comparadas a três funções populares do python: polyfit do numpy ; vestido de linha de scipy ; e a LinearRegression do scikit -learn .

O mais interessante é que o método da equação normal é o mais rápido quando n = 100000000. Os tempos computacionais para mim são: 2,5s para regressão linear; 12.9s para polyfit; 4.2s para regressão linear; e 1,8s para a equação 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
fonte
As respostas são bastante exageradas. Não é tão horrível se você apenas evitar calcular explicitamente o inverso.
mathreadler
3
Algumas notas sobre velocidade: você está apenas olhando para uma única covariável, portanto o custo da inversão da matriz é essencialmente 0. Se você observar alguns milhares de covariáveis, isso mudará. Segundo, como você tem apenas uma única covariável, a troca de dados é o que realmente leva muito tempo nos concorrentes empacotados (mas isso deve ser dimensionado apenas linearmente, portanto não é grande coisa). A solução de equações normais não faz a troca de dados, por isso é mais rápida, mas não possui sinos e assobios associados aos seus resultados.
Cliff AB

Respostas:

22

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

1081016

Às vezes você se safa das equações normais e às vezes não.

Mark L. Stone
fonte
2
Uma maneira mais simples de vê-lo (se você não conhece / se importa com os números de condição) é que você está (essencialmente) multiplicando algo por si só ("esquadrinhando-o"), o que significa que você pode esperar perder cerca de metade dos seus bits de precisão. (Isto deve ser mais óbvio, se A é um escalar, e ele deve ser fácil ver que fazendo uma matriz realmente não muda o problema subjacente.)
Mehrdad
Além das diferenças de precisão, há também uma grande diferença de velocidade entre o QR e as equações normais? porque neste último caso você pode resolver (X'X) -1 * X'Y, o que é lento por causa do inverso? Eu pergunto porque não tenho certeza de como o QR funciona, então talvez haja algo lá que seja tão lento quanto inverter uma matriz. Ou o único ponto de consideração é a perda de precisão?
Simon
4
ATAATb
8

Se você apenas tiver que resolver esse problema de uma variável, vá em frente e use a fórmula. Não há nada errado com isso. Pude ver você escrevendo algumas linhas de código no ASM para um dispositivo incorporado, por exemplo. De fato, usei esse tipo de solução em algumas situações. Você não precisa arrastar grandes bibliotecas estatísticas apenas para resolver esse pequeno problema, é claro.

A instabilidade e desempenho numéricos são questões de problemas maiores e de configuração geral. Se você resolver mínimos quadrados multivariados, etc. Para um problema geral, você não usaria isso, é claro.

Aksakal
fonte
0

Nenhum pacote estatístico moderno resolveria uma regressão linear com as equações normais. As equações normais existem apenas nos livros estatísticos.

As equações normais não devem ser usadas, pois calcular o inverso da matriz é muito problemático.

Por que usar descida de gradiente para regressão linear, quando uma solução matemática em formato fechado está disponível?

... embora a equação normal direta esteja disponível. Observe que na equação normal é preciso inverter uma matriz. Agora, inverter uma matriz custa O (N3) para o cálculo, onde N é o número de linhas na matriz X, ou seja, as observações. Além disso, se o X estiver mal condicionado, ele criará erros computacionais na estimativa ...

SmallChess
fonte