Training KMeans
- Machine Learning course
- Intermediate
- Lesson 66/112
- 7 min
Train a KMeans model.
Choosing k and training
For k we'll compare values 2-6 with the silhouette score. A sensible number is also sought from the business side: 2 segments are too coarse for marketing, 8 segments unmanageable.
for k in range(2, 7):
km = KMeans(n_clusters=k, n_init=10, random_state=0).fit(Xs)
print(k, round(silhouette_score(Xs, km.labels_), 3))When the technical criterion and the business need conflict, both must be weighed; the highest silhouette means nothing if the segments can't be used.
Stability check
An ARI comparison across different seeds confirms the chosen k is stable. The segment sizes are also checked: a segment with a single customer, or with 90% of customers, is unusable.
km = KMeans(n_clusters=3, n_init=10, random_state=0).fit(Xs)
print(np.bincount(km.labels_)) # segment sizesBalanced, stable segments make campaigns reach meaningful groups.
Practice Choose k
Train KMeans (n_init=10, random_state=0) on the scaled data for k = 2-5. On each line print k, the silhouette score with round(..., 3) and the size of the smallest segment (np.bincount(km.labels_).min()). Weigh the silhouette and the segment size together.
Starter code
import numpy as np
rng = np.random.default_rng(5)
n = 400
grup = rng.integers(0, 3, n)
harcama = np.array([300, 1500, 800])[grup] + rng.normal(0, 120, n)
ziyaret = np.array([2, 4, 12])[grup] + rng.normal(0, 1.2, n)
sepet = harcama / np.maximum(ziyaret, 1)
X = np.column_stack([harcama, ziyaret, sepet])
from sklearn.preprocessing import StandardScaler
Xs = StandardScaler().fit_transform(X)
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# buraya yazSample solution
import numpy as np
rng = np.random.default_rng(5)
n = 400
grup = rng.integers(0, 3, n)
harcama = np.array([300, 1500, 800])[grup] + rng.normal(0, 120, n)
ziyaret = np.array([2, 4, 12])[grup] + rng.normal(0, 1.2, n)
sepet = harcama / np.maximum(ziyaret, 1)
X = np.column_stack([harcama, ziyaret, sepet])
from sklearn.preprocessing import StandardScaler
Xs = StandardScaler().fit_transform(X)
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
for k in range(2, 6):
km = KMeans(n_clusters=k, n_init=10, random_state=0).fit(Xs)
print(k, round(silhouette_score(Xs, km.labels_), 3), np.bincount(km.labels_).min())Expected output
2 0.501 141 3 0.699 128 4 0.711 12 5 0.659 12
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 If the silhouette is almost equal for k=3 and k=4, which is preferred?
- Both are rejected
- The more interpretable for the business, usually fewer clusters Correct answer
- Always the larger
- A random choice
Explanation: Fewer segments are easier to explain and act on.
2 Count the segment sizes.
print(np.____(km.labels_))
print(np.bincount(km.labels_))
Explanation: bincount gives how many times each cluster number appears.
3 Match the checks.
| Term | Meaning |
|---|---|
silhouette |
Separation quality |
ARI across seeds |
Stability |
bincount |
Segment sizes |
business need |
Interpretability |