我有以下 X 和 y 矩阵:
我想使用正规方程方法计算线性回归方程的最佳 θ 值:
theta = inv(X^T * X) * X^T * y
theta 的结果应该是:[188.400,0.3866,-56.128,-92.967,-3.737]
我执行以下步骤:
X=np.matrix([[1,1,1,1],[2104,1416,1534,852],[5,3,3,2],[1,2,2,1],[45,41,30,36]])
y=np.matrix([460,232,315,178])
XT=np.transpose(X)
XTX=XT.dot(X)
inv=np.linalg.inv(XTX)
inv_XT=inv.dot(XT)
theta=inv_XT.dot(y)
print(theta)
但我没有得到想要的结果。相反,它会抛出错误:
回溯(最近一次调用最后一次):文件“C:/”,第 19 行,in theta=inv_XT.dot(y) ValueError:形状 (4,5) 和 (1,4) 未对齐:5 (dim 1) != 1 (dim 0)
我做错了什么?
我认为你把尺寸弄乱了一点。您的
X
实际上是 XT
,而 XT
是 X
。
试试这个:
In [163]: X=np.matrix([[1,1,1,1],[2104,1416,1534,852],[5,3,3,2],[1,2,2,1],[45,41,30,36]]).T
In [164]: y=np.matrix([460,232,315,178])
In [165]: X
Out[165]:
matrix([[ 1, 2104, 5, 1, 45],
[ 1, 1416, 3, 2, 41],
[ 1, 1534, 3, 2, 30],
[ 1, 852, 2, 1, 36]])
In [166]: XT = X.T
In [167]: np.linalg.inv(XT @ X) @ XT @ y.T
Out[167]:
matrix([[243.4453125 ],
[ -0.47787476],
[268.609375 ],
[ 3.1328125 ],
[ -5.83056641]])
更新:这种方法给出的值更接近您想要的值:
In [197]: (np.linalg.inv(X @ X.T) @ X).T @ y.T
Out[197]:
matrix([[182.27200269],
[ 0.34497234],
[-38.43393186],
[-82.90625955],
[ -3.84484213]])
更新2:如何最初创建正确的矩阵:
In [217]: np.array([[1, 2104, 5, 1, 45],
...: [1, 1416, 3, 2, 41],
...: [1, 1534, 3, 2, 30],
...: [1, 852, 2, 1, 36]])
...:
Out[217]:
array([[ 1, 2104, 5, 1, 45],
[ 1, 1416, 3, 2, 41],
[ 1, 1534, 3, 2, 30],
[ 1, 852, 2, 1, 36]])
我已经通过使用 numpy.linalg.pinv() 这是“伪逆”而不是 numpy.linalg.inv() 来解决这个问题,因为文档说:
“矩阵 A 的伪逆,表示为 A^+,定义为:“ ‘解决’[最小二乘问题] Ax = b 的矩阵,”即,如果 ar{x} 是所述解,那么 A^+ 是矩阵,使得 ar{x} = A^+b。”
解决最小二乘问题正是我想要在线性回归的背景下实现的目标。
因此代码是:
X=np.matrix([[1,2104,5,1,45],[1,1416,3,2,40],[1,1534,3,2,30],[1,852,2,1,36]])
y=np.matrix([[460],[232],[315],[178]])
XT=X.T
XTX=XT@X
inv=np.linalg.pinv(XTX)
theta=(inv@XT)@y
print(theta)
[[188.40031946]
[ 0.3866255 ]
[-56.13824955]
[-92.9672536 ]
[ -3.73781915]]
编辑: 还可以通过将正则方程更改为:
进行正则化以消除 NoN 可逆性问题theta = (XT@X + lambda*matrix)^(-1)@XT@y 其中 lambda 是实数,称为 正则化参数,matrix 是 (n+1 x n+ 1)形状的维数矩阵:
0 0 0 0 ... 0 0
0 1 0 0 ... 0 0
0 0 1 0 ... 0 0
0 0 0 1 ... 0 0
.
.
.
0 0 0 0 0 0 0 1
这是一个 eye() 矩阵,元素 [0,0] 设置为 0
有关正则化概念的更多信息可以阅读这里
请参阅为什么 numpy.linalg.solve() 提供比 numpy.linalg.inv() 更精确的矩阵求逆,以提高获得 beta 的速度和准确性。可以使用 np.linalg
theta = np.linalg.solve(X.T @ X, X.T@ y)
print(theta)
theta = np.linalg.lstsq(X.T @ X, X.T@ y)[0]
print(theta)