Линейная регрессия с почти сингулярной инверсией матрицы

У меня есть проблема регрессии, чтобы оценить наклон y = a*x+b, и я попробовал два разных метода для a. Метод 1 оценивает среднее значение двух кластеров данных как две точки, на основе которых вычисляется a. Метод 2 использует стандартное уравнение регрессии.

import numpy as np
import statistics

# find the slope a of y = a*x + b
x = "28.693756 28.850006 28.662506 28.693756 28.756256 28.662506 28.787506 \
    28.818756 28.818756 28.787506 28.787506 28.787506 28.693756 28.787506 \
    28.818756 28.725006 28.725006 28.850006 28.756256 28.725006 28.881256 \
    28.818756 28.756256 28.693756 28.756256 28.787506 28.693756 28.662506 \
    28.662506 28.787506 28.850006 28.756256 28.725006 28.818756 28.600006 \
    28.725006 28.725006 28.850006 28.881256 28.881256 28.818756 28.756256 \
    28.756256 28.787506 28.787506 28.787506 28.756256 28.787506 28.725006 \
    28.725006 28.725006 28.756256 28.818756 28.756256 28.693756 28.818756 \
    28.756256 28.756256 28.693756 28.850006 28.631256 28.693756 28.693756 \
    28.850006 28.756256 28.725006 28.693756 28.756256 28.850006 28.787506 \
    28.600006 28.631256"
x = [float(t) for t in x.split()]
y = [33.8]*36 + [38.7]*36

print(" ")
print("Method 1 ")
x1, x2 = statistics.mean(x[:36]), statistics.mean(x[36:])
y1, y2 = statistics.mean(y[:36]), statistics.mean(y[36:])
slope = (y1-y2)/(x1-x2)
print(f"a = {slope}")

print(" ")
print('Method 2')
x = np.array(x)
y = np.array(y)
X = np.c_[np.ones(x.shape), x]

XXinv = np.linalg.inv(X.transpose().dot(X)).dot(X.transpose())
_beta = XXinv.dot(y)
iv = np.linalg.inv(X.transpose().dot(X)).tolist()
print(f"a = {_beta[1]}")

xx = X.transpose().dot(X)
svd = np.linalg.svd(xx)[1]
print(f"SVD(XX) = {svd}")

Результаты кода:

Method 1
a = 1128.9599999997959

Method 2
a = 1.2136744782028899
SVD(XX) = [5.96125150e+04 3.80959618e-04]

Судя по графикам данных, линия должна быть близка к вертикальной линейной, и результат метода 1 имеет больше смысла, чем метод 2. Кроме того, даже линия с наименьшим наклоном данных (показана на рисунке) имеет наклон 17,5. Для обычных случаев хорошо работает метод 2. Однако в этом случае это дает такой небольшой наклон 1,21, что не имеет смысла.

введите здесь описание изображения

Единственная причина, на которую я могу ссылаться, — это почти сингулярность, как показано в значениях SVD. Но почему? или какое-то исправление?


person Ken S    schedule 10.12.2020    source источник


Ответы (1)


Ваша система линейных уравнений переопределена (уравнений больше, чем неизвестных), поэтому точных решений нет. Решение метода 2 лучше всего подходит для минимизации квадратов ошибок между прогнозами и фактическими значениями.

Линия, полученная с решением 1, визуально выглядит лучше, но с математической точки зрения не минимизирует квадраты ошибок. Причина в том, что некоторые точки (например, 28,600006, 38,7) очень далеки от прогнозируемой линии, и эта ошибка при возведении в квадрат значительно повлияет на сумму квадратов ошибок (SSE), которую регрессия пытается минимизировать.

И наоборот, подбирая линию посередине с наклоном 1,21367, регрессия позволяет избежать очень больших ошибок и дает ошибки среднего размера, которые при возведении в квадрат минимизируют SSE. Однако с визуальной точки зрения полученная линия не соответствует точкам данных, а также решению 1.

person David M.    schedule 20.12.2020
comment
Спасибо за ответ. Ваша точка зрения SSE, основанная на dy, решает мои проблемы. Я забыл, что регрессия сводила к минимуму SSE dy. Теперь я также знаю решение моей проблемы: использовать расстояние до линии как ошибку вместо использования dy. Это может быть хорошим вариантом для всех задач линейной регрессии, чтобы обрабатывать единичные или близкие к единичным случаи. - person Ken S; 21.12.2020
comment
Да, в этом случае ортогональная дистанционная регрессия даст лучшие результаты. - person David M.; 22.12.2020