Clustering is unsupervised, so there is no single “accuracy”. Metrics fall into two families:
| Family | Needs true labels? | Question answered | Examples |
|---|---|---|---|
| External | Yes | How well do the clusters match a known grouping? | Purity, Rand Index, Adjusted Rand Index, NMI |
| Internal | No | Are the clusters compact and well separated? | Inertia, Silhouette, Davies-Bouldin |
Cluster IDs are arbitrary (cluster 0 vs. cluster 2 means nothing), so a good external metric must be invariant to relabeling. Plain accuracy is not, which is why these metrics exist. Classification metrics live in Metrics and Model Evaluation.
All external metrics start from the contingency table, rows = clusters, columns = true classes. Running k-Means () on Iris gives:
| Cluster | setosa | versicolor | virginica | Cluster size |
|---|---|---|---|---|
| 0 | 0 | 48 | 14 | 62 |
| 1 | 50 | 0 | 0 | 50 |
| 2 | 0 | 2 | 36 | 38 |
Purity
Assign each cluster to its majority class and count how many points are then “correct”:
Iris: .
- Range 0 to 1, higher is better; easy to interpret.
- Flaw: purity rewards more clusters. With one cluster per point, purity is 1. Only compare runs with the same .
Rand Index (RI)
Look at every pair of points ( pairs) and check whether the clustering and the ground truth agree about the pair:
- = pairs in the same cluster and the same class
- = pairs in different clusters and different classes
It is the accuracy of the question “do these two points belong together?”. Range 0 to 1, with 1 a perfect match. Iris: .
Flaw: random clusterings do not score 0, and the baseline rises with the number of clusters. That makes RI hard to read on its own.
Adjusted Rand Index (ARI)
ARI corrects RI for chance by subtracting its expected value under random labeling:
Computed directly from the contingency table with (cell counts), (row sums), (column sums):
| ARI | Meaning |
|---|---|
| 1 | Identical partitions (up to relabeling) |
| ~0 | Random labeling |
| < 0 | Worse than random |
Iris: . This is the metric to report by default when ground truth exists, since it is chance-corrected and does not depend on the way purity does.
Normalized Mutual Information (NMI)
Measures how much knowing the cluster reduces uncertainty about the class, using entropy:
Range 0 to 1. Like ARI it ignores labels, but it is information-theoretic rather than pair-counting. Iris: .
Internal Metrics (no ground truth)
- Inertia (within-cluster sum of squares): the quantity k-Means minimizes. Always decreases as grows, so use it with the elbow method rather than as a score.
- Silhouette score: for each point, , where is the mean distance to its own cluster and the mean distance to the nearest other cluster. Range -1 to 1; near 1 means well-matched to its cluster, near 0 means on a boundary, negative means probably misassigned. The mean over all points can be compared across values of . Iris (): about 0.55.
- Davies-Bouldin index: average similarity between each cluster and its most similar neighbor; lower is better.
Which to Use
| Situation | Metric |
|---|---|
| Ground truth available, quick sanity check | Purity |
| Ground truth available, comparing methods or different | ARI (and NMI) |
| No ground truth, choosing | Silhouette, elbow on inertia |
Code
from sklearn.metrics import (adjusted_rand_score, rand_score,
normalized_mutual_info_score, silhouette_score)
import pandas as pd
contingency = pd.crosstab(cluster_labels, y)
purity = contingency.max(axis=1).sum() / contingency.values.sum()
ri = rand_score(y, cluster_labels)
ari = adjusted_rand_score(y, cluster_labels)
nmi = normalized_mutual_info_score(y, cluster_labels)
sil = silhouette_score(X, cluster_labels) # internal: needs only the dataSource: scikit-learn, Clustering performance evaluation. Original ARI: Hubert & Arabie (1985).