在插入符号中使用 glmnet 时出错
下面的示例加载库
library(dplyr)
library(caret)
library(C50)
从库 C50 加载流失数据集
data(churn)
创建 x 和 y 变量
churn_x <- subset(churnTest, select= -churn)
churn_y <- churnTest[[20]]
使用 createFolds(( 在目标变量 churn_y 上创建 5 个 CV 折叠
myFolds <- createFolds(churn_y, k = 5)
创建训练控件对象:我的控件
myControl <- trainControl(
summaryFunction = twoClassSummary,
classProbs = TRUE, # IMPORTANT!
verboseIter = TRUE,
savePredictions = TRUE,
index = myFolds
)
适合 glmnet 型号:model_glmnet
model_glmnet <- train(
x = churn_x, y = churn_y,
metric = "ROC",
method = "glmnet",
trControl = myControl
)
我收到以下错误
lognet(x, is.sparse, ix, jx, y, weights, offset, alpha, nobs, : 外来函数调用中的 NA/NaN/Inf (参数 5(另外: 警告消息:In lognet(x, is.sparse, ix, jx, y, weights, offset, alpha, nobs, : 胁迫引入的 NA
我已经检查过,churn_x变量中没有缺失值
sum(is.na(churn_x))
有谁知道答案?
问题出在模型规范中。如果使用插入符号训练公式接口,则训练将起作用:
train <- data.frame(churn_x, churn_y)
model_glmnet <- train(churn_y ~ ., data = train,
metric = "ROC",
method = "glmnet",
trControl = myControl
)
> model_glmnet$results
alpha lambda ROC Sens Spec ROCSD SensSD SpecSD
1 0.10 0.0001754386 0.6958156 0.2845934 0.9123349 0.01855530 0.01616471 0.004002873
2 0.10 0.0017543858 0.7187303 0.2901986 0.9185721 0.01681286 0.01415863 0.005347573
3 0.10 0.0175438576 0.7399174 0.2355121 0.9487161 0.01482812 0.03932741 0.010769455
4 0.55 0.0001754386 0.6988285 0.2901800 0.9121614 0.01907845 0.01312159 0.004200233
5 0.55 0.0017543858 0.7260286 0.2946617 0.9185714 0.01761485 0.02171189 0.006755247
6 0.55 0.0175438576 0.7630039 0.2008939 0.9617103 0.01743847 0.03989938 0.006118592
7 1.00 0.0001754386 0.7009482 0.2924146 0.9119881 0.01958200 0.01233419 0.004157393
8 1.00 0.0017543858 0.7313495 0.2957728 0.9203040 0.01797853 0.02356945 0.008478577
9 1.00 0.0175438576 0.7672690 0.1595779 0.9760892 0.01935176 0.01935583 0.007938801
但是,当您指定x
并y
它不起作用时,因为 glmnet 以模型矩阵的形式获取x
,当您提供公式插入符号时,它将负责 model.matrix 的创建,但如果您只指定x
和y
那么它将假定x
是一个 model.matrix 并将其传递给 glmnet
.例如,这有效:
x <- model.matrix(churn_y ~ ., data = train)
model_glmnet2 <- train(x = x, y = churn_y,
metric = "ROC",
method = "glmnet",
trControl = myControl
)
> model_glmnet2$results
alpha lambda ROC Sens Spec ROCSD SensSD SpecSD
1 0.10 0.0001754386 0.6958156 0.2845934 0.9123349 0.01855530 0.01616471 0.004002873
2 0.10 0.0017543858 0.7187303 0.2901986 0.9185721 0.01681286 0.01415863 0.005347573
3 0.10 0.0175438576 0.7399174 0.2355121 0.9487161 0.01482812 0.03932741 0.010769455
4 0.55 0.0001754386 0.6988285 0.2901800 0.9121614 0.01907845 0.01312159 0.004200233
5 0.55 0.0017543858 0.7260286 0.2946617 0.9185714 0.01761485 0.02171189 0.006755247
6 0.55 0.0175438576 0.7630039 0.2008939 0.9617103 0.01743847 0.03989938 0.006118592
7 1.00 0.0001754386 0.7009482 0.2924146 0.9119881 0.01958200 0.01233419 0.004157393
8 1.00 0.0017543858 0.7313495 0.2957728 0.9203040 0.01797853 0.02356945 0.008478577
9 1.00 0.0175438576 0.7672690 0.1595779 0.9760892 0.01935176 0.01935583 0.007938801
仅当存在因子特征时才需要model.matrix
使用glmnet
并得到相同的错误,请这样做!
简短的回答:使用data.matrix()
解决了我的问题!
最初,我在做:
# Given X and Y are datframes
cv.glmnet(x = as.matrix(X), y = as.matrix(Y), alpha = 1, family = "binomial")
此问题已由以下方法修复:
cv.glmnet(x = data.matrix(X), y = as.matrix(Y), alpha = 1, family = "binomial")
更长的答案(一点也不长(:
我遇到了同样的问题,我使用 as.matrix()
传递我的 X 矩阵,如果您碰巧在数据框中有因子,as.matrix()
将所有元素转换为所有列的强制类型。使用data.matrix()
为我修复了它。 data.matrix()
可以处理as.matrix
更基本的因子和有序因子。