【问题标题】:R caret package (rpart): constructing a classification treeR caret 包(rpart):构造分类树
【发布时间】:2015-02-17 13:15:09
【问题描述】:

我为使用 caret 包执行分类树而苦苦挣扎了好几天。 问题是我的因素变量。我生成了树,但是当我尝试使用最佳模型对测试样本进行预测时,它失败了,因为 train 函数为我的因子变量创建了虚拟变量,然后 predict 函数在测试集中找不到这些新创建的虚拟变量.我该如何处理这个问题?

我的代码如下:

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)

用于训练/测试的 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

然后我的代码是这样的:

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)

一个样本

summary(tree1$finalModel)

来了

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

这是错误:

model.tree1

我对另一件事感到好奇。我在 Max Kuhn 的“Predictive Modeling with R”中发现了以下语法:

predict(rpartTune$finalModel, newdata, type = "class")

其中rpartTune$finalModel 是与我的(或我的与他的相同)相同的分类树。 现在,R 不接受 type="class"。只键入="prob"。我因此而烦恼。

提前感谢您的回复

【问题讨论】:

    标签: r rpart r-caret


    【解决方案1】:

    据我所知,有两个问题:

    • R 找不到适合tree1$finalModelpredict 函数,它应该是predict.rpart,因为tree1$finalModel 属于rpart 类。我也得到了那个错误,不幸的是不知道根本原因。这也是 R 不接受type = "class" 的原因。 predict.rpart 会接受。
    • train 函数提供公式而不是 x 和 y 对象会导致以后找不到像 sect_isodev1 这样的变量

    使用 x 和 y 对象使用随机数据(类似于您的 str)重现您的错误并从 rpart 显式调用 predict.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") 
    

    顺便说一句,predict(tree1, testing),这意味着将predict.traintrain 对象一起使用,也可以工作并返回预测的类。 编辑:正如 Max 指出的那样,通常最好只使用这种方法,而不是让不同的 predict 函数工作。

    【讨论】:

      【解决方案2】:

      除非您有充分的理由,否则不要将 predict.rparttrain$finalModel 一起使用。 rpart 对象不知道train 所做的任何事情,包括预处理。它可能不会给你正确的答案。毕竟,您可能会使用train 来避免细节问题,所以让predict.train 来完成这项工作。

      最大

      编辑 -

      关于type = "class"type = "prob" 位..

      predict.rpart 默认生成类概率。尽管rpart 是最早的包之一,但它是非典型的,因为默认情况下大多数生产类。

      predict.train 默认生成类,您必须使用type = "prob" 来获取概率。

      【讨论】:

        猜你喜欢
        • 2015-09-18
        • 2018-09-25
        • 2013-04-09
        • 2021-05-30
        • 2015-01-11
        • 2014-04-08
        • 2015-12-23
        • 2011-02-05
        • 2015-08-02
        相关资源
        最近更新 更多