Un cousin de K-means dont chaque centre est un individu réel de la base, le médoïde, et non une moyenne abstraite. Il accepte n'importe quelle distance, y compris sur des données qui mélangent chiffres et catégories, et résiste mieux aux valeurs extrêmes.
Pour représenter chaque région lors d'un test, on ne choisit pas un « magasin moyen » qui n'existe pas. On choisit le vrai magasin qui ressemble le plus à tous les autres de sa région.
Entre chaque paire de magasins. La distance de Gower traite les chiffres (écart rapporté à l'étendue) et les catégories (même zone ou non) dans une même échelle de 0 à 1.
La phase BUILD de PAM ajoute un à un les individus qui réduisent le plus la distance totale de chacun à son médoïde le plus proche.
La phase SWAP essaie de remplacer un médoïde par un autre individu. Si la distance totale baisse, l'échange est gardé. On s'arrête quand plus aucun échange n'améliore le résultat.
Surface, budget publicitaire local, nombre de concurrents, chiffre d'affaires et zone d'implantation. La zone est une catégorie : K-means ne sait pas la traiter sans bricolage.
La direction réseau teste une nouvelle opération dans ces 6 magasins réels. Chacun est le plus représentatif de son groupe, et le résultat se transpose au groupe entier.
La silhouette moyenne mesure la séparation des groupes. Avec Gower, la zone pèse lourd : les groupes se forment d'abord par zone, puis par format. Vérifiez que ce découpage correspond à une réalité terrain avant de lancer le test.
Noms donnés pour R (cluster::pam) et Python (paquet kmedoids).
Le nombre de groupes. La silhouette moyenne aide à le choisir ; ici, un besoin métier (6 magasins pilotes) peut aussi le fixer. Tester plusieurs valeurs reste indispensable.
Euclidienne pour des chiffres standardisés, Manhattan pour limiter l'effet des extrêmes, Gower pour des données mixtes (daisy en R). C'est le choix qui change le plus le résultat.
PAM exact convient jusqu'à quelques milliers de lignes. Les variantes accélérées (FasterPAM, défaut du paquet Python ; argument pamonce en R) vont bien plus vite. CLARA, en R, travaille sur des échantillons pour les grandes bases.
# Magasins pilotes : K-medoids (PAM) en R
library(cluster)
magasins <- read.csv("magasins.csv")
magasins$zone <- factor(magasins$zone)
variables <- c("surface_m2", "budget_pub_k", "nb_concurrents", "zone", "ca_k")
# Distance de Gower : écart rapporté à l'étendue pour les chiffres, 0 ou 1 pour la zone
distances <- daisy(magasins[, variables], metric = "gower")
# PAM : 6 groupes, chacun représenté par un vrai magasin, le médoïde
modele <- pam(distances, k = 6, diss = TRUE)
magasins$groupe <- modele$clustering
# Les 6 magasins pilotes et la composition des groupes
print(magasins[modele$id.med, ])
print(table(groupe = magasins$groupe, zone = magasins$zone))
cat("Silhouette moyenne :", round(modele$silinfo$avg.width, 3), "\n")
# Magasins pilotes : K-medoids (PAM) en Python
import numpy as np
import pandas as pd
import kmedoids
from sklearn.metrics import silhouette_score
magasins = pd.read_csv("magasins.csv")
numeriques = ["surface_m2", "budget_pub_k", "nb_concurrents", "ca_k"]
# Distance de Gower : écart rapporté à l'étendue pour les chiffres, 0 ou 1 pour la zone
X = magasins[numeriques].to_numpy(dtype=float)
X = X / (X.max(axis=0) - X.min(axis=0))
zone = magasins["zone"].to_numpy(dtype=str)
distances = np.abs(X[:, None, :] - X[None, :, :]).sum(axis=2)
distances = (distances + (zone[:, None] != zone[None, :])) / 5
# PAM : 6 groupes, chacun représenté par un vrai magasin, le médoïde
modele = kmedoids.KMedoids(n_clusters=6, metric="precomputed", method="pam", init="build", random_state=42)
modele.fit(distances)
magasins["groupe"] = modele.labels_
# Les 6 magasins pilotes et la composition des groupes
print(magasins.iloc[modele.medoid_indices_].to_string())
print(pd.crosstab(magasins["groupe"], magasins["zone"]))
print("Silhouette moyenne :", round(silhouette_score(distances, modele.labels_, metric="precomputed"), 3))
K-means représente chaque groupe par la moyenne de ses membres, un point qui n'existe pas forcément. K-medoids le représente par un membre réel, celui qui est le plus proche de tous les autres. K-medoids accepte toute distance et résiste mieux aux extrêmes, mais il est plus lent.
Une distance pour données mixtes. Pour une variable numérique, elle calcule l'écart divisé par l'étendue de la variable ; pour une catégorie, elle vaut 0 si les deux individus sont dans la même modalité, 1 sinon. On fait ensuite la moyenne sur toutes les variables.
Partitioning Around Medoids, l'algorithme proposé par Kaufman et Rousseeuw. Il construit d'abord des médoïdes de départ (BUILD), puis teste des échanges entre médoïdes et autres points (SWAP) tant que la distance totale diminue.
Les centres sont des moyennes. Très rapide sur de gros volumes, mais sensible aux extrêmes et limité aux données numériques.
Voir la fiche → pour les données mixtesMélange moyennes pour les chiffres et modes pour les catégories. Tient mieux les gros volumes que PAM.
Voir la fiche → sur la même matriceUtilise la même matrice de distances et montre tous les niveaux de regroupement dans un arbre.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus