r 闪亮的决策树数据输入

r Shiny Decision Tree Data Input

我正在制作一个确定决策树模型然后根据用户输入进行预测的闪亮应用程序。

模型是这样开发的:

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"))

只是 运行 这 returns 给我一个错误 "object 'AGE' not found" (其中 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

好的,我看了一下。令人费解的当然是为什么第二棵树看起来与第一棵树如此不同。如果您保留相同的变量,根分裂应该是相同的,因为具有最大信息增益的维度不应该改变。我检查了一会儿,但您实际上可以在树输出中看到问题。这是第一棵树:

> 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)

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