k-means and customer segmentation

Lecture 11 · room 204

Prof. Niccolò Salvini

HEMA · Università Cattolica del Sacro Cuore, Rome

Tuesday 3 November 2026

Last time

Lecture 10 · Learning without a label · Mon 2 Nov

  • Statistics, machine learning, AI: the same four questions, answered differently
  • Unsupervised means no y and no residual — structure is judged by coherence, stability and usefulness
  • A database is not a dataset; and scale decides who is close — raw, euros swamp days

Today

Time Min
09:00 Last time · questions 10’
09:10 The algorithm: Lloyd’s four lines, by hand 60’
10:10 Two silent failures: scale and shape 20’
10:30 Break 15’
10:45 Choosing k: the elbow, and the elbow you get 35’
11:20 From clusters to segments 25’
11:45 In R · Set 10 15’

Objectives

  • Run the k-means algorithm by hand once, so it is never a black box again
  • Understand what it minimises, and why that makes it fast and fallible
  • Choose k with a method you can defend to a colleague
  • Turn clusters into segments: profiles a marketing team can use

Why a manager cares

One offer for everyone, or one for each customer? Neither.

  • Mass marketing wastes budget on people who would never respond
  • One-to-one is a fantasy at 400 000 customers
  • Segmentation is the working compromise: a handful of groups, each with its own offer, message, and channel
  • Every CRM system you will ever use has a segmentation inside it — usually a k-means, usually run once in 2019 and never revisited

By the end of today you can build one, and you know what is wrong with the one you inherit.

Section 1 The algorithm

What k-means wants

Given n points and a number k that you choose, find k groups C_1,\dots,C_k that minimise the within-cluster sum of squares:

W(C) \;=\; \sum_{j=1}^{k} \;\sum_{i \in C_j} \lVert x_i - \bar{x}_j \rVert^2

  • \bar x_j is the centroid of cluster j: the mean of its points
  • Small W: each point is close to its own centroid — the within-group variance ANOVA puts in its denominator

Note

The true minimum over all partitions is out of reach: n = 100, k = 3 is more partitions than atoms in the universe. k-means finds a good one, fast.

Lloyd’s algorithm, four lines

  1. Pick k points at random as initial centroids
  2. Assign each point to the nearest centroid
  3. Update each centroid to the mean of its assigned points
  4. Repeat 2–3 until nothing moves

Each step can only lower W, so it always stops. Usually within a dozen rounds.

Attention

It stops at a minimum, not the minimum. Different starting points give different answers. Always run it several times and keep the best: nstart = 25, never nstart = 1.

Assign, update, repeat

Deliberately bad starting centroids, so the first update is large. Watch W: it falls at every half-step, which is why the algorithm is guaranteed to stop — it cannot go back up.

By hand: six customers, two variables

Visits per month and average basket, already scaled

A B C D E F
visits 1 2 1 8 9 8
basket 1 1 2 8 8 9

k = 2. Start with centroids at A and D.

  • Assign: B, C nearer A; E, F nearer D → \{A,B,C\}, \{D,E,F\}
  • Update: \bar x_1 = (1.33, 1.33), \bar x_2 = (8.33, 8.33)
  • Assign again: nothing changes. Done in one round.

W = 2.67 + 2.67 = 5.3. Any other split of these six gives a larger W — try \{A,B,C,D\} vs \{E,F\} and see.

By hand, watched

Every squared distance, both centroid updates, and W at the end. Six points is small enough to check the algorithm’s arithmetic against your own.

Two things that silently break it

Both happen in every real dataset

Scale. Income in euros and age in years: income dominates the distance entirely, age is noise. k-means sees only geometry. Standardise first — scale() — unless you have a reason not to.

Scale: the distance is income

Twenty-eight years against six thousand euro, both squared: 784 against 36 million. Age is not weighted lightly, it is absent. The clusters you get back are income bands wearing a segmentation’s clothes.

Shape. k-means draws straight boundaries between centroids. It finds round, similar-sized blobs. Give it two crescents, or one dense core inside a diffuse halo, and it will cut them wrongly and report a fine W.

Shape: the failure with no error message

Two crescents any eye separates instantly. k-means cuts straight down the middle, splits both, and reports a W that looks perfectly reasonable in the output.

Note

Neither failure produces an error message. The output looks like any other segmentation. This is why you look at the plot before you trust the numbers.

Section 2 Choosing k

W always falls as k grows

  • k = 1: W is the total variance
  • k = n: W = 0, every point is its own cluster
  • In between, W falls monotonically. It cannot choose k for you — it always votes for more.

The elbow, and the elbow you actually get

Textbook curves have a corner. Most real ones bend smoothly, and the elbow you find is the elbow you went looking for. Bring a second criterion — silhouette, stability, or a business constraint on how many segments a team can act on.

Two honest tools:

  • Elbow: plot W against k; take k where the curve stops bending. Crude, quick, often enough.
  • Silhouette: for each point, how much closer is it to its own cluster than to the next one? Average it; pick the k that maximises. Ranges -1 to 1; above 0.5 is a real structure, below 0.25 is not.

In R

library(tidyverse); library(factoextra)
X <- scale(USArrests)                      # always: same units for every column

fviz_nbclust(X, kmeans, method = "wss")    # elbow
fviz_nbclust(X, kmeans, method = "silhouette")

set.seed(1)
km <- kmeans(X, centers = 4, nstart = 25)  # 25 random starts, keep the best

fviz_cluster(km, data = X)                 # the picture you show a colleague

Note

set.seed() makes the random starts reproducible. Without it, your colleague reruns your script and gets different segment numbers — the same segments, relabelled — and a meeting is lost to confusion.

Section 3 From clusters to segments

A cluster is a set of rows. A segment is a story.

The algorithm gives you 1, 2, 3, 4. Nobody in marketing can act on 3.

Profile each cluster: the mean of every variable, per cluster, back in the original units.

Segment Visits / month Basket (€) Tenure (yrs) Share
1 0.8 62 1.1 41%
2 6.4 28 4.8 22%
3 2.1 140 3.9 19%
4 4.0 55 0.4 18%

Then name them from the numbers — occasional big-basket, frequent small-basket loyalists, … — and only then hand them over.

What “act on it” looks like

  • Segment 2 (frequent, small basket, long tenure): cross-sell, not discount — they already come; raise the basket
  • Segment 4 (new, mid-frequency): the retention window is now; a churn model (week 5) will tell you which of them
  • Segment 1 (rare, big basket): the campaign question is reach, not offer

Attention

The segmentation is only as good as the variables you fed it. Cluster on demographics and you get demographic segments, which rarely predict behaviour. Cluster on behaviour — recency, frequency, monetary value — and the segments are things a company can move.

k-means answers “how many groups?” with “as many as you asked for.”

The choice of k is a decision, and it is yours.

Before the lab

Friday is clustering end to end, on a real customer table. Come having run today’s R block on USArrests, and with an answer to:

  • What is the elbow k? The silhouette k? Do they agree?
  • Rerun kmeans with nstart = 1 three times. Do the clusters change?
  • Profile the clusters. Write one sentence naming each.

Practice: Set 10

k-means and customer segmentation · about 40 minutes · before Mon 9 Nov

  1. Do it in your own script, with the seed the set gives you.
  2. Check your numbers on Blackboard: test Set 10. Feedback the moment you submit — as many attempts as you like.
  3. Bring the sentences. Questions marked In class have no number to check: we discuss them at the lab on Fri 13 Nov.

Not graded. The test is a mirror, not an exam.

Reading

  • ISLR §12.4.1 — k-means clustering, with the algorithm and its figure
  • Provost & Fawcett chapter 6, Clustering — the business questions, and “what does a cluster mean?”
  • Reference: ?kmeans, and the factoextra vignette for the plots