İlk (ve en kolay) çözüm: Andy Liaw’de uygulandığı gibi klasik RF’ye bağlı kalmak randomForest
istemezseniz , orijinal RF ™ algoritmasının farklı bir uygulamasını sağlayan parti paketini deneyebilirsiniz (şartlı ağaçların ve toplama planının kullanılması birim ağırlığı ortalama). Ardından, bu R-yardım direğinde bildirildiği gibi , ağaç listesinin tek bir üyesini çizebilirsiniz. Anladığım kadarıyla sorunsuz çalışıyor gibi görünüyor. Aşağıda, tarafından üretilen bir ağacın grafiği verilmiştir .cforest(Species ~ ., data=iris, controls=cforest_control(mtry=2, mincriterion=0))
İkinci (neredeyse kolay) çözeltisi: R ağaç esaslı tekniklerin çoğu ( tree
, rpart
, TWIX
vs.) bulunmaktadır tree
, tek ağaç çizme / baskı için benzeri bir yapı. Fikir, randomForest::getTree
istatistiksel bir bakış açısından saçma olmasa bile, böyle bir R nesnesinin çıktısını dönüştürmek olacaktır . Temel olarak, ağaç yapısına tree
aşağıda gösterildiği gibi bir nesneden erişmek kolaydır . Regresyon sınıflandırma - - vs. sonraki durumda, son sütun olarak sınıf özgü olasılıkları katacak nerede hafifçe görevin türüne bağlı olarak farklılık göstereceğini unutmayın obj$frame
(a olan data.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
Sonra, bu nesnelerin güzel yazdırılması ve çizilmesi için yöntemler vardır. Anahtar işlevler genel bir tree:::plot.tree
yöntemdir ( :
kodu doğrudan R'de görüntülemenizi sağlayan üçlü bir koydum ) tree:::treepl
(grafiksel gösterime) ve tree:::treeco
(hesaplama düğümleri koordinatlarına) dayanıyor . Bu fonksiyonlar obj$frame
ağacın temsilini bekler . Diğer ince konular: (1) type = c("proportional", "uniform")
varsayılan çizim yöntemindeki argüman , tree:::plot.tree
düğümler arasındaki dikey mesafeyi yönetmeye yardımcı olur ( proportional
sapma ile orantılı uniform
olduğu, sabit olduğu anlamına gelir); (2) düğümlere ve bölmelere metin etiketleri eklemek plot(tr)
için yapılan bir çağrı ile tamamlamanız gerekir text(tr)
; bu durumda bu, ayrıca bir göz atmanız gerektiği anlamına gelir tree:::text.tree
.
getTree
Dan yöntem randomForest
döndürür çevrimiçi yardımda belgelenmiştir farklı bir yapı. Tipik bir çıktı, status
kod (-1) ile gösterilen terminal düğümleriyle aşağıda gösterilmiştir . (Yine, çıktı, görevin türüne bağlı olarak değişir, ancak yalnızca status
ve prediction
sütunlarına göre değişir .)
> 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
Eğer tarafından oluşturulan birine yukarıdaki tabloya dönüştürmek için yönetebilirsiniz ise tree
, muhtemelen özelleştirmek mümkün olacak tree:::treepl
, tree:::treeco
ve tree:::text.tree
bu yaklaşımın bir örneği yok gerçi, ihtiyaçlarınıza göre. Özellikle, RF'de anlamlı olmayan sapma, sınıf olasılıkları vb. Kullanımından kurtulmak istersiniz. Tek istediğiniz düğümlerin koordinatlarını ayarlamak ve değerleri bölmektir. Bunun için kullanabilirsiniz fixInNamespace()
, ama dürüst olmak gerekirse, bunun doğru yol olduğundan emin değilim.
Üçüncü (ve kesinlikle zekice) çözüm:as.tree
Yukarıdaki tüm "yamaları" azaltan gerçek bir yardımcı işlev yazın . Tek tek ağaçları görüntülemek için R'nin çizim yöntemlerini veya muhtemelen daha iyi olan Klimt'i (doğrudan R'den) kullanabilirsiniz.