caret train()使用rpart时出现警告信息:“在重新采样的性能度量中缺少值”。

33

我正在使用caret软件包来训练一个带有“rpart”软件包的模型;

tr = train(y ~ ., data = trainingDATA, method = "rpart")

数据没有缺失值或NA,但运行命令时会出现警告消息;

    Warning message:
In nominalTrainWorkflow(x = x, y = y, wts = weights, info = trainInfo,  :
  There were missing values in resampled performance measures.

有人知道(或者能指引我找到答案的地方)这个警告是什么意思吗?我知道它在告诉我,在重新采样性能度量中存在缺失值,但具体意思是什么,这种情况如何出现?顺便说一下,predict()函数在拟合模型时运行良好,所以这只是我的好奇心。

6个回答

29

没有足够的数据,不能确定。

如果这是回归问题,最有可能的情况是树没有找到好的分割点,而是使用了结果的平均值作为预测变量。这没关系,但由于预测值的方差为零,因此无法计算 R^2。

如果是分类问题,很难说。您可能会遇到重新采样的情况,其中一个结果类别没有样本,因此灵敏度或特异度未定义,因此为NA


感谢@topepo。这是回归问题,因此没有很好的分割可能是一个合理的原因。顺便问一下,您知道有哪些好的书籍可以解释随机森林中的线性回归吗? - USER_1
@topepo,我在使用rpartnnet时遇到了同样的问题。对于后者,我只需要设置linout = TRUE就可以摆脱警告信息并获得正确的交叉验证预测。然而,我还没有找到rpart的解决方案:交叉验证预测非常好。我感觉rpart期望我们传递一些参数,但是我们无法使用train传递,例如method = "anova"rpart的帮助页面说“最明智的做法是直接指定方法”。 - Samuel-Rosa
我在使用随机森林(method = rf)时遇到了同样的问题,但只有在数据集中的行数太少时才会出现警告。如果数据集更大(与较小的数据集具有相同的结构),则不会出现警告。 - yPennylane

6

问题

问题在于rpart使用的是基于树的算法,只能处理给定特征中有限数量的因素。因此,您可能会遇到一个变量被设置为具有超过53个类别的因素:

> rf.1 <- randomForest(x = rf.train.2, 
+                      y = rf.label, 
+                      ntree = 1000)
Error in randomForest.default(x = rf.train.2, y = rf.label, ntree = 1000) : 
Can not handle categorical predictors with more than 53 categories.

你的问题基本上是因为caret在运行该函数,所以请确保你用超过53个级别修复了分类变量。

以下是我之前遇到的问题(注意邮政编码作为因素输入):

# ------------------------------- #
# RANDOM FOREST WITH CV 10 FOLDS  #
# ------------------------------- #
rf.train.2 <- df_train[, c("v1",
                      "v2",
                      "v3",
                      "v4",
                      "v5",
                      "v6",
                      "v7",
                      "v8",
                      "zipcode",
                      "price",
                      "made_purchase")]
rf.train.2 <- data.frame(v1=as.factor(rf.train.2$v1),
                     v2=as.factor(rf.train.2$v2),
                     v3=as.factor(rf.train.2$v3),
                     v4=as.factor(rf.train.2$v4),
                     v5=as.factor(rf.train.2$v5),
                     v6=as.factor(rf.train.2$v6),
                     v7=as.factor(rf.train.2$v7),
                     v8=as.factor(rf.train.2$v8),
                     zipcode=as.factor(rf.train.2$zipcode),
                     price=rf.train.2$price,
                     made_purchase=as.factor(rf.train.2$made_purchase))
rf.label <- rf.train.2[,"made_purchase"]

解决方案

删除所有具有超过53个级别的分类变量

这是我修改后的代码,调整了分类变量 zipcode,你甚至可以将其包装在数字包装器中,如下所示:as.numeric(rf.train.2$zipcode)

# ------------------------------- #
# RANDOM FOREST WITH CV 10 FOLDS  #
# ------------------------------- #
rf.train.2 <- df_train[, c("v1",
                      "v2",
                      "v3",
                      "v4",
                      "v5",
                      "v6",
                      "v7",
                      "v8",
                      "zipcode",
                      "price",
                      "made_purchase")]
rf.train.2 <- data.frame(v1=as.factor(rf.train.2$v1),
                     v2=as.factor(rf.train.2$v2),
                     v3=as.factor(rf.train.2$v3),
                     v4=as.factor(rf.train.2$v4),
                     v5=as.factor(rf.train.2$v5),
                     v6=as.factor(rf.train.2$v6),
                     v7=as.factor(rf.train.2$v7),
                     v8=as.factor(rf.train.2$v8),
                     zipcode=rf.train.2$zipcode,
                     price=rf.train.2$price,
                     made_purchase=as.factor(rf.train.2$made_purchase))
rf.label <- rf.train.2[,"made_purchase"]

4
我只有男性和女性选项,但我收到了相同的错误信息。 - Jørgen K. Kanters
6
也许我错了,但我不确定将类似邮政编码的内容转换为整数是否明智。如果它是一个整数,那么算法将把它视为协变量而不是因子,因此邮编55105比55104大一单位,当实际上它们之间并没有这种关系。我认为你最好把邮政编码的精度降低到只有前两位数字。我意识到这个讨论有点过时,但我觉得值得讨论。 - Brad Davis

4
这个错误发生在模型未在某些交叉验证折叠中收敛时,预测结果的方差为零。因此,像 RMSE 或 Rsquared 这样的指标无法计算,因此它们成为 NAs。 有时,您可以调整参数以实现更好的收敛性,例如,neuralnet 库提供增加阈值的选项,这几乎总是导致收敛。然而,我不确定 rpart 库是否可行。
导致这种情况发生的另一个原因是训练数据中已经存在NAs。然后,显然的处理方法是在传递之前删除它们,即使用 train(data = na.omit(training.data))。
希望这能多少解释一下。

0

当我将训练数据拟合到单个决策树时,遇到了相同的错误。但是,在将原始数据拆分为训练集和测试集之前,一旦删除NA值,问题就得到解决。我想这是因为我们在拆分和拟合模型时出现了数据不匹配的情况。 步骤: 1:从原始数据中删除NA。 2:现在将其拆分为训练集和测试集。 3:现在训练模型,希望它现在可以修复错误。


这可能是问题,但是原帖作者说数据没有缺失值或NA。 - StupidWolf

0
我的问题是我不小心使用了createDataPartition()(或类似的函数:createFolds()、createMultiFolds()等),而它们所用的元数据没有被分成训练集和验证集。
结果是在交叉验证列表中的某些索引超出了训练数据的范围。

0
在我的情况下,受到bmc的答案的帮助,我发现问题是因为结果列是数值型的(由数据集提供)。将其转换为因子,然后运行train就可以成功地避免错误。

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