【问题标题】:Elasticnet regression(glmnet) predicting the same value for all observations in test dataElasticnet 回归(glmnet)为测试数据中的所有观察结果预测相同的值
【发布时间】:2017-04-05 22:20:04
【问题描述】:

我正在使用following 教程对我自己的数据尝试 ridge、lasso 和弹性网络回归。但是,我为所有不正确的行预测了相同的值,因此我也得到了相同的 fit 和 mse 值。

如果有比我更了解 R 的人查看我的代码并指出我做错了什么,我将不胜感激。这里是:

library (glmnet)
require(caTools)
set.seed(111) 

new_flat <- fread('RED_SAMPLED_DATA_WITH_HEADERS.csv', header=TRUE, sep = ',') 
sample = sample.split(new_flat$SUBSCRIPTION_ID, SplitRatio = .80)
train = subset(new_flat, sample == TRUE)
test = subset(new_flat, sample == FALSE)

x=model.matrix(c201512_TOTAL_MARGIN~.-SUBSCRIPTION_ID,data=train) 
y=train$c201512_TOTAL_MARGIN

x1=model.matrix(c201512_TOTAL_MARGIN~.-SUBSCRIPTION_ID,data=test) 
y1=test$c201512_TOTAL_MARGIN



# Fit models:
fit.lasso <- glmnet(x, y, family="gaussian", alpha=1)
fit.ridge <- glmnet(x, y, family="gaussian", alpha=0)
fit.elnet <- glmnet(x, y, family="gaussian", alpha=.5)


# 10-fold Cross validation for each alpha = 0, 0.1, ... , 0.9, 1.0
fit.lasso.cv <- cv.glmnet(x, y, type.measure="mse", alpha=1, 
                          family="gaussian")
fit.ridge.cv <- cv.glmnet(x, y, type.measure="mse", alpha=0,
                          family="gaussian")
fit.elnet.cv <- cv.glmnet(x, y, type.measure="mse", alpha=.5,
                          family="gaussian")

for (i in 0:10) {
  assign(paste("fit", i, sep=""), cv.glmnet(x, y, type.measure="mse", 
                                            alpha=i/10,family="gaussian"))
}


# Plot solution paths:
par(mfrow=c(3,2))
# For plotting options, type '?plot.glmnet' in R console
plot(fit.lasso, xvar="lambda")
plot(fit10, main="LASSO")

plot(fit.ridge, xvar="lambda")
plot(fit0, main="Ridge")

plot(fit.elnet, xvar="lambda")
plot(fit5, main="Elastic Net")


yhat0 <- predict(fit0, s=fit0$lambda.1se, newx=x1)
yhat1 <- predict(fit1, s=fit1$lambda.1se, newx=x1)
yhat2 <- predict(fit2, s=fit2$lambda.1se, newx=x1)
yhat3 <- predict(fit3, s=fit3$lambda.1se, newx=x1)
yhat4 <- predict(fit4, s=fit4$lambda.1se, newx=x1)
yhat5 <- predict(fit5, s=fit5$lambda.1se, newx=x1)
yhat6 <- predict(fit6, s=fit6$lambda.1se, newx=x1)
yhat7 <- predict(fit7, s=fit7$lambda.1se, newx=x1)
yhat8 <- predict(fit8, s=fit8$lambda.1se, newx=x1)
yhat9 <- predict(fit9, s=fit9$lambda.1se, newx=x1)
yhat10 <- predict(fit10, s=fit10$lambda.1se, newx=x1)

mse0 <- mean((y1 - yhat0)^2)
mse1 <- mean((y1 - yhat1)^2)
mse2 <- mean((y1 - yhat2)^2)
mse3 <- mean((y1 - yhat3)^2)
mse4 <- mean((y1 - yhat4)^2)
mse5 <- mean((y1 - yhat5)^2)
mse6 <- mean((y1 - yhat6)^2)
mse7 <- mean((y1 - yhat7)^2)
mse8 <- mean((y1 - yhat8)^2)
mse9 <- mean((y1 - yhat9)^2)
mse10 <- mean((y1 - yhat10)^2)

编辑:代码中的情节看起来像

【问题讨论】:

  • 对于每个 yhat 中的所有行,我得到 48.1531,所有 mse 的值都是 1003.14。不幸的是,我无法分享数据,但我可以分享代码中提到的情节。
  • 每个模型输出的系数是多少?如果您的因变量和自变量之间的相关性较差,则套索的系数可以减少到 0,岭的系数可以减少到接近 0,这将返回每行的因变量的平均值。您还可以提供一小部分数据样本吗?
  • 你能只提供模型返回的系数吗?还有你的依赖变量 48.1531 的平均值吗? mean(c201512_TOTAL_MARGIN)
  • 你是对的,响应的平均值是 48.1531。你能解释一下这是什么意思吗?
  • 这意味着你的预测函数中的lambda太高了:详见这里:web.stanford.edu/~hastie/glmnet/glmnet_alpha.html

标签: r glmnet


【解决方案1】:

尝试在您的预测函数中使用s=fit0$lambda.min 而不是s=fit0$lambda.1se。你的系数在套索上很快下降到 0,所以 s=fit0$lambda.1se 可能是一个太高的惩罚因素。 lambda 确定系数的惩罚权重,如果它太高,您的系数将为零并且预测将等于截距,这是因变量的平均值,例如Y= 0.48 + 0*X

【讨论】:

  • 你是对的,一旦我更改为 lambda.min ,我确实会得到一些预测。我的原始数据被人为地扩大和展平。即为了获得更多用于预测的变量,我将分类列转换为数值,这导致了一个相当稀疏的 3-4k 列矩阵。你认为这可能是它的原因吗?
  • 是的,这可能是一个原因,因为我认为它会削弱因变量和自变量之间的相关性。我也可能只是因为你的独立变量不是你的依赖变量的一个很好的预测器。对于弹性网络类型回归,您必须记住的是它在减少最小似然(或 OLS)损失函数和减少系数大小之间取得平衡。如果 X 与 Y 的相关性不强,那么即使在较小的 lambda 水平下,系数也可以降低到 0 或接近 0
猜你喜欢
  • 2017-09-01
  • 2016-10-24
  • 1970-01-01
  • 2018-12-23
  • 2013-07-20
  • 2018-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多