glmnet:如何手动恢复原始比例

时间:2018-07-06 13:02:53

标签: r scale glmnet

如果我没记错的话,在高斯情况下glmnet

  1. 缩放数据,以使解释变量和响应均具有零均值和一个标准差(使用具有1 / n的sd公式)。

  2. 获取参数估算值

  3. 根据原始数据缩小系数

我想手动“缩小”部分。所以

我在diabetes data的火车部分上拟合了模型两次(并任意选择s = 0.3)

  1. glmnet自行缩放数据并以原始比例返回估算值

  2. 使用std函数手动调整数据(调整了1 / n因子),使用参数glmnetstandardize=F, intercept=F获取估计值,然后使用函数original_scale获取原始比例

有关原始比例的计算,请参见question

我失败了,不知道原因。

代码如下:

std <- function(X){
  center = colMeans(X)
  X.c = sweep(X, 2, center)
  unit.var = sqrt(apply(X.c, 2, crossprod)/nrow(X))
  val = sweep(X.c, 2, unit.var, "/")
  return(val)
}

original_scale <- function(X,y,beta_std){
  ss=function(v){sd(v)*sqrt((length(v)-1)/length(v))}
  sx=apply(X,2,ss)
  sy=ss(y)
  beta1=sy*diag(1/sx)%*%beta_std
  beta0=mean(y)-t(colMeans(X))%*%beta1
  betas=rbind(beta0,beta1)
}

diabetes <- read.delim("diabetes.data")
x <- model.matrix(Y ~ ., data = diabetes)[, -1]
y <- diabetes$Y
n <- nrow(x)

tr.n <- floor(0.70*n) # train set size
te.n <- n-tr.n # test set size

set.seed(1299)
trainlab <- sort(sample(seq_len(n), size = tr.n))

trainx <- x[trainlab, ]; trainsx <- std(trainx)
trainy <- y[trainlab]; trainsy <- std(as.matrix(trainy))

# no standardization by using scaled data
from.scaled.data <- glmnet(trainsx,trainsy,alpha=0,standardize=F,intercept=F)
# standardized by using original data
from.original.data <- glmnet(trainx,trainy,alpha=0)

coef.from.scaled <- as.vector(coef(from.scaled.data, s=0.3))[-1]
coef.from.original <- as.vector(coef(from.original.data, s=0.3))

coef.from.func <- original_scale(trainx,trainy,coef.from.scaled)

# compare
cbind(coef.from.func,coef.from.original)

0 个答案:

没有答案