Skip to main content

πŸ“ Random Forest

Description​

< What is it? >​

  • A random forest combines many decision trees to make a classification or regression prediction. Each tree learns from a randomized version of the training problem, and the forest combines their outputs. This is an ensemble model.
  • Why combine trees? A single deep tree can change substantially when its training data changes. Averaging diverse trees reduces prediction variance. Google's Random Forest lesson explains this approach.
  • Example: to predict whether a user will click a movie, every tree receives the same candidate features at inference. The forest combines the trees' predictions into a click-probability estimate.

Key points​

< How training works >​

  • Sample training rows: for each tree, draw a bootstrap sampleβ€”sample rows with replacement. Some rows appear multiple times and others are left out. This sampling-and-aggregation approach is called bagging.

  • Randomize candidate features: at each split, consider a random subset of features, then choose a useful split from those candidates. The tree still learns its split rules from the data and labels; its predictions are not random guesses.

  • Train independent trees: each tree learns from its own sample without depending on earlier trees' predictions. Trees can therefore be trained in parallel. Row and feature randomness help make their errors less correlated. See Google's explanation.

    Training rows and labels
    β”œβ”€β”€ Bootstrap sample A β†’ Tree A
    β”œβ”€β”€ Bootstrap sample B β†’ Tree B
    └── Bootstrap sample C β†’ Tree C

< How inference combines predictions >​

  • Classification: in scikit-learn, each tree estimates class probabilities from its reached leaf. The forest averages these probabilities and predicts the class with the largest average. This can differ from taking a majority vote of hard class labels. See the RandomForestClassifier API.

  • Regression: average the numeric predictions from the trees. For example, tree predictions of 4.0, 3.5, and 4.5 produce a forest prediction of 4.0. See the ensemble guide.

  • Input and output: each input row contains the same features, in the same order, as training. Classification returns a class label or class-probability vector; regression returns a number.

    One candidate's features
    β”œβ”€β”€ Tree A β†’ prediction A ─┐
    β”œβ”€β”€ Tree B β†’ prediction B ─┼→ Average β†’ Final prediction
    └── Tree C β†’ prediction C β”€β”˜

< Important parameters >​

  • Control size and diversity: the following parameters apply to scikit-learn's forest estimators.

    ParameterMeaning
    n_estimatorsNumber of trees; more trees increase computation and memory
    max_depthMaximum depth of each tree
    min_samples_leafMinimum training samples in a leaf; larger values smooth predictions
    max_featuresNumber or fraction of candidate features considered at each split
    bootstrapWhether each tree uses sampling with replacement
    n_jobsParallel workers
    random_stateSeed for reproducible sampling and split randomness

    Choose settings using validation data. Adding trees does not replace controlling tree complexity. Parameter reference

Comparison​

< Random Forest vs. XGBoost >​

Both Random Forest and XGBoost are ensemble methods based on decision trees, but they use fundamentally different strategies to combine those trees.

  • The Core Difference

    Random ForestXGBoost
    Ensemble typeBagging (parallel)Boosting (sequential)
    How trees are builtIndependently, on random subsetsSequentially, each fixing prior errors
    Tree depthDeep (low bias, high variance)Shallow (high bias, low variance)
    Training speedFast (parallelizable)Slower (sequential by nature)
    Overfitting riskLower (averaging reduces variance)Higher (needs regularization)
    HyperparametersFewer, easier to tuneMany, needs careful tuning
    InterpretabilityModerateModerate (with feature importance)
  • Random Forest: Bagging

    Idea: Build many independent decision trees, each on a random bootstrap sample of the data and a random subset of features. Then average (regression) or vote (classification).

    Data β†’ Bootstrap sample 1 β†’ Tree 1 ─┐
    β†’ Bootstrap sample 2 β†’ Tree 2 ─┼→ Average/Vote β†’ Prediction
    β†’ Bootstrap sample 3 β†’ Tree 3 β”€β”˜

    Key traits:

    • Trees are independent β€” can be trained in parallel.
    • Reduces variance (averaging many noisy trees).
    • Individual trees are deep and overfit; the ensemble fixes that.
    • Uses bagging (bootstrap aggregating) + feature randomness.
  • XGBoost: Boosting (Gradient Boosting)

    Idea: Build trees sequentially. Each new tree is trained to predict the residual errors of the previous ensemble. Combine them with a weighted sum.

    Tree 1 β†’ predicts y
    Tree 2 β†’ predicts (y - Tree1)
    Tree 3 β†’ predicts (y - Tree1 - Tree2)
    ...
    Final = Tree1 + Tree2 + Tree3 + ...

    Key traits:

    • Trees are dependent β€” each one learns from the previous.
    • Reduces bias (each tree corrects prior mistakes).
    • Individual trees are shallow (weak learners).
    • Uses gradient descent on the loss function to guide tree building.
    • Adds regularization (L1/L2) to prevent overfitting β€” this is XGBoost's key innovation.
  • A Useful Analogy

    Analogy
    Random ForestAsk 100 independent experts and average their opinions
    XGBoostTrain one expert, then train a second to fix the first's mistakes, then a third to fix the second's, etc.
  • The Family Tree

    Decision Trees
    β”œβ”€β”€ Bagging
    β”‚ └── Random Forest
    └── Boosting
    β”œβ”€β”€ AdaBoost (1995)
    └── Gradient Boosting (1999)
    β”œβ”€β”€ XGBoost (2014)
    β”œβ”€β”€ LightGBM (2017)
    └── CatBoost (2017)

    XGBoost is not a descendant of Random Forest. They're siblings under the broader umbrella of tree ensembles. XGBoost descends from gradient boosting, which is a different lineage.

  • Key Similarities

    • Both are tree-based ensembles.
    • Both handle non-linear relationships well.
    • Both work on tabular data (often beat neural nets).
    • Both provide feature importance.
    • Both are off-the-shelf β€” minimal preprocessing needed.
    • Both are interpretable-ish (compared to deep learning).
  • Key Differences in Practice

    AspectRandom ForestXGBoost
    Default performanceGood baselineOften SOTA on tabular
    Tuning effortLowHigh
    Training timeFastSlower
    Prediction timeFast (parallel trees)Slower (sequential sum)
    Handles missing valuesNeeds imputationBuilt-in
    RegularizationImplicit (averaging)Explicit (L1/L2)
    OverfittingHard to overfitEasy to overfit without tuning
  • When to Use Which

    Use Random Forest when...Use XGBoost when...
    You want a quick, solid baselineYou want maximum accuracy
    You have limited time for tuningYou can afford hyperparameter search
    You want parallel trainingYou have sequential time budget
    You want robustness to overfittingYou have lots of data
    You want simplicityYou want to win Kaggle competitions
  • Modern Context

    Both are part of the broader gradient-boosted decision tree (GBDT) ecosystem:

    ModelNotes
    XGBoostThe original high-performance GBDT; still widely used
    LightGBMFaster, lower memory (Microsoft)
    CatBoostBest for categorical features (Yandex)
    Random ForestStill a strong, simple baseline

    For tabular data, XGBoost / LightGBM / CatBoost usually win. Random Forest is a great fallback when you need something quick and reliable.

  • TL;DR

    Random Forest = bagging. Many independent deep trees, averaged. Reduces variance. Parallel, simple, robust.

    XGBoost = boosting. Many sequential shallow trees, each fixing prior errors. Reduces bias. Sequential, powerful, needs tuning.

    They're siblings, not ancestors β€” both are tree ensembles, but they use opposite strategies. Random Forest is the reliable baseline; XGBoost is the competition-winning workhorse.

Implementation​

< Train a movie-click classifier >​

  • Concrete data: each row represents a user–movie impression with features [genre_match, watch_hours_weekly]. The label is 1 for clicked and 0 for not clicked. This small synthetic dataset illustrates the API; it does not establish performance on new users.

    python -m pip install numpy scikit-learn
  • Code: train a forest, then predict two new candidate rows. Inference requires features but no click labels.

    import numpy as np
    from sklearn.ensemble import RandomForestClassifier

    # Columns: [genre_match (0/1), watch_hours_weekly]
    X_train = np.array([
    [0, 2], [0, 4], [0, 6], [0, 8],
    [1, 2], [1, 4], [1, 6], [1, 8],
    ])
    clicked = np.array([0, 0, 0, 0, 1, 1, 1, 1])

    model = RandomForestClassifier(
    n_estimators=100,
    max_depth=3,
    max_features="sqrt",
    bootstrap=True,
    random_state=42,
    n_jobs=1,
    )
    model.fit(X_train, clicked)

    # Two candidate movies for a user who watches 5 hours per week.
    movie_ids = np.array(["movie_A", "movie_B"])
    X_new = np.array([[0, 5], [1, 5]])
    labels = model.predict(X_new)
    probabilities = model.predict_proba(X_new)
    click_column = np.flatnonzero(model.classes_ == 1)[0]
    click_scores = probabilities[:, click_column]

    print("Input:", X_new.tolist())
    print("Classes:", model.classes_.tolist())
    print("Predicted labels:", labels.tolist())
    print("Probability shape:", probabilities.shape)
    print("Click probabilities:", click_scores.round(3).tolist())
    order = np.argsort(-click_scores, kind="stable")
    print("Ranked movies:", movie_ids[order].tolist())
  • Output interpretation: input shape is (2, 2) and class-probability shape is (2, 2). Probability columns follow model.classes_; selecting class 1 gives one click score per movie. For illustration, if the click scores are [0.1, 0.9], the output is:

    Input: [[0, 5], [1, 5]]
    Classes: [0, 1]
    Predicted labels: [0, 1]
    Probability shape: (2, 2)
    Click probabilities: [0.1, 0.9]
    Ranked movies: ['movie_B', 'movie_A']

    This is illustrative output, not a captured run of the training code. Run the example to obtain its actual learned probabilities. Sorting classifier probabilities is a pointwise ranking approach; this forest was trained on clicks, not a pairwise or listwise ranking loss.

< See how averaging produces a score >​

  • Runnable calculation: suppose three trees return the following click probabilities for the same two movies. These are supplied example values, not outputs from the trained forest above.

    import numpy as np

    # Rows: trees. Columns: movie_A, movie_B.
    tree_click_probabilities = np.array([
    [0.1, 0.8],
    [0.2, 0.9],
    [0.3, 0.7],
    ])
    forest_scores = tree_click_probabilities.mean(axis=0)
    print("Forest click probabilities:", forest_scores.round(3).tolist())

    Verified output:

    Forest click probabilities: [0.2, 0.8]

Troubleshoot​

< Common problems >​

  • Training performance is high but validation performance is poor: reduce depth or increase min_samples_leaf, and check for leakage. For time-based recommendation data, evaluate on later requests and compute historical features only from past information.
  • The forest is too large: limit tree count or depth and measure memory and inference latency alongside quality.
  • Feature importance is misleading: impurity-based importance can favor features with many possible split values. Consider permutation importance on held-out data; correlated features still complicate interpretation. See the scikit-learn ensemble guide.
  • Probabilities are used for decisions: check calibration on held-out data. A predicted click probability should be validated before interpreting it as a reliable frequency estimate.

Reference​