我使用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)这是解决方法,添加一个安全的列吗?这样做感觉非常错误/危险,因为我不知道预测方法是否会使用它(为什么它要求此列在那里呢?
b)什么是更好/"正确的"这样做的方法?
提前致谢!
答案 0 :(得分:0)
<强>答案强>
创建矩阵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
会为您的模型添加拦截。因此,最简单的方法是从x
和x.test
矩阵中排除拦截列。