Un algorithme qui range chaque client dans le groupe dont il est le plus proche, sans qu'on lui dise à l'avance quels groupes existent. C'est la méthode de segmentation la plus utilisée : rapide, simple à expliquer, et ses résultats se lisent comme des profils moyens.
Vous placez 4 drapeaux au hasard dans une foule. Chacun rejoint le drapeau le plus proche, puis on replante chaque drapeau au centre de son groupe. On recommence jusqu'à ce que plus personne ne change de drapeau.
Vous fixez le nombre de groupes k. L'algorithme choisit k points de départ parmi les clients : au hasard en R, par tirage espacé (k-means++) dans scikit-learn.
La proximité se mesure par la distance euclidienne sur toutes les variables. D'où l'importance de les mettre à la même échelle.
Chaque centre devient la moyenne des clients de son groupe. On répète les étapes 2 et 3 jusqu'à stabilité. Le résultat dépend du départ : on lance donc plusieurs essais (nstart) et on garde le meilleur.
Panier moyen, achats par mois, jours depuis le dernier achat, nombre de catégories achetées, part des achats faits en promotion. Aucune colonne cible : on ne sait pas à l'avance quels groupes existent.
Sur ce jeu, on obtient par exemple des fidèles gros paniers (achats fréquents, peu de promo), des réguliers, des occasionnels, et des chasseurs de promos inactifs depuis des mois. Nommer les segments est un travail métier : l'algorithme ne donne que des numéros.
La silhouette (de -1 à 1) et la courbe du coude aident à choisir k. Mais le vrai test est métier : chaque segment appelle-t-il une action différente, et reste-t-il stable si l'on relance l'analyse le trimestre suivant ?
K-means a peu de paramètres, mais chacun change le résultat. Noms donnés pour R (kmeans de base) et Python (scikit-learn).
Le nombre de groupes k. On trace l'inertie de k = 2 à 8 et on cherche le coude, là où ajouter un groupe n'apporte plus grand-chose. La silhouette la plus haute confirme. Sur ce jeu, les deux pointent vers 4.
scale() en R, StandardScaler en Python. Sans elle, le panier en euros et la récence en jours écrasent la part de promo, comprise entre 0 et 1. C'est l'erreur la plus fréquente.
Nombre de départs aléatoires. L'algorithme garde celui qui donne les groupes les plus compacts. 25 évite de tomber sur une mauvaise solution par malchance.
K-means donne le même poids à chaque variable. Deux variables qui mesurent la même chose comptent double. Retirer les doublons, ou passer d'abord par une ACP.
# Segmentation clients : K-means en R
clients <- read.csv("clients_segmentation.csv")
vars <- c("panier_moyen", "achats_par_mois", "recence_jours", "nb_categories", "part_promo")
# Standardiser : chaque variable a une moyenne de 0 et un écart-type de 1
X <- scale(clients[, vars])
# Méthode du coude : inertie intra-groupe pour k = 2 à 8
set.seed(42)
inertie <- sapply(2:8, function(k) kmeans(X, centers = k, nstart = 25)$tot.withinss)
print(round(setNames(inertie, 2:8)))
# Segmentation finale en 4 groupes
set.seed(42)
modele <- kmeans(X, centers = 4, nstart = 25)
clients$segment <- modele$cluster
# Taille et profil moyen de chaque segment, en unités d'origine
print(table(clients$segment))
print(round(aggregate(clients[, vars], by = list(segment = clients$segment), FUN = mean), 2))
# Segmentation clients : K-means en Python
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
clients = pd.read_csv("clients_segmentation.csv")
variables = ["panier_moyen", "achats_par_mois", "recence_jours", "nb_categories", "part_promo"]
# Standardiser : chaque variable a une moyenne de 0 et un écart-type de 1
X = StandardScaler().fit_transform(clients[variables])
# Choix de k : inertie (coude) et silhouette (plus haut = mieux)
for k in range(2, 9):
km = KMeans(n_clusters=k, n_init=25, random_state=42).fit(X)
print(k, round(km.inertia_), round(silhouette_score(X, km.labels_), 3))
# Segmentation finale en 4 groupes
modele = KMeans(n_clusters=4, n_init=25, random_state=42).fit(X)
clients["segment"] = modele.labels_
# Taille et profil moyen de chaque segment, en unités d'origine
print(clients["segment"].value_counts().sort_index())
print(clients.groupby("segment")[variables].mean().round(2).to_string())
On lance K-means pour plusieurs valeurs de k et on compare. La méthode du coude repère le k au-delà duquel l'inertie baisse peu. La silhouette mesure si chaque client est plus proche de son groupe que du groupe voisin : on retient le k où elle est la plus haute. Le choix final doit rester exploitable par le métier.
Oui, presque toujours. K-means calcule des distances : une variable en euros qui varie de 1 à 250 pèse bien plus qu'une proportion entre 0 et 1. On standardise chaque variable (moyenne 0, écart-type 1) pour que toutes comptent autant.
Les centres de départ sont tirés au hasard, et l'algorithme peut s'arrêter sur une solution moins bonne. On fixe une graine aléatoire et on multiplie les départs (nstart en R, n_init en Python) pour obtenir un résultat stable. Les numéros de segments peuvent aussi changer d'un logiciel à l'autre sans que les groupes changent.
Construit un arbre de regroupements qu'on coupe à la hauteur voulue. Pratique pour voir combien de groupes se dessinent, lent au-delà de quelques dizaines de milliers de lignes.
Voir la fiche → plus soupleDes groupes en forme d'ellipses et une probabilité d'appartenance pour chaque client. Utile quand les segments se chevauchent.
Voir la fiche → sans fixer kTrouve les zones denses et met à part les points isolés. Adapté aux formes irrégulières, moins aux profils moyens à présenter.
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