3.1 Algoritmul K-Means
Fără etichete, fără „răspuns corect": K-Means descoperă singur grupurile naturale din date — clienți asemănători, pixeli de aceeași culoare, documente pe aceeași temă.
Teorie
Ideea și inițializarea centroizilor
Vrem să împărțim datele în k grupuri (clustere). Fiecare cluster e reprezentat de
centroidul său — punctul din mijlocul grupului. La start, centroizii se aleg
(semi)aleator; sklearn folosește k-means++, care îi împrăștie inteligent ca să evite
startul prost.
Procesul iterativ
Pasul 1 — atribuire: fiecare punct intră în clusterul centroidului cel mai apropiat.
Pasul 2 — actualizare: fiecare centroid se mută în media punctelor din clusterul lui.
Repetă până când nimic nu se mai schimbă.
Criterii de convergență
Algoritmul se oprește când atribuirile nu se mai schimbă, când centroizii se mișcă sub pragul
tol sau după max_iter iterații. Converge mereu, dar posibil într-un optim
local — de aceea sklearn rulează implicit n_init=10 porniri diferite și o păstrează pe
cea cu inerția minimă (suma pătratelor distanțelor punct–centroid).
Alegerea lui k și interpretarea clusterelor
Metoda cotului (elbow): desenezi inerția pentru k = 1..10; punctul unde graficul „se frânge" e un k rezonabil. Scorul silhouette (−1..1) măsoară cât de bine separat e fiecare punct în clusterul lui — mai mare = mai bine.
Interpretare: după clustering, uită-te la mediile fiecărui cluster
(df.groupby("cluster").mean()) și dă-le nume: „clienți tineri care cheltuie mult",
„clienți ocazionali" etc.
Utilizarea scikit-learn
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
X = StandardScaler().fit_transform(df) # scalarea e esențială (distanțe!)
# metoda cotului
inertii = []
for k in range(1, 11):
km = KMeans(n_clusters=k, n_init=10, random_state=42).fit(X)
inertii.append(km.inertia_)
km = KMeans(n_clusters=3, n_init=10, random_state=42)
etichete = km.fit_predict(X)
print(silhouette_score(X, etichete))
print(km.cluster_centers_)
Problemă rezolvată: segmentarea clienților unui magazin
Un magazin are date despre venitul anual și scorul de cheltuieli al clienților. Găsim segmentele naturale și le descriem — schema clasică a problemelor de tip Unsupervised Learning de pe platformă.
Soluția pas cu pas
import pandas as pd, matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
df = pd.read_csv("clienti.csv") # venit_anual, scor_cheltuieli
sc = StandardScaler()
X = sc.fit_transform(df[["venit_anual", "scor_cheltuieli"]])
# 1. alegem k cu metoda cotului
inertii = [KMeans(k, n_init=10, random_state=42).fit(X).inertia_
for k in range(1, 11)]
plt.plot(range(1, 11), inertii, "o-"); plt.xlabel("k"); plt.show()
# cotul apare la k=5
# 2. clustering final + interpretare
km = KMeans(n_clusters=5, n_init=10, random_state=42)
df["cluster"] = km.fit_predict(X)
print(df.groupby("cluster")[["venit_anual", "scor_cheltuieli"]].mean().round(1))
# 3. vizualizare
plt.scatter(df["venit_anual"], df["scor_cheltuieli"], c=df["cluster"], cmap="tab10")
centre = sc.inverse_transform(km.cluster_centers_)
plt.scatter(centre[:, 0], centre[:, 1], marker="X", s=200, c="red")
plt.show()
Interpretarea tipică a celor 5 clustere: venit mare + cheltuieli mari (clienți premium), venit mare + cheltuieli mici (precauți), venit mic + cheltuieli mari (impulsivi), venit mic + cheltuieli mici, și mijlocul.
Probleme propuse
Punctele 1D: {1, 2, 3, 10, 11, 12}, centroizi inițiali 2 și 3. Rulează manual algoritmul (atribuire + actualizare) până la convergență. În câte iterații se stabilizează și unde ajung centroizii?
Citește o imagine ca matrice (H·W, 3) de pixeli RGB și rulează K-Means cu k=8. Înlocuiește fiecare pixel cu centroidul lui și salvează imaginea „posterizată" cu doar 8 culori.
Rulează K-Means cu k=3 pe Iris ignorând coloana speciei, apoi compară clusterele cu speciile reale. Ce procent din flori nimerește în clusterul „corect"?
Rezolvă una dintre cele 4 probleme din categoria Unsupervised Learning.