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.

Lesson 8 stepsPractice 5 problemsExercise Python, 8 functionsQuiz 5 questions

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

Here are 30 students, with no results this time:only how many hours each studied and slept.Are there groups of students who study and sleep alike?Finding groups in the inputs alone is called clustering.With no answers to learn from, it is unsupervised learning.Two ways to do it: k-means, and Gaussian mixtures.0246810468hours studiedhours slept
01/08

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:

StudentStudySleep
12.77.6
28.18.7
34.44.9
43.67.6
55.27.8
64.55.8
72.37.9
877.1
94.15.4
101.37.9
117.77.4
1255.1
131.58
1467.5
153.74.3
163.28
174.86.9
184.35.7
192.67.3
207.57.1
214.35.4
222.36.5
236.48
244.64.2
251.18.3
264.37.7
274.95.5
281.87.7
296.28
305.14.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.

0246810456789hours studiedhours slept

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
Studentd² to (2.3, 7.9)d² to (7.5, 7.1)d² to (3.6, 7.6)Nearest
10.2523.290.811
234.282.9221.462
313.4114.457.933
41.7815.4603
58.425.782.63
69.2510.694.053
7027.681.781
822.730.2511.812
99.4914.455.093
10139.085.381
1129.410.1316.852
1215.1310.258.213
130.6536.814.571
1413.852.415.772
1514.9222.2810.93
160.8219.30.323
177.257.331.933
188.8412.24.13
190.4524.051.091
2027.68015.462
2110.2513.135.333
221.9627.42.91
2316.822.0282
2418.9816.8212.563
251.642.46.741
264.0410.60.53
2712.529.326.13
280.2932.853.251
2915.222.56.922
3018.0811.5210.663

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

  1. Problem 1

    1 point

    What 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

  2. Problem 2

    2 points

    A 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

  3. Problem 3

    2 points

    A 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

  4. Problem 4

    2 points

    A 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

  5. Problem 5

    3 points

    In 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.