I checked many posts to figure out how random forest (RF) learning algorithm (an ensemble of many decision trees (DT) constructed by Rain forest algorithm) within bagging select split points at each leaf. There are some close questions which are have not been answered in this matter: ref1, ref2. I know that some python package use Splitter implementation, probably based on Gini impurity as they asked here for how it works as well as its reason to use in DT. For example, sklearn package uses CART algorithm to build RF Ref1 Ref2. Also, I found below posts without further explanation about how split points are selected as criteria over dataset exactly:
"... Distance is not a factor with trees - what matters is whether the value is greater than or less than the split point, not the distance from the split point." ref
... unlike linear/logistic regression, RF doesn't work by distance (they work with finding good split for your features), so NO NEED for One-Hot Encoding. ref
Considering an example for continuous target variables through dataframe, once I watched carefully StatQuest: Random Forests Part 1 - Building, Using and Evaluating, and the best I could find with a true example is this video:
Knowing that the decision trees in the random forest are trained on different subsets of the training data (using random features ("feature bagging")), I used and developed the bootstrapped tables or sub-dataframe (resampled but with replacement) in the explanation for 1st DT for better understanding and find relationships in the video example:
Here I see 1st DT just both randomly selected variables from data:
x1 =< 4.9 #selected from `id=0` only
x0 =< 4.3 #selected from `id=0` only
So how they selected from id=0
only?
I follow other bootstrapped tables:
Then I see 2nd DT just both randomly selected variables from data:
x3 =< 4.6 #selected from `id=4` only
# No x2 ??
So how they selected just from id=4
only? Is it a random id
?
I follow other bootstrapped tables:
Then I see 3rd DT, just both randomly selected variables from the data:
x2 =< 4.1 #selected from `id=0` or `id=2` not clear?
x2 =< 4.1 #selected from `id=4`
Here is not clear to me why twice x2
was involved in the 3rd tree without involving variable x4
?
Finally, I see the fourth DT in the video, from both randomly selected variables from the data:
Then I see 3rd DT, just both randomly selected variables from the data:
x1 =< 4.4 #selected from `id=3`
x2 =< 6.1 #selected from `id=1`
So Qs:
- Based on which criteria split points are taken/selected for randomly selected pair variables?
- Again, here twice,
x1
was involved in the 4th tree without involving variablex1
? Does it make sense? - I'm unsure what I marked based on my finding; explain the "criteria" of
x > y
, and if so, how it works. Sometimes both randomly selected pair variables are involved in DT; sometimes not. - I didn't get based on the pick split points
y
viaid=#
? Is there any rule, or is it just randomly picked? Can we say it is relative? - Final decision is being made when the end leaf is
0
or1
?
My pythonic implementation:
#Generate data in the video example
import pandas as pd
d = {'x0' : pd.Series([4.3, 3.9, 2.7, 6.6, 6.5, 2.7], index=[0, 1, 2, 3, 4, 5]),
'x1' : pd.Series([4.9, 6.1, 4.8, 4.4, 2.9, 6.7], index=[0, 1, 2, 3, 4, 5]),
'x2' : pd.Series([4.1, 5.9, 4.1, 4.5, 4.7, 4.2], index=[0, 1, 2, 3, 4, 5]),
'x3' : pd.Series([4.7, 5.5, 5.0, 3.9, 4.6, 5.3], index=[0, 1, 2, 3, 4, 5]),
'x4' : pd.Series([5.5, 5.9, 5.6, 5.9, 6.1, 4.8], index=[0, 1, 2, 3, 4, 5]),
'y' : pd.Series([0.0, 0.0, 0.0, 1.0, 1.0, 1.0], index=[0, 1, 2, 3, 4, 5]),
}
df = pd.DataFrame(d)
print(df)
# x0 x1 x2 x3 x4 y
#0 4.3 4.9 4.1 4.7 5.5 0.0
#1 3.9 6.1 5.9 5.5 5.9 0.0
#2 2.7 4.8 4.1 5.0 5.6 0.0
#3 6.6 4.4 4.5 3.9 5.9 1.0
#4 6.5 2.9 4.7 4.6 6.1 1.0
#5 2.7 6.7 4.2 5.3 4.8 1.0
#Create RF model
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')
%matplotlib inline
import random
from pprint import pprint
import pdb
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
#Create and fit RF model with 4 trees
rf = RandomForestClassifier(n_estimators=4, random_state=0)
rf.fit(df.iloc[:,0:5], df.iloc[:,-1])
#len(rf.estimators_) #4
#Plot the trees for monitoring split points in 1/4 of trees (1st tree)
tree.plot_tree(rf.estimators_[0])
#Plot the trees for monitoring split points in 2/4 of trees (2nd tree)
tree.plot_tree(rf.estimators_[1])
#Plot the trees for monitoring split points in 3/4 of trees (3rd tree)
tree.plot_tree(rf.estimators_[2])
#Plot the trees for monitoring split points in 3/4 of trees (4th tree)
tree.plot_tree(rf.estimators_[3])