具有近奇异矩阵求逆的线性回归
Linear regression with near singular matrix inversion
我有一个回归问题来估计 y = a*x+b
的斜率,并尝试了两种不同的方法来 a
。方法一将两个数据簇的均值估计为两个点,据此计算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 值中显示的近奇点。但为什么?或任何修复?
你的线性方程组是超定的(方程比未知数多)所以没有精确解。方法 2 的解决方案是“最佳拟合”,可最大限度地减少预测值与实际值之间的平方误差。
用解决方案 1 获得的一条线在视觉上似乎更合适,但从数学上讲,它并没有最小化平方误差。原因是某些点(例如 28.600006、38.7)与预测线相距甚远,并且此误差在平方时会显着影响误差平方和 (SSE),回归试图将其最小化。
相反,通过在“中间”拟合一条斜率为 1.21367 的线,回归可以避免非常大的错误并产生“中等大小”的错误,当平方时,最小化 SSE。但是,从视觉角度来看,生成的线似乎不适合数据点以及解决方案 1。
我有一个回归问题来估计 y = a*x+b
的斜率,并尝试了两种不同的方法来 a
。方法一将两个数据簇的均值估计为两个点,据此计算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 值中显示的近奇点。但为什么?或任何修复?
你的线性方程组是超定的(方程比未知数多)所以没有精确解。方法 2 的解决方案是“最佳拟合”,可最大限度地减少预测值与实际值之间的平方误差。
用解决方案 1 获得的一条线在视觉上似乎更合适,但从数学上讲,它并没有最小化平方误差。原因是某些点(例如 28.600006、38.7)与预测线相距甚远,并且此误差在平方时会显着影响误差平方和 (SSE),回归试图将其最小化。
相反,通过在“中间”拟合一条斜率为 1.21367 的线,回归可以避免非常大的错误并产生“中等大小”的错误,当平方时,最小化 SSE。但是,从视觉角度来看,生成的线似乎不适合数据点以及解决方案 1。