Skip to content
datarekha
Machine Learning Medium Asked at AmazonAsked at AirbnbAsked at Uber

How do you choose the number of clusters k in k-means?

The short answer

Choose k by combining the elbow method and silhouette score with cluster stability, domain meaning, and downstream performance. There is no universally correct k, and inertia alone is not sufficient because it always decreases as k increases.

How to think about it

The direct answer

I choose k by triangulating several signals: the elbow in inertia, the silhouette score, stability across runs, and whether the resulting clusters are useful in the real problem. There is no universally correct k; if the metrics disagree, I investigate why rather than choosing whichever graph looks most flattering.

Why choosing k is not just a graph exercise

K-means is unsupervised, which means there is no known target label telling us that the “right” answer has four clusters. The algorithm needs us to supply k, the number of groups, before it starts.

For a chosen k, k-means repeatedly does two things:

  1. It assigns each data point to its nearest centroid, where a centroid is the mean position of a cluster.
  2. It recomputes each centroid from the points assigned to it.

It tries to minimise inertia, the sum of squared Euclidean distances from every point to the centroid of its assigned cluster. In notation, inertia is the sum of ||x_i - μ_c(i)||², where x_i is a point and μ_c(i) is the centroid of its cluster.

That objective explains the first important fact. Increasing k gives the algorithm more centroids, so it has more freedom to fit the data. Splitting one cluster into two cannot make the best possible within-cluster sum of squares larger. Inertia therefore falls as k rises, eventually reaching zero when every point has its own cluster.

The question is not “which k has the lowest inertia?” That answer is always the largest k you allowed. The useful question is “when does another cluster stop buying enough improvement to justify its extra complexity?”

The elbow method

The elbow method runs k-means for a range of values, records inertia, and plots inertia against k. We look for a bend where the large improvements start flattening out.

Suppose inertia falls from 18,420 at k = 2 to 12,080 at k = 3, then to 9,310 at k = 4, 7,820 at k = 5, and 6,850 at k = 6.

The reductions are:

k changeInertia reduction
2 to 36,340
3 to 42,770
4 to 51,490
5 to 6970

A reasonable candidate is k = 3: the curve makes a large improvement before flattening. But “elbow” is a visual heuristic, not a statistical law. Real data often produces a smooth curve with no obvious bend. If I have to squint at the plot for ten minutes, the data may not contain a natural cluster count.

The elbow also depends on the features and distance metric. If one feature is measured in dollars and another in a fraction, raw Euclidean distance may be dominated by dollars. A customer’s order count could then matter far more than their return rate simply because the numbers are larger.

That is why I usually scale numeric features before using k-means. Standardisation changes each feature to have roughly zero mean and unit variance, so a one-standard-deviation difference in order count is comparable to a one-standard-deviation difference in return rate. I would not do this mechanically if the original units represent deliberate business weights. Scaling is a modelling choice, not a ritual.

Common mistake: Never choose k by minimising inertia alone. More clusters always make the training objective easier, so a lower inertia does not prove that the segmentation is better.

The silhouette score

The silhouette score asks a different question: is each point closer to its own cluster than to its nearest competing cluster?

For point i:

  • a(i) is the mean distance from the point to the other points in its own cluster. This measures cohesion.
  • b(i) is the mean distance from the point to the points in the nearest other cluster. This measures separation.

The silhouette for that point is:

(b(i) - a(i)) / max(a(i), b(i))

The result ranges from negative one to positive one.

A value near one means the point is close to its own cluster and far from its nearest rival. A value near zero means the point lies near a boundary. A negative value means it may be closer to another cluster than to the one it was assigned.

The mean silhouette across all points gives a compact summary for a candidate k. Higher is generally better, but “highest silhouette wins” is also too simplistic. Silhouette tends to reward compact, well-separated, similarly sized groups. It can prefer two broad clusters over four useful business segments, especially when the data has nested structure.

It also uses distances, so it is not independent of scaling or the geometry assumed by k-means. In high-dimensional data, distances can become less discriminative, making small differences in silhouette less trustworthy.

A concrete example

Imagine segmenting 10,000 retail customers using three features:

  • monthly order count,
  • average order value,
  • return rate.

After checking for leakage and standardising the features, suppose the runs produce the following illustrative results:

kInertiaMean silhouette
218,4200.41
312,0800.52
49,3100.44
57,8200.39
66,8500.35

Both signals point to k = 3. The elbow appears around three clusters, and the silhouette reaches its maximum there.

I would still inspect the actual groups. Perhaps the three clusters are:

  • occasional, low-value shoppers;
  • frequent, high-value shoppers;
  • frequent shoppers with unusually high return rates.

That last group could support a useful operational action, such as reviewing sizing information or return policy friction. If the clusters instead differ only by tiny numerical changes and have no plausible interpretation, a good silhouette score has not rescued the project.

A basic implementation might look like this:

import numpy as np

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler

# Rows are customers; columns are the three selected features.
X = StandardScaler().fit_transform(X_raw)

results = []

for k in range(2, 9):
    model = KMeans(
        n_clusters=k,
        n_init=20,
        random_state=42,
    )
    labels = model.fit_predict(X)
    results.append({
        "k": k,
        "inertia": model.inertia_,
        "silhouette": silhouette_score(X, labels),
    })

best_by_silhouette = max(
    results,
    key=lambda row: row["silhouette"],
)

I would run several initialisations, inspect the inertia curve, and compare the scores across the same scaled dataset. The absolute inertia from a different feature set or scaling scheme is not directly comparable.

The senior-level checks

The elbow and silhouette are starting points. Before committing to a value, I check four things.

Stability. I rerun k-means with different random seeds and, when appropriate, bootstrap samples. If customers move between clusters dramatically from one run to another, the proposed segmentation is weak even if its average silhouette looks respectable. n_init helps find a better local solution for one dataset; it does not prove that the clusters are stable.

Cluster size. A solution with 96 percent of customers in one cluster and four tiny clusters may be mathematically valid but operationally useless. Tiny groups can also be driven by outliers. I inspect counts and feature distributions, not just centroids.

Domain meaning. The clusters should correspond to distinctions someone can explain and act on. If the marketing team can only say “cluster two has a centroid of 0.37,” the segmentation has not earned its keep.

Downstream value. If clusters feed a recommendation, campaign, routing rule, or forecasting model, I measure that outcome on held-out data or with an experiment. For example, if four clusters produce better campaign conversion than three on a future customer cohort, four may be preferable even with a slightly lower silhouette. The business objective is the final judge, provided it was not optimised on the same data used to create the clusters.

The gap statistic is another option. It compares the observed within-cluster dispersion with what would be expected from a reference distribution without meaningful cluster structure. It can make the comparison more principled, but it requires extra computation and still depends on how the reference data is constructed.

When k-means is the wrong tool

Sometimes the correct answer is not a different k; it is a different clustering algorithm.

K-means works best when clusters are reasonably compact, roughly spherical under the chosen distance, and not wildly different in size. It is a poor fit for concentric rings, long curved shapes, strongly varying densities, or data dominated by outliers. It also does not naturally handle categorical features.

A common production symptom is a sudden extra cluster containing a handful of extreme customers. Because k-means squares distances, an outlier can pull a centroid toward itself and make the inertia curve appear to justify a larger k. I would inspect the raw records, consider a transformation such as a log scale for heavily skewed features, and evaluate an algorithm whose assumptions better match the data. I would not simply increase k because the plot dipped.

What they’ll ask next

Why not just choose the k with the highest silhouette score?
Because silhouette favours compact, separated geometry and can reject smaller, meaningful subgroups. I use it as evidence, then check stability, cluster sizes, domain usefulness, and the downstream objective.

What if the elbow says three but the silhouette says four?
I inspect the four-cluster split. It may reveal a useful subgroup, or it may merely carve one coherent cluster into two arbitrary pieces. I compare stability and downstream performance, and I report the disagreement rather than pretending the metrics agree.

Would you always standardise the features first?
No. I standardise when features are on incompatible scales and I want them to contribute comparably. If domain knowledge says one feature should count five times as much as another, I encode that deliberately and validate the resulting distance geometry.

Say this in the interview

“I choose k by combining the elbow and silhouette methods with stability, cluster interpretability, and downstream value; inertia alone cannot choose it because it always decreases as more clusters are added.”

Keep practising

All Machine Learning questions

Explore further