Menu
CoddyTech

When K-Means Fails

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

K-means pictures every cluster as a round blob around its center. Darts make a bullseye with a ring around it, and k-means cuts them in half:

Two charts of 140 darts. Left, the truth: a tight bullseye group inside a wide ring. Right, k-means with k = 2: a straight dashed border splits board, ring and bullseye into a left half and a right half, each with a center cross

Each point joins its nearest center, so the border between two clusters is a straight line halfway between the centers. No straight line separates a ring from its middle.

Long, curved or very uneven groups break k-means the same way. It still returns clusters, so always look at the picture.

challenge icon

Challenge

Medium

A drone spotted 200 seals on two curved sandbars. The starter draws the truth on the left panel.

  1. Cluster the seals with k-means, k = 2.
  2. On the right panel, scatter each cluster, labelled cluster 0 or cluster 1.
  3. Mark the centers as black "X" markers labelled centers. Add a legend, then show.

Coddy describes your chart and counts seals kept with their own sandbar. Like this, for two crowds:

Two charts. Left, the truth: a big spread-out crowd and a small tight crowd to its right. Right, k-means with k = 2: the small crowd's cluster also takes the big crowd's right edge, and black crosses mark the two centers

Try it yourself

import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.cluster import KMeans

# 200 seals resting on two curved sandbars, seen from a drone (positions in 100 m)
X, sandbar = make_moons(n_samples=200, noise=0.07, random_state=4)


# Draws the true sandbars on ax
def draw_truth(ax):
    ax.scatter(X[sandbar == 0, 0], X[sandbar == 0, 1], s=12, label="north bar")
    ax.scatter(X[sandbar == 1, 0], X[sandbar == 1, 1], s=12, label="south bar")
    ax.set_title("The truth")
    ax.legend()


fig, (left, right) = plt.subplots(1, 2, figsize=(9, 4))
draw_truth(left)
right.set_title("K-means, k = 2")

# 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