在glmnet中预测概率时出现错误的解决方法?

9
我将使用glmnet来预测数据集中的概率。我的代码如下:
bank <- read.table("http://www.stat.columbia.edu/~madigan/W2025/data/BankSortedMissing.TXT",header=TRUE)
bank$rich<-sample(c(0:1), 233, replace=TRUE)
    train=bank[1:200,];
    test=bank[201:233,]
    x=model.matrix(rich~., bank)[,-1]
    cv.out=cv.glmnet(x, train$rich, alpha=0, family="binomial")
ridge.mod=glmnet(x, train$rich, alpha=0, family="binomial")
    bank$rich <- NULL
newx = data.matrix(test$rich)
ridge.pred=predict(ridge.mod,newx=newx)

train = data[1:2500,];
test = data[2501:5088,];
x=model.matrix(Y~x1+x2+x3+x4+x5+x6, data)[,-1]
cv.out=cv.glmnet(x, data$Y, alpha=0, family="binomial")
    bestlam=cv.out$lambda.min
ridge.mod=glmnet(x, data$Y, alpha=0, family="binomial")
    test$Y <- NULL
newx = data.matrix(test)
ridge.pred = predict(ridge.mod,newx=newx, type="response")

当使用predict时,我一直收到以下错误信息:

在执行cbind2(1, newx) %*% nbeta的as.matrix函数时出错:在选择函数“as.matrix”的方法时评估参数“x”时出错:在选择函数“t”的方法时评估参数“x”时出错:在../MatrixOps/cholmod_sdmult.c文件的第90行处发生Cholmod错误“X和/或Y具有错误的维度”。

我已经在"Hitters"数据集上尝试过,它可以完美地运行。

library(ISLR);
library(glmnet)
Hitters=na.omit(Hitters)

Hitters$Rich<-ifelse(Hitters$Salary>500,1,0)
Hitters.train = Hitters[1:200,]
Hitters.test = Hitters[201:dim(Hitters)[1],]
x=model.matrix(Rich~.,Hitters)[,-1]
cv.out=cv.glmnet(x, Hitters$Rich, alpha=0, family="binomial")
    bestlam=cv.out$lambda.min
ridge.mod=glmnet(x, Hitters$Rich, alpha=0,lambda=bestlam, family="binomial")
    Hitters.test$Rich <- NULL
newx = data.matrix(Hitters.test)
ridge.pred=predict(ridge.mod,newx=newx, type="response")
head(ridge.pred)
ridge.pred[1:10,]

有人知道我该如何解决这个问题吗?

我投票关闭此问题,因为它涉及如何在没有可重现示例的情况下使用R。 - gung - Reinstate Monica
2
我已经在上面添加了一个可重现的部分。 - Kasia Danilczuk
谢谢!我们现在会尝试为您迁移这个。 - gung - Reinstate Monica
谢谢你的帮助。这个问题困扰了我好几个小时。 - Kasia Danilczuk
1
只是为了标记此答案的回复,因为它是特定错误的第一个谷歌搜索结果。除了使用model.matrix函数时引起的null问题之外,当您的测试x中没有与训练x中找到的变量相同时,也会出现此错误。 - Vlo
7个回答

6
我遇到过同样的问题,我认为这是由于训练和测试集具有不同因素,因此稀疏矩阵的维度也不同导致的。
我的解决方案是创建合并数据集的稀疏矩阵X, traintest=rbind(training,testing)
X = sparse.model.matrix(as.formula(paste("y ~", paste(colnames(training[,-1]), sep = "", collapse=" +"))), data = traintest)
model = cv.glmnet(X[1:nrow(training),], training[,1], family = "binomial",type.measure = "auc",nfolds = 10)
plot(model)
model$lambda.min
#predict on test set
pred = predict(model, s='lambda.min', newx=X[-(1:nrow(training)),], type="response")

这只是为了确保测试集具有相同的维度。


谢谢!这对我有用,我花了几个小时来修复它。 - Usman Khaliq

2

看起来你给newx赋值的东西不对。应该是这样的:

bank$rich <- NULL test$rich <- NULL newx = data.matrix(test) ridge.pred=predict(ridge.mod,newx=newx)

你需要将test中的值清零,然后再将test传递给data.matrix。上面的代码可以解决问题。

另外,你原始数据框中的某些行似乎有一些基于行的模式:200行之后的行在newAccount列中有NA值。在进行回归分析之前,你可能需要处理缺失值和训练/测试拆分。


1

由于不同因素导致训练集和测试集的维度不同,我遇到了相同的错误。问题在于,包含因素/分类数据的列被定义为字符列。因此,在将其拆分为训练和测试集之前,我将这些列从字符列更改为因子列,然后问题得到了解决!

data$factor_column_a <- as.factor(data$factor_column_a)

0

我曾经遇到过同样的问题,也一直收到同样的错误提示,但最终以上方法都没有解决我的问题。但是我找到了解决方案!正如错误提示所说,存在“错误的维度”问题。

关于我的数据

在我的情况下,我使用36 x 895的数据训练了我的glmnet拟合模型,而我的测试数据只有6 x 6。我测试数据集中只有6列的原因是当s="lambda.min"时,套索法选择了这6个特征。

我的解决方案

我使用Matrix包中的稀疏矩阵创建了一个矩阵(您甚至可以使用普通矩阵):

sparsed_test_data <- Matrix(data=0,
                            nrow=nrow(test_data),
                            ncol=ncol(training_data),
                            dimnames=list(rownames(test_data),
                                          colnames(training_data)),
                            sparse = T)

然后我替换了正确列中的值:

for(i in colnames(test_data)){
    sparsed_test_data[, i] <- test_data[, i]
}

现在预测函数运行良好。


0

我之前也遇到过这个错误。我的数据集问题是,训练集和测试集中的因子变量具有不同数量的级别。确保不是这种情况。


0
我发布了一个回答,因为这个问题仍然在搜索结果中显示。以下代码可以运行。我在尝试复制示例时遇到了几个问题。在bank中有缺失的数据;我删除了那些观测值。此外,生成的预测是恒定的(0.4875),因为岭回归将除常数项以外的所有变量设置为(几乎)零(在模拟值rich的情况下并不奇怪)。
library(caret) ## 6.0-81
library(glmnet) ## 2.0-16
url <- "http://www.stat.columbia.edu/~madigan/W2025/data/BankSortedMissing.TXT"
bank <- read.table(url, header=TRUE)
set.seed(1)
bank$rich <- sample(c(0:1), nrow(bank), replace=TRUE)
bank <- na.omit(bank)
trainbank <- bank[1:160, ]
testbank <- bank[161:200, ]
x <- model.matrix(rich~., trainbank)[,-1]
y <- trainbank$rich
cv.out <- cv.glmnet(x, y, alpha=0, family="binomial")
x.test <- model.matrix(rich ~ ., testbank)[,-1]
pred <- predict(cv.out, type='response', newx=x.test)

-2
ridge.mod_P@x  
coef(ridge.mod,s=cv.out$lambda.min)# coeffcience of lambda.min  
ridge.mod_P<-coef(ridge.mod,s=cv.out$lambda.min)  
ridge.mod_P  
matrix(ridge.mod_P@x)  
coe<-matrix(ridge.mod_P@x)  
coe2<-coe[-1,]#1  
newx16<-newx[,-17]  
newx16
newx16%*% matrix(coe2)# NA, This is reason of outputNA.
newx16<-newx[,-c(1,17)]  
coe2<-coe[-(1:2),]#16  
newx16%*% matrix(coe2)#yHat : coefficient and variable.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接