k-means and Gaussian mixtures
With no results to learn from, a model can still find groups in the data. Learn k-means, which finds groups by assigning and averaging, how to choose the number of groups, and Gaussian mixtures, which give each group its own bell curve and each student a share in every group, fitted by the EM algorithm.
Warm-up
One question before the lesson. Choose an answer and check it.
You have 30 students’ hours of study and sleep, but not their results. What can a model still learn?
Show the answer
C: Groups of students who study and sleep alike. Without results a model cannot learn to predict them, but it can still find structure in the inputs: groups of students who are alike. That is clustering, the commonest kind of unsupervised learning.
Step 1 Groups without labels
Every model so far learnt from examples with answers: a score to predict, or pass or fail. Here there are no answers, only 30 students’ hours of study and sleep:
| Student | Study | Sleep |
|---|---|---|
| 1 | 2.7 | 7.6 |
| 2 | 8.1 | 8.7 |
| 3 | 4.4 | 4.9 |
| 4 | 3.6 | 7.6 |
| 5 | 5.2 | 7.8 |
| 6 | 4.5 | 5.8 |
| 7 | 2.3 | 7.9 |
| 8 | 7 | 7.1 |
| 9 | 4.1 | 5.4 |
| 10 | 1.3 | 7.9 |
| 11 | 7.7 | 7.4 |
| 12 | 5 | 5.1 |
| 13 | 1.5 | 8 |
| 14 | 6 | 7.5 |
| 15 | 3.7 | 4.3 |
| 16 | 3.2 | 8 |
| 17 | 4.8 | 6.9 |
| 18 | 4.3 | 5.7 |
| 19 | 2.6 | 7.3 |
| 20 | 7.5 | 7.1 |
| 21 | 4.3 | 5.4 |
| 22 | 2.3 | 6.5 |
| 23 | 6.4 | 8 |
| 24 | 4.6 | 4.2 |
| 25 | 1.1 | 8.3 |
| 26 | 4.3 | 7.7 |
| 27 | 4.9 | 5.5 |
| 28 | 1.8 | 7.7 |
| 29 | 6.2 | 8 |
| 30 | 5.1 | 4.7 |
On the plot the students seem to fall into groups. Finding groups like these in the inputs alone is called clustering. It is one kind of unsupervised learning: learning without answers. The groups a method finds are called clusters.
These students were drawn from three groups, each with its own typical study and sleep, but the methods are never told which student came from which. That makes it possible to check, at the end, how well each method found them.
Try it yourself
Run k-means one step at a time: assign every student to the nearest centre, move the centres, and watch the error fall until nothing changes. Try new starts and other values of k. Then fit a Gaussian mixture by EM, a round at a time, and see each student’s shares.
Diamonds: the centres. Each student takes its centre’s colour once assigned.
No error yet
Start 1: the centres are 3 students picked at random. Press Assign.
Next: give each student to its nearest centre.
Show the calculation
| Student | d² to (2.3, 7.9) | d² to (7.5, 7.1) | d² to (3.6, 7.6) | Nearest |
|---|---|---|---|---|
| 1 | 0.25 | 23.29 | 0.81 | 1 |
| 2 | 34.28 | 2.92 | 21.46 | 2 |
| 3 | 13.41 | 14.45 | 7.93 | 3 |
| 4 | 1.78 | 15.46 | 0 | 3 |
| 5 | 8.42 | 5.78 | 2.6 | 3 |
| 6 | 9.25 | 10.69 | 4.05 | 3 |
| 7 | 0 | 27.68 | 1.78 | 1 |
| 8 | 22.73 | 0.25 | 11.81 | 2 |
| 9 | 9.49 | 14.45 | 5.09 | 3 |
| 10 | 1 | 39.08 | 5.38 | 1 |
| 11 | 29.41 | 0.13 | 16.85 | 2 |
| 12 | 15.13 | 10.25 | 8.21 | 3 |
| 13 | 0.65 | 36.81 | 4.57 | 1 |
| 14 | 13.85 | 2.41 | 5.77 | 2 |
| 15 | 14.92 | 22.28 | 10.9 | 3 |
| 16 | 0.82 | 19.3 | 0.32 | 3 |
| 17 | 7.25 | 7.33 | 1.93 | 3 |
| 18 | 8.84 | 12.2 | 4.1 | 3 |
| 19 | 0.45 | 24.05 | 1.09 | 1 |
| 20 | 27.68 | 0 | 15.46 | 2 |
| 21 | 10.25 | 13.13 | 5.33 | 3 |
| 22 | 1.96 | 27.4 | 2.9 | 1 |
| 23 | 16.82 | 2.02 | 8 | 2 |
| 24 | 18.98 | 16.82 | 12.56 | 3 |
| 25 | 1.6 | 42.4 | 6.74 | 1 |
| 26 | 4.04 | 10.6 | 0.5 | 3 |
| 27 | 12.52 | 9.32 | 6.1 | 3 |
| 28 | 0.29 | 32.85 | 3.25 | 1 |
| 29 | 15.22 | 2.5 | 6.92 | 2 |
| 30 | 18.08 | 11.52 | 10.66 | 3 |
Press Assign and Move centres in turn until nothing changes. Then try New start, or another k.
Practice problems
Work each problem out on paper, then type your answer and press Check. Every problem has hints and a full solution.
Score: 0 of 10 points
Problem 1
1 pointWhat is the squared distance between the points (2, 7) and (5, 3)?
Hint 1
Square the difference in each input, then add.
Solution
d² = (2 − 5)² + (7 − 3)² = 9 + 16 = 25
Problem 2
2 pointsA cluster holds the points (2, 7), (4, 5) and (3, 9). Its centre moves to their mean. What is the cluster’s error then, the total squared distance from its points to its centre?
Hint 1
First find the centre: the mean of the first inputs, and the mean of the second.
Hint 2
Then add each point’s squared distance to that centre.
Solution
centre = ((2 + 4 + 3) ÷ 3 = 9 ÷ 3 = 3, (7 + 5 + 9) ÷ 3 = 21 ÷ 3 = 7)
(2, 7): (2 − 3)² + (7 − 7)² = 1 + 0 = 1
(4, 5): (4 − 3)² + (5 − 7)² = 1 + 4 = 5
(3, 9): (3 − 3)² + (9 − 7)² = 0 + 4 = 4
error = 1 + 5 + 4 = 10
Problem 3
2 pointsA normal distribution has centre μ = 5 and spread σ = 2. What is its density at x = 7? Give it to 2 decimal places.
Hint 1
p(x) = e^(−(x − μ)² ÷ 2σ²) ÷ (σ√(2π)).
Hint 2
Here (x − μ)² = 4 and 2σ² = 8.
Solution
(x − μ)² = (7 − 5)² = 4
2σ² = 2 × 2² = 8
e^(−4 ÷ 8) = e^(−0.5) = 0.6065
σ√(2π) = 2 × 2.5066 = 5.0133
p(x) = 0.6065 ÷ 5.0133 = 0.121
Problem 4
2 pointsA mixture has two clusters with weights 0.5 and 0.5. At one student the first cluster’s density is 0.3 and the second’s is 0.1. What is the student’s share in the first cluster?
Hint 1
Multiply each density by its cluster’s weight.
Hint 2
The share is the first of those divided by their total.
Solution
weight × density: 0.5 × 0.3 = 0.15, 0.5 × 0.1 = 0.05
share = 0.15 ÷ (0.15 + 0.05) = 0.15 ÷ 0.2 = 0.75
Problem 5
3 pointsIn an M step, three students who studied 2, 4 and 6 hours have shares 1, 0.5 and 0 in a cluster. What is the cluster’s new centre in study hours? Give it to 2 decimal places.
Hint 1
Each student counts by its share: multiply each study value by its share, and add.
Hint 2
Divide by the total of the shares, not by the number of students.
Solution
weighted sum = 1 × 2 + 0.5 × 4 + 0 × 6 = 4
total share = 1 + 0.5 + 0 = 1.5
centre = 4 ÷ 1.5 = 2.6667
Programming exercise
Write k-means, the normal density and a round of EM in plain Python. Save clusters.py and test_clusters.py in the same folder, fill in each function in clusters.py, and run the tests:
python test_clusters.py
"""k-means and Gaussian mixtures: programming exercise. Write k-means in plain Python, then the normal distribution's density and around of the EM algorithm for a mixture in one input. Run the tests fromthis folder: python test_clusters.py A point is a list of two numbers, such as [hours studied, hours slept]. Acentre is a point too. labels[i] is the number of the centre point i belongsto: 0 for the first centre, 1 for the second, and so on.""" import math # noqa: F401 (you will need math.exp, math.sqrt and math.pi) def dist2(a, b): """Return the squared distance between points a and b: (a[0] - b[0])**2 + (a[1] - b[1])**2.""" raise NotImplementedError def assign(points, centres): """Return each point's label: the number of its nearest centre by squared distance. If two centres are equally near, use the first.""" raise NotImplementedError def update(points, labels, centres): """Return the new centres: each one moved to the mean of its points. A centre with no points stays where it is.""" raise NotImplementedError def inertia(points, labels, centres): """Return the error: the total squared distance from each point to its own centre.""" raise NotImplementedError def kmeans(points, centres): """Run k-means from the given centres and return (centres, labels). Assign every point, then move every centre, and repeat. Stop as soon as an assignment is the same as the one before it, and return the centres that assignment was made with, and the assignment. """ raise NotImplementedError def normal_pdf(x, mu, sigma): """Return the normal distribution's density at x: e^(-(x - mu)**2 / (2 * sigma**2)) / (sigma * sqrt(2 * pi)).""" raise NotImplementedError def shares(x, weights, mus, sigmas): """Return the shares of a value x in each cluster of a mixture in one input: each weight times its cluster's density at x, divided by their total.""" raise NotImplementedError def em_step(xs, weights, mus, sigmas): """Do one round of EM for a mixture in one input, and return (weights, mus, sigmas). E step: work out every value's shares. M step: for each cluster, the new weight is its total share divided by the number of values, the new mu is the share-weighted mean of the values, and the new sigma is the square root of the share-weighted mean of (x - new mu)**2. """ raise NotImplementedError Stuck? Write dist2 first, then assign and update, which kmeans repeats until no point changes centre. em_step works in one input: shares first, then each cluster’s weight, mean and spread from the shares. The Solution tab has one way to write each function.
In practice: clustering in real projects
Scale the inputs. k-means and Gaussian mixtures measure distances, so an input in large units drowns out the others. Standardise the inputs first, as in Lesson 6.
scikit-learn. KMeans(n_clusters=k) picks its first centres by k-means++, which spreads them apart, and n_init sets how many times the whole run is repeated, keeping the lowest error. GaussianMixture(n_components=k) is fitted by EM from a k-means start. Its covariance_type="diag" gives each cluster a spread per input, as in this lesson; its default, "full", lets each ellipse tilt as well.
Checking clusters. Clusters always come out, even from data with no groups in it. Check that they mean something: look at them, compare them with labels held back, as this lesson does, or see whether the same clusters come out of new data.
Test your knowledge
01How does k-means work?Show answer
Pick k starting centres. Give every point to its nearest centre, then move each centre to the mean of its points. Repeat until no point changes centre. Neither step can raise the total squared distance, so it always stops.
02Why run k-means from several starts?Show answer
It stops at a local minimum that depends on where it started, so some starts end with a much higher error. Running it several times and keeping the lowest error, or starting from spread-out centres with k-means++, avoids most bad endings.
03How do you choose k?Show answer
Plot the lowest error against k. It always falls as k grows, so look for the elbow, where one more cluster stops helping much. The silhouette score, or a mixture’s likelihood with a penalty for extra clusters (BIC), are other ways.
04How is a Gaussian mixture different from k-means?Show answer
Each cluster is a normal distribution with its own centre, spread and weight, and each point gets a share in every cluster instead of one label. k-means is close to the special case where every cluster is the same round bell and every share is 0 or 1.
05What do the E and M steps of EM do?Show answer
The E step works out each point’s share in each cluster from the current fit. The M step refits each cluster’s weight, centre and spread from all the points, each counted by its share. No round lowers the likelihood, so it converges, though possibly to a local best.
Exit ticket
One last question on the main idea of the lesson.
One run of k-means ends with a lower error than another. Is the lower one always closer to the true groups?
Show the answer
A: No: here the lowest error, 28.46, puts 2 students in the wrong group, because k-means treats every group as round. In this lesson the lowest error, 28.46, puts 28 of the 30 students with their own group, and an ending with the higher error 30.1 puts all 30. The Gaussian mixture, which gives each group its own spread, puts 30.