在 Matlab 中使用最小二乘法进行参数估计
Parameters Estimation using Least Square Method in Matlab
我有以下问题:
考虑一组方程 y=ax+b
,其中我知道 y 和 x,并想使用最小二乘法估计 a
和 b
。
让我们假设有 Y=[y1 ; y2]
和
A=[x1 1; x2 1]
这样 Y=A*[a;b]
根据最小二乘法:
B=[a;b]=( transpose(A)*A )^-1*transpose(A)*Y
(A'*A) \ A'*Y
和A\Y
是一样的吗?
哪个是计算B的最佳方法:
inv( transpose(A)*A ) *transpose(A)*Y
(transpose(A)*A) \ transpose(A)*Y
(A'*A) \ A'*Y
pinv(A)*Y
(计算伪逆矩阵)
以上所有给出的结果略有不同
在解决您的疑惑之前,必须先说明一下。当您想使用 shorthand 运算符转置矩阵时...您不应使用 '
,而应使用 .'
。第一个是 conjugate transpose while the second one is the correct shorthand operator to use for the transpose 的 shorthand 运算符。虽然它们通常会产生相同的结果,但将前者与包含复数的矩阵一起使用可能会扰乱您的计算。
由于您没有提供数据样本,以下是我为测试部署的设置:
Y = [2; 4];
A = [3 1; 7 1];
现在,让我们开始step-by-step。对于您的第一个答案,是的,这两个操作在数学观点上是等价的,并且产生基本相同的结果:
>> B = A \ Y
B =
0.5
0.5
-----------------------------
>> B = inv(A.' * A) * A.' * Y
B =
0.500000000000001
0.5
您看到的细微差别是由于 INV(A) * b
不如 A \ b
准确,如果您将鼠标悬停在 inv
函数后跟乘法(应该用橙色警告突出显示):
这也部分回答了您的第二个问题,但让我们做一个详尽的基准测试。我放弃了使用 inv(A.' * A) * A.' * Y
执行的计算,因为建议避免它。我们开始吧:
tic();
for i = 1:100000
B = A \ Y;
end
toc();
tic();
for i = 1:100000
B = pinv(A) * Y;
end
toc();
tic();
for i = 1:100000
B = (A.' * A) \ A.' * Y;
end
toc();
这是基准测试的结果:
Elapsed time is 0.187067 seconds.
Elapsed time is 2.987651 seconds.
Elapsed time is 2.173117 seconds.
鉴于这三种方法具有相同的准确度...第一种方法是迄今为止最快的方法。
我有以下问题:
考虑一组方程 y=ax+b
,其中我知道 y 和 x,并想使用最小二乘法估计 a
和 b
。
让我们假设有 Y=[y1 ; y2]
和
A=[x1 1; x2 1]
这样 Y=A*[a;b]
根据最小二乘法:
B=[a;b]=( transpose(A)*A )^-1*transpose(A)*Y
(A'*A) \ A'*Y
和A\Y
是一样的吗?哪个是计算B的最佳方法:
inv( transpose(A)*A ) *transpose(A)*Y
(transpose(A)*A) \ transpose(A)*Y
(A'*A) \ A'*Y
pinv(A)*Y
(计算伪逆矩阵)
以上所有给出的结果略有不同
在解决您的疑惑之前,必须先说明一下。当您想使用 shorthand 运算符转置矩阵时...您不应使用 '
,而应使用 .'
。第一个是 conjugate transpose while the second one is the correct shorthand operator to use for the transpose 的 shorthand 运算符。虽然它们通常会产生相同的结果,但将前者与包含复数的矩阵一起使用可能会扰乱您的计算。
由于您没有提供数据样本,以下是我为测试部署的设置:
Y = [2; 4];
A = [3 1; 7 1];
现在,让我们开始step-by-step。对于您的第一个答案,是的,这两个操作在数学观点上是等价的,并且产生基本相同的结果:
>> B = A \ Y
B =
0.5
0.5
-----------------------------
>> B = inv(A.' * A) * A.' * Y
B =
0.500000000000001
0.5
您看到的细微差别是由于 INV(A) * b
不如 A \ b
准确,如果您将鼠标悬停在 inv
函数后跟乘法(应该用橙色警告突出显示):
这也部分回答了您的第二个问题,但让我们做一个详尽的基准测试。我放弃了使用 inv(A.' * A) * A.' * Y
执行的计算,因为建议避免它。我们开始吧:
tic();
for i = 1:100000
B = A \ Y;
end
toc();
tic();
for i = 1:100000
B = pinv(A) * Y;
end
toc();
tic();
for i = 1:100000
B = (A.' * A) \ A.' * Y;
end
toc();
这是基准测试的结果:
Elapsed time is 0.187067 seconds.
Elapsed time is 2.987651 seconds.
Elapsed time is 2.173117 seconds.
鉴于这三种方法具有相同的准确度...第一种方法是迄今为止最快的方法。