Introduction
Dans ce laboratoire, nous explorerons le concept de décomposition biais-variance et la manière dont il est lié aux estimateurs individuels par rapport aux ensembles bagging. Nous utiliserons scikit-learn pour générer et visualiser des problèmes de régression simplifiés et comparer l'erreur quadratique moyenne attendue d'un estimateur individuel avec celle d'un ensemble bagging d'arbres de décision.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter pour pratiquer.
Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez des commentaires après la session, et nous résoudrons rapidement le problème pour vous.
Importez les bibliothèques requises
Tout d'abord, nous devons importer les bibliothèques nécessaires pour générer des données, entraîner des modèles et visualiser les résultats.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import DecisionTreeRegressor
Fixez les paramètres
Nous devons fixer les paramètres qui contrôlent la taille des jeux de données, le nombre d'itérations et l'écart-type du bruit.
n_repeat = 50 ## Nombre d'itérations pour le calcul des espérances
n_train = 50 ## Taille de l'ensemble d'entraînement
n_test = 1000 ## Taille de l'ensemble de test
noise = 0.1 ## Écart-type du bruit
np.random.seed(0)
Générez des données
Nous allons générer un problème de régression 1D simplifié en utilisant une fonction connue, et ajouter du bruit aléatoire aux ensembles d'entraînement et de test. Nous allons générer plusieurs ensembles d'entraînement pour calculer l'erreur quadratique moyenne attendue.
def f(x):
x = x.ravel()
return np.exp(-(x**2)) + 1.5 * np.exp(-((x - 2) ** 2))
def generate(n_samples, noise, n_repeat=1):
X = np.random.rand(n_samples) * 10 - 5
X = np.sort(X)
if n_repeat == 1:
y = f(X) + np.random.normal(0.0, noise, n_samples)
else:
y = np.zeros((n_samples, n_repeat))
for i in range(n_repeat):
y[:, i] = f(X) + np.random.normal(0.0, noise, n_samples)
X = X.reshape((n_samples, 1))
return X, y
X_train = []
y_train = []
for i in range(n_repeat):
X, y = generate(n_samples=n_train, noise=noise)
X_train.append(X)
y_train.append(y)
X_test, y_test = generate(n_samples=n_test, noise=noise, n_repeat=n_repeat)
Définissez les modèles à comparer
Nous allons définir deux modèles à comparer : un arbre de décision unique et un ensemble bagging d'arbres de décision.
estimators = [
("Tree", DecisionTreeRegressor()),
("Bagging(Tree)", BaggingRegressor(DecisionTreeRegressor())),
]
n_estimators = len(estimators)
Entraînez les modèles et calculez l'erreur quadratique moyenne attendue
Nous allons parcourir les estimateurs, les entraîner sur les multiples ensembles d'entraînement et calculer l'erreur quadratique moyenne attendue en la décomposant en termes de biais, de variance et de bruit. Nous allons également tracer les prédictions des modèles et la décomposition biais-variance.
plt.figure(figsize=(10, 8))
## Boucle sur les estimateurs à comparer
for n, (name, estimator) in enumerate(estimators):
## Calculez les prédictions
y_predict = np.zeros((n_test, n_repeat))
for i in range(n_repeat):
estimator.fit(X_train[i], y_train[i])
y_predict[:, i] = estimator.predict(X_test)
## Décoposition de l'erreur quadratique moyenne en Bias^2 + Variance + Bruit
y_error = np.zeros(n_test)
for i in range(n_repeat):
for j in range(n_repeat):
y_error += (y_test[:, j] - y_predict[:, i]) ** 2
y_error /= n_repeat * n_repeat
y_noise = np.var(y_test, axis=1)
y_bias = (f(X_test) - np.mean(y_predict, axis=1)) ** 2
y_var = np.var(y_predict, axis=1)
print(
"{0}: {1:.4f} (erreur) = {2:.4f} (bias^2) "
" + {3:.4f} (var) + {4:.4f} (bruit)".format(
name, np.mean(y_error), np.mean(y_bias), np.mean(y_var), np.mean(y_noise)
)
)
## Tracez les figures
plt.subplot(2, n_estimators, n + 1)
plt.plot(X_test, f(X_test), "b", label="$f(x)$")
plt.plot(X_train[0], y_train[0], ".b", label="LS ~ $y = f(x)+bruit$")
for i in range(n_repeat):
if i == 0:
plt.plot(X_test, y_predict[:, i], "r", label=r"$\^y(x)$")
else:
plt.plot(X_test, y_predict[:, i], "r", alpha=0.05)
plt.plot(X_test, np.mean(y_predict, axis=1), "c", label=r"$\mathbb{E}_{LS} \^y(x)$")
plt.xlim([-5, 5])
plt.title(name)
if n == n_estimators - 1:
plt.legend(loc=(1.1, 0.5))
plt.subplot(2, n_estimators, n_estimators + n + 1)
plt.plot(X_test, y_error, "r", label="$erreur(x)$")
plt.plot(X_test, y_bias, "b", label="$bias^2(x)$"),
plt.plot(X_test, y_var, "g", label="$variance(x)$"),
plt.plot(X_test, y_noise, "c", label="$bruit(x)$")
plt.xlim([-5, 5])
plt.ylim([0, 0.1])
if n == n_estimators - 1:
plt.legend(loc=(1.1, 0.5))
plt.subplots_adjust(right=0.75)
plt.show()
Interprétez les résultats
Nous pouvons observer la décomposition biais-variance de l'erreur quadratique moyenne attendue pour chaque modèle, ainsi que les prédictions des modèles. Nous pouvons également comparer l'erreur totale des deux modèles et leur compromis entre biais et variance.
Sommaire
Dans ce laboratoire, nous avons exploré le concept de décomposition biais-variance et la manière dont il se rapporte aux estimateurs individuels par rapport aux ensembles bagging. Nous avons généré et visualisé des problèmes de régression simplifiés à l'aide de scikit-learn, et comparé l'erreur quadratique moyenne attendue d'un arbre de décision unique et d'un ensemble bagging d'arbres de décision. Nous avons constaté que le compromis entre biais et variance est meilleur pour le bagging, car il augmente légèrement le terme de biais mais permet une plus grande réduction de la variance, ce qui résulte en une erreur quadratique moyenne globale plus faible.