我正在努力使用插入符号包来执行分类树几天.问题是我的因素变量.我生成了树,但是当我尝试使用最佳模型对测试样本进行预测时,它失败了,因为列车函数为我的因子变量创建了虚拟对象,然后预测函数无法在测试集中找到这些新创建的虚拟对象.我该如何处理这个问题?
我的代码如下:
install.packages("caret", dependencies = c("Depends", "Suggests"))
library(caret)
db=data.frame(read.csv ("db.csv", head=TRUE, sep=";", na.strings ="?"))
fix(db)
db$defaillance=factor(db$defaillance)
db$def=ifelse(db$defaillance==0,"No","Yes")
db$def=factor(db$def)
db$defaillance=NULL
db$canal=factor(db$canal)
db$sect_isodev=factor(db$sect_isodev)
db$sect_risq=factor(db$sect_risq)
#delete zero variance predictors
nzv <- nearZeroVar(db[,-78])
db_new <- db[,-nzv]
inTrain <- createDataPartition(y = db_new$def, p = .75, list = FALSE)
training <- db_new[inTrain,]
testing <- db_new[-inTrain,]
str(training)
str(testing)
dim(training)
dim(testing)
Run Code Online (Sandbox Code Playgroud)
用于训练/测试的str()函数示例如下:
$ FDR : num 1305 211 162 131 143 ...
$ FCYC : num 0.269 0.18 0.154 0.119 0.139 ...
$ BFDR : num 803 164 108 72 76 63 100 152 188 80 ...
$ TRES : num 502 47 54 59 67 49 53 -7 -103 -109 ...
$ sect_isodev: Factor w/ 9 levels "1","2","3","4",..: 4 3 3 3 3 3 3 3 3 3 ...
$ sect_risq : Factor w/ 6 levels "0","1","2","3",..: 6 6 6 6 6 6 6 6 6 6 ...
$ def : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
> dim(training)
[1] 14553 42
> dim(testing)
[1] 4850 42
Run Code Online (Sandbox Code Playgroud)
然后我的代码是这样的:
fitControl <- trainControl(method = "repeatedcv",
number = 10,
repeats = 10,
classProbs = TRUE,
summaryFunction = twoClassSummary)
#CART1
set.seed(1234)
tree1 = train (def~.,
training,
method = "rpart",
tuneLength=20,
metric="ROC",
trControl = fitControl)
Run Code Online (Sandbox Code Playgroud)
一个样本
summary(tree1$finalModel)
Run Code Online (Sandbox Code Playgroud)
在这儿
RNTB 38.397731
sect_isodev1 6.742289
sect_isodev3 4.005016
sect_isodev8 2.520850
sect_risq3 9.909127
sect_risq4 6.737908
sect_risq5 3.085714
SOLV 73.067539
TRES 47.906884
sect_isodev2 0.000000
sect_isodev4 0.000000
sect_isodev5 0.000000
sect_isodev6 0.000000
sect_isodev7 0.000000
sect_isodev9 0.000000
sect_risq0 0.000000
sect_risq1 0.000000
sect_risq2 0.000000
Run Code Online (Sandbox Code Playgroud)
这是错误:
model.tree1 < - predict(tree1 $ finalModel,testing)eval中的错误(expr,envir,enclos):找不到对象'sect_isodev1'
我很好奇另一件事.我在Max Kuhn的"用R预测建模"中找到了以下语法:
predict(rpartTune$finalModel, newdata, type = "class")
Run Code Online (Sandbox Code Playgroud)
哪rpartTune$finalModel一个是与我相同的分类树(或者与我相同的分类树).现在,R不接受type ="class".只有type ="prob".我因此而感到困扰.
提前感谢您的回复
top*_*epo 10
不要使用predict.rpart与train$finalModel除非你有一个很好的理由.该rpart对象确实知道train所做的任何事情,包括预处理.它可能不会给你正确的答案.毕竟,你可能正在使用train以避免细节,所以让我们predict.train做工作.
马克斯
编辑 -
关于type = "class"和type = "prob"位..
predict.rpart默认为生成类概率.尽管rpart是最早的包之一,但默认情况下这是非典型的大多数生产类.
predict.train默认情况下会生成类,您必须使用它type = "prob"来获取概率.
据我所知,有两个问题:
predict函数tree1$finalModel,predict.rpart因为tree1$finalModel它属于类rpart.我也得到了这个错误,遗憾的是不知道其根本原因.这也是R不接受的原因type = "class".predict.rpart会接受它.train使用公式而不是x和y对象来提供函数会导致sect_isodev1以后无法找到变量的问题用随机数据(类似你的str)使用x和y对象重现你的错误并predict.rpart明确地rpart为我工作:
tree1 = train (y = training$def,
x = training[, -which(colnames(training) == "def")],
method = "rpart",
tuneLength=20,
metric="ROC",
trControl = fitControl)
summary(tree1$finalModel)
# This still results in Error: could not find function "predict.rpart":
model.tree1 <- predict.rpart(tree1$finalModel, newdata = testing)
# Explicitly calling predict.rpart from the rpart package works:
rpart:::predict.rpart(object = tree1$finalModel,
newdata = testing,
type = "class")
Run Code Online (Sandbox Code Playgroud)
顺便说一句,predict(tree1, testing),这意味着使用predict.train与train对象,也适用和回报预测类.编辑:正如Max指出的那样,通常使用这种方法而不是使不同的predict功能工作更好.