【问题标题】:r Shiny Decision Tree Data Inputr 闪亮的决策树数据输入
【发布时间】:2017-08-17 15:28:47
【问题描述】:

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

模型是这样开发的:

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

简单地运行它会返回一个错误“找不到对象'AGE'”(其中 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

【问题讨论】:

  • 我现在不能尝试,但是尝试将textOutput替换为verbatimTextOutuput,并将renderText替换为renderPrint
  • @Smich7 谢谢,但不幸的是,这会导致同样的错误。
  • 非常抱歉,dataset 中有变量“AGE”吗?因为如果它是真的,你不会在predict 函数的测试数据框中给出任何“AGE”变量。 treepredict 中的数据框应具有相同数量的具有相同名称的变量。那么你在训练你的树时不应该使用Y ~ .,而应该使用Y ~ PREVIOUS+NR_EMPLOYED+CAMPAIGN+EMP_VAR_RATE+CONS_PRICE_IDX
  • @Smich7 数据集中确实有一个 AGE 变量,但树模型实际上并没有使用该变量(如果您键入 summary(tr) 可以看到)。我也尝试使用您建议的方法训练树,但不幸的是,这会产生完全不同(并且基本上无法使用)的树。
  • 一直在看,挺有意思的。很快就会有答案。我认为这只是“复杂”,并且您的数据具有高度的“随机性”,即您拥有的变量无法可靠地预测结果。这会导致“不稳定的树木”。

标签: r tree shiny decision-tree


【解决方案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 数据框以编程方式访问这些分支和值。

【讨论】:

  • 我明白了.. 这完全是由于 NA 值(所有这些都是由于一个变量,我现在将删除)。所以理论上,如果我在没有问题变量的情况下再试一次,我应该得到相同的树。非常感谢!
  • 是的,我刚才也做了最后的说明。
  • 我不知道树包也考虑了这些概率,我认为只是派对和 rpart 做到了这一点。非常感谢哈哈,我实际上是想弄清楚如果它们确实存在,如何访问这些概率。
猜你喜欢
  • 2015-01-04
  • 2020-03-28
  • 2014-04-11
  • 1970-01-01
  • 2018-09-23
  • 2014-01-08
  • 1970-01-01
  • 1970-01-01
  • 2014-09-18
相关资源
最近更新 更多