Menu
CoddyTech

The Elbow Method

Part of the Unsupervised Learning section of Coddy's Machine Learning journey. Lesson 7 of 51.

Plot inertia against k. While each new center splits a real group, inertia plunges; then it flattens. The bend, the elbow, is a good k:

Two inertia curves for k from 1 to 8. Left, the apples: a steep fall to k = 3, then nearly flat, with a dashed line at 3. Right, points with no groups: a smooth curve with no bend

A rule of thumb: stop when one more center cuts inertia by less than a quarter. The apples' cuts: 56%, then 69%, then only 15%. So k = 3:

ax.plot(ks, inertias, marker="o")
ax.axvline(3, linestyle="--")

A gentle curve with no bend means no clear groups. The next lesson brings a second judge.

challenge icon

Challenge

Easy

A plant app sorts houseplants into care plans by light and water need. The starter holds inertias for k from 1 to 8, a chart, and cutoff.

  1. Going up from k = 1, stop where the next k cuts inertia by less than cutoff. Print that k.
  2. Plot inertia by k with dots, a dashed vertical line at your k, and show.

For another app, cutoff 0.25:

Care plans: 3

An inertia curve titled Elbow: Care Plans for k from 1 to 8, with a dot at each k: a steep fall to k = 3, then nearly flat, and a dashed vertical line at 3

Then Coddy describes your chart.

Try it yourself

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

# Don't change the lines below
rng = np.random.default_rng(17)
# Four kinds of plant: typical light and water need, and how many
kinds = [(8.5, 2, 35), (2.5, 7.5, 30), (5, 5, 30), (8, 8, 25)]
parts = []
for l, w, n in kinds:
    parts.append(np.column_stack([rng.normal(l, 0.8, n), rng.normal(w, 0.8, n)]))
# 120 houseplants, one row each: light need and water need, scored 1 to 10
plants = np.clip(np.round(np.concatenate(parts), 1), 1, 10)

# Inertia for k = 1 to 8, from Inertia
ks = list(range(1, 9))
inertias = []
for k in ks:
    km = KMeans(n_clusters=k, n_init=10, random_state=0)
    km.fit(plants)
    inertias.append(km.inertia_)

cutoff = float(input())
fig, ax = plt.subplots()
ax.set_title("Elbow: Care Plans")
ax.set_xlabel("k")
ax.set_ylabel("Inertia")

# Write your code below
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Unsupervised Learning

Practice on your own: Online Python compiler