Maîtriser l'Apprentissage Non Supervisé : Concepts, Algorithmes et Implémentation en Python

Introduction à l'Apprentissage Non Supervisé

L'apprentissage non supervisé constitue une branche fondamentale du machine learning où les ensembles de données ne possèdent pas d'étiquettes explicites ni de variables cibles. L'objectif principal est d'extraire des structures sous-jacentes, des regroupements ou des distributions cachées au sein de données brutes. Contrairement à l'apprentissage supervisé, qui s'appuie sur des exemples annotés pour établir une fonction de prédiction, l'approche non supervisée explore la nature intrinsèque des données.

Motivations et Cas d'Usage

  • Abondance de données non annotées : La majorité des données générées (textes, flux de capteurs, images brutes) ne sont pas étiquetées.
  • Analyse exploratoire : Comprendre la topologie et la distribution des données avant d'appliquer des modèles prédictifs.
  • Compression et réduction de bruit : Diminuer la dimensionalité pour optimiser le stockage et éliminer les caractéristiques redondantes.
  • Détection d'anomalies : Isoler les comportements rares ou les points aberrants dans un système.
  • Modélisation générative : Apprendre la distribution sous-jacente pour synthétiser de nouvelles observations plausibles.

Comparaison : Supervisé vs Non Supervisé

Dans un cadre supervisé, le modèle ingère des paires $(x, y)$ pour approximer une fonction $f(x) = y$. Les étiquettes agissent comme un guide pendant l'entraînement et comme une référence pour l'évaluation. À l'inverse, l'apprentissage non supervisé ne reçoit que des vecteurs de caractéristiques $x$. Le but est de partitionner, compresser ou modéliser la densité de ces vecteurs sans aucune supervision externe.

Algorithmes de Clustering

Le clustering vise à partitionner un ensemble d'observations en sous-groupes (clusters) de sorte que les éléments d'un même groupe partagent une forte similarité, tout en étant dissimilaires aux éléments des autres groupes.

K-Means (K-Moyennes)

Cet algorithme partitionne les données en $k$ clusters en minimisant la variance intra-cluster. Il est rapide mais nécessite de prédéfinir $k$ et suppose des clusters sphériques.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans

# Génération de données synthétiques avec 4 centres
features, _ = make_blobs(n_samples=400, centers=4, cluster_std=0.8, random_state=99)

# Initialisation et entraînement du modèle
model_kmeans = KMeans(n_clusters=4, init='k-means++', n_init=10, random_state=99)
model_kmeans.fit(features)
predictions = model_kmeans.labels_
centers = model_kmeans.cluster_centers_

# Affichage graphique
plt.figure(figsize=(8, 6))
plt.scatter(features[:, 0], features[:, 1], c=predictions, cmap='plasma', alpha=0.6)
plt.scatter(centers[:, 0], centers[:, 1], c='black', marker='P', s=250, label='Centroïdes')
plt.title("Partitionnement K-Means")
plt.legend()
plt.show()

Classification Hiérarchique

Cette méthode construit une hiérarchie de clusters (dendrogramme) par une approche agglomérative (bottom-up) ou divisive (top-down). Elle ne requiert pas de spécifier le nombre de clusters à l'avance.

import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram

# Création d'un jeu de données réduit pour le dendrogramme
np.random.seed(12)
data_points = np.random.rand(12, 2)

# Calcul de la matrice de liaison (méthode de Ward)
linkage_matrix = linkage(data_points, method='ward')

# Tracé du dendrogramme
plt.figure(figsize=(10, 5))
dendrogram(linkage_matrix, leaf_rotation=90, leaf_font_size=12)
plt.title("Dendrogramme Hiérarchique")
plt.ylabel("Distance Euclidienne")
plt.show()

DBSCAN (Regroupement basé sur la densité)

DBSCAN identifie les zones de forte densité comme des clusters et isole les points dans les zones de faible densité comme du bruit. Il excelle dans la détection de formes arbitraires.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons

# Données en forme de lunes
X_moons, _ = make_moons(n_samples=300, noise=0.08, random_state=42)

# Application de DBSCAN
dbscan_model = DBSCAN(eps=0.2, min_samples=5)
cluster_labels = dbscan_model.fit_predict(X_moons)

plt.figure(figsize=(8, 6))
# Les points de bruit (label -1) seront en noir
plt.scatter(X_moons[:, 0], X_moons[:, 1], c=cluster_labels, cmap='coolwarm', edgecolors='k')
plt.title("Clustering DBSCAN sur données non linéaires")
plt.show()

Modèles de Mélange Gaussien (GMM)

Le GMM suppose que les données sont générées par un mélange de plusieurs distributions gaussiennes. Il offre une affectation probabiliste (soft clustering) aux clusters.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

# Données aléatoires
np.random.seed(7)
X_data = np.vstack([np.random.randn(100, 2) + [2, 2], 
                    np.random.randn(100, 2) + [-2, -2],
                    np.random.randn(100, 2) + [2, -2]])

# Ajustement du GMM
gmm_estimator = GaussianMixture(n_components=3, covariance_type='full', random_state=7)
gmm_estimator.fit(X_data)
gmm_labels = gmm_estimator.predict(X_data)

plt.scatter(X_data[:, 0], X_data[:, 1], c=gmm_labels, cmap='Set2', s=40)
plt.title("Affectation Probabiliste avec GMM")
plt.show()

Métriques de Similarité et Distances

La quantification de la proximité entre deux vecteurs de caractéristiques est cruciale pour de nombreux algorithmes non supervisés.

Distanec Euclidienne (Norme L2)

Correspond à la longueur du segment de droite reliant deux points dans un espace multidimensionnel.

import numpy as np

def compute_l2_distance(vec_a, vec_b):
    arr_a, arr_b = np.asarray(vec_a), np.asarray(vec_b)
    return np.sqrt(np.sum(np.square(arr_a - arr_b)))

Distance de Manhattan (Norme L1)

Somme des valeurs absolues des différences le long de chaque dimension. Utile dans les espaces discrets ou en grille.

def compute_l1_distance(vec_a, vec_b):
    arr_a, arr_b = np.asarray(vec_a), np.asarray(vec_b)
    return np.sum(np.abs(arr_a - arr_b))

Distance de Chebyshev

Retient la différence maximale absolue sur une seule coordonnée. Souvent utilisée dans les jeux de stratégie (comme les mouvements du roi aux échecs).

def compute_chebyshev_distance(vec_a, vec_b):
    arr_a, arr_b = np.asarray(vec_a), np.asarray(vec_b)
    return np.max(np.abs(arr_a - arr_b))

Distance de Hamming

Mesure la proportion de positions où les symboles diffèrent entre deux séquences de même longueur. Idéale pour les données catégorielles ou binaires.

from scipy.spatial.distance import hamming
import numpy as np

# Vecteurs binaires
binary_matrix = np.array([
    [1, 1, 0, 0, 1],
    [1, 0, 0, 1, 1],
    [0, 1, 1, 0, 0]
])

# Calcul de la matrice de distance de Hamming (non normalisée)
num_cols = binary_matrix.shape[1]
hamming_dist_matrix = np.zeros((len(binary_matrix), len(binary_matrix)))

for i in range(len(binary_matrix)):
    for j in range(len(binary_matrix)):
        # La fonction scipy retourne une proportion, on multiplie par la longueur
        hamming_dist_matrix[i, j] = hamming(binary_matrix[i], binary_matrix[j]) * num_cols

print(hamming_dist_matrix)

Réduction de Dimensionnalité

Ces techniques projettent des données de haute dimension dans un espace de plus faible dimension, préservant ainsi l'information essentielle pour la visualisation ou l'accélération des calculs.

Analyse en Composantes Principales (ACP / PCA)

Transformation linéaire qui identifie les axes orthogonaux (composantes) maximisant la variance des données.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

# Génération de données corrélées en 4D
np.random.seed(21)
cov_matrix = [[1, 0.8, 0.2, 0.1], [0.8, 1, 0.3, 0.2], [0.2, 0.3, 1, 0.5], [0.1, 0.2, 0.5, 1]]
X_4d = np.random.multivariate_normal([0, 0, 0, 0], cov_matrix, 200)

# Projection sur 2 dimensions
pca_transformer = PCA(n_components=2)
X_reduced = pca_transformer.fit_transform(X_4d)

plt.scatter(X_reduced[:, 0], X_reduced[:, 1], alpha=0.7, c='teal')
plt.xlabel(f"PC1 ({pca_transformer.explained_variance_ratio_[0]:.1%} variance)")
plt.ylabel(f"PC2 ({pca_transformer.explained_variance_ratio_[1]:.1%} variance)")
plt.title("Projection ACP")
plt.show()

UMAP (Uniform Manifold Approximation and Projection)

Cet algorithme non linéaire est particulièrement efficace pour visualiser des clusters complexes en 2D ou 3D. UMAP tend à mieux préserver la structure globale que t-SNE tout en étant plus rapide à l'exécution.

import numpy as np
import matplotlib.pyplot as plt
import umap

# Données multidimensionnelles
np.random.seed(33)
X_high_dim = np.random.rand(150, 15)

# Réduction via UMAP
umap_reducer = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1, random_state=33)
X_umap = umap_reducer.fit_transform(X_high_dim)

plt.scatter(X_umap[:, 0], X_umap[:, 1], c='purple', s=30)
plt.title("Projection UMAP")
plt.show()

Métriques d'Évaluation

Évaluer la qualité d'un clustering sans étiquettes de vérité terrain repose sur des métriques internes.

Coefficient de Silhouette

Mesure à quel point un objet est similaire à son propre cluster par rapport aux autres clusters. Les valeurs varient de -1 à 1, où une valeur élevée indique une bonne séparation.

from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

X_eval, _ = make_blobs(n_samples=500, centers=5, random_state=10)
kmeans_eval = KMeans(n_clusters=5, random_state=10, n_init='auto').fit(X_eval)

sil_score = silhouette_score(X_eval, kmeans_eval.labels_)
print(f"Score de Silhouette moyen : {sil_score:.3f}")

Mise à l'Échelle des Caractéristiques (Feature Scaling)

Les algorithmes basés sur les distances (K-Means, KNN, SVM) ou la descente de gradient sont extrêmement sensibles à l'échelle des variables. La standardisation est donc une étape préalable indispensable.

Normalisation Min-Max

Redimensionne les valeurs pour qu'elles s'inscrivent dans une plage donnée, généralement $[0, 1]$. Formule : $x_{norm} = \frac{x - \min(x)}{\max(x) - \min(x)}$. Cette méthode est vulnérable aux valeurs aberrantes (outliers).

Standardisation (Z-score)

Centre les données autour de 0 avec un écart-type de 1. Formule : $x_{std} = \frac{x - \mu}{\sigma}$. Elle est plus robuste face aux outliers et est privilégiée pour les algorithmes supposant une distribution gaussienne (comme le GMM ou l'ACP).

Applications Concrètes

  • Segmentation marketing : Regrouper les consommateurs par comportements d'achat pour des campagnes ciblées.
  • Détection de fraude : Isoler les transactions financières atypiques via des modèles de densité ou d'isolation.
  • Bio-informatique : Identifier des sous-types de maladies à partir de profils d'expression génique.
  • Systèmes de recommandation : Clusteriser les utilisateurs ou les produits pour suggérer des éléments similaires (filtrage collaboratif).

Étiquettes: machine-learning unsupervised-learning clustering kmeans dbscan

Publié le 4 juillet à 00h24