【问题标题】:How to solve a least squares (underdetermined system) quickly?如何快速求解最小二乘(欠定系统)?
【发布时间】:2019-07-21 18:10:45
【问题描述】:

我在 R 中有一个程序正在计算大量最小二乘解决方案(>10,000:通常为 100,000+),并且在分析之后,这些是程序的当前瓶颈。我有一个矩阵A,其列向量对应于跨越向量和一个解决方案b。我正在尝试求解Ax=b 的最小二乘解x。矩阵的大小通常为 4xj - 其中许多不是正方形 (j

主要问题:在 R 中解决欠定系统的最快方法是什么?我有许多使用Normal Equation 的解决方案,但我正在寻找比以下任何方法都快的 R 例程。

例如: 给定Ax = b 给出的x 系统,给定以下约束:

  • 系统没有必要确定[通常未确定](ncol (A) <= length(b) 始终成立)。因此solve(A,b) 不起作用,因为solve 需要一个方阵。
  • 您可以假设t(A) %*% A(等同于crossprod(A))是非单数的 - 它在程序的前面被检查过
  • 您可以使用 R 中免费提供的任何包
  • 解决方案不需要漂亮 - 它只需要快速
  • A 大小的上限合理地为 10x10,零元素很少出现 - A 通常非常密集

用于测试的两个随机矩阵...

A = matrix(runif(12), nrow = 4)
b = matrix(runif(4), nrow = 4)

已对以下所有功能进行了分析。它们在这里转载:

f1 = function(A,b)
{
  solve(t(A) %*% A, t(A) %*% b)
}
f2 = function(A,b)
{
  solve(crossprod(A), crossprod(A, b))
}
f3 = function(A,b)
{
  ginv(crossprod(A)) %*% crossprod(A,b) # From the `MASS` package
}
f4 = function(A,b)
{
  matrix.inverse(crossprod(A)) %*% crossprod(A,b) # From the `matrixcalc` package
}
f5 = function(A,b)
{
  qr.solve(crossprod(A), crossprod(A,b))
}
f6 = function(A,b)
{
  svd.inverse(crossprod(A)) %*% crossprod(A,b)
}
f7 = function(A,b)
{
  qr.solve(A,b)
}
f8 = function(A,b)
{
  Solve(A,b) # From the `limSolve` package
}

经过测试,f2 是当前的获胜者。我还测试了线性模型方法——考虑到它们产生的所有其他信息,它们的速度慢得离谱。使用以下代码对代码进行了分析:

library(ggplot2)
library(microbenchmark)

all.equal(
  f1(A,b),
  f2(A,b),
  f3(A,b),
  f4(A,b),
  f5(A,b),
  f6(A,b),
  f7(A,b),
  f8(A,b),
          )

compare = microbenchmark(
  f1(A,b),
  f2(A,b),
  f3(A,b),
  f4(A,b),
  f5(A,b),
  f6(A,b),
  f7(A,b),
  f8(A,b),
  times = 1000)

autoplot(compare)

【问题讨论】:

标签: r matrix linear-algebra least-squares


【解决方案1】:

Rcpp怎么样?

library(Rcpp)
cppFunction(depends='RcppArmadillo', code='
            arma::mat fRcpp (arma::mat A, arma::mat b) {
            arma::mat betahat ;
            betahat = (A.t() * A ).i() * A.t() * b ;
            return(betahat) ;
            }                                
            ')

all.equal(f1(A, b), f2(A, b), fRcpp(A, b))
#[1] TRUE
microbenchmark(f1(A, b), f2(A, b), fRcpp(A, b))
#Unit: microseconds
#        expr    min     lq     mean  median      uq     max neval
#    f1(A, b) 55.110 57.136 67.42110 59.5680 63.0120 160.873   100
#    f2(A, b) 34.444 37.685 43.86145 39.7120 41.9405 117.920   100
# fRcpp(A, b)  3.242  4.457  7.67109  8.1045  8.9150  39.307   100

【讨论】:

  • 与我尝试过的所有方法相比,这看起来很有希望。太感谢了。在Rcpp,你有什么最适合学习 Rcpp 的资源吗? (我精通 C++)。我本来打算早点深入研究它,但这证明我真的需要它。再次感谢。
猜你喜欢
  • 2014-03-25
  • 1970-01-01
  • 2014-04-12
  • 2017-03-23
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多