r - glmnet 拒绝预测

标签 r glmnet r-caret

我有一个有效的 glm 模型。因为我想添加(脊)正则化我想我会切换到 glmnet。出于某种原因,我无法让 glmnet 工作。它似乎总是预测第一类,而不是第二类,这导致精度低且 kappa = 0。

下面是一些重现问题的代码。我做错了什么?

它生成的测试数据如下所示:

Data

由于数据不能线性分离,所以添加了两个多项式 A^2 和 B^2。

glm 模型可以正确预测数据(准确度 = 1 且 kappa = 1)。这是它的预测边界:

GLM

虽然 glmnet 模型始终具有 kappa = 0,但无论它尝试什么 lambda:

  lambda  Accuracy  Kappa  Accuracy SD  Kappa SD
  0       0.746     0      0.0295       0       
  1e-04   0.746     0      0.0295       0       
  0.01    0.746     0      0.0295       0       
  0.1     0.746     0      0.0295       0       
  1       0.746     0      0.0295       0       
  10      0.746     0      0.0295       0

重现问题的代码:

library(caret)

# generate test data
set.seed(42)
n <- 500; m <- 100
data <- data.frame(A=runif(n, 98, 102), B=runif(n, 98, 102), Type="foo")
data <- subset(data, sqrt((A-100)^2 + (B-100)^2) > 1.5)
data <- rbind(data, data.frame(A=rnorm(m, 100, 0.25), B=rnorm(m, 100, 0.25), Type="bar"))

# add a few polynomial features to match ellipses
polymap <- function(data) cbind(data, A2=data$A^2, B2=data$B^2)
data <- polymap(data)

plot(x=data$A, y=data$B, pch=21, bg=data$Type, xlab="A", ylab="B")

# train a binomial glm model
model.glm <- train(Type ~ ., data=data, method="glm", family="binomial",
                   preProcess=c("center", "scale"))

# train a binomial glmnet model with ridge regularization (alpha = 0)
model.glmnet <- train(Type ~ ., data=data, method="glmnet", family="binomial",
                      preProcess=c("center", "scale"),
                      tuneGrid=expand.grid(alpha=0, lambda=c(0, 0.0001, 0.01, 0.1, 1, 10)))

print(model.glm)    # <- Accuracy = 1,   Kappa = 1 - good!
print(model.glmnet) # <- Accuracy = low, Kappa = 0 - bad!

直接调用 glmnet(没有插入符号)会导致同样的问题:

x <- as.matrix(subset(data, select=-c(Type)))
y <- data$Type
model.glmnet2 <- cv.glmnet(x=x, y=y, family="binomial", type.measure="class")
preds <- predict(model.glmnet2, x, type="class", s="lambda.min")
# all predictions are class 1...

编辑:缩放数据图和 glm 找到的决策边界:

decision boundary as found by glm

型号:-37 + 6317*A + 6059*B - 6316*A2 - 6059*B2

最佳答案

在制作预测变量的多项式版本之前,您应该对数据进行居中和缩放。从数字上讲,事情以这种方式工作得更好:

set.seed(42)
n <- 500; m <- 100
data <- data.frame(A=runif(n, 98, 102), B=runif(n, 98, 102), Type="foo")
data <- subset(data, sqrt((A-100)^2 + (B-100)^2) > 1.5)
data <- rbind(data, data.frame(A=rnorm(m, 100, 0.25), B=rnorm(m, 100, 0.25), Type="bar"))
data2 <- data
data2$A <- scale(data2$A, scale = TRUE)
data2$B <- scale(data2$B, scale = TRUE)
data2$A2 <- data2$A^2
data2$B2 <- data2$B^2

# train a binomial glm model
model.glm2 <- train(Type ~ ., data=data2, method="glm")

# train a binomial glmnet model with ridge regularization (alpha = 0)
model.glmnet2 <- train(Type ~ ., data=data2, method="glmnet", 
                       tuneGrid=expand.grid(alpha=0, 
                                            lambda=c(0, 0.0001, 0.01, 0.1, 1, 10)))

来自这些:

> getTrainPerf(model.glm2)
  TrainAccuracy TrainKappa method
1             1          1    glm
> getTrainPerf(model.glmnet2)
  TrainAccuracy TrainKappa method
1             1          1 glmnet

最大

关于r - glmnet 拒绝预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25146552/

相关文章:

r - 随机森林中的tuneGrid参数问题

r - summary.connection(connection) : invalid connection 中的错误

使用 dplyr 在组内重复第一次观察

r - R 中的多种绘图设备

r - 使用 cv.glmnet 并行设置种子在 R 中给出不同的结果

r - 在 R 泊松回归中使用 CARET 和 GAM ("gamSpline"方法)

r - 如何计算第 "x"列中报告字符 "ID"的次数,并报告每行的权重度量?

r - ggplot 不绘制箱线图

r - glmnet:在什么 lambda 时每个系数缩小到 0?

r - 尝试从 glmnet 模型中提取系数返回 NULL 或 "type must be either "raw"或 "prob""错误