我正在使用R中的glmnet包,并在尝试重现“旧”分类器时遇到了问题。如果解释变量是置换的(比如反向),则cv.glmnet得到的系数不等于使用未计算设计矩阵的系数。
例如,请考虑以下数据:
library(glmnet)
set.seed(1)
#Set initial parameters
n <- 100
p <- 1000
#Simulate data
x <- matrix(rnorm(n * p), nrow = n, ncol = p)
colnames(x) <- as.character(1:p)
beta <- rnorm(n = p, mean = 2, sd = 2)
beta[rbinom(p, size = 1, prob = 0.5) == 0] <- 0
y <- x %*% beta + rnorm(100, sd = 0.1)
然后对设计矩阵x和x的置换版本运行带有LASSO惩罚(alpha = 1)的glmnet。
#Set parameters for cross validation with cv.glmnet
lambda <- exp(seq(-1, 1, length.out = 100))
alpha <- 1
foldid <- rep(1:10, each = 10)
#Run cross validation
fit <- cv.glmnet(x = x, y = y, family = "gaussian", alpha = alpha,
lambda = lambda,
foldid = foldid)
#Save coefficients
coef1 <- as.matrix(coef(fit, s = "lambda.min"))
#Run cross validation with rearranged design matrix
order <- ncol(x):1
fit2 <- cv.glmnet(x = x[,order], y = y, family = "gaussian", alpha = alpha,
lambda = lambda,
foldid = foldid)
#Save coefficients
coef2 <- as.matrix(coef(fit2, s = "lambda.min"))
coef2 <- coef2[rownames(coef1),]
然后比较系数,交叉验证误差和线性预测值。
> summary(coef2 - coef1)
1
Min. :-0.2738963
1st Qu.: 0.0000000
Median : 0.0000000
Mean : 0.0003739
3rd Qu.: 0.0000000
Max. : 0.3643040
> min(fit$cvm)
[1] 4584.373
> min(fit2$cvm)
[1] 4596.626
> summary(cbind(1,x) %*% coef2 - cbind(1, x) %*% coef1)
1
Min. :-0.5100
1st Qu.:-0.1613
Median : 0.0210
Mean : 0.0000
3rd Qu.: 0.1333
Max. : 0.6139
对于所有三个度量,我们看到模型之间的差异,而只有变量的顺序已经改变。有人可以解释一下吗?
答案 0 :(得分:1)
Glmnet通过坐标下降来计算LASSO正则化路径(参见例如Trevor Hastie的演讲第15页:http://web.stanford.edu/~hastie/TALKS/glmnet.pdf)。由于算法迭代系数,因此变量的顺序会影响所采用的路径。根据收敛阈值和最大迭代次数,这可能导致系数的最终值不同。对于您的示例,请尝试更改
fit <- cv.glmnet(x = x, y = y, family = "gaussian", alpha = alpha,
lambda = lambda,
foldid = foldid)
例如
fit <- cv.glmnet(x = x, y = y, family = "gaussian", alpha = alpha,
lambda = lambda,
foldid = foldid, standardize=TRUE, thresh=1e-20, maxit=10^6)
为您的fit2
做同样的事情。这可能需要一分钟左右来计算,但你会发现差异变得可以忽略不计:
> summary(coef2 - coef1)
1
Min. :-2.038e-08
1st Qu.: 0.000e+00
Median : 0.000e+00
Mean : 1.050e-10
3rd Qu.: 0.000e+00
Max. : 3.028e-08
>
> min(fit$cvm)
[1] 4598.242
>
> min(fit2$cvm)
[1] 4598.242
>
> summary(cbind(1,x) %*% coef2 - cbind(1, x) %*% coef1)
1
Min. :-5.175e-08
1st Qu.:-1.457e-08
Median :-2.959e-10
Mean : 0.000e+00
3rd Qu.: 1.503e-08
Max. : 5.555e-08
答案 1 :(得分:0)
我相信这是因为glmnet使用坐标下降,其中迭代变量以最小化损失函数。在这种情况下,变量的顺序会改变迭代的顺序,这会改变最小化损失函数的路径。