Чому б не використати «звичайні рівняння», щоб знайти прості найменші коефіцієнти квадратів?


17

Я побачив цей список тут і не міг повірити, що існує стільки способів вирішити найменші квадрати. «Нормальні рівняння» на Вікіпедії , здавалося, досить прямим

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

То чому б просто не використовувати їх? Я припускав, що має виникнути обчислювальна чи точна проблема, враховуючи, що в першому посиланні вище Марка Л. Стоун згадується, що SVD або QR є популярними методами в статистичному програмному забезпеченні і що нормальні рівняння є "ГОЛОВНІ з точки зору надійності та чисельної точності". Однак у наступному коді звичайні рівняння дають мені точність до 12 знаків після коми, порівняно з трьома популярними функціями пітона: polyfit numpy ; SciPy в linregress ; та лінійна регресія scikit- learn .

Що цікавіше, що звичайний метод рівняння є найшвидшим, коли n = 100000000. Для мене обчислювальні періоди: 2,5s для прямого прогресу; 12,9 за поліфіт; 4.2s для LinearRegression; і 1,8s для нормального рівняння.

Код:

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. Якщо ви подивитеся на кілька тисяч коваріатів, це зміниться. По-друге, оскільки у вас є лише один коваріат, обмін даними - це те, що насправді займає багато часу в упакованих конкурентів (але це має масштабуватися лише лінійно, так що це не велика справа). Звичайне рішення рівнянь не виконує обмін даними, тому воно швидше, але не має дзвінків, що додаються за його результатами.
Кліф АВ

Відповіді:


23

AxbAАТАлог10(cонг)АТААТАх=АТблог10(cонг(АТА))=2лог10(cонг(А))

1081016

Іноді ти йдеш із рівняннями Normal, а іноді - ні.


2
Найпростіший спосіб побачити це (якщо ви не знаєте / не цікавитеся номерами умов) - це те, що ви (по суті) множите щось щось на себе ("квадратизуючи"), це означає, що ви можете розраховувати втратити приблизно половину своїх шматочків точність. (Це має бути більш очевидним, якщо A скалярний, і слід легко зрозуміти, що створення матриці насправді не змінює основної проблеми.)
user541686,

Окрім відмінностей у точності, чи існує велика різниця швидкостей між QR та нормальними рівняннями? тому що в останньому випадку ви можете вирішити (X'X) -1 * X'Y, що повільно через зворотне? Я запитую, тому що я не впевнений, як працює QR, тому, можливо, є щось таке, що так само повільно, як перевернення матриці. Або єдиний момент врахування втрати точності?
Саймон

4
@Simon Що ж, коли ти розв'язуєш нормальні рівняння, ти фактично ніколи не формуєш зворотну матрицю, яка занадто повільна. Вам потрібно сформувати матрицюАТА і вектор АТбхоча, і тоді ви вирішите систему.
Мураха

8

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

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


0

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

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

Навіщо використовувати градієнтний спуск для лінійної регресії, коли доступний математичний розчин закритої форми?

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.