Random Forest — Instacart Stock Prediction
Bagging, random feature subsets, out-of-bag evaluation, and the feature importance that actually works. Why Random Forest beats a single tree on every real dataset.
A single decision tree is unstable. One noisy sample can change everything.
You trained a decision tree on Capital One loan data and got 88% accuracy. You add 50 new training samples — a routine monthly data refresh — and retrain. The tree looks completely different. Different root split, different branches, different feature importances. The accuracy barely changed but the structure changed dramatically. This is variance. The tree is too sensitive to the specific samples it saw.
The fix was published by Leo Breiman in 2001. His insight: if one tree is unstable and noisy, train 500 trees on slightly different versions of the data and average their predictions. Each individual tree is still noisy, but the noise is random and independent across trees. It cancels out in the average. What remains is the underlying signal.
That is Random Forest. It is still, in 2026, one of the first algorithms you should try on any tabular ML problem. It almost never catastrophically fails, requires minimal tuning, handles missing values gracefully, provides reliable feature importances, and trains in parallel across cores. The Instacart data science team uses it for demand forecasting, inventory reorder prediction, and fraud detection — often as a strong baseline before reaching for XGBoost.
What this module covers:
Bagging — bootstrap aggregation
Bagging starts with a simple observation: if you had access to many independent training datasets, you could train one model per dataset and average their predictions. The average would be more stable and accurate than any single model.
You only have one training dataset. The trick: create many simulated datasets by sampling from it with replacement. This is called bootstrap sampling. Each bootstrap sample is the same size as the original but contains roughly 63% unique samples (some samples appear 2 or 3 times, about 37% never appear). Train one tree on each bootstrap sample. Average the predictions. That is bagging.
Random feature subsets — why RF beats plain bagging
Plain bagging with decision trees works but has a problem. If one feature is very predictive of the target — say, days_of_stock for stock-out prediction — every tree will put it at the root. The 500 trees will all look similar in their top splits, making them highly correlated. Correlated trees cancel each other's errors poorly. The benefit of averaging is reduced.
Random Forest fixes this by constraining each split to consider only a random subset of features — typically sqrt(n_features) for classification and n_features/3 for regression. Now no single feature can dominate every tree. Different trees explore different feature combinations. The trees are decorrelated, and averaging them cancels much more error. This is the one addition that makes Random Forest beat plain bagging by a significant margin.
Out-of-bag evaluation — cross-validation at no extra cost
Each bootstrap sample leaves out roughly 37% of the training data. Those left-out samples are called out-of-bag (OOB) samples. For any given training sample, there will be trees in the forest that never saw it during training — because it was OOB for those trees. We can evaluate each sample using only those trees, giving us an unbiased estimate of generalisation performance without any separate validation set or cross-validation loop.
Set oob_score=True and the OOB score is computed automatically. For large datasets, OOB evaluation is often preferred over k-fold CV because it is effectively one-pass rather than k-pass, much faster.
Key hyperparameters — what to tune and in what order
Random Forest is remarkably robust to hyperparameter choices compared to other algorithms. The defaults often work well. But three parameters consistently matter and are worth tuning in this order.
Number of trees. More is always better — adding trees never hurts, it only reduces variance. Keep adding until OOB error stops improving. 100 is often enough; 500 for important production models.
Features considered at each split. sqrt(n_features) for classification, n_features/3 for regression are the theory-backed defaults. Smaller = more decorrelated trees = less variance. Larger = more powerful individual trees = less bias. Try "sqrt", "log2", 0.3, 0.5.
Minimum samples at a leaf. Controls tree depth indirectly. Higher = shallower trees = less overfitting but more bias. Try 1, 2, 5, 10, 20. For noisy datasets increase this.
Feature importance — MDI and permutation importance
Random Forest provides two types of feature importance. Mean Decrease in Impurity (MDI) is fast — it's computed during training as the total Gini reduction per feature. But MDI has a known bias: it overestimates the importance of high-cardinality features (features with many unique values like IDs or continuous floats). Permutation importance is slower but unbiased — it measures how much model performance degrades when a feature's values are randomly shuffled.
Random Forest for regression — predicting demand quantity
Random Forest vs XGBoost — when to use which
Both algorithms are dominant in tabular ML. The choice between them depends on your priorities — not on a blanket "XGBoost is always better" rule that many tutorials incorrectly state.
The practical rule: start with Random Forest. It gives you a strong baseline in minutes with minimal tuning. If you need every last point of AUC and have time to tune properly, switch to XGBoost or LightGBM. At most top product companies, a well-tuned Random Forest is already good enough for production — and it deploys faster and is easier to maintain.
Day-one task at Instacart — stock-out predictor end to end
Every common Random Forest error — explained and fixed
Five things people get wrong about Random Forest
It is true that adding trees never increases overfitting risk — each tree trains on an independent bootstrap sample, so more trees just average the ensemble more thoroughly. But the improvement follows a curve of diminishing returns, not a straight line. Going from 10 to 100 trees usually buys a real AUC jump; going from 300 to 3,000 usually buys almost nothing while multiplying training time, memory, and inference latency linearly. For the Instacart stock-out model, 300 trees might already capture 99% of the achievable OOB AUC that 3,000 trees provide, while a request serving 3,000 trees is far slower to score. The right practice is exactly what this module's tuning section showed: plot OOB error against n_estimators and stop near the elbow, not add trees indefinitely because "more can't hurt."
Bagging, and the extra feature randomisation Random Forest adds on top, is a variance-reduction technique, full stop. Averaging many independent, unbiased-but-noisy trees cancels out their independent errors. But if every individual tree is systematically biased — all trees too shallow to capture a real nonlinear pattern, or a genuinely predictive feature missing from the dataset entirely — averaging 500 identically biased trees still gives you that same bias. You cannot average away a mistake every tree is making the same way. This is why Random Forest, even with 1,000 trees, cannot fix underfitting the way boosting can — boosting attacks bias directly, bagging attacks variance directly, and conflating the two is a common conceptual slip.
This module already covered one bias — MDI favours high-cardinality features. There is a second bias that trips people up even after switching to permutation importance: correlated features split credit unpredictably. If days_of_stock and avg_daily_sale are correlated, the forest can split on either at any node — whichever gets picked first "steals" importance from the other, and removing just one barely changes the model because it leans harder on its correlated twin instead. Low importance does not always mean "not predictive" — it can mean "predictive, but a correlated feature already gets the credit." Always check correlations among top features before concluding an unimportant one is safe to drop.
OOB evaluation is a legitimately useful, no-extra-cost estimate of generalisation — but it is not a universal replacement for a real test set. It assumes rows are i.i.d, with no time-based leakage or repeated entities spanning bootstrap samples in a way that correlates the "unseen" points with the training ones. More importantly: if OOB score itself drives model selection — trying twenty hyperparameter combinations and picking whichever produces the best OOB number — you are implicitly fitting to that score the same way repeatedly checking a validation set overfits to it. You still need a genuinely untouched test set to confirm the winner generalises, exactly why this module's own pipeline keeps a separate X_test even with oob_score=True enabled.
A Random Forest prediction is always an average of leaf values seen during training — a tree can never output a number larger than the largest target value in its training leaves, or smaller than the smallest. If days_of_stock in training only ever ranged from 0 to 60, a new product arriving with 90 days of stock will not get a proportionally higher prediction — the forest caps out near whatever the highest training examples produced, because no leaf reflects anything beyond that. This is fundamentally different from linear regression, which does extrapolate, sometimes badly but at least directionally. Any deployment where the feature distribution can drift — new suppliers, new price ranges, a demand spike beyond anything seen before — needs monitoring for out-of-range inputs, because Random Forest silently returns a flat, capped, wrong answer instead of an error.
Random Forest — 5 questions interviewers actually ask
A good answer avoids jargon: "Imagine asking 500 people to independently guess whether a product will run out of stock, where each person only sees a random slice of the data and a random subset of the available information — some will guess wrong, but their mistakes tend to differ from each other. Average all 500 guesses and the individual errors mostly cancel out, leaving a far more reliable answer than any one guesser alone could give. That's a Random Forest: many decision trees, each trained slightly differently, whose combined vote is much more stable than any single tree's." A strong answer also connects this to why a single decision tree is unstable in the first place — small changes to the training data produce a very different tree, and averaging hundreds of them smooths that instability away.
Two mechanisms combine. Bagging: each tree trains on a different bootstrap sample, so each overfits to different noise, and averaging their predictions cancels most of that noise out. And, specific to Random Forest rather than plain bagging: restricting each split to a random subset of features forces trees to disagree with each other even when one feature is dominant — without this, every tree would put the single strongest feature at the root and the trees would end up highly correlated, and averaging correlated errors does not cancel them out nearly as well as averaging independent ones. Bootstrap rows plus random feature subsets per split is what decorrelates the trees enough that averaging genuinely reduces variance rather than just producing 500 near-identical copies of the same overfit tree.
Start with generous defaults and oob_score=True so every fit gives a free validation signal. Tune in order of impact: first n_estimators — plot OOB error against tree count and stop at the elbow, since more trees beyond that cost training and inference time for negligible gain. Second, and most impactful, max_features — try "sqrt", "log2", and a couple of fractional values, since this single parameter controls the tradeoff between decorrelated-but-weaker trees and correlated-but-stronger trees. Third, min_samples_leaf — increase it if OOB and training accuracy diverge, a sign individual trees are memorising noise. Only after those three would I reach for a broader RandomizedSearchCV sweep, and I'd always confirm the final choice against a genuinely held-out test set, not just the OOB score, since a long tuning search can overfit to OOB the same way it can to a validation set.
MDI is computed for free during training — it sums how much each feature reduced Gini impurity across every split where it was used. It's fast but structurally biased toward features with many unique values, because more possible split points give the tree more chances to find a locally good split purely by luck. Permutation importance instead measures the actual drop in a real scoring metric when a feature's values are shuffled — unbiased with respect to cardinality, but it can still underrate features that are highly correlated with another feature the model already relies on, since shuffling one of two redundant features barely hurts performance if the model leans on its twin. In practice: use MDI only for a fast first look, use permutation importance before any real feature-selection decision, and check both against a correlation matrix of the top features.
Random Forest wins on time-to-first-good-model, tuning friction, and operational simplicity — it trains trees in parallel and independently, is far more forgiving of default hyperparameters, and is harder to accidentally overfit badly since bagging is a gentler variance-reduction mechanism than sequential boosting. XGBoost usually wins on raw predictive performance once you're willing to tune it — its native missing-value handling and stronger regularisation let it push accuracy further than RF typically can. The practical rule: reach for Random Forest first as a fast, low-risk baseline; move to XGBoost when the last few points of AUC materially matter for the business and there is engineering time to tune and monitor it properly in production.
Random Forest is parallel averaging. The next step is sequential correction.
Random Forest trains all trees independently and averages them. Gradient Boosting trains trees sequentially — each new tree is built specifically to correct the errors of all previous trees. This sequential error correction is why XGBoost and LightGBM consistently outperform Random Forest on most tabular benchmarks. Module 22 explains how it works from scratch.
Sequential weak learners, residuals, learning rate, and why gradient boosting wins almost every tabular ML competition.
🎯 Key Takeaways
- ✓Random Forest = bootstrap sampling (bagging) + random feature subsets at each split. The random features are the key innovation — they decorrelate the trees so averaging them cancels much more error than plain bagging.
- ✓Each bootstrap sample leaves out ~37% of training data as out-of-bag (OOB) samples. Setting oob_score=True gives a free, unbiased evaluation of generalisation performance without any separate validation set or cross-validation loop.
- ✓The three parameters that matter most in order: n_estimators (more is always better, find the elbow), max_features (sqrt for classification, n_features/3 for regression — the most impactful param), min_samples_leaf (increase for noisy data).
- ✓MDI feature importance is biased toward high-cardinality features. For feature selection decisions always use permutation_importance from sklearn.inspection — it is unbiased and directly measures impact on model performance.
- ✓Random Forest needs no feature scaling — trees are threshold-based and scale-invariant. It also handles mixed feature types natively and is robust to outliers, making it one of the lowest-friction algorithms to deploy.
- ✓On class-imbalanced datasets always set class_weight="balanced". Evaluate with ROC-AUC or average precision, not accuracy — accuracy is trivially gamed by predicting the majority class.
- ✓Use Random Forest as your first strong baseline on any tabular problem. It gives production-quality results with minimal tuning. Switch to XGBoost/LightGBM only when you need maximum performance and can afford proper hyperparameter tuning.
Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.