DS701 Session 4 — Wed Sep 16, 2026
Name the quantity and write it as a formula.
Answer: the Within-Cluster Sum of Squares (WCSS), a.k.a. the inertia:
\[ \underset{C_1, \dots, C_K}{\arg\min} \hspace{1em} \sum_{k=1}^K \hspace{1em} \sum_{x\in C_k} \Vert x-c_k\Vert^2. \]
For every point, the squared Euclidean distance to its own cluster center, summed over all points. In scikit-learn this is kmeans.inertia_.
Points \(1.2,\ 1.8,\ 2.1,\ 7.3,\ 7.9,\ 8.2,\ 9.1,\ 10.5\), initial centers \(A = 4.0\), \(B = 11.0\).
Assign — closest center wins (watch \(7.9\): \(|7.9-4.0| = 3.9\) vs. \(|7.9-11.0| = 3.1 \Rightarrow B\)):
| Cluster | Points |
|---|---|
| A | 1.2, 1.8, 2.1, 7.3 |
| B | 7.9, 8.2, 9.1, 10.5 |
Update — center of mass of each cluster:
\[ A' = \frac{1.2+1.8+2.1+7.3}{4} = 3.1, \qquad B' = \frac{7.9+8.2+9.1+10.5}{4} = 8.9 \]
Next round, \(7.3\) defects to \(B\) (\(4.2\) vs. \(1.6\)) and we settle at \(A^\ast = 1.7\), \(B^\ast = 8.6\).
Cluster customers on age (18–80) and income ($20k–$200k), unscaled. What determines the clusters?
Answer: income, and only income.
A clustering is a grouping of data objects such that objects within a group are similar and objects in different groups are dissimilar.
So we want to:
And it is unsupervised — no labels go in, and any labels we put on the clusters we invent afterwards.

Partitional setup for \(k\)-means: data are points in \(\mathbb{R}^d\), every object belongs to one and only one cluster (mutually exclusive), the clusters cover everything (exhaustive), and \(K\) is given in advance.
Neither step 2 nor step 3 can increase WCSS \(\Rightarrow\) it always converges — but only to a local minimum.
scikit-learn’s default, and n_init restarts the whole thing several times and keeps the best WCSS.
\(K\) is our first hyperparameter: a parameter that must be set before the model parameters (the centers) can be learned.
WCSS alone can’t pick it — WCSS decreases monotonically in \(K\), all the way to \(0\) at \(K = n\).
So: sweep \(K = 1, 2, 3, \dots\), fit each, and score it.
We’ll also talk about the silhouette coefficient in an upcoming lecture.
Assignment is “nearest center”, so cluster regions are straight-sided Voronoi cells and clusters are implicitly assumed to be spheres around their center.
Because \(k\)-means looks for spherical clusters in Euclidean distance, the units of each feature are part of the model.
\[ \begin{bmatrix}\text{age } 27\\\text{income } 75000\\\text{gender } 0\end{bmatrix}, \qquad \begin{bmatrix}\text{age } 45\\\text{income } 42000\\\text{gender } 1\end{bmatrix} \]
Standard remedy, per feature and independently:
Whenever you build or pick a distance metric, think about feature scale first.
\(k\)-means is a workhorse when the assumptions roughly hold:


scikit-learnGoal: implement one Lloyd’s iteration yourself, check it against sklearn.cluster.KMeans, then the stretch — sweep \(k\), and settle a case where the elbow is not clear — and finally break \(k\)-means on purpose and diagnose why.
numpy, matplotlib, scikit-learn only.The activity notebook goes live on the day of the lecture. Colab is optional — you can also open it on GitHub and run it locally.
Full lecture notes: \(k\)-Means Clustering
Also see:
Other clustering evaluation metrics:
Also see k-means++ initialization
Next up: hierarchical clustering (04) — clusters without choosing \(k\) up front.