TAI BUI
Back to curriculum
BuildPython

Ensemble Methods

A group of weak learners, combined correctly, becomes a strong learner. This is not a metaphor. It is a theorem.

TIME: ~120 minutesPREREQUISITES: Phase 2, Lesson 10 (Bias-Variance Tradeoff)

Learning Objectives

  • Implement AdaBoost and gradient boosting from scratch and explain how boosting sequentially reduces bias
  • Build a bagging ensemble and demonstrate how averaging decorrelated models reduces variance without increasing bias
  • Compare bagging, boosting, and stacking in terms of what error component each method targets
  • Evaluate ensemble diversity and explain why majority voting accuracy improves with more independent weak learners

The Problem

A single decision tree is fast to train and easy to interpret, but it overfits. A single linear model underfits on complex boundaries. You could spend days engineering the perfect model architecture. Or you could combine a bunch of imperfect models and get something better than any of them individually.

Ensemble methods do exactly this. They are the most reliable technique for winning Kaggle competitions on tabular data, they power most production ML systems, and they illustrate the bias-variance tradeoff in action: bagging reduces variance, boosting reduces bias, and stacking learns which models to trust on which inputs.

Warm-up0/3
1. A model scores 99% on its training data but only 71% on new data. What is the most likely diagnosis?Warm-up
Two horizontal bars: accuracy on training data 99 percent and accuracy on new data 71 percent, followed by the line diagnosis of the gap with a question mark.
2. You average 50 noisy, independent measurements of the same quantity. Compared with one measurement, the average's random error is usually:Warm-up
A dot plot of fifty simulated measurements scattered around a dashed true-value line, and a box asking where the average of the fifty readings lands, marked with a question mark.
Simulated for illustration; the horizontal axis has no units.
3. In regression, what is the residual for a training point?Warm-up
A scatter of eight training points with a fitted straight line. One point is highlighted and a dashed vertical segment joins it to the line, marked with a question mark.
Illustrative data.

The Concept

Why Ensembles Work

An ensemble is a set of models whose predictions get combined into a single output, and that combined output beats any one model in the set, provided the models don't all fail on the same inputs. The claim is not hand-waving. Suppose you have N independent classifiers, each with accuracy p > 0.5. The majority vote has accuracy:

P(majority correct) = sum over k > N/2 of C(N,k) * p^k * (1-p)^(N-k)

For 21 classifiers each with 60% accuracy, majority vote accuracy is about 83%. With 101 classifiers, it rises to about 98%. The errors cancel out when the models make different mistakes.

The key requirement is diversity. If all models make the same errors, combining them helps nothing. Ensembles work because they produce diverse models through:

  • Different training subsets (bagging)
  • Different feature subsets (random forests)
  • Sequential error correction (boosting)
  • Different model families (stacking)

Bagging (Bootstrap Aggregating)

Bagging creates diversity by training each model on a different bootstrap sample of the training data.

Mermaid diagram

A bootstrap sample is drawn with replacement from the original data, same size as the original. About 63.2% of unique samples appear in each bootstrap. The remaining 36.8% (out-of-bag samples) provide a free validation set.

Bagging reduces variance without increasing bias much. Each individual tree overfits to its bootstrap sample, but the overfitting is different for each tree, so averaging cancels out the noise.

Random Forests are bagging with an extra twist: at each split, only a random subset of features is considered. This forces even more diversity among trees. The typical number of candidate features is sqrt(n_features) for classification and n_features / 3 for regression.

Boosting (Sequential Error Correction)

Boosting trains models sequentially. Each new model focuses on the examples that previous models got wrong.

Mermaid diagram

Boosting reduces bias. Each new model corrects the systematic errors of the ensemble so far. The final prediction is a weighted sum of all models, where better models get higher weights.

The tradeoff: boosting can overfit if you run too many rounds, because it keeps fitting harder examples, some of which may be noise.

AdaBoost

AdaBoost (Adaptive Boosting) was the first practical boosting algorithm. It works with any base learner, typically decision stumps (depth-1 trees).

The algorithm:

1. Initialize sample weights: w_i = 1/N for all i

2. For t = 1 to T:
   a. Train weak learner h_t on weighted data
   b. Compute weighted error:
      err_t = sum(w_i * I(h_t(x_i) != y_i)) / sum(w_i)
   c. Compute model weight:
      alpha_t = 0.5 * ln((1 - err_t) / err_t)
   d. Update sample weights:
      w_i = w_i * exp(-alpha_t * y_i * h_t(x_i))
   e. Normalize weights to sum to 1

3. Final prediction: H(x) = sign(sum(alpha_t * h_t(x)))

Models with lower error get higher alpha. Misclassified samples get higher weights so the next model focuses on them.

Gradient Boosting

Gradient boosting generalizes boosting to arbitrary loss functions. Instead of reweighting samples, it fits each new model to the residuals (negative gradient of the loss) of the current ensemble.

1. Initialize: F_0(x) = argmin_c sum(L(y_i, c))

2. For t = 1 to T:
   a. Compute pseudo-residuals:
      r_i = -dL(y_i, F_{t-1}(x_i)) / dF_{t-1}(x_i)
   b. Fit a tree h_t to the residuals r_i
   c. Find optimal step size:
      gamma_t = argmin_gamma sum(L(y_i, F_{t-1}(x_i) + gamma * h_t(x_i)))
   d. Update:
      F_t(x) = F_{t-1}(x) + learning_rate * gamma_t * h_t(x)

3. Final prediction: F_T(x)

For squared error loss, the pseudo-residuals are just the actual residuals: r_i = y_i - F_{t-1}(x_i). Each tree literally fits the errors of the previous ensemble.

The learning rate (shrinkage) controls how much each tree contributes. Smaller learning rates require more trees but generalize better. Typical values: 0.01 to 0.3.

XGBoost: Why It Dominates Tabular Data

XGBoost (eXtreme Gradient Boosting) is gradient boosting with engineering optimizations that make it fast, accurate, and resistant to overfitting:

  • Regularized objective: L1 and L2 penalties on leaf weights prevent individual trees from being too confident
  • Second-order approximation: Uses both first and second derivatives of the loss, giving better split decisions
  • Sparsity-aware splits: Handles missing values natively by learning the best direction for missing data at each split
  • Column subsampling: Like random forests, samples features at each split for diversity
  • Weighted quantile sketch: Efficiently finds split points for continuous features on distributed data
  • Cache-aware block structure: Memory layout optimized for CPU cache lines

You don't need to reimplement any of this. Knowing the list exists is enough to explain why XGBoost beats a naive from-scratch gradient booster on both speed and resistance to overfitting.

For tabular data, XGBoost (and its successor LightGBM) consistently outperforms neural networks. This is not changing anytime soon. If your data fits in a table with rows and columns, start with gradient boosting.

Stacking (Meta-Learning)

Stacking uses the predictions of multiple base models as features for a meta-learner.

Mermaid diagram

The meta-learner learns which base model to trust for which inputs. If the random forest is better at certain regions and the SVM at others, the meta-learner will learn to route accordingly.

To avoid data leakage, base model predictions must be generated via cross-validation on the training set. You never train base models and generate meta-features on the same data.

Voting

The simplest ensemble. Just combine predictions directly.

  • Hard voting: Majority vote on class labels.
  • Soft voting: Average predicted probabilities, pick the class with highest average probability. Usually better because it uses confidence information.
Check: The Concept0/26
1. What is bagging?Define
Ten numbered training rows, then three trees each with its own list of ten row numbers (some numbers repeat), with arrows from the trees into an ensemble box that reads prediction with a question mark.
Row lists drawn at random with numpy for illustration.
2. What is boosting?Define
A line chart of ensemble training accuracy against the number of rounds from 1 to 50, rising from about 0.83 to 0.98.
Lesson's AdaBoostScratch on its synthetic demo data (320 training rows, 5 features).
3. What is AdaBoost?Define
A table of the first three decision stumps from a real AdaBoost run: the split rule, its weighted error and its alpha for each round.
Real run of the lesson's code (demo data, seed 42, 80/20 split).
4. What is gradient boosting?Define
Sixty noisy points following a sine shape, with the ensemble's fitted curve after one, five and thirty trees and a dashed horizontal line for the starting prediction.
Lesson's GradientBoostingScratch (learning_rate 0.1, max_depth 3) on synthetic 1-D data.
5. What is XGBoost?Define
A small table with columns f1, f2, f3 and label and four rows of numbers, an arrow into a box named XGBoost and an arrow out to a box with a question mark.
Typed example values, not from a real dataset.
6. What is stacking?Define
A table with five rows: predicted probabilities of class 1 from a forest, an SVM and a logistic regression, plus the true label.
Typed example values, not from a real run.
7. What is a random forest?Define
Three small decision trees, each with a root box and two child boxes holding a feature test: tree 1 uses x3, x7, x3; tree 2 uses x3, x2, x7; tree 3 uses x1, x3, x9.
Typed illustration, not from a trained model.
8. What does ensemble diversity mean?Define
Three boxes, Model 1 to 3, with arrows into an ensemble box that uses a majority vote, and a box asking about the diversity among the models with a question mark.
9. What is out-of-bag error?Define
A grid of ten training rows by three trees giving how many times each row was drawn into that tree's sample, some counts zero or higher than one, and a box reading out-of-bag error is measured on with a question mark.
Draws made at random with numpy for illustration.
10. In bagging, approximately what percentage of unique samples appear in a single bootstrap sample, and what happens to the rest?Define
A training set drawn as a row of squares, an arrow labelled N picks each chosen at random from all N rows into a row of empty slots, and two boxes asking for the distinct rows in the sample and the rows never picked, both marked with question marks.
11. Which of the following is one of XGBoost's engineering optimizations described in the lesson?Define
A chain of boxes F0, tree 1, tree 2, dots, tree T and F_T joined by arrows, and a panel stating that XGBoost is this loop plus engineering around it and asking which optimization the lesson describes.
Loop shape from the lesson's gradient boosting pseudocode.
12. What is the difference between hard voting and soft voting in an ensemble?Define
A table of three models' predicted probabilities for class A and class B on one input (0.85, 0.40, 0.30 for class A) and two boxes asking what hard voting and soft voting predict.
Typed example values.
13. Why does combining multiple weak classifiers into an ensemble improve accuracy?Explain
A line chart of majority-vote accuracy against the number of classifiers from 1 to 101, each classifier 60 percent accurate, rising from 0.60 to about 0.98.
Binomial sum from the lesson's formula, computed with numpy.
14. What is the main difference between bagging and boosting?Explain
A table of test accuracy on one synthetic dataset for a single model, bagging with 20 models combined and AdaBoost with 50, with a closing line asking for the main difference between bagging and boosting.
Real runs of the lesson's code: 400 samples, 80/20 split.
15. Why must base model predictions used as meta-features in stacking be generated via cross-validation on the training set?Explain
A pipeline: training rows feed three base models, whose outputs become prediction columns that feed a next model; a box asks how the prediction columns for the training rows should be produced.
Pipeline shape from the lesson's stacking section.
16. In AdaBoost, why does a stump with lower weighted error receive a larger alpha?Explain
A table of three stumps with weighted errors 0.10, 0.30 and 0.45 and an alpha column filled with question marks.
Typed example errors.
17. Why does bagging reduce variance but leave bias roughly where it was?Explain
Fifty noisy points around a sine-shaped true curve, with eight thin step-shaped tree fits that differ from one another and a dashed line for the true curve.
Lesson's SimpleRegressionTree (depth 2) on synthetic data.
18. Why does a smaller learning rate in gradient boosting usually need more trees?Explain
Three curves of training mean squared error against number of trees, for learning rates 0.5, 0.1 and 0.01; the larger the rate, the faster the curve falls.
Lesson's GradientBoostingScratch (depth 3) on its synthetic regression data, 320 training rows.
19. After AdaBoost finishes all rounds, how is the final class for a new point produced?Explain
A table of three trained stumps with their training weighted errors 0.15, 0.30 and 0.40 and their predictions plus one, minus one and minus one for a new point x, and a line asking for the final class.
Typed example values.
20. With squared error loss, how do gradient boosting's pseudo-residuals relate to ordinary residuals?Explain
A table of three rows with y of 3, 5 and 8 and current ensemble prediction of 4, 5 and 6; the ordinary residual and pseudo-residual columns are question marks.
Typed example values.
21. Three models give class A probabilities of 0.9, 0.4 and 0.4 for one input (two classes). What do hard and soft voting predict?Apply
Three horizontal bars, one per model, each split into the probability of class A in orange and class B in blue: 0.9 and 0.1, 0.4 and 0.6, 0.4 and 0.6, with a line asking what hard and soft voting predict.
22. An ensemble of 50 decision trees performs no better than one tree. Inspection shows the trees all give the same predictions. Which ingredient is missing?Analyze
A grid of four of the fifty trees by ten test inputs showing each tree's plus or minus prediction; all four rows are identical.
Typed illustration, not from a real run.
23. A boosted model keeps lowering training error as rounds increase, but validation error starts rising. What is the most likely cause?Analyze
Two curves against boosting rounds: training error falling toward zero and validation error falling at first and then slowly rising.
Lesson's GradientBoostingScratch (learning_rate 0.2, depth 4), 60 training and 60 validation points of noisy synthetic data.
24. A stacking ensemble scores 0.97 on its own training rows but only 0.90 on new data. The meta-features came from base models scored on the rows they were trained on. What went wrong?Analyze
Two bars for the stacking ensemble, 0.97 on its own training rows and 0.90 on new data, beside a three-step flow: base models trained on the training rows, scored on those same rows, then a meta-learner trained on those scores.
25. You bag 100 full-feature decision trees, but one very strong feature wins the top split in nearly every tree, so the trees look alike and the ensemble barely beats one tree. What change targets this?Analyze
A bar chart over nine features: the share of 100 bagged trees using each one for the root split. Feature x1 holds a share of 1.00 and all others are zero.
Real run on synthetic data: 300 rows, nine features, one clearly strongest.
26. Your tabular data has many missing values and you would rather not write imputation code. Which choice follows from the lesson?Design
A small table of three feature columns where several cells are blank, an arrow into a box labelled model with a question mark, and a note that blank cells are missing values and no imputation code is wanted.
Typed example values.

Build It

Step 1: Decision Stump (Base Learner)

code/ensembles.py implements everything from scratch, starting with a decision stump: a tree with a single split.

python
class DecisionStump:
    def __init__(self):
        self.feature_idx = None
        self.threshold = None
        self.polarity = 1
        self.alpha = None
 
    def fit(self, X, y, weights):
        n_samples, n_features = X.shape
        best_error = float("inf")
 
        for f in range(n_features):
            thresholds = np.unique(X[:, f])
            for thresh in thresholds:
                for polarity in [1, -1]:
                    pred = np.ones(n_samples)
                    pred[polarity * X[:, f] < polarity * thresh] = -1
                    error = np.sum(weights[pred != y])
                    if error < best_error:
                        best_error = error
                        self.feature_idx = f
                        self.threshold = thresh
                        self.polarity = polarity
 
    def predict(self, X):
        n = X.shape[0]
        pred = np.ones(n)
        idx = self.polarity * X[:, self.feature_idx] < self.polarity * self.threshold
        pred[idx] = -1
        return pred

Step 2: AdaBoost from Scratch

AdaBoost reuses the DecisionStump above as its weak learner and runs the reweighting scheme from the Concept section directly: fit a stump, score its weighted error, boost the weight of whatever it got wrong, repeat.

python
class AdaBoostScratch:
    def __init__(self, n_estimators=50):
        self.n_estimators = n_estimators
        self.stumps = []
        self.alphas = []
 
    def fit(self, X, y):
        n = X.shape[0]
        weights = np.full(n, 1 / n)
 
        for _ in range(self.n_estimators):
            stump = DecisionStump()
            stump.fit(X, y, weights)
            pred = stump.predict(X)
 
            err = np.sum(weights[pred != y])
            err = np.clip(err, 1e-10, 1 - 1e-10)
 
            alpha = 0.5 * np.log((1 - err) / err)
            weights *= np.exp(-alpha * y * pred)
            weights /= weights.sum()
 
            stump.alpha = alpha
            self.stumps.append(stump)
            self.alphas.append(alpha)
 
    def predict(self, X):
        total = sum(a * s.predict(X) for a, s in zip(self.alphas, self.stumps))
        return np.sign(total)

Step 3: Gradient Boosting from Scratch

Gradient boosting swaps the stump for a small regression tree and swaps reweighting for residual-fitting: each new tree learns to predict what the current ensemble still gets wrong, then gets added back in at a fraction of its full value (learning_rate).

python
class GradientBoostingScratch:
    def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3):
        self.n_estimators = n_estimators
        self.lr = learning_rate
        self.max_depth = max_depth
        self.trees = []
        self.initial_pred = None
 
    def fit(self, X, y):
        self.initial_pred = np.mean(y)
        current_pred = np.full(len(y), self.initial_pred)
 
        for _ in range(self.n_estimators):
            residuals = y - current_pred
            tree = SimpleRegressionTree(max_depth=self.max_depth)
            tree.fit(X, residuals)
            update = tree.predict(X)
            current_pred += self.lr * update
            self.trees.append(tree)
 
    def predict(self, X):
        pred = np.full(X.shape[0], self.initial_pred)
        for tree in self.trees:
            pred += self.lr * tree.predict(X)
        return pred

Step 4: Bagging Ensemble from Scratch

AdaBoost and gradient boosting both build sequentially, each new model reacting to the last one's mistakes. Bagging does the opposite: every tree trains independently on its own bootstrap sample of the data, and the ensemble just averages what comes out. That independence is the whole point. It's what lets the variance cancel instead of compound.

python
class BaggingClassifier:
    def __init__(self, n_estimators=20, max_depth=5):
        self.n_estimators = n_estimators
        self.max_depth = max_depth
        self.trees = []
 
    def fit(self, X, y):
        rng = np.random.RandomState(42)
        n = len(y)
 
        for _ in range(self.n_estimators):
            idx = rng.choice(n, size=n, replace=True)
            tree = SimpleRegressionTree(max_depth=self.max_depth)
            tree.fit(X[idx], y[idx])
            self.trees.append(tree)
 
    def predict(self, X):
        predictions = np.array([tree.predict(X) for tree in self.trees])
        return np.sign(np.mean(predictions, axis=0))

Each tree reuses the same SimpleRegressionTree from Step 3, just trained on a resampled idx instead of the full training set. Running demo_bagging() on the same synthetic data: a single depth-5 tree scores 0.750 test accuracy; 20 of those trees bagged together score 0.863, a +0.113 jump from averaging alone. No new features, no different model, just less noise.

Step 5: Compare against sklearn

The code checks that these from-scratch implementations land close to sklearn's AdaBoostClassifier, RandomForestClassifier, and GradientBoostingClassifier in accuracy, then lines up every method side by side.

Check: Build It0/6
1. A single decision tree scores 0.750 test accuracy. Bagging 20 of the same trees, each trained on its own bootstrap sample, raises accuracy to 0.863 with no change to tree depth. What best explains the jump?Apply
Two bars of test accuracy: a single decision tree at 0.750 and an ensemble of 20 trees, each trained on its own bootstrap sample, at 0.863.
Numbers from the lesson's demo_bagging.
2. `GradientBoostingScratch` is fit on y = [2, 4, 6]. What are the residuals its first tree is trained on?Apply
Three points at y equal 2, 4 and 6 for rows 1 to 3, and a panel asking for the initial prediction and the residual of each row, all marked with question marks.
3. Using that same data with learning_rate=0.1, suppose the first tree predicts the residuals [-2, 0, 2] exactly. What is current_pred after round one?Apply
A table with rows 1 to 3 giving y of 2, 4 and 6, the prediction before the round of 4, the tree output of -2, 0 and 2, and the prediction after the round as question marks; learning rate 0.1.
4. In `AdaBoostScratch.fit`, a stump has weighted error 0.2. What alpha does it get?Apply
A number line for weighted error from 0 to 0.5 with a marker at 0.2 labelled this stump, and a box asking for the alpha of this stump with a question mark.
5. Ten samples start with weight 0.1 each. A stump gets two wrong (alpha about 0.69, so exp(alpha) = 2). After the update and normalization, what is each misclassified sample's weight?Apply
Ten bars each of height 0.1 for the sample weights, the first two coloured red and labelled wrong and the other eight blue and labelled right, with a box asking for the weight of each wrong sample after update and normalization.
6. A `DecisionStump` has polarity 1, threshold 3 and is applied to X = [[1], [2], [3], [4]]. What does `predict` return?Apply
A number line with four circled points labelled [1] to [4] and a dashed vertical line at the threshold 3, followed by the input X and predict(X) with a question mark.

Use It

When to Use Each Method

MethodReducesBest forWatch out for
Bagging / Random ForestVarianceNoisy data, many featuresDoes not help with bias
AdaBoostBiasClean data, simple base learnersSensitive to outliers and noise
Gradient BoostingBiasTabular data, competitionsSlow to train, easy to overfit without tuning
XGBoost / LightGBMBothProduction tabular MLMany hyperparameters
StackingBothGetting last 1-2% accuracyComplex, risk of overfitting meta-learner
VotingVarianceQuick combination of diverse modelsOnly helps if models are diverse

The Production Stack for Tabular Data

For most tabular prediction problems, this is the order to try:

  1. LightGBM or XGBoost with default parameters
  2. Tune n_estimators, learning_rate, max_depth, min_child_weight
  3. If you need the last 0.5%, build a stacking ensemble with 3-5 diverse models
  4. Use cross-validation throughout

Neural networks on tabular data are almost always worse than gradient boosting, despite continued research attempts. TabNet, NODE, and similar architectures occasionally match but rarely beat a well-tuned XGBoost.

Check: Use It0/4
1. According to the lesson's 'When to Use Each Method' table, what should you watch out for with gradient boosting?Define
The header of the lesson's comparison table with columns Method, Reduces, Best for and Watch out for, and one row for Gradient Boosting with every other cell a question mark.
2. You have bagged 100 depth-1 stumps on a problem where the true boundary is far from a single axis-aligned split. Accuracy is poor. Why does adding more stumps not help?Analyze
Left: a scatter of orange and blue points arranged in a checkerboard pattern. Right: test accuracy of the bagged stump ensemble against ensemble size, staying near 0.5 from 1 to 100 stumps.
Lesson's SimpleRegressionTree (depth 1) bagged on synthetic data; the label is the sign of x1 times x2.
3. You have a noisy tabular dataset with many features, and a single deep tree overfits badly. You want a low-tuning fix. Which method fits best?Design
Two bars for a single deep decision tree on synthetic noisy data: training accuracy 1.000 and test accuracy 0.675.
Lesson's SimpleRegressionTree (depth 12) on synthetic data with noisy labels.
4. A new tabular prediction problem lands on your desk and you need a strong baseline in an afternoon. What does the lesson's production order suggest?Design
Three boxes: tabular data with rows and columns, one afternoon of time, and a strong baseline as the goal, and a prompt asking what to try first and in what order.

Ship It

This lesson produces outputs/prompt-ensemble-selector.md, a prompt that helps you pick the right ensemble method for a given dataset. Describe your data (size, feature types, noise level, class balance) and the problem you are solving. The prompt walks through a decision checklist, recommends a method, suggests starting hyperparameters, and warns about common mistakes for that method. Also produces outputs/skill-ensemble-builder.md with the full selection guide.

Author's Note

The mistake I see most often with ensembles isn't picking the wrong method. It's tuning the wrong knob first. People will grid-search learning rate and n_estimators on a gradient boosting model for a full afternoon before checking whether their missing-value handling or categorical encoding is even sane. Fix the data first. A sloppy encoding scheme will eat any gain an ensemble tweak could give you.

The other one: when someone tells you stacking bought them the last percentage point of accuracy, ask how they generated the meta-features. If the base models saw the same rows they're being scored on, that percentage point isn't signal. It's leakage wearing a nicer outfit.

Exercises

  1. Modify the AdaBoost implementation to track training accuracy after each round. Plot accuracy vs. number of estimators. When does it converge?

  2. Implement a random forest from scratch by adding random feature subsampling to the regression tree. Train 100 trees with max_features=sqrt(n_features) and average predictions. Compare variance reduction to a single tree.

  3. In the gradient boosting implementation, add early stopping: track validation loss after each round and stop when it has not improved for 10 consecutive rounds. How many trees does it actually need?

  4. Build a stacking ensemble with three base models (logistic regression, decision tree, k-nearest neighbors) and a logistic regression meta-learner. Use 5-fold cross-validation to generate meta-features. Compare to each base model alone.

  5. Run XGBoost on the same dataset with default parameters. Compare its accuracy to your from-scratch gradient boosting. Time both. How large is the speed difference?

Key Terms

TermWhat people sayWhat it actually means
Bagging"Train on random subsets"Bootstrap aggregating: train models on bootstrap samples, average predictions to reduce variance
Boosting"Focus on hard examples"Train models sequentially, each correcting errors of the ensemble so far, to reduce bias
AdaBoost"Reweight the data"Boosting via sample weight updates; misclassified points get higher weight for the next learner
Gradient boosting"Fit the residuals"Boosting via fitting each new model to the negative gradient of the loss function
XGBoost"The Kaggle weapon"Gradient boosting with regularization, second-order optimization, and systems-level speed tricks
Stacking"Models on top of models"Use predictions of base models as input features for a meta-learner
Random forest"Many randomized trees"Bagging with decision trees, adding random feature subsampling at each split for diversity
Ensemble diversity"Make different mistakes"Models must be uncorrelated in their errors for the ensemble to improve over individuals
Out-of-bag error"Free validation"Samples not in a bootstrap draw (~36.8%) serve as a validation set without needing a holdout

Further Reading