Skip to main content

How to Train a Random Forest Regression Model with scikit-learn

· 6 min read
Jagdish Kumawat
Founder @ Dewiride

A random forest is one of the most dependable models for tables of numbers. It trains many decision trees on random slices of the data and averages their answers, so one odd tree can't throw it off. This guide trains scikit-learn's RandomForestRegressor to predict house values, explains its main settings, and shows which features it relied on, with real output.

Syntax​

Syntax
from sklearn.ensemble import RandomForestRegressor

model = RandomForestRegressor(n_estimators=100, max_depth=None, random_state=None, n_jobs=None)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
PartWhat it meansDefault
n_estimatorsHow many trees the forest has100
max_depthHow deep each tree may grow. None lets it grow until every leaf is pure or too small to splitNone
random_stateA number that makes training repeatableNone
n_jobsHow many processor cores to use. -1 means all of themNone, one core
model.fit(X, y)Trains the forest on the training rows
model.predict(X)Predicts a value for each row

Prerequisites​

Step 1: Load and Split the Data​

random_forest.py
import time

from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

frame = fetch_california_housing(as_frame=True).frame
X, y = frame.drop(columns="MedHouseVal"), frame["MedHouseVal"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Step 2: Create and Train the Forest​

Add:

random_forest.py (add at the end)
model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)
start = time.perf_counter()
model.fit(X_train, y_train)
print(f"Trained {len(model.estimators_)} trees in {time.perf_counter() - start:.1f} seconds")
SettingWhat it doesDefault
n_estimatorsHow many trees to grow. More trees give steadier answers but take longer100
max_depthHow deep each tree may grow. None means no limitNone
random_stateFixes the randomness, so training twice gives the same forestNone (different every time)
n_jobsHow many processor cores to use. -1 means all of themNone (one core)

model.fit(X_train, y_train) trains the forest on the training rows only. model.estimators_ holds the trained trees.

Step 3: Make Predictions​

Add:

random_forest.py (add at the end)
print("First five test houses:")
for predicted, actual in zip(model.predict(X_test[:5]), y_test[:5], strict=True):
print(f" predicted {predicted:.2f} actual {actual:.2f}")

model.predict() takes rows of features and returns one prediction per row.

Step 4: See Which Features Mattered​

Add:

random_forest.py (add at the end)
print("Which features mattered most:")
for importance, name in sorted(zip(model.feature_importances_, X.columns, strict=True), reverse=True):
print(f" {name:<10} {importance:.3f}")

Run the script:

Terminal
uv run python random_forest.py
Output
Trained 100 trees in 1.1 seconds
First five test houses:
predicted 0.51 actual 0.48
predicted 0.73 actual 0.46
predicted 4.94 actual 5.00
predicted 2.51 actual 2.19
predicted 2.27 actual 2.78
Which features mattered most:
MedInc 0.525
AveOccup 0.138
Latitude 0.089
Longitude 0.089
HouseAge 0.055
AveRooms 0.044
Population 0.031
AveBedrms 0.030

A terminal showing 100 random forest trees trained in 1.1 seconds, the first five test predictions next to the actual house values, and the feature importances with MedInc at 0.525 far ahead of AveOccup at 0.138.

Step 5: Read the Result​

  • Training took 1.1 seconds on the Mac used for this guide, with all cores. Your time will differ.
  • The predictions are close but not exact. The third house is predicted at 4.94 against 5.00 ($494,000 against $500,000); the second is off by 0.27. One average score for all 4,128 test houses comes next: How to Calculate MAE, RMSE and R² in scikit-learn.
  • Median income dominates. MedInc carries 0.525 of the importance, more than half. Location (Latitude, Longitude) and household size (AveOccup) come next.

The importances add up to 1. They measure how much each feature helped the trees split the data during training. scikit-learn's documentation warns that these impurity-based importances can be biased toward features with many distinct values, so treat them as a guide, not a proof.

Common Mistakes​

MistakeWhat happensDo this instead
No random_stateEvery training run gives a slightly different forest, so you can't compare runs fairlySet random_state and record it
Training on all rows, then testing on some of themThe score looks better than it really isSplit first, train on X_train only
Raising n_estimators a lotTraining gets slower for little gainCompare a few values. scikit-learn's guide notes that "results will stop getting significantly better beyond a critical number of trees"

Troubleshooting​

SymptomLikely causeFix
Training takes longn_jobs isn't set, so one core does all the work: 7.1 seconds here, against 1.2 seconds with n_jobs=-1n_jobs=-1
ValueError: The feature names should match those that were passed during fit.The prediction rows have different columns, or the same columns in another orderPredict with the same columns, in the same order

FAQ​

Why a random forest for house prices?​

It handles features of very different scales without any preparation and captures non-linear patterns, which makes it a strong first model for tables of numbers.

How do I choose n_estimators and max_depth?​

Try several values and compare the test scores. Tracking each try with MLflow makes that easy: MLflow Tutorial for Machine Learning in Python — Part 1 compares four forests.

Does a random forest need scaled features?​

No. Trees split on thresholds, so the scale of a feature doesn't matter.

Conclusion​

RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1) trained 100 trees on 16,512 rows in about a second, predicted house values close to the real ones, and showed that median income drives more than half of its decisions.

Additional Resources​