r闪亮的决策树数据输入

时间:2017-03-24 15:45:28

标签: r tree shiny decision-tree

我正在创建一个确定决策树模型的闪亮应用程序,然后根据用户输入提出预测。

该模型的开发方式如下:

tr<-prune.tree(tree(Y ~ ., dataset,split="gini"),best=4)

总共有20个变量,实际上只有5个变量在树中使用。所以,我想创建我的应用程序,使用户只需要输入这5个变量,而不是所有变量。这是我尝试的内容(仅显示重要代码):

在server.r中:

 output$treepred<-renderText({
predict(tr,data.frame(PREVIOUS=input$numeric6,NR_EMPLOYED=input$numeric1,CAMPAIGN=input$numeric7,EMP_VAR_RATE=input$numeric8,CONS_PRICE_IDX=input$numeric9),type="class")
})

在ui.r:

box(textOutput("treepred"))

只需运行此操作即可返回错误&#34; object&#39; AGE&#39;找不到&#34; (其中AGE是未使用的变量)。如果我仅使用被发现相关的变量重建树,我会得到一个完全不同(甚至更糟)的树。 (我也试过包含那些不相关的变量,但是将它们设置为NULL或NA,但这也没有用。)

实质上,问题在于r希望用户在他们真的不需要时输入所有数据。有谁知道怎么解决这个问题?

编辑:

一个小例子:

    dir <- "Your directory"
    dataset <- read.csv(paste(dir, "Data.csv",sep = ""))
    dataset[, c(1, 11:13)] <- lapply(dataset[, c(1, 11:13)],as.integer)
    dataset[, c(2:10, 14, 20)] <- lapply(dataset[, c(2:10,14,20)], as.factor)
    dataset[, c(15:19)] <- lapply(dataset[, c(15:19)],as.numeric)
    dataset$PDAYS[dataset$PDAYS == 999] <- NA #this is NA by the definition of the data

    library(tree)

    tree<-prune.tree(tree(Y ~ ., dataset,split="gini"),best=4)

    plot(tree, type="uniform")
    text(tree, pretty=0)

    predict(tree,newdata=dataset,type="class")
    #The above all works perfectly.

    summary(tree)
    #This tells us which variables are relevant

    predict(tree,newdata=data.frame(PREVIOUS=1,CAMPAIGN=1,EMP_VAR_RATE=50,CONS_PRICE_IDX=100,NR_EMPLOYED=5000))
    #returns error: object 'AGE' not found.

    #Retraining the tree with only relevant variables:
    tree2<-prune.tree(tree(Y ~ PREVIOUS+NR_EMPLOYED+CAMPAIGN+EMP_VAR_RATE+CONS_PRICE_IDX, dataset,split="gini"),best=4)

    plot(tree2, type="uniform")
    text(tree2, pretty=0)

    #This tree is completely different and only ever predicts "no"

以下是数据:

https://www.dropbox.com/s/d11tc9d23mw64s5/Data.csv?dl=0

1 个答案:

答案 0 :(得分:1)

好的,我看了一眼。当然令人费解的是为什么第二棵树看起来与第一棵树差别很大。如果要保留相同的变量,则根分割应该相同,因为具有最大信息增益的维度不应更改。我花了一段时间,但你实际上可以在树输出中看到问题。这是第一棵树:

> tree
node), split, n, deviance, yval, (yprob)
      * denotes terminal node

 1) root 1515 1983.00 yes ( 0.3617 0.6383 )  
   2) PREVIOUS < 1.5 865 1167.00 yes ( 0.4035 0.5965 )  
     4) CAMPAIGN < 1.5 460  618.40 yes ( 0.3978 0.6022 )  
       8) EMP_VAR_RATE < -3.2 91  110.70 yes ( 0.2967 0.7033 ) *
       9) EMP_VAR_RATE > -3.2 369  502.70 yes ( 0.4228 0.5772 )  
        18) CONS_PRICE_IDX < 93.2845 221  303.50 no ( 0.5566 0.4434 ) *
        19) CONS_PRICE_IDX > 93.2845 148  157.10 yes ( 0.2230 0.7770 ) *
     5) CAMPAIGN > 1.5 405  548.20 yes ( 0.4099 0.5901 )  
      10) CAMPAIGN < 2.5 256  338.70 yes ( 0.3750 0.6250 )  
        20) NR_EMPLOYED < 5087.65 193  220.80 yes ( 0.2591 0.7409 ) *
        21) NR_EMPLOYED > 5087.65 63   73.47 no ( 0.7302 0.2698 ) *
      11) CAMPAIGN > 2.5 149  206.00 yes ( 0.4698 0.5302 ) *
   3) PREVIOUS > 1.5 650  800.80 yes ( 0.3062 0.6938 ) *

这是第二个。

> tree2
node), split, n, deviance, yval, (yprob)
      * denotes terminal node

 1) root 41188 29000 no ( 0.88735 0.11265 )  
   2) PREVIOUS < 0.5 35563 21240 no ( 0.91168 0.08832 )  
     4) NR_EMPLOYED < 5087.65 2634  3496 no ( 0.62073 0.37927 ) *
     5) NR_EMPLOYED > 5087.65 32929 15850 no ( 0.93495 0.06505 ) *
   3) PREVIOUS > 0.5 5625  6522 no ( 0.73351 0.26649 )  
     6) PREVIOUS < 1.5 4561  4713 no ( 0.78799 0.21201 )  
      12) NR_EMPLOYED < 5087.65 1433  1986 no ( 0.51082 0.48918 ) *
      13) NR_EMPLOYED > 5087.65 3128  1820 no ( 0.91496 0.08504 ) *
     7) PREVIOUS > 1.5 1064  1475 no ( 0.50000 0.50000 ) *
>

第一棵树在PREVIOUS = 1.5找到了最大的基尼分裂,第二棵树在0.5。但是你也可以看到第一棵树出于某种原因只看了1515点,但第二棵树看了41188,还有更多。

为什么呢?如果查看公式,您会看到第一个树查看了所有列,第二个树查看了子集。因此,让我们计算所有行而不会丢失数据:

> sum(complete.cases(dataset))
[1] 1515

这是你的答案。没有为第一个树查看缺少数据的行,但是当您将其限制为某些列时,它们位于第二个树中。难怪树木不同......

至于你的另一个问题,那就是predict.tree算法的工作方式,它确保所有数据都在前面。这允许它使用与其他predict.xxx函数共同的编码基础结构。答案很简单,只需确保在您不关心的所有列中都有虚拟数据。你可以使用这样的东西:

ddf1 <- dataset[1,]
ddf1$PREVIOUS <- 1
ddf1$CAMPAIGN <- 1
ddf1$EMP_VAR_RATE <- 50
ddf1$CONS_PRICE_IDX <- 100
ddf1$CONS_PRICE_IDX <- 5000
predict(tree,newdata=ddf1)

最后一点是,即使在你的第二棵树中,也不是一直只是预测“不”。那些不可能的概率(也可以在树输出中看到)变化很大。您可以通过查看tree$frame数据框以编程方式访问这些分支和值。