如何处理R的预测函数中的错误?

Anu*_*hit 5 r try-catch predict

我有一个数据帧df,我正在构建一个机器学习模型(C5.0决策树)来预测列的类(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
Run Code Online (Sandbox Code Playgroud)

处理:

  • 我随机将数据框分成测试和训练,在火车数据集上学习(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)
    }
Run Code Online (Sandbox Code Playgroud)

应用预测功能:

test <- mutate(test, predicted_class = error_free_predict(1:NROW(test)))
Run Code Online (Sandbox Code Playgroud)

问题:

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
Run Code Online (Sandbox Code Playgroud)

题:

我知道这是因为测试数据框架有一个新的级别,而这个级别在列车数据中没有出现,但除了这个以外,我的功能不应该在所有情况下工作吗?

PS:没有使用sapply,因为它太慢了

abh*_*eor 2

这个问题有两个部分。

  1. 问题的第一部分出现在训练模型期间,因为如果进行随机分割,则分类变量在训练和测试之间不会平均分配。在您的情况下,假设您只有一条职业为“水手”的记录,那么当您进行随机分割时,它可能最终会出现在测试集中。使用训练数据集构建的模型永远不会看到职业“水手”的影响,因此会抛出错误。在更一般的情况下,一些其他分类变量级别可能在随机分割后完全进入测试集。

因此,您可以进行分层抽样,而不是在训练和测试之间随机划分数据。用于 70:30 分割的代码data.table是:

ind <- total_data[, sample(.I, round(0.3*.N), FALSE),by="occupation"]$V1
train <- total_data[-ind,]
test <- total_data[ind,]
Run Code Online (Sandbox Code Playgroud)

这确保了任何级别在训练和测试数据集之间均等划分。因此,您不会在测试数据集中获得“新”分类级别;在随机分裂的情况下可能存在。

  1. 问题的第二部分出现在模型投入生产时,它遇到了一个全新的变量,而这个变量在训练或测试集中都不存在。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)] 
    
    Run Code Online (Sandbox Code Playgroud)

然后对于默认预测执行以下操作:

new_lvl_data$predicted_class <- "no" 
Run Code Online (Sandbox Code Playgroud)

以及 pred_data 的全面预测。