diag(X V X ^ T)的紧凑/高效替代品?

时间:2019-07-10 01:12:56

标签: r linear-algebra

在对线性统计模型进行预测时,通常会有一个预测变量的模型矩阵X与我们要进行预测的点相对应;系数beta的向量;和方差-协方差矩阵V。计算预测只是X %*% beta

计算预测的方差的最直接方法是

diag(X %*% V %*% t(X))

或更有效

diag(X %*% tcrossprod(V,X))

但是,这效率很低,因为当我们真正想要的只是对角线时,它会构造一个n * n矩阵。我知道我可以写一些Rcpp-loopy东西,只计算对角线项,但是我想知道R中是否有一个线性代数技巧可以很好地完成我想要的...(如果有人想写对于我来说,rcpp-loopy是我不反对的答案,但我更喜欢纯R解决方案)

FWIW predict.lm通过将X乘以lm的QR分解的R分量的倒数,似乎做得很聪明;我不确定是否总是可以使用它,但这可能是一个很好的起点(请参见here

2 个答案:

答案 0 :(得分:3)

沿着这个Octave/Matlab问题的线,对于两个矩阵AB,我们可以利用以下事实:{{1 }}将是nth的{​​{1}}行与AB的{​​{1}}列的乘积。我们可以天真地将其扩展到三个矩阵nth的情况。我没有考虑过在A的情况下如何进行优化,但是除此之外,这段代码看起来很有希望实现加速:

nth

运行此代码时,使用B似乎并没有加快结果的速度。但是,仅使用行和点乘积方法似乎已经非常有效,至少在这个愚蠢的示例中,该示例建议(尽管我不确定){{1 }}在返回对角线条目之前计算完整的中间矩阵,就像我期望的那样ABC一样。

答案 1 :(得分:0)

我不确定这有多有效

  1. 找到U,使SELECT song_label_content->'$[*].SongLabels[*].SongLabelName' FROM t_music_song_label_relation; ;因为V是cov矩阵,所以这是可能的。
  2. V = U %*% t(U)
  3. XU = X %*% U

演示

result =  apply(XU, 1, function(x) sum(x^2))

使用SVD

V <- cov(iris[, -5])
X <- as.matrix(iris[1:5, -5])

另一种方法-这也不会比@davewy的

更快
svd_v <- svd(V)
U <- svd_v$u %*% diag(sqrt(svd_v$d))
XU = X %*% U
apply(XU, 1, function(x) sum(x^2))
#       1        2        3        4        5 
#41.35342 39.36286 35.42369 38.25584 40.30839