如何处理 R 预测函数中的错误?
How to handle errors in predict function of R?
我有一个数据框 df,我正在构建一个机器学习模型(C5.0 决策树)来预测列的 class (loan_approved):
结构(非真实数据):
id occupation income loan_approved
1 business 4214214 yes
2 business 32134 yes
3 business 43255 no
4 sailor 5642 yes
5 teacher 53335 no
6 teacher 6342 no
进程:
- 我随机将数据框分成测试和训练,在训练中学习
数据集(第 1、2、3、5、6 行训练和第 4 行作为测试)
- 为了考虑一个或多个列中的新分类级别,我使用了 try 函数
函数:
error_free_predict = function(x){
output = tryCatch({
predict(C50_model, newdata = test[x,], type = "class")
}, error = function(e) {
"no"
})
return(output)
}
应用了预测函数:
test <- mutate(test, predicted_class = error_free_predict(1:NROW(test)))
问题:
id occupation income loan_approved predicted_class
1 business 4214214 yes no
2 business 32134 yes no
3 business 43255 no no
4 sailor 5642 yes no
5 teacher 53335 no no
6 teacher 6342 no no
问题:
我知道这是因为测试数据帧有一个新的级别,它在训练数据中不存在,但我的函数不应该在除此之外的所有情况下工作吗?
P.S: 没用sapply因为太慢
这个问题有两个部分。
- 问题的第一部分出现在训练模型期间,因为如果进行随机拆分,则分类变量在训练和测试之间的分配不均。在您的情况下,假设您只有一个职业 "sailor" 的记录,那么当您进行随机拆分时,它可能最终会出现在测试集中。使用火车数据集构建的模型永远不会看到职业 "sailor" 的影响,因此它会抛出错误。在更一般的情况下,一些其他分类变量级别可能在随机拆分后完全进入测试集。
因此,您可以进行分层抽样,而不是在训练和测试之间随机划分数据。使用 data.table
进行 70:30 拆分的代码是:
ind <- total_data[, sample(.I, round(0.3*.N), FALSE),by="occupation"]$V1
train <- total_data[-ind,]
test <- total_data[ind,]
这确保任何级别在训练和测试数据集之间平均分配。所以你不会在测试数据集中得到 "new" 分类级别;在随机分裂的情况下可能存在。
问题的第二部分出现在模型投入生产时,它遇到了一个全新的变量,这个变量甚至在训练或测试集中都不存在。为了解决这个问题,可以通过使用维护所有分类变量的所有级别的列表
lvl_cat_var1 <- unique(cat_var1)
和 lvl_cat_var2 <- unique(cat_var2)
等。然后在预测之前可以检查新级别和过滤器:
new_lvl_data <- total_data[!(var1 %in% lvl_cat_var1 & var2 %in% lvl_cat_var2)]
pred_data <- total_data[(var1 %in% lvl_cat_var1 & var2 %in% lvl_cat_var2)]
然后对于默认预测执行:
new_lvl_data$predicted_class <- "no"
和 pred_data 的全面预测。
我通常使用一个循环来执行此操作,在这个循环中,列车之外的任何级别都会被此函数重新编码为 NA。这里的 train 是您用于训练模型的数据,而 test 是将用于预测的数据。
for(i in 1:ncol(train)){
if(is.factor(train[,i])){
test[,i] <- factor(test[,i],levels=levels(train[,i]))
}
}
Trycatch 是一种错误处理机制,即在遇到错误之后。除非您想在遇到错误后做一些不同的事情,否则它将不适用。但是你仍然想要 运行 模型,那么这个循环会处理新的关卡。
我有一个数据框 df,我正在构建一个机器学习模型(C5.0 决策树)来预测列的 class (loan_approved):
结构(非真实数据):
id occupation income loan_approved
1 business 4214214 yes
2 business 32134 yes
3 business 43255 no
4 sailor 5642 yes
5 teacher 53335 no
6 teacher 6342 no
进程:
- 我随机将数据框分成测试和训练,在训练中学习 数据集(第 1、2、3、5、6 行训练和第 4 行作为测试)
- 为了考虑一个或多个列中的新分类级别,我使用了 try 函数
函数:
error_free_predict = function(x){
output = tryCatch({
predict(C50_model, newdata = test[x,], type = "class")
}, error = function(e) {
"no"
})
return(output)
}
应用了预测函数:
test <- mutate(test, predicted_class = error_free_predict(1:NROW(test)))
问题:
id occupation income loan_approved predicted_class
1 business 4214214 yes no
2 business 32134 yes no
3 business 43255 no no
4 sailor 5642 yes no
5 teacher 53335 no no
6 teacher 6342 no no
问题:
我知道这是因为测试数据帧有一个新的级别,它在训练数据中不存在,但我的函数不应该在除此之外的所有情况下工作吗?
P.S: 没用sapply因为太慢
这个问题有两个部分。
- 问题的第一部分出现在训练模型期间,因为如果进行随机拆分,则分类变量在训练和测试之间的分配不均。在您的情况下,假设您只有一个职业 "sailor" 的记录,那么当您进行随机拆分时,它可能最终会出现在测试集中。使用火车数据集构建的模型永远不会看到职业 "sailor" 的影响,因此它会抛出错误。在更一般的情况下,一些其他分类变量级别可能在随机拆分后完全进入测试集。
因此,您可以进行分层抽样,而不是在训练和测试之间随机划分数据。使用 data.table
进行 70:30 拆分的代码是:
ind <- total_data[, sample(.I, round(0.3*.N), FALSE),by="occupation"]$V1
train <- total_data[-ind,]
test <- total_data[ind,]
这确保任何级别在训练和测试数据集之间平均分配。所以你不会在测试数据集中得到 "new" 分类级别;在随机分裂的情况下可能存在。
问题的第二部分出现在模型投入生产时,它遇到了一个全新的变量,这个变量甚至在训练或测试集中都不存在。为了解决这个问题,可以通过使用维护所有分类变量的所有级别的列表
lvl_cat_var1 <- unique(cat_var1)
和lvl_cat_var2 <- unique(cat_var2)
等。然后在预测之前可以检查新级别和过滤器:new_lvl_data <- total_data[!(var1 %in% lvl_cat_var1 & var2 %in% lvl_cat_var2)] pred_data <- total_data[(var1 %in% lvl_cat_var1 & var2 %in% lvl_cat_var2)]
然后对于默认预测执行:
new_lvl_data$predicted_class <- "no"
和 pred_data 的全面预测。
我通常使用一个循环来执行此操作,在这个循环中,列车之外的任何级别都会被此函数重新编码为 NA。这里的 train 是您用于训练模型的数据,而 test 是将用于预测的数据。
for(i in 1:ncol(train)){
if(is.factor(train[,i])){
test[,i] <- factor(test[,i],levels=levels(train[,i]))
}
}
Trycatch 是一种错误处理机制,即在遇到错误之后。除非您想在遇到错误后做一些不同的事情,否则它将不适用。但是你仍然想要 运行 模型,那么这个循环会处理新的关卡。