Régression Logistique Multinomiale : Guide Complet — Principes, Exemples et Implémentation Python
Résumé : La régression logistique multinomiale est l’algorithme de référence pour la classification supervisée multi-classes. Elle étend la régression logistique binaire grâce à la fonction softmax, qui produit une distribution de probabilités sur l’ensemble des classes. Ce guide couvre les fondements mathématiques, l’intuition, l’implémentation Python avec scikit-learn, le réglage des hyperparamètres, et des cas d’usage concrets.
Principe mathématique
Fonction softmax
La régression logistique multinomiale repose sur la fonction softmax (parfois appelée fonction softmax normalisée), qui transforme un vecteur de scores bruts en une distribution de probabilités dont la somme vaut 1 :
σ(z)k = exp(z_k) / Σ exp(z_j)}^{K
où :
- K est le nombre total de classes
- z_k est le score linéaire pour la classe k, calculé comme z_k = w_kᵀx + b_k
- exp(·) est la fonction exponentielle
- σ(z)_k représente la probabilité estimée que l’observation x appartienne à la classe k
Chaque classe k possède son propre vecteur de poids w_k et son propre biais b_k, appris séparément lors de l’entraînement.
Prédiction
La classe prédite pour une observation x est celle qui maximise la probabilité softmax :
ŷ = argmax_{k ∈ {1,…,K}} σ(z)_k
Fonction de coût : entropie croisée catégorielle
L’entraînement de la régression logistique multinomiale minimise l’entropie croisée catégorielle (categorical cross-entropy), également appelée log-loss multi-classes :
L(W, b) = -Σ{i=1}^{N} Σ{k=1}^{K} y_{ik} · log(σ(z^{(i)})_k)
où :
- N est le nombre d’échantillons
- y_{ik} vaut 1 si l’échantillon i appartient à la classe k, 0 sinon (encodage one-hot)
- σ(z^{(i)})_k est la probabilité prédite par softmax pour la classe k de l’échantillon i
Cette fonction de coût pénalise fortement les erreurs de confiance : si le modèle attribue une probabilité faible à la véritable classe, la pénalité explose logarithmiquement.
Régularisation
Pour éviter le surapprentissage, on ajoute généralement un terme de régularisation L1 (Lasso) ou L2 (Ridge) à la fonction de coût :
L_régularisée = L(W, b) + λ · R(W)
- Régularisation L2 : R(W) = ||W||₂² (pénalise les grands poids)
- Régularisation L1 : R(W) = ||W||₁ (favorise la parcimonie, met des poids à zéro)
Le paramètre C (inverse de λ) contrôle l’intensité de la régularisation : un C faible signifie une régularisation forte, et inversement.
Intuition
De la classification binaire à la classification multi-classes
La régression logistique binaire utilise la fonction sigmoïde pour estimer P(y=1|x). Mais que fait-on quand il y a plus de deux classes ?
Il existe deux stratégies principales :
One-vs-Rest (OvR) : on entraîne K classifieurs binaires indépendants. Chaque classifieur distingue une classe de toutes les autres. Lors de la prédiction, on choisit la classe dont le score est le plus élevé. Le problème ? Les probabilités ne sont pas normalisées : leur somme n’est pas garantie d’être égale à 1.
Multinomial (softmax) : on entraîne un seul modèle qui produit directement une distribution de probabilités cohérente sur les K classes. Les probabilités somment toujours à 1, ce qui permet une interprétation probabiliste directe.
Pourquoi choisir la régression logistique multinomiale ?
La régression logistique multinomiale est préférable à l’approche OvR lorsque :
- Les probabilités doivent être comparables entre classes — la softmax garantit une distribution cohérente.
- Les classes sont mutuellement exclusives — chaque observation appartient à exactement une classe.
- L’interprétabilité est importante — les poids peuvent être analysés comme l’influence de chaque caractéristique sur chaque classe.
Contrairement aux arbres de décision ou aux forêts aléatoires, ce modèle reste linéaire dans ses décisions, ce qui le rend rapide, interprétable et excellent comme modèle de référence (baseline).
Implémentation Python
Environnement et imports
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris, make_classification
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import (
accuracy_score, classification_report,
confusion_matrix, ConfusionMatrixDisplay
)
import warnings
warnings.filterwarnings('ignore')
# Reproductibilité
np.random.seed(42)
Chargement des données : le jeu de données Iris
Le jeu de données Iris est un classique pour illustrer la classification multi-classes. Il contient 150 échantillons de fleurs répartis en 3 espèces, décrits par 4 caractéristiques morphologiques.
# Charger le jeu de données Iris
iris = load_iris()
X, y = iris.data, iris.target
# Affichage des informations du jeu de données
print(f"Nombre d'échantillons : {X.shape[0]}")
print(f"Nombre de caractéristiques : {X.shape[1]}")
print(f"Nombre de classes : {len(np.unique(y))}")
print(f"Noms des classes : {iris.target_names}")
# Division train/test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
# Standardisation
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Entraînement du modèle
# Création et entraînement du modèle de régression logistique multinomiale
model = LogisticRegression(
multi_class='multinomial', # Force l'approche multinomiale (softmax)
solver='lbfgs', # Solveur par défaut pour multinomial
max_iter=1000, # Augmenter si non-convergence
penalty='l2', # Régularisation L2
C=1.0, # Inverse de la régularisation
random_state=42
)
model.fit(X_train_scaled, y_train)
# Prédictions
y_pred = model.predict(X_test_scaled)
y_proba = model.predict_proba(X_test_scaled)
# Évaluation
accuracy = accuracy_score(y_test, y_pred)
print(f"\nExactitude (accuracy) : {accuracy:.4f}")
print(f"\nRapport de classification :")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
Matrice de confusion
# Matrice de confusion
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(7, 5))
sns.heatmap(
cm, annot=True, fmt='d', cmap='Blues',
xticklabels=iris.target_names,
yticklabels=iris.target_names
)
plt.ylabel('Étiquette réelle')
plt.xlabel('Prédiction')
plt.title('Matrice de confusion — Régression logistique multinomiale (Iris)')
plt.tight_layout()
plt.show()
# Validation croisée
cv_scores = cross_val_score(
LogisticRegression(
multi_class='multinomial', solver='lbfgs',
max_iter=1000, random_state=42
),
scaler.fit_transform(X), y,
cv=5, scoring='accuracy'
)
print(f"\nValidation croisée (5 folds) :")
print(f" Moyenne : {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")
Visualisation des probabilités softmax
# Visualisation des probabilités softmax pour les premiers échantillons de test
n_samples = 10
x_pos = np.arange(n_samples)
width = 0.25
fig, ax = plt.subplots(figsize=(10, 5))
for k in range(3):
ax.bar(
x_pos + k*width,
y_proba[:n_samples, k],
width,
label=f'Classe {iris.target_names[k]}'
)
ax.set_xlabel('Échantillon')
ax.set_ylabel('Probabilité softmax')
ax.set_title('Distribution des probabilités softmax sur 10 échantillons')
ax.set_xticks(x_pos + width)
ax.set_xticklabels([str(i) for i in range(n_samples)])
ax.legend()
ax.set_ylim(0, 1.1)
plt.tight_layout()
plt.show()
# Analyse des poids du modèle
fig, ax = plt.subplots(figsize=(10, 5))
feature_names = iris.feature_names
for k in range(3):
ax.barh(
[f'{n} → {iris.target_names[k]}' for n in feature_names],
model.coef_[k],
label=iris.target_names[k]
)
ax.set_xlabel('Poids (coefficient)')
ax.set_title('Poids du modèle par caractéristique et par classe')
ax.legend()
plt.tight_layout()
plt.show()
Exemple alternatif : données synthétiques à 5 classes
Pour illustrer la régression logistique multinomiale sur un problème plus complexe, générons des données artificielles avec 5 classes :
# Génération de données synthétiques
X_synth, y_synth = make_classification(
n_samples=2000,
n_features=10,
n_informative=8,
n_redundant=2,
n_classes=5,
n_clusters_per_class=1,
random_state=42
)
X_s_train, X_s_test, y_s_train, y_s_test = train_test_split(
X_synth, y_synth, test_size=0.3, random_state=42, stratify=y_synth
)
scaler_s = StandardScaler()
X_s_train_scaled = scaler_s.fit_transform(X_s_train)
X_s_test_scaled = scaler_s.transform(X_s_test)
# Entraînement
model_s = LogisticRegression(
multi_class='multinomial', solver='saga',
max_iter=2000, penalty='l2', C=1.0, random_state=42
)
model_s.fit(X_s_train_scaled, y_s_train)
y_s_pred = model_s.predict(X_s_test_scaled)
print(f"Exactitude sur données synthétiques (5 classes) : {accuracy_score(y_s_test, y_s_pred):.4f}")
print(f"\n{classification_report(y_s_test, y_s_pred)}")
Hyperparamètres
Le tableau ci-dessous résume les hyperparamètres essentiels de la régression logistique multinomiale dans scikit-learn :
| Hyperparamètre | Valeurs possibles | Défaut | Description |
|---|---|---|---|
| multi_class | 'auto', 'multinomial', 'ovr' |
'auto' |
Stratégie de classification. 'multinomial' utilise la softmax (recommandé). 'auto' choisit selon le solveur. |
| solver | 'lbfgs', 'saga', 'newton-cg', 'liblinear' |
'lbfgs' |
Algorithme d’optimisation. 'lbfgs' et 'saga' supportent 'multinomial'. 'saga' supporte aussi L1. |
| penalty | 'l1', 'l2', 'elasticnet', 'none' |
'l2' |
Type de régularisation. L1 pour la sélection de variables, L2 pour la stabilité. |
| C | Float positif (typiquement 0.001 à 1000) | 1.0 |
Inverse de la force de régularisation. C petit = régularisation forte. C grand = modèle plus flexible. |
| max_iter | Entier positif | 100 |
Nombre maximum d’itérations. Augmenter à 1000+ si le modèle ne converge pas. |
| class_weight | None, 'balanced', dict |
None |
Poids des classes. 'balanced' ajuste automatiquement selon la fréquence. Indispensable en cas de déséquilibre. |
Guide rapide de sélection du solveur
lbfgs: solveur par défaut robuste et rapide, supporte L2 et multinomial. Idéal en premier choix.saga: généralisation desag, supporte L1, L2, elasticnet et multinomial. Recommandé pour les grands jeux de données.newton-cg: méthode de Newton, rapide sur données de taille moyenne. Supporte uniquement L2.liblinear: ne supporte pas'multinomial', uniquement OvR. À éviter pour la softmax.
Avantages et Limites
Avantages
- Interprétabilité : les coefficients sont directement lisibles. Un poids positif pour la classe k indique une association positive entre la caractéristique et cette classe.
- Probabilités calibrées : la softmax produit des probabilités bien calibrées, exploitables pour la prise de décision et l’analyse de risque.
- Rapidité : l’entraînement est extrêmement rapide, même sur des centaines de milliers d’échantillons.
- Pas d’hyperparamètres sensibles : contrairement aux forêts aléatoires ou aux réseaux de neurones, peu de réglages sont nécessaires.
- Excellent modèle de référence : sert de baseline solide. Si un modèle complexe ne bat pas la régression logistique multinomiale, il n’apporte pas de valeur ajoutée.
- Gère bien la colinéarité modérée grâce à la régularisation L2.
Limites
- Frontières de décision linéaires : le modèle ne peut pas capturer des relations non linéaires complexes entre les caractéristiques et les classes.
- Sensible aux caractéristiques non normalisées : la standardisation est quasi obligatoire pour de bons résultats.
- Suppose l’indépendance des observations : comme tous les modèles linéaires généralisés.
- Peut sous-performer sur des données très non linéaires : les SVM avec noyau, les forêts aléatoires ou les réseaux de neurones seront supérieurs dans ces cas.
- Pas de gestion native des valeurs manquantes : il faut imputer avant l’entraînement.
- L’hypothèse d’indépendance des options non pertinentes (IIA) : la régression logistique multinomiale suppose que le rapport des probabilités entre deux classes ne dépend pas des autres classes, ce qui peut être irréaliste dans certains contextes.
Cas d’usage
1. Classification d’images — Reconnaissance de chiffres manuscrits (MNIST)
La régression logistique multinomiale est un point de départ classique pour la reconnaissance de chiffres manuscrits. Chaque image 28×28 est aplatie en un vecteur de 784 pixels, et le modèle apprend 10 vecteurs de poids (un par chiffre de 0 à 9). Bien qu’un réseau de neurones convolutionnel surpasse ce modèle en précision, la régression logistique multinomiale atteint environ 92 % d’exactitude en quelques secondes, ce qui en fait une baseline incontournable.
2. NLP — Classification de sentiments multi-niveaux
Dans le traitement du langage naturel (NLP), la classification de texte en plusieurs catégories (par exemple : très négatif, négatif, neutre, positif, très positif) utilise couramment la régression logistique multinomiale. Les caractéristiques d’entrée sont des vecteurs TF-IDF ou des embeddings de mots. Chaque classe de sentiment obtient son propre hyperplan de décision, et la softmax distribue les probabilités de manière cohérente. Cette approche est particulièrement efficace quand le volume de données d’entraînement est limité.
3. Diagnostics médicaux — Classification multi-maladies
En santé, un modèle peut classer les symptômes d’un patient parmi plusieurs pathologies possibles (grippe, COVID-19, rhume, allergie, etc.). La régression logistique multinomiale offre ici un avantage crucial : les probabilités softmax permettent au médecin d’évaluer non seulement le diagnostic le plus probable, mais aussi les diagnostics alternatifs et leur degré de vraisemblance. Cette transparence est essentielle en médecine, où les faux négatifs peuvent avoir des conséquences graves.
4. Prédiction de segments clients — Marketing et segmentation
En marketing, les entreprises souhaitent classer leurs clients dans des segments comportementaux (fidèle, opportuniste, dormant, à risque de départ, nouvel acquéreur). La régression logistique multinomiale utilise des caractéristiques comme le panier moyen, la fréquence d’achat, la récence de la dernière interaction, ou le score de satisfaction. Les probabilités par segment permettent ensuite de personnaliser les campagnes : un client avec 60 % de probabilité d’être “à risque de départ” recevra une offre de rétention ciblée.
Voir aussi
- Implémentez l’algorithme de hachage SHA-1 en Python : Guide étape par étape
- Tracer un Triangle avec des Arcs de Cercle en Python : Guide Complet pour les Développeurs

