我有一个(随机)采样的训练数据集,用于在R中训练模型。
sampleSize <- floor(0.1 * nrow(trainingDataFrame))
train_index <- sample(seq_len(nrow(trainingDataFrame)), size = sampleSize)
trainDF <- trainingDataFrame[train_index,]
fit <- train(dependentVariable ~ ., data=trainDF,
trControl = trainControl(method = "cv",number = 10),method="lm")
然后,我使用该模型在单独的测试数据集中predict
个值。但是,对于我的测试数据集中的某些行,有一个因子字段,偶尔会出现在训练集中未遇到的值,因为我是随机从训练集中取样的。这将导致"factor ... has new levels"
错误。
我实际上是在多次迭代中重复执行 sample-train-predict 过程,因此每个测试数据集记录最终都将有一些有效的预测。因此,就我的用例而言,某些记录在任何特定的迭代中都是不可{predict
-的,实际上是可以的。我不想在模型训练中排除相关领域。
相反,是否可以指示predict
函数为我提供na
或这些无效行的其他默认值?
答案 0 :(得分:1)
这里有可能。
键是定义您自己的predict
函数,该函数将factor
对象中的lm
变量与newdata
中的变量进行比较。然后,我们仅predict
对具有匹配factor
级别的那些观测,并为所有其他观测返回NA
。
我将演示如何使用mtcars
数据。
让我们首先创建由一个数字响应(mpg
)和3个类别预测变量(cyl
,gear
,carb
)组成的示例数据。
library(tidyverse)
df <- mtcars %>%
select(mpg, cyl, gear, carb) %>%
mutate_at(vars(-mpg), as.factor)
然后,我们在观察的训练数据集上训练模型,该观察数据集仅具有cyl
和gear
的某些(但不是全部)因子水平。
df.train <- df %>% filter(cyl %in% c(4, 6) & gear %in% c(3, 4))
我们拟合了一个简单的线性模型。
fit <- lm(mpg ~ ., data = df.train)
我们现在定义一个自定义函数,该函数将newdata
分为以下观察结果:(1)匹配factor
级别,对此我们可以predict
进行响应,以及(2)“新颖我们返回NA
作为响应的级别。
factor
级别都以fit$xlevels
的形式存储在list
中。我们使用purrr::imap
和purrr::reduce(..., intersect)
从newdata
确定具有匹配的factor
级别的那些观测的行索引。
my.predict <- function(fit, newdata) {
lvls <- fit$xlevels
idx <- reduce(imap(lvls, ~which(newdata[, .y] %in% .x)), intersect)
res <- rep(NA, nrow(newdata))
res[idx] <- predict(fit, newdata = newdata[idx, ])
return(res)
}
我们在完整的df
数据集中确认结果:
df$pred <- my.predict(fit, df)
df
# mpg cyl gear carb pred
#1 21.0 6 4 4 19.75
#2 21.0 6 4 4 19.75
#3 22.8 4 4 1 29.10
#4 21.4 6 3 1 19.75
#5 18.7 8 3 2 NA
#6 18.1 6 3 1 19.75
#7 14.3 8 3 4 NA
#8 24.4 4 4 2 24.75
#9 22.8 4 4 2 24.75
#10 19.2 6 4 4 19.75
#11 17.8 6 4 4 19.75
#12 16.4 8 3 3 NA
#13 17.3 8 3 3 NA
#14 15.2 8 3 3 NA
#15 10.4 8 3 4 NA
#16 10.4 8 3 4 NA
#17 14.7 8 3 4 NA
#18 32.4 4 4 1 29.10
#19 30.4 4 4 2 24.75
#20 33.9 4 4 1 29.10
#21 21.5 4 3 1 21.50
#22 15.5 8 3 2 NA
#23 15.2 8 3 2 NA
#24 13.3 8 3 4 NA
#25 19.2 8 3 2 NA
#26 27.3 4 4 1 29.10
#27 26.0 4 5 2 NA
#28 30.4 4 5 2 NA
#29 15.8 8 5 4 NA
#30 19.7 6 5 6 NA
#31 15.0 8 5 8 NA
#32 21.4 4 4 2 24.75