【问题标题】:how to debug errors like: "dim(x) must have a positive length" with caret如何调试错误,例如:“dim(x) must have a positive length” with caret
【发布时间】:2016-12-22 05:09:19
【问题描述】:

我正在对拟合进行预测,类似于插入符指南中的内容:

Caret Measuring Performance

predictions <-  predict(caretfit, testing, type = "prob")

但我得到了错误:

Error in apply(x, 1, paste, collapse = ",") : 
dim(X) must have a positive length

我想知道 1) 诊断这些错误的一般方法,这些错误是由于错误输入此类函数或 2) 我的代码失败的原因。

1) 所以看错误与'X'有关。哪个参数是 x?显然是'apply'中的第一个,但是predict中的哪个参数最终被传递给apply?查看 traceback():

10: stop("dim(X) must have a positive length")
9: apply(x, 1, paste, collapse = ",")
8: paste(apply(x, 1, paste, collapse = ","), collapse = "\n")
7: makeDataFile(x = newdata, y = NULL)
6: predict.C5.0(modelFit, newdata, type = "prob")
5: predict(modelFit, newdata, type = "prob") at C5.0.R#59
4: method$prob(modelFit = modelFit, newdata = newdata, submodels = param)
3: probFunction(method = object$modelInfo, modelFit = object$finalModel, 
   newdata = newdata, preProc = object$preProcess)
2: predict.train(caretfit, testing, type = "prob")
1: predict(caretfit, testing, type = "prob")

现在,如果我能够遵循代码并理解问题而不是这些一般错误,那么这个问题将很容易解决。我可以使用此回溯到 C5.0.R#59 处的代码来跟踪代码。 (看起来没有办法在每条跟踪上获取行号?)我可以按照这段代码一直到第 59 行,然后(我认为)第 44 行的预测函数:

Github Caret C5.0 source

但在此之后,我不确定逻辑流向何处。我在插入符号源中的任何地方都看不到“makeDataFile”,或者,如果它在另一个包中,它是如何到达那里的。我还尝试过 Rstudio 调试、debug() 和 browser()。没有提供我期望从其他语言获得的堆栈跟踪。当您不知道错误消息的含义时,有关如何遵循代码的任何建议?

2) 至于我的特定输入,“caretfit”只是插入符拟合的结果,测试数据是 300 万行 x 59 列:

fitcontrol <- trainControl(method = "repeatedcv",
                       number = 10,
                       repeats = 1,
                       classProbs = TRUE,
                       summaryFunction = custom.summary,
                       allowParallel = TRUE)


fml <- as.formula(paste("OUTVAR ~",paste(colnames(training[,1:(ncol(training)-2)]),collapse="+")))
caretfit <- train(fml,
             data = training[1:200000,],
             method = "C5.0",
             trControl = fitcontrol,
             verbose = FALSE,
             na.action = na.pass)

【问题讨论】:

  • 你在使用 RStudio 吗?
  • 我正在使用 nvim-r 和 vim。但我愿意使用 RStudio 进行调试。实际上我一直在尝试使用 RStudio 进行调试,问题是当我尝试单步执行我的代码时,它要么 1)进入一个似乎永远不会完成的步骤 2)没有某个特定文件的来源,我得到一个大意的错误(抱歉不记得错误)
  • 如果你提供一个可重现的例子,我可以看看它......
  • 由于数据的私密性,提供 MWE 很棘手,但我会看看我能做些什么。
  • 只需运行您的代码并删除您想要保密或(似乎)无关紧要的内容。最后,获取MCVE 的过程有时会导致解决方案......

标签: r r-caret


【解决方案1】:

1调试过程

您可以使用几个函数来查明问题。

虽然似乎仍然无法在代码中获得带有行号的完整堆栈跟踪(嘘!),但您可以使用从回溯中获得的函数并使用函数 getAnywhere() 来搜索您正在寻找的功能。例如,你可以这样做:

getAnywhere(makeDataFile)

查看位置和来源。 (当库通常捆绑在二进制文件中时,这在 Windows 中也很有效。)然后您必须使用 source 或 github 来查找特定的行号或跟踪代码的逻辑。

如果我运行,在我的特定问题中:

newdata <- testing
caseString <- C50:::makeDataFile(x = newdata, y = NULL)

(请注意三个“:”。)我可以看到此步骤在此级别完成,因此在此过程中我的训练数据集似乎发生了一些事情。

所以通过我的回溯一遍又一遍地使用 gitAnywhere() 和 github,我可以手动找到行号(嘘!)

  1. 在 caret/R/predict.train.R 中,predict.train(在第 108 行定义) 在第 153 行调用 probFunction
  2. 在插入符号/R/probFunction、probFunction (在第 3 行定义)调用 method$prob 函数,它是一个存储的 fit 对象 caretfit$modelInfo$prob 中的函数可以是 通过将其输入控制台进行检查。这是一样的 在第 58 行的 caret/models/files/C5.0.R 中找到的函数调用 第 59 行的“预测”
  3. 插入符号中的东西知道使用 C50/R/predict.C5.0.R 通过搜索可以看到 getAnywhere()
  4. 此函数在第 25 行运行 makeDataFile(部分 C50 包)
  5. 调用粘贴,调用应用,死亡 停止

2 插入符号预测的特殊问题

至于我的问题,我一直在检查代码,并在不同级别添加输入,它会成功完成。发生的情况是我在 predict.train.R 中的数据集发生了一些修改,导致它失败。好吧,事实证明我没有包括我的“na.action”参数,对于我的基于树的数据,它使用了“na.pass”。如果我包含这个论点:

prediction <- predict(caretfit, testing, type = "prob", na.action = na.pass)

它按预期工作。 predict.train 的第 126 行利用这个参数来决定是否在预测中包含不完整的案例。我的数据没有完整的案例,因此无法抱怨需要某个正长度的矩阵。

现在如何知道这个应用错误的答案是由于缺少 na.action 参数根本不明显,因此需要一个良好的调试过程。如果有人知道其他调试方法(请记住,在 windows 中,在 Rstudio 中单步执行库源代码并不能很好地工作),请回答或评论。

【讨论】:

    猜你喜欢
    • 2022-10-21
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多