वास्तव में यादृच्छिक से एक नमूना पेड़ की साजिश कैसे करें :: getTree ()? [बन्द है]


62

किसी को भी पुस्तकालय या कोड के सुझाव मिले कि कैसे वास्तव में नमूना पेड़ों के एक जोड़े की साजिश रचें :

getTree(rfobj, k, labelVar=TRUE)

(हाँ, मुझे पता है कि आप इसे ऑपरेशनल तरीके से नहीं कर रहे हैं, RF एक ब्लैकबॉक्स है, आदि। मैं नेत्रहीन स्वच्छता-जांच करना चाहता हूं कि कोई वृक्ष यह देखने के लिए कि क्या कोई चर प्रतिरूप व्यवहार कर रहा है, ट्विकिंग / संयोजन / विवेचना / परिवर्तन की आवश्यकता है, जांचें मेरे एन्कोड किए गए कारक कितनी अच्छी तरह काम कर रहे हैं, आदि)


एक सभ्य जवाब के बिना पहले सवाल:

मैं वास्तव में एक नमूना पेड़ की साजिश करना चाहता हूं । तो मेरे साथ उस बारे में बहस मत करो, पहले से ही। मैं varImpPlot(वैरिएबल इम्पोर्टेंस प्लॉट) या partialPlotया MDSPlot, या इन अन्य प्लॉटों के बारे में नहीं पूछ रहा हूं , मेरे पास पहले से ही हैं, लेकिन वे एक नमूना पेड़ देखने के लिए कोई विकल्प नहीं हैं। हां, मैं नेत्रहीन के उत्पादन का निरीक्षण कर सकता हूं getTree(...,labelVar=TRUE)

(मुझे लगता है कि एक plot.rf.tree()योगदान बहुत अच्छी तरह से प्राप्त होगा।)


6
मुझे विशेष रूप से तर्क-वितर्क करने की आवश्यकता नहीं है, खासकर यदि आप किसी स्वयंसेवक से आपकी मदद करने के लिए कह रहे हैं; यह अच्छी तरह से भर नहीं आता है। CV की एक शिष्टाचार नीति है - आप हमारे अक्सर पूछे जाने वाले प्रश्न पढ़ना चाहते हैं ।
गंग -

9
@gung: इस विषय पर हर पिछला प्रश्न लोगों में इस बात का क्षय कर गया है कि यह आवश्यक नहीं था, और वास्तव में आनुवांशिक, एक नमूना पेड़ की साजिश करने के लिए। मेरे द्वारा दिए गए उद्धरणों को पढ़ें। मैं यहाँ एक स्केच की तलाश कर रहा हूँ कि कैसे एक rf ट्री को कोड करना है।
21

3
मुझे कुछ उत्तर मिलते हैं जहाँ उपयोगकर्ता मददगार होने की कोशिश कर रहे हैं और प्रश्न को संबोधित कर रहे हैं, साथ ही विचार के आधार पर सवाल करने वाले w / कुछ टिप्पणी (जो, मैं ईमानदारी से मानता हूं, एक उपयोगी भावना के रूप में भी इरादा है)। यह निश्चित रूप से स्वीकार करना संभव है कि कुछ लोग डब्ल्यू / ओ के परीक्षण से असहमत होंगे।
गंग -

4
मैं शून्य जवाब देखता हूं जहां किसी ने भी एक साल में, एक पेड़ लगाया है। मैं उस विशिष्ट प्रश्न के विशिष्ट उत्तर की तलाश में हूं।
21

1
cforest( पार्टी पैकेज में) के साथ निर्मित एकल पेड़ की साजिश करना संभव है । अन्यथा, आपको data.frameलौटे randomForest::getTreeको एक समान treeवस्तु में बदलना होगा ।
chl

जवाबों:


44

पहला और सबसे आसान) समाधान: यदि आप शास्त्रीय आरएफ के साथ छड़ी करने के लिए उत्सुक नहीं हैं, जैसा कि एंडी लियाव में लागू किया गया है randomForest, तो आप पार्टी पैकेज की कोशिश कर सकते हैं जो मूल आरएफ एल्गोरिथ्म का एक अलग कार्यान्वयन प्रदान करता है (सशर्त पेड़ों और एकत्रीकरण योजना का उपयोग आधारित) इकाइयों पर औसत वजन)। फिर, जैसा कि इस आर-हेल्प पोस्ट पर बताया गया है , आप पेड़ों की सूची के एकल सदस्य की साजिश कर सकते हैं। यह आसानी से चलता है, जहां तक ​​मैं बता सकता हूं। नीचे एक पेड़ की एक साजिश है cforest(Species ~ ., data=iris, controls=cforest_control(mtry=2, mincriterion=0))

यहाँ छवि विवरण दर्ज करें

दूसरा (लगभग रूप में आसान) समाधान: आर में पेड़-आधारित तकनीकों में से अधिकांश ( tree, rpart, TWIX, आदि) एक प्रदान करता है treeएक भी पेड़ की साजिश रचने मुद्रण के लिए की तरह संरचना /। यह विचार randomForest::getTreeऐसे आर ऑब्जेक्ट के आउटपुट को परिवर्तित करने के लिए होगा , भले ही वह सांख्यिकीय दृष्टिकोण से निरर्थक हो। मूल रूप से, पेड़ की संरचना को किसी treeऑब्जेक्ट से एक्सेस करना आसान है , जैसा कि नीचे दिखाया गया है। कृपया ध्यान दें कि यह कार्य के प्रकार के आधार पर थोड़ा भिन्न होगा - प्रतिगमन बनाम वर्गीकरण - जहां बाद के मामले में यह वर्ग-विशेष संभावनाओं को अंतिम स्तंभ obj$frame(जो कि एक है 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

फिर, उन वस्तुओं की सुंदर छपाई और साजिश रचने के तरीके हैं। प्रमुख कार्य एक सामान्य tree:::plot.treeविधि हैं (मैंने एक ट्रिपल रखा है :जो आपको आर को सीधे कोड में देखने की अनुमति देता है) tree:::treepl(ग्राफिकल डिस्प्ले) पर निर्भर करता है और tree:::treeco(कंप्यूट नोड्स निर्देशांक)। इन कार्यों obj$frameसे पेड़ के प्रतिनिधित्व की उम्मीद है । अन्य सूक्ष्म मुद्दे: (1) type = c("proportional", "uniform")डिफ़ॉल्ट प्लॉटिंग विधि में तर्क tree:::plot.tree, नोड्स के बीच ऊर्ध्वाधर दूरी का प्रबंधन करने में मदद करता है ( proportionalइसका अर्थ है कि यह विचलन के लिए आनुपातिक है, uniformइसका मतलब यह तय है); (2) आपको टेक्स्ट लेबल को नोड्स और स्प्लिट्स में जोड़ने के plot(tr)लिए एक कॉल द्वारा पूरक करने की आवश्यकता text(tr)है, जो इस मामले में इसका मतलब है कि आपको भी एक नज़र डालनी होगी tree:::text.tree

getTreeसे विधि 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अपनी आवश्यकताओं के अनुसार अनुकूलित कर पाएंगे , हालांकि मेरे पास इस दृष्टिकोण का उदाहरण नहीं है। विशेष रूप से, आप शायद डिविज़न, क्लास प्रोबेबिलिटीज़ आदि के उपयोग से छुटकारा पाना चाहते हैं, जो आरएफ में सार्थक नहीं हैं। आप सभी चाहते हैं कि नोड्स निर्देशांक और विभाजन मान सेट करें। आप इसके लिए उपयोग कर सकते हैं fixInNamespace(), लेकिन, ईमानदार होने के लिए, मुझे यकीन नहीं है कि यह जाने का सही तरीका है।

तीसरा (और निश्चित रूप से चतुर) समाधान: एक सच्चे as.treeसहायक फ़ंक्शन लिखें जो उपरोक्त सभी "पैच" को कम करेगा। तब आप R के प्लॉटिंग के तरीकों का इस्तेमाल कर सकते हैं या, शायद बेहतर, क्लीमट (सीधे आर से) व्यक्तिगत पेड़ों को प्रदर्शित करने के लिए।


40

मुझे चार साल की देर हो गई है, लेकिन अगर आप वास्तव में randomForestपैकेज से चिपके रहना चाहते हैं (और ऐसा करने के लिए कुछ अच्छे कारण हैं), और वास्तव में पेड़ की कल्पना करना चाहते हैं, तो आप रिप्रिट्री पैकेज का उपयोग कर सकते हैं ।

पैकेज सुपर अच्छी तरह से प्रलेखित नहीं है (आप यहां डॉक्स पा सकते हैं ), लेकिन सब कुछ बहुत सीधा है। रेपो में पैकेज को आरंभीकृत करने के लिए देखें।

options(repos='http://cran.rstudio.org')
have.packages <- installed.packages()
cran.packages <- c('devtools','plotrix','randomForest','tree')
to.install <- setdiff(cran.packages, have.packages[,1])
if(length(to.install)>0) install.packages(to.install)

library(devtools)
if(!('reprtree' %in% installed.packages())){
  install_github('araastat/reprtree')
}
for(p in c(cran.packages, 'reprtree')) eval(substitute(library(pkg), list(pkg=p)))

फिर आगे बढ़ें और अपना मॉडल और पेड़ बनाएं:

library(randomForest)
library(reprtree)

model <- randomForest(Species ~ ., data=iris, importance=TRUE, ntree=500, mtry = 2, do.trace=100)

reprtree:::plot.getTree(model)

और वहाँ तुम जाओ! सुंदर और सरल।

प्लॉट से उत्पन्न पेड़ .getTree (मॉडल)

आप पैकेज में अन्य तरीकों के बारे में जानने के लिए गिटब रेपो की जांच कर सकते हैं। वास्तव में, यदि आप plot.getTree.R की जाँच करते हैं , तो आप देखेंगे कि लेखक अपने स्वयं के कार्यान्वयन का उपयोग करता है as.tree()जिसमें chl yourself ने सुझाव दिया कि आप उसके उत्तर में खुद का निर्माण कर सकते हैं। इसका मतलब है कि आप ऐसा कर सकते हैं:

tree <- getTree(model, k=1, labelVar=TRUE)
realtree <- reprtree:::as.tree(tree, model)

और फिर संभावित रूप realtreeसे अन्य पेड़ प्लॉटिंग पैकेज जैसे कि पेड़ के साथ उपयोग करें ।


बहुत बहुत धन्यवाद, मैं अभी भी खुशी से जवाब स्वीकार कर रहा हूं, यह ऐसा क्षेत्र प्रतीत होता है जहां लोग प्रसाद से असंतुष्ट हैं। मुझे लगता है कि नई नई चीज xgboostभी समर्थन के लिए होगी ।
smci

6
कोई दिक्कत नहीं है। मुझे लाइब्रेरी / पैकेज खोजने में घंटों लग गए इसलिए मुझे लगा कि अगर यह आपके लिए उपयोगी नहीं है, तो यह randomForestपैकेज से चिपके रहते हुए पेड़ों को खींचने की कोशिश करने वाले अन्य लोगों के लिए होगा ।
जंजाल

2
शांत खोज। नोट: यह कुछ अर्थों में, प्रतिनिधि पेड़, भूखंड में पेड़ है, जो कलाकारों की टुकड़ी में अन्य सभी पेड़ों के लिए "निकटतम" औसत पर हैं
क्रिस

2
@ क्रिस समारोह plot.getTree()एक व्यक्तिगत पेड़ भूखंडों। plot.reprtree()उस पैकेज में फ़ंक्शन एक प्रतिनिधि पेड़ प्लॉट करता है।
चुन ली

1
मैं कैरेट से मॉडल प्राप्त किया है और reprtree:::plot.getTree(mod_rf_1$finalModel)फिर से reptree में खिलाना चाहते हैं , हालांकि, वहाँ एक "data.frame (var = fr $ var, splits = as.character (gTree [," स्प्लिट पॉइंट ")) में त्रुटि है: पंक्तियों की संख्या: 2631, 0 "
हैप्पीकोडिंग

15

मैंने एक पेड़ के नियमों को निकालने के लिए कुछ कार्य बनाए हैं।

#**************************
#return the rules of a tree
#**************************
getConds<-function(tree){
  #store all conditions into a list
  conds<-list()
  #start by the terminal nodes and find previous conditions
  id.leafs<-which(tree$status==-1)
	  j<-0
	  for(i in id.leafs){
		j<-j+1
		prevConds<-prevCond(tree,i)
		conds[[j]]<-prevConds$cond
		while(prevConds$id>1){
		  prevConds<-prevCond(tree,prevConds$id)
		  conds[[j]]<-paste(conds[[j]]," & ",prevConds$cond)
        }
		if(prevConds$id==1){
			conds[[j]]<-paste(conds[[j]]," => ",tree$prediction[i])
    }
    }

  }

  return(conds)
}

#**************************
#find the previous conditions in the tree
#**************************
prevCond<-function(tree,i){
  if(i %in% tree$right_daughter){
		id<-which(tree$right_daughter==i)
		cond<-paste(tree$split_var[id],">",tree$split_point[id])
	  }
	  if(i %in% tree$left_daughter){
    id<-which(tree$left_daughter==i)
		cond<-paste(tree$split_var[id],"<",tree$split_point[id])
  }

  return(list(cond=cond,id=id))
}

#remove spaces in a word
collapse<-function(x){
  x<-sub(" ","_",x)

  return(x)
}


data(iris)
require(randomForest)
mod.rf <- randomForest(Species ~ ., data=iris)
tree<-getTree(mod.rf, k=1, labelVar=TRUE)
#rename the name of the column
colnames(tree)<-sapply(colnames(tree),collapse)
rules<-getConds(tree)
print(rules)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.