Gradient Boosting
Gradient Boosting is an ensemble method that builds models sequentially, where each new model corrects the errors (residuals) of the previous model.
Basic Concept
- Create an initial model (bias)
- Compute the residuals (errors) of the current model
- Train a new model to predict the residuals
- Update the prediction: prediction = prediction + learning_rate × residual
- Repeat until n_estimators is reached
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
X, y = make_regression(n_samples=500, n_features=10, noise=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
gb = GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
random_state=42
)
gb.fit(X_train, y_train)
y_pred = gb.predict(X_test)
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"R²: {gb.score(X_test, y_test):.4f}")
Sequential Learning
Each new tree focuses on the errors of the previous tree:
import numpy as np
# Simulation of simple gradient boosting
def simple_gb(X, y, n_trees=5, lr=0.1):
predictions = np.zeros(len(y))
for i in range(n_trees):
residuals = y - predictions
# In practice: train a tree to predict the residuals
# Here it is just a simulation
tree_pred = residuals * 0.5 # simplified
predictions += lr * tree_pred
mse = np.mean((y - predictions) ** 2)
print(f"Tree {i+1}: MSE = {mse:.4f}")
np.random.seed(42)
y = np.random.randn(100)
simple_gb(None, y, n_trees=10)
Learning Rate
The learning rate determines the contribution of each tree. Smaller → more trees required.
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
import numpy as np
iris = load_iris()
X, y = iris.data, iris.target
learning_rates = [0.01, 0.05, 0.1, 0.2, 0.5]
for lr in learning_rates:
gb = GradientBoostingClassifier(
n_estimators=100,
learning_rate=lr,
random_state=42
)
scores = cross_val_score(gb, X, y, cv=5)
print(f"lr={lr:5.2f}: {scores.mean():.4f}")
Loss Function
| Type | Loss Function | Use Case |
|---|---|---|
| Regression | MSE, MAE, Huber | Predicting values |
| Classification | Log-loss (deviance) | Classification |
from sklearn.ensemble import GradientBoostingRegressor
# Regression with different losses
for loss in ['squared_error', 'absolute_error', 'huber']:
gb = GradientBoostingRegressor(loss=loss, random_state=42)
gb.fit(X_train, y_train)
print(f"Loss {loss:15s}: R² = {gb.score(X_test, y_test):.4f}")
Feature Importance
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_wine
import pandas as pd
wine = load_wine()
X, y = wine.data, wine.target
gb = GradientBoostingClassifier(n_estimators=100, random_state=42)
gb.fit(X, y)
importance = pd.Series(gb.feature_importances_, index=wine.feature_names)
importance = importance.sort_values(ascending=False)
print("Feature Importance:")
print(importance)
Staged Predictions
Viewing predictions at each iteration:
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
import numpy as np
iris = load_iris()
X, y = iris.data, iris.target
gb = GradientBoostingClassifier(n_estimators=100, random_state=42)
gb.fit(X, y)
# Staged predictions
train_scores = []
for y_pred in gb.staged_predict(X):
train_scores.append(accuracy_score(y, y_pred))
optimal_trees = np.argmax(train_scores) + 1
print(f"Optimal trees: {optimal_trees}")
print(f"Best accuracy: {max(train_scores):.4f}")
Example: Price Prediction
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
gb = GradientBoostingRegressor(
n_estimators=200,
learning_rate=0.1,
max_depth=5,
random_state=42
)
gb.fit(X_train, y_train)
y_pred = gb.predict(X_test)
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"R²: {r2_score(y_test, y_pred):.4f}")
Important Hyperparameters
| Parameter | Default | Explanation |
|---|---|---|
| n_estimators | 100 | Number of trees |
| learning_rate | 0.1 | Contribution of each tree |
| max_depth | 3 | Depth of the tree |
| subsample | 1.0 | Proportion of data per tree |
| min_samples_split | 2 | Minimum samples to split |
Next chapter: XGBoost, a faster and more efficient implementation of gradient boosting.