Clustering and k-means

Machine Learning Notes · unsupervised 1 of 2 · Clustering and k-means ← the hub Anomaly detection →

Every algorithm up to this point was handed the answers. A training set was a list of pairs $\left(\vec{x}^{(i)}, y^{(i)}\right)$ — the input and what the output should have been — and learning meant shrinking the distance between the two. Unsupervised learning removes the $y$. The data is now just ${\vec{x}^{(1)}, \vec{x}^{(2)}, \ldots, \vec{x}^{(m)}}$, and there is no longer a right answer to be close to.

What is left to find is structure. Clustering is the first and most direct version of that question: which of these points belong together? The algorithm below, k-means, is the one people reach for first, and its entire content is two steps repeated until nothing moves.

In one line. Guess $K$ centroids, then repeat: assign every point to its nearest centroid, and move every centroid to the mean of the points that chose it. Both halves lower the same cost $J = \frac{1}{m}\sum_i \lVert \vec{x}^{(i)} - \vec{\mu}_{c^{(i)}}\rVert^2$, so the loop always converges — but only to a local minimum, which is why you run it many times and keep the best.

Contents
  1. Learning without labels
  2. The two-step idea
  3. Step 1: assign each point to a centroid
  4. Step 2: move each centroid
  5. The algorithm in full
  6. What it is actually minimising
  7. Initialization, and getting stuck
  8. Choosing $K$
  9. Where this goes next

Learning without labels

Two kinds of training set

The difference is visible in the notation alone, before any algorithm is written:

$$ \begin{align} \text{supervised:} \quad & \left\{\left(\vec{x}^{(1)}, y^{(1)}\right), \left(\vec{x}^{(2)}, y^{(2)}\right), \ldots, \left(\vec{x}^{(m)}, y^{(m)}\right)\right\} \tag{1.1} \\ \text{unsupervised:} \quad & \left\{\vec{x}^{(1)}, \vec{x}^{(2)}, \ldots, \vec{x}^{(m)}\right\} \tag{1.2} \end{align} $$
Equation 1: The supervised training set carries the answer with every example; the unsupervised one does not. Everything that follows is forced by that single missing symbol.

With labels, the same scatter of points has a line drawn through it separating crosses from circles, and "good" means the line puts them on the right sides. Without labels every point is the same colour, and "good" has to be defined by the geometry of the data itself.

What a clustering algorithm is asked for

Given the points and a number $K$, produce two things:

There are $K^m$ possible assignments, so searching them all is hopeless even for a small dataset. What makes k-means work is that it never searches: it alternates between two steps, each of which is the exact solution to half of the problem when the other half is held fixed.


The two-step idea

Figure 1: The thirty examples this note keeps returning to, drawn exactly as the algorithm receives them: no colours, no labels, thirty pairs of numbers. Three groups are obvious to a reader in one glance, which is precisely the intuition k-means is trying to mechanise — and also the reason the method is hard to trust on data with more than two features, where no such glance is available.

Fix the centroids and the best assignment is obvious — send each point to whichever centroid is nearest. Fix the assignment and the best centroid is equally obvious — put it at the mean of its points. Neither half is a search. The algorithm is just the two of them, alternating:

Figure 2: The k-means loop. Both boxes are exact solutions to half the problem, which is why the cost can only fall; the loop stops when an assignment step changes nothing, because from then on every step would repeat itself forever.

Ng's slides show exactly this as two pictures: Step 1, the points take the colour of the nearest cross; Step 2, each cross slides to the middle of its own colour. Run them again and a few points on the boundary switch colour, and the crosses slide a little less. Run them again and nothing moves at all — that is convergence.


Step 1: assign each point to a centroid

Squared Euclidean distance

Each example is given the index of the closest centroid:

$$ c^{(i)} := \arg\min_{k} \; \left\lVert \vec{x}^{(i)} - \vec{\mu}_k \right\rVert^2 = \arg\min_{k} \; \sum_{j=1}^{n} \left(x_j^{(i)} - \mu_{kj}\right)^2 . \tag{2} $$
Equation 2: The assignment step. For every example, take the centroid that minimises the squared distance and record its index; $c^{(i)}$ is a number between 1 and $K$, not a vector.

The square root is missing on purpose. $\sqrt{\cdot}$ is monotonically increasing, so it cannot change which centroid comes out smallest — and skipping it removes $K$ square roots per example per iteration for free.

Two worked assignments

example and centroidsto $\vec{\mu}_1$to $\vec{\mu}_2$assigned
$\vec{x} = (3, 5)$, $\vec{\mu}_1 = (1,2)$, $\vec{\mu}_2 = (4,8)$$2^2 + 3^2 = 13$$(-1)^2 + (-3)^2 = 10$cluster 2
the same, as true distances$\sqrt{13} \approx 3.606$$\sqrt{10} \approx 3.162$cluster 2
$\vec{x} = (2,-1,4)$, $\vec{\mu}_1 = (0,0,0)$, $\vec{\mu}_2 = (3,-2,5)$$4 + 1 + 16 = 21$$1 + 1 + 1 = 3$cluster 2
Table 1: Two assignments computed in full, in two and three dimensions. Both land on centroid 2, and in the 2-D case the winner is the one whose true distance is 3.162 rather than 3.606 — the ordering the squares gave is the ordering the roots would have given.

Why the feature scales matter

$\lVert \cdot \rVert^2$ adds the squared differences of every feature with equal weight, so the feature with the largest numerical range decides the clustering almost by itself. A dataset of house sizes in square feet ($10^3$) and bedroom counts ($10^0$) is, to k-means, a dataset about size alone. Standardize the features first — the same z-score step used before gradient descent in linear regression, and for the same reason: the algorithm assumes the axes are comparable.

Figure 3: Thirty-six homes of similar floor area that divide cleanly into two kinds — open-plan with two bedrooms, and subdivided with four or five. Left, k-means on the raw numbers: because square feet run in the thousands and bedrooms in single digits, 99.99 percent of every squared distance is contributed by the area alone, so the algorithm cuts the data into wide and narrow houses and recovers the real split only 58 percent of the time — barely better than a coin. Right, the same algorithm after each column is turned into a z-score: the two features now carry comparable weight, the cut runs horizontally between two bedrooms and four, and it agrees with the truth 97 percent of the time. Both panels show the same houses on the same axes; only the units the distance was measured in changed.

Step 2: move each centroid

With the assignments fixed, each centroid moves to the average of the examples that chose it:

$$ \vec{\mu}_k := \frac{1}{m_k} \sum_{i \,:\, c^{(i)} = k} \vec{x}^{(i)} . \tag{3} $$
Equation 3: The move step. The sum runs over the examples currently assigned to cluster $k$, and $m_k$ is how many there are; the result is the centre of mass of that cluster.

Concretely, if cluster 1 currently holds examples 1, 5, 6 and 10, then

$$ \vec{\mu}_1 = \tfrac{1}{4}\left[\vec{x}^{(1)} + \vec{x}^{(5)} + \vec{x}^{(6)} + \vec{x}^{(10)}\right], $$

averaged per feature — the first coordinate of $\vec{\mu}_1$ is the mean of the first coordinates, and so on.


The algorithm in full

The loop

Randomly initialize K cluster centroids  μ₁, μ₂, …, μ_K

Repeat {
    # Step 1 — assign points to cluster centroids
    for i = 1 to m:
        c⁽ⁱ⁾ := index (1…K) of the centroid closest to x⁽ⁱ⁾      # argmin_k ‖x⁽ⁱ⁾ − μ_k‖²

    # Step 2 — move cluster centroids
    for k = 1 to K:
        μ_k := mean of the points assigned to cluster k
}
until no c⁽ⁱ⁾ changes

That is the whole algorithm. There is no learning rate, no gradient, and nothing to tune except $K$ and where you start.

The empty-cluster case

One edge case has no natural answer: if a centroid ends up with no points assigned to it, its mean is $0/0$. Two conventions are used — delete the cluster and continue with $K-1$, or re-initialize that centroid at a random example and carry on. Deleting is the common choice; re-initializing is the one to use when $K$ is fixed by the downstream application.


What it is actually minimising

The distortion

The two steps look like a heuristic. They are not — they are alternating minimisation of one cost, which the course calls the distortion:

$$ J\left(c^{(1)}, \ldots, c^{(m)}, \vec{\mu}_1, \ldots, \vec{\mu}_K\right) = \frac{1}{m}\sum_{i=1}^{m} \left\lVert \vec{x}^{(i)} - \vec{\mu}_{c^{(i)}} \right\rVert^2 . \tag{4} $$
Equation 4: The k-means cost. $\mu_{c^{(i)}}$ is the centroid of the cluster that example $i$ is currently assigned to, so each term is the squared distance from a point to its own centroid — and the whole thing is the average of those.

The optimisation problem is to minimise $J$ over both sets of variables at once — the assignments $c^{(i)}$ and the centroids $\vec{\mu}_k$.

Why both steps lower it

The argument is short and worth making explicit, because it is the only guarantee k-means offers:

So $J$ never rises. It is bounded below by zero, and there are finitely many possible assignments, so the sequence must stop — k-means always converges. Note carefully what the argument does not say: nothing here claims the value it converges to is the smallest one.

A cost that goes up means a bug. This is the practical use of the fact. If you print $J$ after every half-step and it ever increases, the implementation is wrong — usually a centroid updated with the wrong subset, or assignments computed against the new centroids and then compared with the old cost.

A real run

Thirty points in three well-separated blobs, $K = 3$, cost printed after each half-step:

Figure 4: Distortion after every half-step of a real run. Odd positions are assign steps, even ones move steps; both fall, the largest single drop — 5.07 to 1.73 — is one move step, and by half-step 6 the value has stopped changing, so the run has converged after four full iterations.
iterationafter the assign stepafter the move step
1$13.1726$$6.8598$
2$5.0658$$1.7332$
3$0.9894$$0.9014$
4$0.9014$$0.9014$
Table 2: The same run as numbers. Every entry is smaller than the one before it until the fourth iteration, where the assign step changes no assignment and the cost repeats — the stopping condition.

Four iterations on thirty points, and the final centroids sit at $(1.79, 2.00)$, $(7.48, 3.18)$ and $(4.41, 7.98)$ — the three blobs the data was built from.

Figure 5: The same thirty points after the run in the chart above, coloured by the cluster they ended in, with the three converged centroids as crosses at $(1.79, 2.00)$, $(7.48, 3.18)$ and $(4.41, 7.98)$. Each cross sits at the centre of mass of its own colour — that is what the move step guarantees — and every point is nearer its own cross than either of the others, which is what the assign step guarantees. When both statements hold at once, neither step can change anything, and that is what convergence is.

Initialization, and getting stuck

Random initialization

The standard choice is the simplest one that cannot land a centroid somewhere absurd:

Starting from real data points guarantees every centroid begins somewhere the data actually is, which a uniform random point in space does not.

Local optima are real

The convergence argument says $J$ stops falling; it says nothing about where. Different starts genuinely end in different places, and the bad ones are visibly bad — one blob split across two centroids while two other blobs share the third.

Figure 6: A converged run that got it wrong, from the same data. Two centroids have divided the bottom-left blob between them while the third has been left to cover the other twenty points on its own, and its cross sits at $(5.95, 5.58)$ — in the empty middle, where no example is. The distortion is $6.1388$, nearly seven times the $0.9014$ of the good run, and yet nothing here is broken: no single point wants to change cluster and no centroid wants to move. This is a local minimum, and the run reports success.

Running the earlier dataset from eight different random starts:

start01234567
final $J$$0.9014$$0.9014$$0.9014$$0.9014$$0.9014$$0.9014$$6.3691$$0.9014$
Table 3: Eight random initializations of the same data with the same $K$. Seven find the true structure; one converges to a distortion seven times worse and stays there, because from that configuration no single reassignment or centroid move improves anything.

One start in eight was stuck. That is the whole reason for the next section — and note that nothing in the run reports the failure: the bad run converges just as cleanly as the good ones, and its final $J$ is the only evidence that anything went wrong.

Figure 7: Every possible initialization, not a sample of eight. Choosing 3 of the 30 examples as starting centroids can be done in 4,060 ways, and running all of them to convergence gives 3,383 correct answers and 677 failures — so a single run of k-means on this very easy dataset has about a one-in-six chance of being wrong. The failures are not one failure: they fall into seventeen distinct local minima, the mildest at 6.1386 and the worst at 7.9539. The bar heights are logarithmic, and the practical reading is the ratio, not the shape — with restarts the probability of missing the global optimum every time falls as $0.167^{\,n}$, which is under one in a thousand by the fourth restart.

The fix: restart and keep the best

Because $J$ is computable, the failure is detectable, and the remedy is to run the whole algorithm many times and keep the winner:

For i = 1 to 100 {                      # typically 50–1000 restarts
    randomly initialize k-means         # K random training examples
    run k-means to convergence          # get c⁽¹⁾…c⁽ᵐ⁾ and μ₁…μ_K
    compute the distortion  J(c⁽¹⁾,…,c⁽ᵐ⁾, μ₁,…,μ_K)
}
Pick the set of clusters with the lowest J

Fifty restarts is usually plenty; a thousand costs little on a small dataset and buys insurance on a hard one. The cost of a restart is one full run, and runs are cheap — the example above converged in four iterations.


Choosing $K$

Nothing so far says how many clusters there should be. Because the data has no labels, there is often no single right answer — Ng's own slide shows the same scatter cut convincingly into two clusters or into four, and both readings are defensible.

The elbow method

Run k-means for a range of $K$, plot the best distortion against $K$, and look for the point where the curve stops dropping steeply and flattens out:

Figure 8: The elbow, on the three-blob dataset — each point is the best distortion found over thousands of restarts, so none of these is a stuck run. The fall from 13.00 to 6.31 to 0.90 is the algorithm discovering real structure; from $K = 4$ onward it is only slicing genuine clusters into pieces, and each extra centroid buys about 0.13. The bend at $K = 3$ is the number of blobs the data was built from.

The method is honest about its own weakness: on real data the curve is often a smooth slide with no bend at all, and then it tells you nothing. The right $K$ is frequently ambiguous.

Why you cannot just minimise $J$

The obvious idea — try every $K$ and keep the one with the lowest distortion — always picks the largest $K$ you allow. Adding a centroid can only reduce the distortion, and at $K = m$ every point is its own cluster and $J = 0$. Figure 8 shows it happening: $J$ keeps falling past the elbow, all the way down to $0.2412$ at $K = 8$, and none of that fall means anything.

Never choose $K$ to minimise $J$. $J$ is the right tool for comparing restarts at the same $K$, and the wrong tool for comparing different $K$.

Choosing for the downstream purpose

The usable answer is that clustering is nearly always a means to something else, so let the something else decide. Ng's example is t-shirt sizing: cluster customers by height and weight, and $K = 3$ gives S/M/L while $K = 5$ gives XS/S/M/L/XL. Neither is statistically better — the trade is between a better fit per customer and the cost of manufacturing five sizes. That is a business decision, and the data cannot make it.

The same shape of argument decides $K$ for image compression, another standard use: cluster the pixel colours and store each pixel as the index of its centroid. $K$ is then literally the size of the palette, and it is chosen against a file-size budget and how bad the result is allowed to look.

The general rule. Evaluate the clustering by how well it serves the task it feeds, not by how tight the clusters are. Where there is no downstream task, the elbow and a look at the clusters is all there is — and that is a legitimate reason to be unsure.


Where this goes next

k-means answers "which points belong together". The second unsupervised algorithm answers a different question about the same unlabelled data: which points do not belong at all?

Backwards from here: linear regression has the feature-scaling machinery this note assumes, and model development has the train/cv/test discipline that the next note needs in order to pick $\epsilon$.

Machine Learning Notes · unsupervised 1 of 2 · Clustering and k-means ← the hub Anomaly detection →