第一个(也是最简单的)解决方案:如果您不愿意像Andy Liaw的那样坚持使用经典的RF,则randomForest可以尝试party包,它提供了原始RF ™算法的不同实现(使用条件树和基于聚合的方案单位重量平均值)。然后,如该R-help文章所述,您可以绘制树列表的单个成员。据我所知,它似乎运行顺利。下面是由生成的一棵树的图cforest(Species ~ ., data=iris, controls=cforest_control(mtry=2, mincriterion=0))。

第二(几乎一样简单)溶液:大多数的基于树的技术在R( ,,tree 等)提供一个样结构进行打印/绘制一棵树。这个想法是将R 的输出转换为这样的R对象,即使从统计的角度来看这是毫无意义的。基本上,很容易从对象访问树结构,如下所示。请注意,根据任务类型(回归与分类)的不同,它会稍有不同。在后一种情况下,它将添加特定于类的概率作为的最后一列(即)。rpartTWIXtreerandomForest::getTreetreeobj$framedata.frame
> library(tree)
> tr <- tree(Species ~ ., data=iris)
> tr
node), split, n, deviance, yval, (yprob)
      * denotes terminal node
 1) root 150 329.600 setosa ( 0.33333 0.33333 0.33333 )  
   2) Petal.Length < 2.45 50   0.000 setosa ( 1.00000 0.00000 0.00000 ) *
   3) Petal.Length > 2.45 100 138.600 versicolor ( 0.00000 0.50000 0.50000 )  
     6) Petal.Width < 1.75 54  33.320 versicolor ( 0.00000 0.90741 0.09259 )  
      12) Petal.Length < 4.95 48   9.721 versicolor ( 0.00000 0.97917 0.02083 )  
        24) Sepal.Length < 5.15 5   5.004 versicolor ( 0.00000 0.80000 0.20000 ) *
        25) Sepal.Length > 5.15 43   0.000 versicolor ( 0.00000 1.00000 0.00000 ) *
      13) Petal.Length > 4.95 6   7.638 virginica ( 0.00000 0.33333 0.66667 ) *
     7) Petal.Width > 1.75 46   9.635 virginica ( 0.00000 0.02174 0.97826 )  
      14) Petal.Length < 4.95 6   5.407 virginica ( 0.00000 0.16667 0.83333 ) *
      15) Petal.Length > 4.95 40   0.000 virginica ( 0.00000 0.00000 1.00000 ) *
> tr$frame
            var   n        dev       yval splits.cutleft splits.cutright yprob.setosa yprob.versicolor yprob.virginica
1  Petal.Length 150 329.583687     setosa          <2.45           >2.45   0.33333333       0.33333333      0.33333333
2        <leaf>  50   0.000000     setosa                                  1.00000000       0.00000000      0.00000000
3   Petal.Width 100 138.629436 versicolor          <1.75           >1.75   0.00000000       0.50000000      0.50000000
6  Petal.Length  54  33.317509 versicolor          <4.95           >4.95   0.00000000       0.90740741      0.09259259
12 Sepal.Length  48   9.721422 versicolor          <5.15           >5.15   0.00000000       0.97916667      0.02083333
24       <leaf>   5   5.004024 versicolor                                  0.00000000       0.80000000      0.20000000
25       <leaf>  43   0.000000 versicolor                                  0.00000000       1.00000000      0.00000000
13       <leaf>   6   7.638170  virginica                                  0.00000000       0.33333333      0.66666667
7  Petal.Length  46   9.635384  virginica          <4.95           >4.95   0.00000000       0.02173913      0.97826087
14       <leaf>   6   5.406735  virginica                                  0.00000000       0.16666667      0.83333333
15       <leaf>  40   0.000000  virginica                                  0.00000000       0.00000000      1.00000000
然后,有一些方法可以漂亮地打印和绘制这些对象。关键功能是一种通用tree:::plot.tree方法(我放了一个三元组:,使您可以直接在R中查看代码),它依赖于tree:::treepl(图形显示)和tree:::treeco(计算节点坐标)。这些功能需要obj$frame树的表示。其他细微的问题:(1)type = c("proportional", "uniform")默认绘图方法中的参数tree:::plot.tree有助于管理节点之间的垂直距离(proportional意味着它与偏差成正比,uniform意味着它是固定的);(2)您需要plot(tr)通过调用来text(tr)补充内容,以向节点和拆分添加文本标签,在这种情况下,这意味着您还必须查看tree:::text.tree。
getTreefrom中的方法randomForest返回不同的结构,该结构在联机帮助中进行了说明。典型输出如下所示,终端节点用status代码(-1)表示。(同样,输出将根据任务的类型而有所不同,但仅取决于status和prediction列。)
> library(randomForest)
> rf <- randomForest(Species ~ ., data=iris)
> getTree(rf, 1, labelVar=TRUE)
   left daughter right daughter    split var split point status prediction
1              2              3 Petal.Length        4.75      1       <NA>
2              4              5 Sepal.Length        5.45      1       <NA>
3              6              7  Sepal.Width        3.15      1       <NA>
4              8              9  Petal.Width        0.80      1       <NA>
5             10             11  Sepal.Width        3.60      1       <NA>
6              0              0         <NA>        0.00     -1  virginica
7             12             13  Petal.Width        1.90      1       <NA>
8              0              0         <NA>        0.00     -1     setosa
9             14             15  Petal.Width        1.55      1       <NA>
10             0              0         <NA>        0.00     -1 versicolor
11             0              0         <NA>        0.00     -1     setosa
12            16             17 Petal.Length        5.40      1       <NA>
13             0              0         <NA>        0.00     -1  virginica
14             0              0         <NA>        0.00     -1 versicolor
15             0              0         <NA>        0.00     -1  virginica
16             0              0         <NA>        0.00     -1 versicolor
17             0              0         <NA>        0.00     -1  virginica
如果您可以设法将上表转换为生成的表,尽管我没有这种方法的示例,但tree您也许可以自定义tree:::treepl,tree:::treeco并tree:::text.tree满足您的需求。特别是,您可能希望摆脱使用偏差,类概率等问题,这些问题在RF中没有意义。您只需要设置节点坐标和分割值。您可以使用fixInNamespace()它,但是老实说,我不确定这是正确的方法。
第三种(当然也是聪明的)解决方案:编写一个真正的as.tree帮助程序函数,以减轻上述所有“补丁”。然后,您可以使用R的绘图方法,或者更好的是使用Klimt(直接来自R)来显示单个树。