【问题标题】:predict.glm() on blind test datapredict.glm() 对盲测数据
【发布时间】:2023-04-05 00:07:01
【问题描述】:

我正在使用 glmnet 包对分类问题使用正则化逻辑回归。在开发过程中,一切正常,但是在对盲测数据进行预测时,我遇到了问题。

因为我不知道类标签,所以我用于测试的数据框的一列比我用于训练的那一列少。这对predict.glm() 来说似乎是个问题,因为它需要匹配的尺寸——我可以通过在测试数据中添加一个带有一些任意标签的列来“修复”它,但这似乎是个坏主意。我希望这个例子能说明问题:

library(glmnet)
example = data.frame(rnorm(20))
colnames(example) = "A"
example$B = rnorm(20)
example$class = ((example$A + example$B) > 0)*1

testframe = data.frame(rnorm(20))
colnames(testframe) = "A"
testframe$B = rnorm(20)

x = model.matrix(class ~ ., data = example)
y = data.matrix(example$class)

# this is similar to the situation I have with my data
# the class labels are ommited on the blind test set

所以如果我这样继续下去,我会得到一个错误:

x.test = as.matrix(testframe)
ridge = glmnet(x,y, alpha = 0, family = "binomial", lambda = 0.01789997)
ridge.pred = predict(ridge, newx = x.test, s = 0.01789997, type = "class")

cbind2(1, newx) %*% nbeta 中的错误: Cholmod 错误 'X 和/或 Y 有 文件 ../MatrixOps/cholmod_sdmult.c,第 90 行中的错误尺寸

我可以通过在我的测试数据中添加一个类列来“修复”这个问题:

testframe$class = 0
x.test = model.matrix(class ~ ., data = testframe)
ridge.pred2 = predict(ridge, newx = x.test, s = 0.01789997, type = "class")

所以我对此有几个问题:
a)添加列的解决方法是否安全?这样做感觉非常错误/危险,因为我不知道 predict 方法是否会使用它(否则为什么需要此列?
b) 有什么更好/“正确”的方法来做到这一点?

提前致谢!

【问题讨论】:

  • x 删除拦截列,您的原始代码将起作用。即这样做,x = model.matrix(class ~ ., data = example)[,-1]。当我有时间更详细地解释时,将在今天晚些时候发布完整的答案。

标签: r logistic-regression glmnet


【解决方案1】:

回答

创建矩阵x 时,删除(Intercept) 列(始终是第一列)。然后您的 predict 函数将在没有解决方法的情况下工作。具体来说,使用这一行来创建 x。

x = model.matrix(class ~ ., data = example)[,-1]

说明

您收到错误是因为 model.matrix 正在为模型中的截距创建一列,该列不在您的 x.test 矩阵中。

colnames(x)
# [1] "(Intercept)" "A"           "B"          
colnames(x.test)
# [1] "A" "B"

除非您设置intercept=FALSE,否则glmnet 将为您在模型中添加截距。因此,最简单的做法是从xx.test 矩阵中排除截距列。

【讨论】:

    猜你喜欢
    • 2016-09-15
    • 2020-11-17
    • 2017-01-04
    • 2013-04-22
    • 1970-01-01
    • 2014-07-11
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多