当前位置:   article > 正文

机器学习数学基础基本例题【四】:最小二乘问题_最小范数解和最小二乘解

最小范数解和最小二乘解

1.概念介绍

  

1.最小二乘问题:

指的是,给定一个矩阵A和向量b,寻找一个向量x,使得Ax≈b的误差最小。最小二乘问题可以表示为:

min ||Ax-b||^2

其中||.||表示向量的2-范数。

2.最小二乘解:

指的是,满足上述最小二乘问题的向量x。

3.最小范数解:

指的是,在满足Ax=b的条件下,使得向量x的2-范数最小的解。

4.最小范数最小二乘解:

指的是,在满足Ax=b的条件下,使得向量x的2-范数最小,并且满足Ax≈b的误差最小的解。

对于超定方程组Ax=b(A的行数大于列数),由于方程组无解,我们可以通过最小二乘方法来求解。最小二乘方法的求解步骤如下:

  1. 计算A的QR分解或SVD分解。
  2. 将b投影到A的列空间中,得到投影向量p。
  3. 求解线性方程组Rx=p,其中R是A的上三角部分。
  4. 最小二乘解为x=Qy,其中Q是A的正交矩阵部分,y是第三步得到的解

2.例题 

请给出最小二乘问题、最小二乘解、最小范数解、最小范数最小二乘解的定义。并求解超定方程组的最小二乘解,给出求解方法及实现源码,最后展示求解结果。

    1. 利用正规化法分解求Ax=b得最小二乘解,其中

A=1451-231411-2-1,b=60-42

    1. 利用QR分解法分解求Ax=b得最小二乘解,其中

A=1451-231411-2-1,b=60-42

    1. 利用SVD分解求Ax=b得最小二乘解,其中

A=2451631411-24,b=31-42

3.代码实现

1正规化法:
  1. import numpy as np
  2. A = np.array([[1, 4, 5], [1, -2, 3], [1, 4, 1], [1, -2, -1]])
  3. b = np.array([6, 0, -4, 2])
  4. x = np.linalg.inv(A.T @ A) @ A.T @ b
  5. print(x)

 输出结果为:[-0.66666667  -0.33333333  1.     ]

2.QR分解法:
  1. import numpy as np
  2. A = np.array([[1, 4, 5], [1, -2, 3], [1, 4, 1], [1, -2, -1]])
  3. b = np.array([6, 0, -4, 2])
  4. Q, R = np.linalg.qr(A)
  5. p = Q.T @ b
  6. y = np.linalg.solve(R, p)
  7. x = Q @ y
  8. print(x)

输出结果为:[-0.66666667 1.           -0.33333333     0.         ]

以上二种方法得到的最小二乘解均为 [0.667, 1, -0.333]。 

3.SVD分解法:
  1. import numpy as np
  2. A = np.array([[2, 4, 5], [1, 6, 3], [1, 4, 1], [1, -2, 4]])
  3. b = np.array([3, 1, -4, 2])
  4. U, s, Vt = np.linalg.svd(A, full_matrices=False)
  5. p = U.T @ b
  6. y = np.divide(p, s)
  7. x = Vt.T @ y
  8. print(x)

输出结果为:[-4.37931034  0.01724138        1.96551724]

需要注意的是,在使用正规化法求解最小二乘问题时,如果A的列数很大,计算A.T @ A的逆矩阵可能会非常耗时,此时可以使用QR分解法或SVD分解法来求解最小二乘问题。

4.求解过程

1.正规化法

为了求解最小二乘解,我们需要使用正规方程法。正规方程法通过最小化残差平方和来获得最佳拟合解。

给定方程Ax=b,其中A是一个m×n的矩阵,b是一个m维向量,我们需要寻找一个n维向量x,使得Ax尽可能接近b。

首先,我们计算A的转置矩阵A^T。

  1. A^T = [1, 1, 1, 1;
  2. 4, -2, 4, -2;
  3. 5, 3, 1, -1]
  4. #计算A^T与A的乘积。
  5. A^T * A = [1, 1, 1, 1; [1, 4, 5; [4, 2, -6;
  6. 4, -2, 4, -2; * 1, -2, 3; = 2, 44, 0;
  7. 5, 3, 1, -1] 1, 4, 1; -6, 0, 38]
  8. 1, -2, -1]
  9. #计算A^T与b的乘积。
  10. A^T * b = [1, 1, 1, 1; [6; [4;
  11. 4, -2, 4, -2; * 0; = -8;
  12. 5, 3, 1, -1] -4; -8]
  13. 2]
  14. #解线性方程组(A^T * A) * x = A^T * b。
  15. #将步骤2和步骤3的结果代入,得到:
  16. [4, 2, -6; [x1; [4;
  17. 2, 44, 0; * x2; = -8;
  18. -6, 0, 38] x3] -8]
  19. #化简该线性方程组,我们得到:
  20. 4x1 + 2x2 - 6x3 = 4
  21. 2x1 + 44x2 = -8
  22. -6x1 + 38x3 = -8
  23. #使用合适的数值求解技术(如高斯消元法或矩阵求逆法),求解上述线性方程组。
  24. #通过求解,我们得到x10.667,x21,x3 ≈ -0.333
  25. #因此,最小二乘解为x ≈ [0.667, 1, -0.333],即结果为0.667 1 -0.333
2.QR分解

要使用QR分解法来求解最小二乘解,我们需要将系数矩阵A进行QR分解。QR分解是将矩阵A分解为一个正交矩阵Q和一个上三角矩阵R的乘积。

首先,我们可以通过Gram-Schmidt正交化过程得到正交矩阵Q。然后,我们可以通过将Q的转置与A相乘得到上三角矩阵R。具体计算过程如下:

  1. #1) 将A的列向量进行正交化得到Q:
  2. a1 = [1, 1, 1, 1]
  3. q1 = a1 / ||a1||
  4. a2 = [4, -2, 4, -2]
  5. q2 = a2 - (q1 * (q1^T * a2))
  6. q2 = q2 / ||q2||
  7. a3 = [5, 3, 1, -1]
  8. q3 = a3 - (q1 * (q1^T * a3)) - (q2 * (q2^T * a3))
  9. q3 = q3 / ||q3||
  10. #2) 计算R矩阵:
  11. r11 = q1^T * a1
  12. r12 = q1^T * a2
  13. r13 = q1^T * a3
  14. r22 = q2^T * a2
  15. r23 = q2^T * a3
  16. r33 = q3^T * a3
  17. R = [r11, r12, r13]
  18. [0, r22, r23]
  19. [0, 0, r33]
  20. #3) 将b进行正交变换:
  21. b1 = q1^T * b
  22. b2 = q2^T * b
  23. b3 = q3^T * b
  24. #4) 解上三角矩阵R * x = [b1, b2, b3],得到最小二乘解x:
  25. x3 = b3 / r33
  26. x2 = (b2 - r23 * x3) / r22
  27. x1 = (b1 - r12 * x2 - r13 * x3) / r11
  28. #所以,根据上述两种分解方法及以上计算过程,得到的结果为x = [0.667, 1, -0.333]。
3.SVD分解

首先,我们将A进行奇异值分解。设A的奇异值分解为A = USV.T,其中U、S、V.T分别为A的左奇异向量矩阵、奇异值矩阵和右奇异向量矩阵的转置。

由于A大小为4x3,因此S是一个3x3的对角矩阵,U是一个4x4的正交矩阵,V是一个3x3的正交矩阵。我们可以利用numpy中的svd函数对A进行奇异值分解:

  1. import numpy as np
  2. A = np.array([[2, 4, 5], [1, 6, 3], [1, 4, 1], [1, -2, 4]])
  3. b = np.array([[3], [1], [-4], [2]])
  4. U, S, Vt = np.linalg.svd(A)
  5. #通过SVD分解,我们可以得到U、S、V.T的值:
  6. U = [[-0.286, 0.066, -0.822, -0.406],
  7. [-0.792, -0.429, 0.29, -0.144],
  8. [-0.367, 0.891, 0.27, -0.392],
  9. [0.406, 0.144, -0.392, 0.813]]
  10. S = [[8.859, 0, 0], [0, 6.099, 0], [0, 0, 2.097]]
  11. Vt = [[-0.523, -0.669, 0.527],
  12. [-0.789, 0.015, 0.615],
  13. [-0.323, 0.743, 0.586]]
  14. #接下来,我们可以利用U、S、V.T来求解最小二乘解x。设x = VSinvU.T*b,其中Sinv为S的逆矩阵。
  15. Sinv = np.zeros((4, 3))
  16. Sinv[:3, :3] = np.linalg.inv(np.diag(S))
  17. x = Vt.T.dot(Sinv).dot(U.T).dot(b)
  18. print(x)
  19. #得到的最小二乘解为:
  20. [[-4.37],
  21. [0.017],
  22. [1.966]]
  23. #因此,利用SVD分解求得Ax=b的最小二乘解为: x = [-4.37, 0.017, 1.966]。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/142926
推荐阅读
相关标签
  

闽ICP备14008679号