Compromis biais-variance

CSI 4506 - Automne 2025

Marcel Turcotte

Version: sept. 28, 2025 16h07

Préambule

Résumé

Dans cette présentation, nous explorons comment la complexité du modèle influence le biais, la variance, et la généralisation en examinant le sous-ajustement et le sur-ajustement à travers les courbes d’apprentissage pour divers modèles, y compris les modèles linéaires, polynomiaux, basés sur des arbres, KNN et les réseaux profonds.

Résultats d’apprentissage

  • Comprendre comment la complexité du modèle affecte le biais, la variance et la généralisation.
  • Analyser les courbes d’apprentissage pour diagnostiquer le sous-ajustement et le sur-ajustement.

Complexité du modèle

Justification

L’optimisation de la performance du modèle dépend de manière cruciale de la sélection et du réglage minutieux des hyperparamètres.

Ces hyperparamètres jouent un rôle central dans la régulation de la complexité des modèles d’apprentissage machine.

Définition

La complexité du modèle se réfère à la capacité d’un modèle à capturer des motifs complexes dans les données.

Elle est déterminée par le nombre de paramètres ou la structure du modèle.

Exploration

Code
import numpy as np

np.random.seed(42)

X = 6 * np.random.rand(100, 1) - 3
y = 0.5 * X ** 2 - X + 2 + np.random.randn(100, 1)

import matplotlib as mpl
import matplotlib.pyplot as plt

plt.figure(figsize=(6,4))

plt.plot(X, y, "b.")
plt.xlabel("$x$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
plt.grid(True)
plt.show()

Régression linéaire

Code
from sklearn.linear_model import LinearRegression

lin_reg = LinearRegression()
lin_reg.fit(X, y)

X_new = np.array([[-3], [3]])
y_pred = lin_reg.predict(X_new)

plt.figure(figsize=(6,4))

plt.plot(X, y, "b.")
plt.plot(X_new, y_pred, "r-")
plt.xlabel("$x$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
plt.show()

Un modèle linéaire représente mal cet ensemble de données.

Définition

L’ingénierie des attributs est le processus de création, transformation et sélection de variables (attributs) à partir de données brutes pour améliorer la performance des modèles d’apprentissage automatique.

Ingénierie de l’apprentissage automatique

PolynomialFeatures

from sklearn.preprocessing import PolynomialFeatures

poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
X[0]
array([-0.75275929])
X_poly[0]
array([-0.75275929,  0.56664654])

Générez une nouvelle matrice d’attributs constituée de toutes les combinaisons polynomiales des attributs avec un degré inférieur ou égal au degré spécifié. Par exemple, si un échantillon d’entrée est bidimensionnel et de la forme \([a, b]\), les attributs polynomials de degré 2 sont \([1, a, b, a^2, ab, b^2]\).

PolynomialFeatures

Étant donné deux attributs \(a\) et \(b\), PolynomialFeatures avec degree=3 ajouterait \(a^2\), \(a^3\), \(b^2\), \(b^3\), ainsi que \(ab\), \(a^2b\), \(ab^2\) !

Avertissement

PolynomialFeatures(degree=d) ajoute \(\frac{(D+d)!}{d!D!}\) attributs, où \(D\) est le nombre initial d’attributs.

Régression polynomiale

Code
lin_reg = LinearRegression()
lin_reg = lin_reg.fit(X_poly, y)

X_new = np.linspace(-3, 3, 100).reshape(100, 1)
X_new_poly = poly_features.transform(X_new)
y_new = lin_reg.predict(X_new_poly)

plt.figure(figsize=(5, 3))
plt.plot(X, y, "b.")
plt.plot(X_new, y_new, "r-", linewidth=2, label="Prédictions")
plt.xlabel("$x_1$")
plt.ylabel("$y$", rotation=0)
plt.legend(loc="upper left")
plt.axis([-3, 3, 0, 10])
plt.grid()
plt.show()

LinearRegression sur PolynomialFeatures

lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)

Régression polynomiale

Les données ont été générées selon l’équation suivante, avec l’inclusion de bruit gaussien.

\[ y = 0.5 x^2 - 1.0 x + 2.0 \]

Présenté ci-dessous est le modèle appris.

\[ \hat{y} = 0.56 x^2 + (-1.06) x + 1.78 \]

lin_reg.coef_, lin_reg.intercept_
(array([[-1.06633107,  0.56456263]]), array([1.78134581]))

Complexité du modèle

Code
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline

plt.figure(figsize=(5, 3))

for style, width, degree in (("r-+", 2, 1), ("b--", 2, 2), ("g-", 1, 300)):
    polybig_features = PolynomialFeatures(degree=degree, include_bias=False)
    std_scaler = StandardScaler()
    lin_reg = LinearRegression()
    polynomial_regression = make_pipeline(polybig_features, std_scaler, lin_reg)
    polynomial_regression.fit(X, y)
    y_newbig = polynomial_regression.predict(X_new)
    label = f"{degree} degré{'s' if degree > 1 else ''}"
    plt.plot(X_new, y_newbig, style, label=label, linewidth=width)

plt.plot(X, y, "b.", linewidth=3)
plt.legend(loc="upper left")
plt.xlabel("$x_1$")
plt.ylabel("$y$", rotation=0)
plt.axis([-3, 3, 0, 10])
plt.grid()
plt.show()

Une faible valeur de perte sur l’ensemble d’entraînement n’indique pas nécessairement un modèle “meilleur”.

Sous- et sur- ajustement

  • Sous-ajustement (underfitting):
    • Votre modèle est trop simple (ici, linéaire).
    • Attributs non informatifs.
    • Mauvaise performance sur les données d’entraînement et de test.
  • Sur-ajustement (overfitting):
    • Votre modèle est trop complexe (arbre de décision haut, réseaux neuronaux profonds et larges, etc.).
    • Trop d’attributs étant donné le nombre d’exemples disponibles.
    • Excellente performance sur l’ensemble d’entraînement, mais mauvaise performance sur l’ensemble de test.

Courbes d’apprentissage

  • Une façon d’évaluer nos modèles est de visualiser les courbes d’apprentissage :
    • Une courbe d’apprentissage montre la performance de notre modèle, ici en utilisant la RMSE, à la fois sur le jeu d’entraînement et le jeu de test.
    • Plusieurs mesures sont obtenues en entraînant le modèle de manière répétée sur des sous-ensembles de données de plus en plus grands.

Courbe d’apprentissage – Sous-ajustement

Code
from sklearn.model_selection import learning_curve

train_sizes, train_scores, valid_scores = learning_curve(
    LinearRegression(), X, y, train_sizes=np.linspace(0.01, 1.0, 40), cv=5,
    scoring="neg_root_mean_squared_error")

train_errors = -train_scores.mean(axis=1)
valid_errors = -valid_scores.mean(axis=1)

plt.figure(figsize=(6, 4))  # code supplémentaire – non nécessaire, juste pour le formatage
plt.plot(train_sizes, train_errors, "r-+", linewidth=2, label="train")
plt.plot(train_sizes, valid_errors, "b-", linewidth=3, label="test")

# code supplémentaire – embellit
plt.xlabel("Taille du jeu d'entraînement")
plt.ylabel("RMSE")
plt.grid()
plt.legend(loc="upper right")
plt.axis([0, 80, 0, 2.5])
plt.show()

  • Polynôme avec degré=1.

  • Performance médiocre sur les données de formation et de test.

Courbe d’apprentissage – Surapprentissage

Code
from sklearn.pipeline import make_pipeline

polynomial_regression = make_pipeline(
    PolynomialFeatures(degree=14, include_bias=False),
    LinearRegression())

train_sizes, train_scores, valid_scores = learning_curve(
    polynomial_regression, X, y, train_sizes=np.linspace(0.01, 1.0, 40), cv=5,
    scoring="neg_root_mean_squared_error")
# code supplémentaire – génère et enregistre la Figure 4–16

train_errors = -train_scores.mean(axis=1)
valid_errors = -valid_scores.mean(axis=1)

plt.figure(figsize=(6, 4))
plt.plot(train_sizes, train_errors, "r-+", linewidth=2, label="train")
plt.plot(train_sizes, valid_errors, "b-", linewidth=3, label="test")
plt.legend(loc="upper right")
plt.xlabel("Taille de l'ensemble d'entraînement")
plt.ylabel("RMSE")
plt.grid()
plt.axis([0, 80, 0, 2.5])
plt.show()

  • Polynôme avec degré=14.

  • Performance excellente sur l’ensemble d’entraînement, mais performance médiocre sur l’ensemble de test.

Surapprentissage - Réseaux profonds

Surapprentissage - Réseau profond

Compromis biais-variance

Biais

  • Biais fait référence à l’erreur introduite en approximant un problème du monde réel, qui peut être complexe, en utilisant un modèle simplifié.

  • Il représente la différence entre la prédiction moyenne du modèle et le résultat vrai.

  • Un biais élevé peut amener un algorithme à manquer des motifs importants, conduisant à un sous-ajustement.

Biais

\[ \text{Biais}(\hat{f}) = \mathbb{E}[\hat{f}(x)] - f(x) \] où :

  • \(\hat{f}(x)\) est la prédiction faite par le modèle,
  • \(f(x)\) est la fonction vraie,
  • \(\mathbb{E}[\hat{f}(x)]\) est la prédiction attendue sur différents ensembles de données.

Variance

  • Variance mesure la sensibilité du modèle aux fluctuations dans les données d’entraînement.

  • Une variance élevée indique que le modèle capture le bruit comme s’il s’agissait d’un vrai motif, conduisant à un surdéajustement.

  • Elle reflète combien les prédictions du modèle varieraient si différentes données d’entraînement étaient utilisées.

Variance

\[ \text{Variance}(\hat{f}) = \mathbb{E}[(\hat{f}(x) - \mathbb{E}[\hat{f}(x)])^2] \]

où :

  • \(\hat{f}(x)\) est la prédiction faite par le modèle,
  • \(\mathbb{E}[\hat{f}(x)]\) est la prédiction attendue sur différents ensembles de données.

Remarques

  • L’apprentissage statistique fait des hypothèses sur le modèle, la distribution des données et le bruit pour dériver analytiquement les valeurs attendues.

  • Dans les applications pratiques, des techniques empiriques comme la validation croisée et le bootstrapping sont utilisées pour estimer le biais et la variance.

Compromis biais-variance

\[ \text{Erreur} = \text{Biais}^2 + \text{Variance} + \text{Erreur Irréductible} \]

  • La sélection de modèle vise à minimiser le biais, qui provient de modèles trop simplistes, et la variance, qui résulte de modèles trop complexes sujets au surapprentissage.

  • Idéalement, avec des données infinies, à la fois le biais et la variance pourraient être réduits à zéro.

  • Cependant, en pratique, les données sont généralement bruitées, et une certaine erreur irréductible persiste en raison de facteurs non pris en compte au-delà de la portée du modèle.

Compromis biais-variance

Compromis biais-variance

Biais élevé, faible variance

Code
from sklearn.model_selection import KFold
from sklearn.metrics import mean_squared_error

def true_function(x):
    return np.sin(x)

def plot_fold_predictions(degree, X, y, X_grid, y_true_grid, n_splits=5, random_state=42):
    """
    For a given polynomial degree, perform KFold cross-validation,
    plot the individual fold predictions along with the average prediction 
    and the true function (with y-axis limited to [-2, 2]),
    and return predictions and errors.
    """
    kf = KFold(n_splits=n_splits, shuffle=True, random_state=random_state)
    fold_predictions = []  # To store predictions on the evaluation grid for each fold
    fold_errors = []       # To store test errors for each fold

    for train_index, test_index in kf.split(X):
        poly = PolynomialFeatures(degree=degree)
        X_train_poly = poly.fit_transform(X[train_index])
        X_test_poly = poly.transform(X[test_index])
        X_grid_poly = poly.transform(X_grid)
        
        model = LinearRegression()
        model.fit(X_train_poly, y[train_index])
        
        # Predictions on the dense grid for bias-variance analysis
        y_pred_grid = model.predict(X_grid_poly)
        fold_predictions.append(y_pred_grid)
        
        # Test error on held-out data
        y_pred_test = model.predict(X_test_poly)
        fold_errors.append(mean_squared_error(y[test_index], y_pred_test))
    
    fold_predictions = np.array(fold_predictions)
    avg_prediction = np.mean(fold_predictions, axis=0)
    
    # Plot individual fold predictions with y-axis limited to [-2, 2]
    plt.figure(figsize=(8, 5))
    for i in range(n_splits):
        plt.plot(X_grid, fold_predictions[i], color='gray', alpha=0.5, 
                 label='Fold prediction' if i == 0 else "")
    plt.plot(X_grid, avg_prediction, color='red', linewidth=2, label='Average prediction')
    plt.plot(X_grid, y_true_grid, color='blue', linewidth=2, label='True function')
    plt.scatter(X, y, color='black', s=20, label='Data points')
    plt.ylim(-2, 2)
    plt.title(f'Polynomial Degree {degree}')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.legend()
    plt.show()
    
    return fold_predictions, avg_prediction, fold_errors

# --- Data Generation with Increased Noise and Reduced Sample Size ---
np.random.seed(0)
n_samples = 40  # Reduced sample size increases model sensitivity to training data
X = np.linspace(0, 2 * np.pi, n_samples).reshape(-1, 1)
noise_std = 0.25  # Increased noise level amplifies prediction variability
y = true_function(X).ravel() + np.random.normal(0, noise_std, size=n_samples)

# Create a dense evaluation grid and compute the true function values
X_grid = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
y_true_grid = true_function(X_grid).ravel()

# --- Plot Individual Fold Predictions for Selected Degrees ---
_ = plot_fold_predictions(1, X, y, X_grid, y_true_grid, n_splits=5)

Biais faible, variance élevée

Code
_ = plot_fold_predictions(15, X, y, X_grid, y_true_grid, n_splits=5)

Parfait

Code
_ = plot_fold_predictions(3, X, y, X_grid, y_true_grid, n_splits=5)

Biais, variance et erreur de validation

Code
# --- Compute Bias², Variance, and CV Error Across Degrees 1 to 10 ---
degrees = range(1, 10)
bias_list = []
variance_list = []
cv_error_list = []

for degree in degrees:
    kf = KFold(n_splits=5, shuffle=True, random_state=42)
    fold_predictions = []
    fold_errors = []
    
    for train_index, test_index in kf.split(X):
        poly = PolynomialFeatures(degree=degree)
        X_train_poly = poly.fit_transform(X[train_index])
        X_test_poly = poly.transform(X[test_index])
        X_grid_poly = poly.transform(X_grid)
        
        model = LinearRegression()
        model.fit(X_train_poly, y[train_index])
        
        y_pred_grid = model.predict(X_grid_poly)
        fold_predictions.append(y_pred_grid)
        
        y_pred_test = model.predict(X_test_poly)
        fold_errors.append(mean_squared_error(y[test_index], y_pred_test))
    
    fold_predictions = np.array(fold_predictions)
    mean_prediction = np.mean(fold_predictions, axis=0)
    
    # Bias²: Average squared difference between the average prediction and the true function
    bias_sq = np.mean((mean_prediction - y_true_grid)**2)
    # Variance: Average variance of the predictions across the evaluation grid
    variance = np.mean(np.var(fold_predictions, axis=0))
    # CV Error: Mean of the MSE on held-out test sets
    cv_error = np.mean(fold_errors)
    
    bias_list.append(bias_sq)
    variance_list.append(variance)
    cv_error_list.append(cv_error)

# --- Plot Bias², Variance, and CV Error vs. Polynomial Degree ---
plt.figure(figsize=(8, 5))
plt.plot(degrees, bias_list, marker='o', label='Bias²')
plt.plot(degrees, variance_list, marker='o', label='Variance')
plt.plot(degrees, cv_error_list, marker='o', label='CV Error (MSE)')
plt.title('Bias, Variance, and CV Error vs. Polynomial Degree')
plt.xlabel('Polynomial Degree')
plt.ylabel('Error')
plt.ylim(0, 1)
plt.legend()
plt.show()

Abre de décision

Code
from sklearn.tree import DecisionTreeRegressor

def plot_tree_fold_predictions(max_depth, X, y, X_grid, y_true_grid, n_splits=5, random_state=42):
    """
    For a given tree max_depth, perform KFold cross-validation with a DecisionTreeRegressor,
    plot the individual fold predictions along with the average prediction and the true function.
    The y-axis is limited to [-2, 2] for clarity.
    """
    kf = KFold(n_splits=n_splits, shuffle=True, random_state=random_state)
    fold_predictions = []  # Store predictions on the evaluation grid for each fold
    fold_errors = []       # Store test errors for each fold

    for train_index, test_index in kf.split(X):
        X_train = X[train_index]
        X_test = X[test_index]
        
        model = DecisionTreeRegressor(max_depth=max_depth, random_state=random_state)
        model.fit(X_train, y[train_index])
        
        # Prediction on a dense evaluation grid
        y_pred_grid = model.predict(X_grid)
        fold_predictions.append(y_pred_grid)
        
        # Test error on held-out data
        y_pred_test = model.predict(X_test)
        fold_errors.append(mean_squared_error(y[test_index], y_pred_test))
    
    fold_predictions = np.array(fold_predictions)
    avg_prediction = np.mean(fold_predictions, axis=0)
    
    plt.figure(figsize=(8, 5))
    for i in range(n_splits):
        plt.plot(X_grid, fold_predictions[i], color='gray', alpha=0.5,
                 label='Fold prediction' if i == 0 else "")
    plt.plot(X_grid, avg_prediction, color='red', linewidth=2, label='Average prediction')
    plt.plot(X_grid, y_true_grid, color='blue', linewidth=2, label='True function')
    plt.scatter(X, y, color='black', s=20, label='Data points')
    plt.ylim(-2, 2)
    plt.title(f'Regression Tree (max_depth={max_depth})')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.legend()
    plt.show()
    
    return fold_predictions, avg_prediction, fold_errors

# --- Plot Individual Fold Predictions for Selected Tree Depths ---
_ = plot_tree_fold_predictions(1, X, y, X_grid, y_true_grid, n_splits=5)

Arbre de décision

Code
_ = plot_tree_fold_predictions(10, X, y, X_grid, y_true_grid, n_splits=5)

Arbre de décision

Code
_ = plot_tree_fold_predictions(3, X, y, X_grid, y_true_grid, n_splits=5)

Biais, variance et erreur de validation

Code
# --- Compute Bias², Variance, and CV Error vs. Tree Depth ---
max_depths = range(1, 8)
bias_list = []
variance_list = []
cv_error_list = []

for depth in max_depths:
    kf = KFold(n_splits=5, shuffle=True, random_state=42)
    fold_predictions = []
    fold_errors = []
    
    for train_index, test_index in kf.split(X):
        X_train = X[train_index]
        X_test = X[test_index]
        
        model = DecisionTreeRegressor(max_depth=depth, random_state=42)
        model.fit(X_train, y[train_index])
        
        y_pred_grid = model.predict(X_grid)
        fold_predictions.append(y_pred_grid)
        
        y_pred_test = model.predict(X_test)
        fold_errors.append(mean_squared_error(y[test_index], y_pred_test))
    
    fold_predictions = np.array(fold_predictions)
    mean_prediction = np.mean(fold_predictions, axis=0)
    
    # Bias²: Mean squared difference between the average prediction and the true function
    bias_sq = np.mean((mean_prediction - y_true_grid)**2)
    # Variance: Average variance of predictions across the evaluation grid
    variance = np.mean(np.var(fold_predictions, axis=0))
    # CV Error: Average test error over folds
    cv_error = np.mean(fold_errors)
    
    bias_list.append(bias_sq)
    variance_list.append(variance)
    cv_error_list.append(cv_error)

plt.figure(figsize=(8, 5))
plt.plot(max_depths, bias_list, marker='o', label='Bias²')
plt.plot(max_depths, variance_list, marker='o', label='Variance')
plt.plot(max_depths, cv_error_list, marker='o', label='CV Error (MSE)')
plt.title('Bias, Variance, and CV Error vs. Regression Tree Depth')
plt.xlabel('Max Depth')
plt.ylabel('Error')
# plt.ylim(0, 1)
plt.legend()
plt.show()

KNN Regression

Code
from sklearn.neighbors import KNeighborsRegressor

def plot_knn_fold_predictions(n_neighbors, X, y, X_grid, y_true_grid, n_splits=5, random_state=42):
    """
    For a given number of neighbors, perform KFold cross-validation using KNeighborsRegressor,
    plot the predictions from each fold along with the average prediction and the true function.
    The y-axis is limited to [-2, 2] for clarity.
    """
    kf = KFold(n_splits=n_splits, shuffle=True, random_state=random_state)
    fold_predictions = []  # Store predictions on the evaluation grid for each fold
    fold_errors = []       # Store test errors for each fold

    for train_index, test_index in kf.split(X):
        X_train = X[train_index]
        X_test = X[test_index]
        
        model = KNeighborsRegressor(n_neighbors=n_neighbors)
        model.fit(X_train, y[train_index])
        
        # Prediction on a dense evaluation grid for bias-variance analysis
        y_pred_grid = model.predict(X_grid)
        fold_predictions.append(y_pred_grid)
        
        # Test error on held-out data
        y_pred_test = model.predict(X_test)
        fold_errors.append(mean_squared_error(y[test_index], y_pred_test))
    
    fold_predictions = np.array(fold_predictions)
    avg_prediction = np.mean(fold_predictions, axis=0)
    
    # Plot individual fold predictions
    plt.figure(figsize=(8, 5))
    for i in range(n_splits):
        plt.plot(X_grid, fold_predictions[i], color='gray', alpha=0.5,
                 label='Fold prediction' if i == 0 else "")
    plt.plot(X_grid, avg_prediction, color='red', linewidth=2, label='Average prediction')
    plt.plot(X_grid, y_true_grid, color='blue', linewidth=2, label='True function')
    plt.scatter(X, y, color='black', s=20, label='Data points')
    plt.ylim(-2, 2)
    plt.title(f'KNN Regression (n_neighbors = {n_neighbors})')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.legend()
    plt.show()
    
    return fold_predictions, avg_prediction, fold_errors

# --- Plot Individual Fold Predictions for Selected Values of k ---
_ = plot_knn_fold_predictions(1, X, y, X_grid, y_true_grid, n_splits=5)

KNN Regression

Code
_ = plot_knn_fold_predictions(10, X, y, X_grid, y_true_grid, n_splits=5)

KNN Regression

Code
_ = plot_knn_fold_predictions(4, X, y, X_grid, y_true_grid, n_splits=5)

Biais, variance et erreur de validation

Code
# --- Compute Bias², Variance, and CV Error vs. Number of Neighbors ---
neighbors_range = range(1, 21)  # Vary k from 1 to 20
bias_list = []
variance_list = []
cv_error_list = []

for k in neighbors_range:
    kf = KFold(n_splits=5, shuffle=True, random_state=42)
    fold_predictions = []
    fold_errors = []
    
    for train_index, test_index in kf.split(X):
        X_train = X[train_index]
        X_test = X[test_index]
        
        model = KNeighborsRegressor(n_neighbors=k)
        model.fit(X_train, y[train_index])
        
        y_pred_grid = model.predict(X_grid)
        fold_predictions.append(y_pred_grid)
        
        y_pred_test = model.predict(X_test)
        fold_errors.append(mean_squared_error(y[test_index], y_pred_test))
    
    fold_predictions = np.array(fold_predictions)
    mean_prediction = np.mean(fold_predictions, axis=0)
    
    # Bias²: Mean squared difference between the average prediction and the true function
    bias_sq = np.mean((mean_prediction - y_true_grid)**2)
    # Variance: Average variance of predictions across the evaluation grid
    variance = np.mean(np.var(fold_predictions, axis=0))
    # CV Error: Average MSE on the held-out test sets
    cv_error = np.mean(fold_errors)
    
    bias_list.append(bias_sq)
    variance_list.append(variance)
    cv_error_list.append(cv_error)

# --- Plot Bias², Variance, and CV Error vs. Number of Neighbors ---
plt.figure(figsize=(8, 5))
plt.plot(neighbors_range, bias_list, marker='o', label='Bias²')
plt.plot(neighbors_range, variance_list, marker='o', label='Variance')
plt.plot(neighbors_range, cv_error_list, marker='o', label='CV Error (MSE)')
plt.title('Bias, Variance, and CV Error vs. Number of Neighbors (KNN)')
plt.xlabel('Number of Neighbors')
plt.ylabel('Error')
# plt.ylim(0, 1)
plt.legend()
plt.show()

Prologue

Résumé

  • Évaluation de la complexité des modèles et de son impact sur la performance.
  • Illustration du sous-ajustement, du sur-ajustement, et du compromis biais-variance.
  • Démonstration des courbes d’apprentissage et de la validation croisée à travers divers modèles (linéaire, polynomial, arbre, KNN, réseaux profonds).

Prochain cours

  • Ingénierie de l’apprentissage automatique

Références

Burkov, A. 2020. Machine Learning Engineering. True Positive Incorporated. https://books.google.ca/books?id=HeXizQEACAAJ.
Burkov, Andriy. 2019. The Hundred-Page Machine Learning Book. Andriy Burkov.
Chollet, François. 2017. Deep learning with Python. Manning Publications.
Géron, Aurélien. 2022. Hands-on Machine Learning with Scikit-Learn, Keras, and TensorFlow. 3ᵉ éd. O’Reilly Media, Inc.
Russell, Stuart, et Peter Norvig. 2020. Artificial Intelligence: A Modern Approach. 4ᵉ éd. Pearson. http://aima.cs.berkeley.edu/.

Marcel Turcotte

Marcel.Turcotte@uOttawa.ca

École de science informatique et de génie électrique (SIGE)

Université d’Ottawa