对于NxP矩阵x
和Nx1向量y
,其中N> P,两个表达式
x \ y -- (1)
和
(x' * x) \ (x' * y) -- (2)
计算解决方案b
到矩阵方程
x * b = y
在最小二乘意义上,即使得数量
norm(y - x * b)
最小化。表达式(2)使用经典算法来解决普通最小二乘回归,其中\
运算符的左手参数是正方形。它相当于写作
inv(x' * x) * (x' * y) -- (3)
但它使用的算法在数值上更稳定。事实证明,(3)比(2)适度快,即使(2)不必产生作为副产品的逆矩阵,但我可以接受给定的额外数值稳定性。
然而,一些简单的时间(N = 100,000和P = 30)表明表达式(2)比表达式(1)快5倍以上,即使(1)具有更大的灵活性来选择所使用的算法!例如,对(1)的任何调用都可以只调度X的大小,并且在N> P的情况下它可以减少到(2),这会增加很少的开销,但肯定不会5倍。
表达式(1)中发生了什么导致它花费更长时间?
编辑:这是我的时间
x = randn(1e5, 30);
y = randn(1e5,1);
tic, for i = 1:100; x\y; end; t1=toc;
tic, for i = 1:100; (x'*x)\(x'*y); end; t2=toc;
assert( abs(norm(x\y) - norm((x'*x)\(x'*y))) < 1e-10 );
fprintf('Speedup: %.2f\n', t1/t2)
加速:5.23
答案 0 :(得分:5)
你知道你的考试中的事实
size(x) == [1e5 30] but size(x'*x) == [30 30]
size(y) == [1e5 1] but size(x'*y) == [30 1]
这意味着进入mldivide
函数的矩阵的大小 大小不等4个数量级! 这会产生确定使用哪种算法的任何开销相当大和重要(也许还在两个不同的问题上运行相同的算法)。
换句话说,你有一个有偏见的考试。要进行合理测试,请使用类似
的内容x = randn(1e3);
y = randn(1e3,1);
我发现(最差的5次运行):
Speedup: 1.06 %// R2010a
Speedup: 1.16 %// R2010b
Speedup: 0.97 %// R2013a
......差异已经消失了。
但是,这确实表明,如果你确实有一个与观察数量相比维度较低的回归问题,那么首先进行乘法确实是值得的:)
mldivide
是一个包罗万象,真的很棒。但通常情况下,有关于问题的知识可能会产生更多特定的解决方案,例如预乘,预处理,lu
,qr
,{ {1}}等等数量级更快。
答案 1 :(得分:2)
即使(1)具有更大的灵活性来选择使用的算法! 例如,对(1)的任何调用都可以调度X的大小,并且 在N> P的情况下,它可以减少到(2),这将增加很小的量 开销,但肯定不会花费5倍。
事实并非如此。选择使用哪种算法可能需要很多开销,特别是与相对较小的输入(例如这些)的计算相比时。在这种情况下,因为MATLAB可以看到你有x'*x
,它知道其中一个参数必须是正方形和对称(是的 - 线性代数的知识内置于MATLAB中即使在解析器级别),也可以直接调用\
中的一个适当的代码路径。
我不能说这是否完全解释了你所看到的时间差异。我想进一步调查,至少是:
feature('accel', 'off')
尝试相同的操作以消除JIT的影响