對於我正在構建的應用程序,我需要在大型數據集上運行線性迴歸以獲得殘差。例如,一個數據集的維數超過100萬x 20k。對於較小的數據集,我使用的是RcppArmadillo
軟件包中的fastLm
,這對於那些目前來說非常適用。隨着時間的推移,這些數據集也將增長超過100萬行。SparseQR for Least Squares
我的解決方案是使用稀疏矩陣和特徵。我無法找到在RcppEigen中使用SparseQR的好例子。基於很多小時的閱讀(例如:rcpp-gallery,stackoverflow,rcpp-dev mailinglist,eigen docs,rcpp-gallery,stackoverflow以及許多我已經忘記但肯定已經閱讀的內容),我寫了下面這段代碼;
(注:我的第一個C++程序 - 請好:) - 改善任何的建議是歡迎)
// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
using namespace Eigen;
using Eigen::Map;
using Eigen::SparseMatrix;
using Eigen::MappedSparseMatrix;
using Eigen::VectorXd;
using Eigen::SimplicialCholesky;
// [[Rcpp::export]]
List sparseLm_eigen(const SEXP Xr,
const NumericVector yr){
typedef SparseMatrix<double> sp_mat;
typedef MappedSparseMatrix<double> sp_matM;
typedef Map<VectorXd> vecM;
typedef SimplicialCholesky<sp_mat> solver;
const sp_mat Xt(Rcpp::as<sp_matM>(Xr).adjoint());
const VectorXd Xty(Xt * Rcpp::as<vecM>(yr));
const solver Ch(Xt * Xt.adjoint());
if(Ch.info() != Eigen::Success) return "failed";
return List::create(Named("betahat") = Ch.solve(Xty));
}
這適用於例如對;
library(Matrix)
library(speedglm)
Rcpp::sourceCpp("sparseLm_eigen.cpp")
data("data1")
data1$fat1 <- factor(data1$fat1)
mm <- model.matrix(formula("y ~ fat1 + x1 + x2"), dat = data1)
sp_mm <- as(mm, "dgCMatrix")
y <- data1$y
res1 <- sparseLm_eigen(sp_mm, y)$betahat
res2 <- unname(coefficients(lm.fit(mm, y)))
abs(res1 - res2)
但是,對於我的大型數據集(正如我期望的那樣),它失敗了。我最初的意圖是使用SparseQR
作爲求解器,但我不知道如何實現它。
所以我的問題 - 有人可以幫助我用RcppEigen實現稀疏矩陣QR分解?
稀疏QR求解器的使用在這裏詳細描述:https://eigen.tuxfamily.org/dox/group__TopicSparseSystems.html – coatless
@無厘頭我已經通過Eigen文檔 - 所有的誠實(因爲我沒有正式的數學或編程教育)很難閱讀和理解。我非常喜歡犰狳文檔 - 但從我所瞭解的情況來看,它目前在沒有SuperLU庫的密集矩陣中效果最佳。目前安裝SuperLU是不可能的。 – tstev