在 R 中使用插入符号进行分类的 predict(model) 和 predict(model$finalModel) 之间的区别
Posted
技术标签:
【中文标题】在 R 中使用插入符号进行分类的 predict(model) 和 predict(model$finalModel) 之间的区别【英文标题】:Difference between predict(model) and predict(model$finalModel) using caret for classification in R 【发布时间】:2014-02-01 12:44:04 【问题描述】:有什么区别
predict(rf, newdata=testSet)
和
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 在居中和缩放的 testSet 上接收一些真正的正数,在未缩放的测试集上接收 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)
在居中和缩放的 testSetCS 上:
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? 【参考方案1】:弗兰克,
这与您在Cross Validated 上的其他问题非常相似。
你真的需要
1) 显示每个结果的准确预测代码
2) 给我们一个可重现的例子。
使用普通的testSet
、RF.CS
和RF.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 对象,因为我认为它包含最终(最佳)树,因此可以计算新数据集的预测和概率。 确实如此,这就是predict.train
使用的。但是,它可能会对中间的数据做一些事情。
也许您可以澄清testing
和testing2
之间的区别,因为preProcess
以及predict.train
上的调用确实在内部使用preProcess
而predict(xx$finalModel)
没有。否则,由于preProcess
的角色从未被澄清,该帖子会显示为“voodoo-stuff-happens”。 (不过显然 +1。)
最后一个例子不应该比较RF
+ testing2
vs RF.CS
+ testing
吗?以上是关于在 R 中使用插入符号进行分类的 predict(model) 和 predict(model$finalModel) 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
在使用插入符号的 train() 使用公式训练的 randomForest 对象上使用 predict() 时出错
如何一次在 R 中的插入符号中为所有算法查找算法类型(回归、分类)?