我正在尝试使用R来实现Ridge回归。但是在确保每个函数都能正常工作之后,当我最终尝试可视化结果时。函数myRidge()
不断返回NULL
。
我对R不太熟悉,我想我可能会犯一些根本性的错误,并使myRidge()
错误地返回NULL
。
library(Rcpp)
sourceCpp(file="./sweep.cpp")
myRidge <- function(X, Y, lambda, use_QR = FALSE, use_C = TRUE){
n <- dim(X)[1]
p <- dim(X)[2]
Z <- cbind(rep(1, n), X, Y)
A <- t(Z) %*% Z
D <- diag(rep(lambda, p + 2))
D[p + 2, p + 2] <- 0
D[1, 1] <- 0
A <- A + D
S <- mySweepC(A, p + 1)
beta_ridge <- S[1:(p + 1), p + 2]
return(beta_ridge)
}
n <- 50
p <- 200
X <- matrix(rnorm(n * p), nrow=n)
beta_true <- matrix(rep(0, p), nrow=p)
beta_true[1:5] <- seq(5) # 1, 2,..., 5
# add noise with mu = 1
Y <- 1 + X %*% beta_true + rnorm(n)
# regularization
lambda_all <- 10 ^ seq(-3, 3)
# solve for beta for different regularization
beta_est <- matrix(rep(0, p), nrow=p)
Y_hat <- matrix(rep(0, length(lambda_all)*n), nrow=n)
for(i in 1:length(lambda_all)){
beta_est <- myRidge(X, Y, lambda_all[i])
Y_hat[,i] <- X %*% beta_est
}
# visualization
estimation_error <- rep(0, length(lambda_all))
for (i in 1:length(lambda_all)){
estimation_error[i] <- sum((Y-Y_hat[,i])^2)
}
matplot(t(matrix(rep(1,p+1),nrow=1)%*%abs(beta_all)), t(beta_all), type = 'l')
matplot(estimation_error,type = 'l')
我使用Rcpp
来实现mySweepC()
。
# include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export()]]
mat mySweepC(const mat A, int m){
mat B = A;
int n = B.n_rows;
for(int k = 0; k < m; k++){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if((i != k) & (j != k))
B(i, j) = B(i, j) - B(i, k) * B(k, j) / B(k, k);
}
}
for(int i = 0; i < n; i++){
if(i != k)
B(i, k) = B(i, k) / B(k, k);
}
for(int j = 0; j < n; j++){
if(j != k)
B(k, j) = B(k, j) / B(k, k);
}
B(k, k) = - 1 / B(k, k);
}
return(B);
}