Почему бы не использовать «нормальные уравнения», чтобы найти простые коэффициенты наименьших квадратов?

17

Я видел этот список здесь и не мог поверить, что было так много способов решить наименьших квадратов. «Нормальные уравнения» на Википедии , казалось, довольно прямым

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

Так почему бы просто не использовать их? Я предположил, что должна быть проблема с вычислениями или точностью, учитывая, что в первой ссылке выше Марк Л. Стоун упоминает, что SVD или QR являются популярными методами в статистическом программном обеспечении и что нормальные уравнения «УЖАСНЫ с точки зрения надежности и численной точности». Однако в следующем коде нормальные уравнения дают мне точность ~ 12 десятичных знаков по сравнению с тремя популярными функциями python: полифит numpy ; регресс Сципи ; и scikit-Learn LinearRegression .

Что еще интереснее, метод нормальных уравнений самый быстрый, когда n = 100000000. Время вычислений для меня: 2,5 с для линейного хода; 12,9 с для полифита; 4.2s для LinearRegression; и 1,8 с для нормального уравнения.

Код:

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) 
Оливер Анжелил
источник
Ответы довольно преувеличены. Это не так ужасно, если вы просто избегаете явного вычисления обратного.
mathreadler
3
Несколько замечаний по скорости: вы смотрите только на один ковариат, поэтому стоимость инверсии матрицы по существу равна 0. Если вы посмотрите на несколько тысяч ковариат, это изменится. Во-вторых, поскольку у вас есть только одна ковариата, объединение данных - это то, что на самом деле отнимает много времени у упакованных конкурентов (но это должно масштабироваться только линейно, поэтому не имеет большого значения). Решение для нормальных уравнений не выполняет манипулирование данными, поэтому оно быстрее, но не имеет никаких наворотов, связанных с его результатами.
Клифф А.Б.

Ответы:

22

AxbAATAlog10(cоNd)ATAATAx=ATblog10(cond(ATA))=2log10(cond(A))

1081016

Иногда вам не хватает нормальных уравнений, а иногда нет.

Марк Л. Стоун
источник
2
Более простой способ увидеть это (если вы не знаете / не заботитесь о числах условий) - это то, что вы (по существу) что-то умножаете сами («возводя в квадрат»), то есть вы можете ожидать потерять около половины своих битов. точность. (Это должно быть более очевидно, если A - скаляр, и должно быть легко увидеть, что создание матрицы A на самом деле не меняет основной проблемы.)
user541686
Помимо различий в точности, есть ли большая разница в скорости между QR и нормальными уравнениями? потому что в последнем случае вы можете решить (X'X) -1 * X'Y, что медленно из-за обратного? Я спрашиваю, потому что я не уверен, как работает QR, так что, может быть, есть нечто такое же медленное, как инвертирование матрицы. Или единственной точкой рассмотрения является потеря точности?
Симон
4
ATAATб
8

Если вам нужно решить только эту проблему с одной переменной, то используйте формулу. В этом нет ничего плохого. Я мог видеть, как вы пишете несколько строк кода в ASM для встроенного устройства, например. На самом деле, я использовал такое решение в некоторых ситуациях. Конечно, вам не нужно перетаскивать большие статистические библиотеки, чтобы решить эту маленькую проблему.

Числовая нестабильность и производительность - это проблемы больших проблем и общей настройки. Если вы решаете многомерный метод наименьших квадратов и т. Д. Для общей проблемы вы, конечно, не будете использовать это.

Аксакал
источник
0

Ни один современный статистический пакет не решит линейную регрессию с помощью нормальных уравнений. Нормальные уравнения существуют только в статистических книгах.

Нормальные уравнения не должны использоваться, поскольку вычисление обратной матрицы очень проблематично.

Зачем использовать градиентный спуск для линейной регрессии, когда доступно математическое решение замкнутой формы?

... хотя прямое нормальное уравнение доступно. Обратите внимание, что в нормальном уравнении нужно инвертировать матрицу. Теперь инвертирование матрицы стоит O (N3) для вычислений, где N - количество строк в матрице X, т.е. наблюдений. Более того, если X плохо обусловлен, то это приведет к ошибкам вычислений в оценке ...

SmallChess
источник