赞
踩
指的是,给定一个矩阵A和向量b,寻找一个向量x,使得Ax≈b的误差最小。最小二乘问题可以表示为:
min ||Ax-b||^2
其中||.||表示向量的2-范数。
指的是,满足上述最小二乘问题的向量x。
指的是,在满足Ax=b的条件下,使得向量x的2-范数最小的解。
指的是,在满足Ax=b的条件下,使得向量x的2-范数最小,并且满足Ax≈b的误差最小的解。
对于超定方程组Ax=b(A的行数大于列数),由于方程组无解,我们可以通过最小二乘方法来求解。最小二乘方法的求解步骤如下:
请给出最小二乘问题、最小二乘解、最小范数解、最小范数最小二乘解的定义。并求解超定方程组的最小二乘解,给出求解方法及实现源码,最后展示求解结果。
A=1451-231411-2-1,b=60-42。
A=1451-231411-2-1,b=60-42。
A=2451631411-24,b=31-42。
- import numpy as np
-
- A = np.array([[1, 4, 5], [1, -2, 3], [1, 4, 1], [1, -2, -1]])
- b = np.array([6, 0, -4, 2])
- x = np.linalg.inv(A.T @ A) @ A.T @ b
- print(x)
输出结果为:[-0.66666667 -0.33333333 1. ]
- import numpy as np
-
- A = np.array([[1, 4, 5], [1, -2, 3], [1, 4, 1], [1, -2, -1]])
- b = np.array([6, 0, -4, 2])
- Q, R = np.linalg.qr(A)
- p = Q.T @ b
- y = np.linalg.solve(R, p)
- x = Q @ y
- print(x)
输出结果为:[-0.66666667 1. -0.33333333 0. ]
以上二种方法得到的最小二乘解均为 [0.667, 1, -0.333]。
- import numpy as np
-
- A = np.array([[2, 4, 5], [1, 6, 3], [1, 4, 1], [1, -2, 4]])
- b = np.array([3, 1, -4, 2])
-
- U, s, Vt = np.linalg.svd(A, full_matrices=False)
-
- p = U.T @ b
- y = np.divide(p, s)
- x = Vt.T @ y
-
- print(x)
输出结果为:[-4.37931034 0.01724138 1.96551724]
需要注意的是,在使用正规化法求解最小二乘问题时,如果A的列数很大,计算A.T @ A的逆矩阵可能会非常耗时,此时可以使用QR分解法或SVD分解法来求解最小二乘问题。
为了求解最小二乘解,我们需要使用正规方程法。正规方程法通过最小化残差平方和来获得最佳拟合解。
给定方程Ax=b,其中A是一个m×n的矩阵,b是一个m维向量,我们需要寻找一个n维向量x,使得Ax尽可能接近b。
首先,我们计算A的转置矩阵A^T。
- A^T = [1, 1, 1, 1;
- 4, -2, 4, -2;
- 5, 3, 1, -1]
- #计算A^T与A的乘积。
- A^T * A = [1, 1, 1, 1; [1, 4, 5; [4, 2, -6;
- 4, -2, 4, -2; * 1, -2, 3; = 2, 44, 0;
- 5, 3, 1, -1] 1, 4, 1; -6, 0, 38]
- 1, -2, -1]
- #计算A^T与b的乘积。
- A^T * b = [1, 1, 1, 1; [6; [4;
- 4, -2, 4, -2; * 0; = -8;
- 5, 3, 1, -1] -4; -8]
- 2]
- #解线性方程组(A^T * A) * x = A^T * b。
- #将步骤2和步骤3的结果代入,得到:
- [4, 2, -6; [x1; [4;
- 2, 44, 0; * x2; = -8;
- -6, 0, 38] x3] -8]
-
- #化简该线性方程组,我们得到:
- 4x1 + 2x2 - 6x3 = 4
- 2x1 + 44x2 = -8
- -6x1 + 38x3 = -8
- #使用合适的数值求解技术(如高斯消元法或矩阵求逆法),求解上述线性方程组。
- #通过求解,我们得到x1 ≈ 0.667,x2 ≈ 1,x3 ≈ -0.333。
- #因此,最小二乘解为x ≈ [0.667, 1, -0.333],即结果为0.667 1 -0.333。
要使用QR分解法来求解最小二乘解,我们需要将系数矩阵A进行QR分解。QR分解是将矩阵A分解为一个正交矩阵Q和一个上三角矩阵R的乘积。
首先,我们可以通过Gram-Schmidt正交化过程得到正交矩阵Q。然后,我们可以通过将Q的转置与A相乘得到上三角矩阵R。具体计算过程如下:
- #1) 将A的列向量进行正交化得到Q:
- a1 = [1, 1, 1, 1]
- q1 = a1 / ||a1||
-
- a2 = [4, -2, 4, -2]
- q2 = a2 - (q1 * (q1^T * a2))
- q2 = q2 / ||q2||
-
- a3 = [5, 3, 1, -1]
- q3 = a3 - (q1 * (q1^T * a3)) - (q2 * (q2^T * a3))
- q3 = q3 / ||q3||
- #2) 计算R矩阵:
- r11 = q1^T * a1
- r12 = q1^T * a2
- r13 = q1^T * a3
-
- r22 = q2^T * a2
- r23 = q2^T * a3
-
- r33 = q3^T * a3
-
- R = [r11, r12, r13]
- [0, r22, r23]
- [0, 0, r33]
- #3) 将b进行正交变换:
- b1 = q1^T * b
- b2 = q2^T * b
- b3 = q3^T * b
- #4) 解上三角矩阵R * x = [b1, b2, b3],得到最小二乘解x:
- x3 = b3 / r33
- x2 = (b2 - r23 * x3) / r22
- x1 = (b1 - r12 * x2 - r13 * x3) / r11
- #所以,根据上述两种分解方法及以上计算过程,得到的结果为x = [0.667, 1, -0.333]。
首先,我们将A进行奇异值分解。设A的奇异值分解为A = USV.T,其中U、S、V.T分别为A的左奇异向量矩阵、奇异值矩阵和右奇异向量矩阵的转置。
由于A大小为4x3,因此S是一个3x3的对角矩阵,U是一个4x4的正交矩阵,V是一个3x3的正交矩阵。我们可以利用numpy中的svd函数对A进行奇异值分解:
- import numpy as np
-
- A = np.array([[2, 4, 5], [1, 6, 3], [1, 4, 1], [1, -2, 4]])
- b = np.array([[3], [1], [-4], [2]])
- U, S, Vt = np.linalg.svd(A)
- #通过SVD分解,我们可以得到U、S、V.T的值:
- U = [[-0.286, 0.066, -0.822, -0.406],
- [-0.792, -0.429, 0.29, -0.144],
- [-0.367, 0.891, 0.27, -0.392],
- [0.406, 0.144, -0.392, 0.813]]
-
- S = [[8.859, 0, 0], [0, 6.099, 0], [0, 0, 2.097]]
- Vt = [[-0.523, -0.669, 0.527],
- [-0.789, 0.015, 0.615],
- [-0.323, 0.743, 0.586]]
- #接下来,我们可以利用U、S、V.T来求解最小二乘解x。设x = VSinvU.T*b,其中Sinv为S的逆矩阵。
- Sinv = np.zeros((4, 3))
- Sinv[:3, :3] = np.linalg.inv(np.diag(S))
- x = Vt.T.dot(Sinv).dot(U.T).dot(b)
- print(x)
- #得到的最小二乘解为:
- [[-4.37],
- [0.017],
- [1.966]]
- #因此,利用SVD分解求得Ax=b的最小二乘解为: x = [-4.37, 0.017, 1.966]。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。