我有一个模型(fit
),基于上个月的历史信息。现在我想使用我的模型预测当前月份。当我尝试调用以下代码时:
predicted <- predict(fit, testData[-$Readmit])
我得到以下错误:
Error in UseMethod("predict") : no applicable method for 'predict'
applied to an object of class "train"
备注:
1.通过以下方式创建拟合模型:train
函数,来自caret包,使用随机森林算法
predict
是一个泛型函数,它将根据第一个输入参数调用特定的predict函数。在我的例子中,它将是:>fit$modelInfo$label
[1] "Random Forest"
因此,调用的predict方法将是:predict.randomForest。更多信息请参见[插入符号文档][3]。
下面是生成模型和调用模型的源代码摘要:
# Script-1: create a model:
fit <- train(testData[-$Readmit], testData$Readmit)
saveRDS(fit, modelFileName) # save the fit object into a file
# Script-2: predict
fit <- readRDS(modelFileName) # Load the model (generated previously)
predicted <- predict(fit, testData[-$Readmit])
注意:生成模型的执行时间约为3个小时,所以我将对象保存起来,以便以后重用。
来自训练模型的数据集为以下结构:
> str(fit$trainingData)
'data.frame': 29955 obs. of 27 variables:
$ Acuity : Factor w/ 3 levels "Elective ","Emergency ",..: 2 2 2 1 1 2 2 2 1 1 ...
$ AgeGroup : Factor w/ 10 levels "100-105","65-70",..: 8 6 9 9 5 4 9 2 3 2 ...
$ IsPriority : int 0 0 0 0 0 0 0 0 0 0 ...
$ QNXTReferToId : int 115 1703712 115 3690 1948 115 109 512 481 1785596 ...
$ QNXTReferFromId : int 1740397 1724801 1711465 1704170 1714272 1731911 1535 1712758 1740614 1760252 ...
$ iscasemanagement : Factor w/ 2 levels "N","Y": 2 1 1 2 2 1 2 1 2 2 ...
$ iseligible : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 2 2 2 2 ...
$ referralservicecode : Factor w/ 11 levels "12345","278",..: 1 1 1 9 9 1 1 6 9 9 ...
$ IsHighlight : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 1 ...
$ admittingdiagnosiscode: num 439 786 785 786 428 ...
$ dischargediagnosiscode: num 439 0 296 786 428 ...
$ RealLengthOfStay : int 3 1 6 1 2 3 3 7 3 2 ...
$ QNXTPCPId : int 1740397 1724801 1711465 1704170 1714272 1731911 1535 1712758 1740614 1760252 ...
$ QNXTProgramId : Factor w/ 3 levels "QMXHPQ0839 ",..: 1 1 1 1 1 1 1 1 1 1 ...
$ physicalzipcode : int 33054 33712 33010 33809 33010 33013 33142 33030 33161 33055 ...
$ gender : Factor w/ 2 levels "F","M": 1 1 1 1 2 1 1 2 2 1 ...
$ ethnicitycode : Factor w/ 4 levels "ETHN0001 ",..: 4 4 4 4 4 4 4 4 4 4 ...
$ dx1 : num 439 786 296 786 428 ...
$ dx2 : num 439 292 785 786 428 ...
$ dx3 : num 402 0 250 0 0 ...
$ svc1 : int 0 120 120 762 762 120 120 120 762 762 ...
$ svc2 : int 120 0 0 0 0 0 0 0 0 0 ...
$ svc3 : int 0 0 0 0 0 0 0 0 0 0 ...
$ Disposition : Factor w/ 28 levels "0","APPEAL & GRIEVANCE REVIEW ",..: 11 11 16 11 11 11 11 11 11 11 ...
$ AvgIncome : Factor w/ 10 levels "-1",">100k","0-25k",..: 3 6 3 8 3 4 3 5 4 4 ...
$ CaseManagerNameID : int 124 1 1 19 20 1 16 1 43 20 ...
$ .outcome : Factor w/ 2 levels "NO","YES": 1 2 2 1 1 1 2 2 1 1 ...
现在testData
将具有以下结构:
> str(testData[-$Readmit])
'data.frame': 610 obs. of 26 variables:
$ Acuity : Factor w/ 4 levels "0","Elective ",..: 3 2 4 2 2 2 4 3 3 3 ...
$ AgeGroup : Factor w/ 9 levels "100-105","65-70",..: 4 3 5 4 2 9 4 2 4 6 ...
$ IsPriority : int 0 0 0 0 0 0 1 1 1 1 ...
$ QNXTReferToId : int 2140 482 1703785 1941 114 1714905 1703785 98 109 109 ...
$ QNXTReferFromId : int 1791383 1729375 1718532 1746336 1718267 1718267 1718532 98 109 109 ...
$ iscasemanagement : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 1 2 2 1 ...
$ iseligible : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 2 2 2 2 ...
$ referralservicecode : Factor w/ 7 levels "12345","IPMAT ",..: 5 1 1 1 1 1 1 5 1 5 ...
$ IsHighlight : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 1 ...
$ admittingdiagnosiscode: num 11440 11317 11420 11317 1361 ...
$ dischargediagnosiscode: num 11440 11317 11420 11317 1361 ...
$ RealLengthOfStay : int 1 2 4 3 1 1 16 1 1 3 ...
$ QNXTPCPId : int 3212 1713678 1738430 1713671 1720569 1791640 1725962 1148 1703290 1705009 ...
$ QNXTProgramId : Factor w/ 2 levels "QMXHPQ0839 ",..: 1 1 1 1 1 1 1 1 1 1 ...
$ physicalzipcode : int 34744 33175 33844 33178 33010 33010 33897 33126 33127 33125 ...
$ gender : Factor w/ 2 levels "F","M": 2 1 2 1 2 2 2 1 1 2 ...
$ ethnicitycode : Factor w/ 1 level "No Ethnicity ": 1 1 1 1 1 1 1 1 1 1 ...
$ dx1 : num 11440 11317 11420 11317 1361 ...
$ dx2 : num 11440 11317 11420 11317 1361 ...
$ dx3 : num 0 1465 0 11326 0 ...
$ svc1 : int 52648 27447 50040 27447 55866 55866 51595 0 99221 300616 ...
$ svc2 : int 76872 120 50391 120 120 38571 120 762 120 0 ...
$ svc3 : int 762 0 120 0 0 51999 0 0 0 762 ...
$ Disposition : Factor w/ 14 levels "0","DENIED- Not Medically Necessary ",..: 3 5 3 4 3 3 5 3 3 5 ...
$ AvgIncome : Factor w/ 10 levels "-1",">100k","0-25k",..: 6 7 5 9 3 3 6 4 3 4 ...
$ CaseManagerNameID : int 1 2 3 4 5 6 7 8 9 7 ...
变量结构是一样的,只是某些因子变量的水平不同,因为某些变量有了新的值。例如:Acuity
在模型中具有3个水平,而在测试数据中具有4个水平。
我没有办法预先知道所有变量的所有可能水平。
任何建议,请…
先谢谢你,
大卫
3条答案
按热度按时间aelbi1ox1#
我想我找到了为什么会发生这种情况...
predict
是一个泛型函数:stats
包。我使用命名空间::
-notation来调用caret
包中的函数(这是创建用户包的建议),而caret
包中的等效predict
函数是:predict.train
,这是一个内部函数,不能被外部应用程序调用。调用此函数的唯一方法是使用stats
包中的通用predict
函数,然后基于第一个输入参数的类:predicted <- predict(fit, testData[-$Readmit])
它标识将调用的特定predict
函数。对于这个特定的例子,这个函数的类是
train
,所以它实际上会调用这个函数:train.predict
来自caret
包。此函数还根据所使用的算法(方法)处理预测请求的特定函数,例如:predict.gbm
或predict.glm
等。在插入符号documentation部分中进行了详细说明:5.7提取预测和分类概率因此,
::
-表示法适用于包中的其他函数,例如:例如caret.train
,但不是针对这个特定的:predict
。在这种情况下,需要显式加载库,以便在内部调用predict.train
函数。简而言之,解决方案只是在调用
predict
函数之前添加以下行:然后错误消失。
1dkrff032#
根据@大卫Leal的回答,我尝试在调用predict函数之前加载
library(caret)
,但没有帮助。在尝试了一点之后,我意识到我必须加载包含模型本身的库。在我的例子中,我必须调用
library(kenlab)
来获得支持向量。bvjveswy3#
在解决类似问题时遇到了这个帖子,并希望添加我的解决方案。特别是,上面的答案涉及在包内调用
library()
,强烈建议不要这样做,因为它可能会在不知不觉中改变用户的库搜索路径并导致命名空间冲突。我的答案可能是特定于具体情况的,但它们在不需要library()
或require()
的情况下工作。我的目标是创建一个包,允许用户使用我已经创建的模型从他们自己的数据生成预测。这些模型将被硬编码到包中。它们包括基于
kknn
的k-最近邻模型和基于rpart
的决策树模型。这两个模型都是使用tidymodels
包创建的。从
rpart
树模型开始,因为它是最简单的。当尝试运行stats::predict(hla_tree$model, new_data = df)
时,我最初收到了与OP相同的错误:幸运的是,在
parsnip
(tidymodels
的相关部分)中,predict.model_fit
是一个导出对象,因此只需将该行更改为parsnip::predict.model_fit(hla_tree$model, new_data = df)
就可以纠正这一点kknn
k近邻模型更具挑战性。这个错误似乎是特定于
kknn
包以及contr.dummy
函数如何在kknn()
中被引用为引用对象。我对为什么会发生这种情况的最佳猜测是基于函数如何从包内的kknn
命名空间加载的顺序。在包内,对kknn()
的调用将在contr.dummy()
加载到命名空间之前引用contr.dummy
,导致在调用kknn()
时出错。在包外部,library(kknn)
将在开始时将contr.dummy()
添加到名称空间,所以kknn()
会成功。幸运的是,这个问题已经在pending pull request to
kknn
中得到了解决。usethis::use_dev_package("kknn", remote = "https://github.com/KlausVigo/kknn#24")
将特定于拉取请求的包添加到DESCRIPTION
文件roxygen
注解中添加了@import kknn
stats::predict(knn_model$fit, df)
在这些步骤之后,包通过了所有的
devtools::check()
步骤,并且看起来像预期的那样工作。