AI Hints
Home›Machine Learning Tutorial›Decision Trees and Forests
Machine Learning · Lesson 36 of 85

Random Forests

The wisdom of the crowd.

⏱ 2 min read▶ Video at 1:18:12🎓 Free
Watch this lesson in the Machine Learning courseWatch on YouTube ↗Full Machine Learning course

In nineteen oh six, at a country fair, eight hundred people guessed the weight of an ox. Many guesses were wildly wrong. But the average of all the guesses was almost exactly correct. Individually, people are noisy. Together, their errors cancel out. What if we built a crowd of trees?

Random Forests
From the video: Random Forests
  • 800 guesses at a country fair
  • The average was nearly perfect
  • Errors cancel out

A forest votes

That is a random forest. We train hundreds of trees. But if they were all the same, the crowd would be pointless. We need diversity, and we get it in two ways. Each tree sees a random sample of the rows. And at each split, it can only consider a random handful of features. So each tree is a little different, and a little wrong in its own way. Then they all vote, or for regression, we average them. The noise cancels, and the signal remains.

One tree against a forest

Let's run the contest. One tree, against a forest of two hundred trees. N jobs minus one uses all your computer's cores. Run it. The forest slashes the error, to around thirty four thousand dollars. And we did almost no tuning. Remember our linear model, at over fifty thousand? That is a huge improvement. Your boss will be very pleased. There is also a bonus here, the out of bag score. Since each tree skips some rows, those rows can be used as a free validation set.

forest.pypython
from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor

X, y = fetch_california_housing(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=0)

one = DecisionTreeRegressor(random_state=0).fit(X_tr, y_tr)
forest = RandomForestRegressor(n_estimators=200, n_jobs=-1,
                               oob_score=True, random_state=0).fit(X_tr, y_tr)

print(f"One tree  MAE ${mean_absolute_error(y_te, one.predict(X_te)) * 1e5:,.0f}")
print(f"Forest    MAE ${mean_absolute_error(y_te, forest.predict(X_te)) * 1e5:,.0f}")
print(f"Forest R2 {forest.score(X_te, y_te):.3f}")
print(f"Out-of-bag R2 {forest.oob_score_:.3f}")
Output
One tree  MAE $47,582
Forest    MAE $33,767
Forest R2 0.795
Out-of-bag R2 0.805

What did the forest learn?

Forests are harder to read than one tree, but they can tell us what they used. Feature importances shows how much each feature reduced the error. We sort them, and draw simple bars. Med inc dominates, followed by average occupancy, and then location. A quick warning though. These importances can favour features with many unique values. Later in this course, we will meet a more trustworthy method.

importance.pypython
from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import RandomForestRegressor

data = fetch_california_housing()
forest = RandomForestRegressor(n_estimators=100, n_jobs=-1, random_state=0)
forest.fit(data.data, data.target)

ranked = sorted(zip(forest.feature_importances_, data.feature_names),
                reverse=True)
for share, name in ranked:
    print(f"{name:<11} {share:6.3f}  {'#' * int(share * 60)}")
Output
MedInc       0.521  ###############################
AveOccup     0.137  ########
Latitude     0.093  #####
Longitude    0.091  #####
HouseAge     0.053  ###
AveRooms     0.045  ##
Population   0.032  #
AveBedrms    0.029  #

Summary

A crowd of diverse trees beats any single expert. Random forests are accurate, robust, and very hard to break, which makes them a wonderful default. But there is an even more powerful idea. Instead of a crowd working separately, what if each model learned from the mistakes of the last?

Key takeaways
  • Bagging: random rows
  • Random features at each split
  • Averaging cancels the noise
Next up: Gradient Boosting — learning from mistakes