Skip to main content
Create your own

Implementing Boosting Algorithms from Scratch

Hello! Welcome to your next lesson on ensemble learning.

Introduction

In our previous lessons, we delved into ensemble methods by exploring bagging and implementing a Random Forest from scratch. You learned that bagging reduces variance by training multiple models in parallel on bootstrapped data samples and averaging their predictions. This is a "divide and conquer" strategy where independent models collectively contribute to a more robust result.

Today, we pivot to the other major ensemble paradigm: boosting. Unlike the parallel nature of bagging, boosting is a sequential process where models are built one after another, each one learning from the mistakes of its predecessor. This iterative refinement process is exceptionally powerful for reducing model bias and often leads to state-of-the-art performance on tabular data.

Our learning goal for this lesson is to implement AdaBoost and Gradient Boosting Machines (GBMs) from first principles. By the end, you'll understand the core mechanics of how these two foundational boosting algorithms work and will have built them from the ground up.

1. AdaBoost: The First Successful Boosting Algorithm

AdaBoost, short for Adaptive Boosting, was one of the first and most influential boosting algorithms. Its core idea is elegant: it combines multiple "weak learners"—classifiers that are only slightly better than random guessing—into a single "strong learner."

The algorithm works by:

  1. Training a sequence of weak learners (typically decision stumps, which are simple one-level decision trees).
  2. Paying more attention to data points that were misclassified by previous learners. It does this by increasing their sample weights.
  3. Giving a final, weighted vote where learners that performed better (had lower error) get a larger "say" in the final prediction.

Conceptual Overview

To build a strong intuition for AdaBoost, let's watch a video from StatQuest that clearly explains these three core ideas.

AdaBoost, Clearly Explained

This video, "AdaBoost, Clearly Explained" from StatQuest with Josh Starmer, provides an excellent high-level overview of how AdaBoost works. It contrasts AdaBoost with Random Forests, which will help connect to our previous lesson.

Watch the following segments: Main Ideas (00:00 - 03:42): Focus on the three key differences between AdaBoost and Random Forests: using stumps, giving some stumps more "say," and building stumps sequentially based on errors. Calculating 'Amount of Say' (03:42 - 08:31): Understand how the total error of a stump is used to calculate its influence (alpha). Updating Sample Weights (10:31 - 13:40): Pay close attention to how weights are increased for misclassified samples and decreased for correct ones. Final Prediction (19:06 - 19:54): See how the individual stump predictions are combined using their 'amount of say' to make a final classification.

The AdaBoost Algorithm in Detail

Let's formalize the steps we saw in the video. For a binary classification problem with labels :

  1. Initialize Weights: Assign an equal weight to each of the training samples.

  2. Iterate and Train Weak Learners: For classifiers:
    a. Train a weak classifier (a decision stump) that minimizes the weighted classification error:

    where is an indicator function that is 1 if the condition is true and 0 otherwise.

    b. Calculate the classifier's weight (its "say"), :

    Notice that if the error is low (near 0), is large and positive. If is 0.5 (random guessing), is 0. If is high (near 1), becomes a large negative number.

    c. Update Sample Weights: Increase the weights of misclassified samples and decrease the weights of correctly classified ones.

    The term is +1 for a correct classification and -1 for an incorrect one. This formula elegantly handles both cases: multiplying by for incorrect samples and for correct ones.

    d. Normalize the weights so they sum to 1: .

  3. Final Prediction: The final classifier combines the votes of all weak learners, weighted by their values. The final prediction is the sign of this weighted sum:

Implementing AdaBoost from Scratch

Now, let's implement this. Your Python and software engineering skills will make this process straightforward. We will follow a from-scratch tutorial that builds both the DecisionStump weak learner and the main Adaboost class.

AdaBoost in Python - Machine Learning From Scratch 13 - Python Tutorial

This video, "AdaBoost in Python" from Patrick Loeber's "Machine Learning From Scratch" series, will guide our implementation. It's a clear, concise walkthrough that aligns perfectly with the theory we've just covered.

You can code along with the video. Focus on these parts: DecisionStump Class (08:52 - 12:59): Understand how this simple weak learner is built. It only needs to store one feature index, one threshold, and a 'polarity' to decide which side of the threshold maps to which class. AdaBoost fit method (12:59 - 23:56): This is the core of the algorithm. Pay attention to the nested loops that perform the greedy search for the best stump, the error and alpha calculation, and the weight update logic. AdaBoost predict method (23:56 - 26:02): See how the final prediction is assembled by summing the predictions of all stored classifiers, weighted by their alpha values.

Here is the core structure of the code from the video, which you can use as a reference. You can also refer to the complete code in the accompanying article resource.

AdaBoost in Python - ML From Scratch 13

This article by Python Engineer is the text-based version of the video we just watched. It's a great resource to copy the final code from or to review the implementation logic without re-watching.

Review the Python code in the "Implementation" section. It provides the full code for both DecisionStump and Adaboost classes.

Test your understanding!

In the AdaBoost algorithm, if a weak learner (a stump) performs very poorly and has a weighted error , what happens during the training process? How does the algorithm handle this? (Hint: The implementation in the video includes a clever trick.)

Show answer

If a stump has an error greater than 0.5, it means it's performing worse than random guessing. AdaBoost handles this by "flipping" its predictions. This is done by changing the polarity of the stump. For example, if it was predicting +1 for values less than the threshold and -1 for values greater, it will now do the opposite.

This flip also changes the error. The new error becomes . Since the original was > 0.5, the new error is < 0.5. This ensures the learner is now better than random, and its value will be positive, allowing it to contribute meaningfully (albeit with opposite predictions) to the final ensemble.

2. Gradient Boosting Machines (GBMs)

While AdaBoost focuses on sample weights, Gradient Boosting takes a more generalized approach. It frames the boosting problem as an optimization problem where the goal is to minimize a loss function.

The core idea of Gradient Boosting is to sequentially add new models (typically decision trees) that predict the residuals (the errors) of the preceding model ensemble.

In essence:

  1. Start with a simple initial prediction (e.g., the mean of the target values).
  2. Calculate the errors (residuals) of this prediction.
  3. Build a new model (a decision tree) that tries to predict these errors.
  4. Add this new "error-correcting" model to the ensemble, scaled by a learning rate.
  5. Repeat steps 2-4, with each new model trying to fix the remaining errors of the updated ensemble.

The "Gradient" in the name comes from the fact that this process is a form of gradient descent. The residuals are the negative gradient of the Mean Squared Error (MSE) loss function. This insight allows GBMs to be generalized to any differentiable loss function, making them applicable to a wide variety of regression and classification tasks.

From AdaBoost to GBM

Let's read a short article that introduces Gradient Boosting, explains its connection to AdaBoost, and outlines the algorithm.

Gradient Boosting – A Concise Introduction from Scratch

This article, "Gradient Boosting – A Concise Introduction from Scratch" from MachineLearningPlus, provides an excellent bridge from AdaBoost to GBMs.

Read through the following sections: "How does Gradient Boosting Works?" to "Gradient Boosting Decision Trees": Understand the fundamental principle of sequentially predicting errors and how GBM differs from AdaBoost. "Understanding the Hyperparameters": Grasp the importance of the learning_rate (shrinkage) and n_estimators. "Gradient Boosting Algorithm": Look at the mathematical formulation, which shows how each consecutive tree models the residual of the previous one.

Implementing a Simple GBM from Scratch

Implementing a full GBM from scratch requires a regression tree learner. Since we have built decision trees before, we will focus on the boosting logic that wraps around the tree learners. The article we just read provides a simplified Python implementation that demonstrates this core loop.

Let's break down the logic for a regression task:

  1. Initialize Prediction: Start with an initial prediction for all samples. For a simple regression case, this is just the mean of the target variable y.
    predf = np.mean(y)

  2. Iterative Correction Loop: For a set number of estimators (trees):
    a. Calculate Residuals: Find the difference between the true values y and the current ensemble prediction predf. These are the errors we want the next tree to correct.
    residuals = y - predf

    b. Fit a Tree to Residuals: Train a new decision tree (a weak learner, e.g., with max_depth=3) to predict these residuals, not the original y.
    tree.fit(X, residuals)

    c. Update Ensemble Prediction: Get the predictions from the new tree and add them to the overall prediction, scaled by a learning_rate ().
    predf = predf + learning_rate * tree.predict(X)

    d. Repeat, storing each tree along the way.

  3. Final Prediction: The final prediction for a new data point is the initial mean plus the sum of predictions from all the trees in the ensemble, each scaled by the learning rate.

The article "Gradient Boosting – A Concise Introduction from Scratch" contains a code block under the "Gradient Boosting from Scratch" section that implements this logic. Let's examine it.

Gradient Boosting – A Concise Introduction from Scratch

Let's study the from-scratch implementation provided in the article.

Find the section titled "Gradient Boosting from Scratch". Analyze the Python code block that starts with xi = x. This snippet demonstrates the core GBM loop for a regression problem. Trace how predf (the final prediction) and yi (the target for the next tree, which are the residuals) are updated in each iteration of the for loop.

This simplified process gives you the fundamental "first principles" understanding of how GBMs work: they are an additive model where each new term is a function trained to correct the errors of the existing model.

Test your understanding!

In Gradient Boosting, what is the role of the learning_rate (also called shrinkage)? What would be the potential consequence of setting a very high learning rate (e.g., 1.0) versus a very low one (e.g., 0.01)?

Show answer

The learning_rate controls the contribution of each new tree to the final ensemble. It "shrinks" the impact of each tree's prediction.

  • High Learning Rate (e.g., 1.0): The model learns very quickly. Each new tree makes a large correction to the overall prediction. This can lead to overfitting, as the model may chase the noise in the residuals of the training data too aggressively.
  • Low Learning Rate (e.g., 0.01): The model learns very slowly. Each tree makes a very small, incremental correction. This forces the model to find more general patterns and makes it more robust to noise, reducing the risk of overfitting. The trade-off is that you typically need more trees (n_estimators) to achieve good performance, which increases training time.

In practice, finding a good balance between learning_rate and n_estimators is key to building a high-performing GBM.

Conclusion

In this lesson, you have moved from the parallel world of bagging to the sequential world of boosting. You have implemented two of the most important algorithms in classical machine learning from first principles.

Key Takeaways:

  • Boosting is an ensemble technique that builds models sequentially, where each new model corrects the errors of its predecessors.
  • AdaBoost works by increasing the weights of misclassified samples, forcing subsequent weak learners (stumps) to focus on them. The final prediction is a weighted vote based on each learner's performance ().
  • Gradient Boosting Machines (GBMs) generalize this idea. Each new weak learner (a shallow tree) is trained to predict the residuals (errors) of the current ensemble. This is equivalent to performing gradient descent on a loss function.
  • The learning rate is a critical hyperparameter in GBMs that controls the contribution of each tree and helps prevent overfitting.

Preview of the next lesson:
Building AdaBoost and GBMs from scratch provides a deep understanding of their mechanics. However, in practice, we use highly optimized libraries that have made Gradient Boosting a dominant force in machine learning competitions and industry. In the next lesson, we will explore these high-performance libraries: XGBoost, LightGBM, and CatBoost, and learn how to apply them effectively.

Can't find a good explanation? Sign up and we'll make it for you

Sign up