使用caret进行R语言分类问题中,predict(model)和predict(model$finalModel)的区别

9

这两者有何不同?

predict(rf, newdata=testSet)

and

predict(rf$finalModel, newdata=testSet) 

我使用preProcess=c("center", "scale")来训练模型。

tc <- trainControl("repeatedcv", number=10, repeats=10, classProbs=TRUE, savePred=T)
rf <- train(y~., data=trainingSet, method="rf", trControl=tc, preProc=c("center", "scale"))

当我在一个经过居中和缩放的测试集上运行它时,我收到了0个真阳性。

testSetCS <- testSet
xTrans <- preProcess(testSetCS)
testSetCS<- predict(xTrans, testSet)
testSet$Prediction <- predict(rf, newdata=testSet)
testSetCS$Prediction <- predict(rf, newdata=testSetCS)

但是当我在未经缩放的测试集上运行时,仍然会获得一些真正的阳性结果。我必须使用rf$finalModel在经过居中和缩放的测试集上获得一些真正的阳性结果,而在未经缩放的测试集上使用rf对象... 我漏了什么?


编辑

测试:

tc <- trainControl("repeatedcv", number=10, repeats=10, classProbs=TRUE, savePred=T)
RF <-  train(Y~., data= trainingSet, method="rf", trControl=tc) #normal trainingData
RF.CS <- train(Y~., data= trainingSet, method="rf", trControl=tc, preProc=c("center", "scale")) #scaled and centered trainingData

在普通的测试集上:

RF predicts reasonable              (Sensitivity= 0.33, Specificity=0.97)
RF$finalModel predicts bad       (Sensitivity= 0.74, Specificity=0.36)
RF.CS predicts reasonable           (Sensitivity= 0.31, Specificity=0.97)
RF.CS$finalModel same results like RF.CS    (Sensitivity= 0.31, Specificity=0.97)

在测试集上进行居中和缩放:

RF predicts very bad                (Sensitivity= 0.00, Specificity=1.00)
RF$finalModel predicts reasonable       (Sensitivity= 0.33, Specificity=0.98)
RF.CS predicts like RF              (Sensitivity= 0.00, Specificity=1.00)
RF.CS$finalModel predicts like RF       (Sensitivity= 0.00, Specificity=1.00)

看起来$finalModel需要与trainingSet和testSet相同的格式,而训练对象只接受未居中和未缩放的数据,无论选择了哪个preProcess参数。

预测代码(其中testSet是普通数据,testSetCS是居中和缩放后的数据):

testSet$Prediction <- predict(RF, newdata=testSet)
testSet$PredictionFM <- predict(RF$finalModel, newdata=testSet)
testSet$PredictionCS <- predict(RF.CS, newdata=testSet)
testSet$PredictionCSFM <- predict(RF.CS$finalModel, newdata=testSet)

testSetCS$Prediction <- predict(RF, newdata=testSetCS)
testSetCS$PredictionFM <- predict(RF$finalModel, newdata=testSetCS)
testSetCS$PredictionCS <- predict(RF.CS, newdata=testSetCS)
testSetCS$PredictionCSFM <- predict(RF.CS$finalModel, newdata=testSetCS)

请问您能否发布一下您最后的训练对象 RF 和 RF.CS 的预测代码? - doctorate
1个回答

12

Frank,

这与您在Cross Validated上的另一个问题非常相似。

您确实需要:

1)为每个结果显示您的精确预测代码

2)给我们提供可重现的示例。

使用正常的testSetRF.CSRF.CS$finalModel不应该给您相同的结果,我们应该能够重现它。此外,您的代码中存在语法错误,因此它不能完全执行。

最后,我真的不确定为什么您会使用finalModel对象。 train的目的是处理细节,以这种方式(这是您的选择)绕过通常应用的完整代码集。

以下是可重现的示例:

 library(mlbench)
 data(Sonar)

 set.seed(1)
 inTrain <- createDataPartition(Sonar$Class)
 training <- Sonar[inTrain[[1]], ]
 testing <- Sonar[-inTrain[[1]], ]

 pp <- preProcess(training[,-ncol(Sonar)])
 training2 <- predict(pp, training[,-ncol(Sonar)])
 training2$Class <- training$Class
 testing2 <- predict(pp, testing[,-ncol(Sonar)])
 testing2$Class <- testing2$Class

 tc <- trainControl("repeatedcv", 
                    number=10, 
                    repeats=10, 
                    classProbs=TRUE, 
                    savePred=T)
 set.seed(2)
 RF <-  train(Class~., data= training, 
              method="rf", 
              trControl=tc)
 #normal trainingData
 set.seed(2)
 RF.CS <- train(Class~., data= training, 
                method="rf", 
                trControl=tc, 
                preProc=c("center", "scale")) 
 #scaled and centered trainingData

这是一些结果:
 > ## These should not be the same
 > all.equal(predict(RF, testing,  type = "prob")[,1],
 +           predict(RF, testing2, type = "prob")[,1])
 [1] "Mean relative difference: 0.4067554"
 > 
 > ## Nor should these
 > all.equal(predict(RF.CS, testing,  type = "prob")[,1],
 +           predict(RF.CS, testing2, type = "prob")[,1])
 [1] "Mean relative difference: 0.3924037"
 > 
 > all.equal(predict(RF.CS,            testing, type = "prob")[,1],
 +           predict(RF.CS$finalModel, testing, type = "prob")[,1])
 [1] "names for current but not for target"
 [2] "Mean relative difference: 0.7452435" 
 >
 > ## These should be and are close (just based on the 
 > ## random sampling used in the final RF fits)
 > all.equal(predict(RF,    testing, type = "prob")[,1],
 +           predict(RF.CS, testing, type = "prob")[,1])
 [1] "Mean relative difference: 0.04198887"

最大值


我使用了$finalModel对象,因为我认为它包含了最终(最佳)的决策树,因此可以计算新数据集的预测和概率。 - Frank
2
它确实如此,这就是predict.train使用的内容。然而,在此期间,它可能会对数据进行一些重要的处理。 - topepo
4
也许你可以澄清preProcess对于testingtesting2之间差异的影响,同时指出predict.train的调用会在内部使用preProcess,而predict(xx$finalModel)则不会。否则,这篇文章看起来有点像“神秘事情发生了”,因为preProcess的作用从未被澄清。(当然还是要给你一个赞的。) - usεr11852
最后一个例子不应该将 RF + testing2RF.CS + testing 进行比较吗? - jiggunjer

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