응용 프로그램에 대해 나는 잔차를 얻기 위해 큰 데이터 세트에서 선형 회귀 분석을 실행해야합니다. 예를 들어, 하나의 데이터 세트는 차원이 1 백만 x 20k 이상입니다. 더 작은 데이터 세트의 경우 RcppArmadillo
패키지의 fastLm
을 사용했습니다. 시간이 지나면 해당 데이터 세트는 1 백만 행을 초과하여 커집니다.최소 사각형에 대한 SparseQR
내 솔루션은 희소 행렬과 Eigen을 사용했습니다. RcppEigen에서 SparseQR을 사용하는 좋은 예를 찾을 수 없었습니다. 여러 시간의 독서 (예 : rcpp-gallery, stackoverflow, rcpp-dev mailinglist, eigen docs, rcpp-gallery, stackoverflow 및 그 이상을 잊어 버렸지만 확실하게 읽음)을 기반으로 다음 코드를 작성했습니다.
(NB : 내 첫 번째 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 문서를 읽었습니다. 공식적인 수학이나 프로그래밍 교육이 없기 때문에 모든 정직함에서 읽고 이해하는 것은 매우 어렵습니다. 나는 Armadillo 문서를 정말 좋아하지만, 현재 SuperLU 라이브러리가없는 조밀 한 행렬에서 가장 잘 작동한다는 것을 이해합니다. SuperLU 설치는 현재 의문입니다. – tstev