Concepts / Clustering Evaluation without Ground Truth

Clustering Evaluation without Ground Truth

A cluster label is an arbitrary name. Two labelings that give the same points the same grouping are the same clustering, even when every individual number differs.

  • Programming

Why Counting Matching Labels Feels Right

A very common first instinct when checking a clustering result is to compare its labels with a known answer and count how many labels match. That instinct comes from classification, where a predicted class either equals the true class or it does not. Applied to clustering, the same instinct produces a wrong verdict. This article follows that mistake step by step, shows exactly where the evaluation goes wrong, and replaces it with a metric that measures what a clustering actually is.

The lesson is best learned by tracing a small comparison script. Before each result is printed, you will be asked to predict it. The first printed result that disagrees with your prediction marks the place to examine most closely.

What a Cluster Label Really Is

When a clustering algorithm returns an array of numbers, each number is a cluster label. If a reference array of true labels exists, it seems natural to ask whether the two arrays agree, element by element. accuracy_score does exactly that: it checks each position and reports the fraction of positions where the two values are identical.

The trouble is that the numbers in a clustering are arbitrary names. A cluster labeled 0 in one run might be labeled 1 in another run, with no change to which points are grouped together. The meaningful content of a clustering is which points share a group, not which integer each group received.

Key point

A cluster label is an arbitrary name. Two labelings that give the same points the same grouping are the same clustering, even when every individual number differs.

Two Labelings of the Same Five Points

Consider five points. The first labeling puts points 0 and 1 in group 0, points 2 and 3 in group 1, and point 4 in group 2. The second labeling puts the same points together, but uses different names: points 0 and 1 get 1, points 2 and 3 get 2, and point 4 gets 0. Nothing about the grouping has changed. Only the names have been rotated.

python
Output (expected)
0.0
1.0
Notes on the code
  • labels_a and labels_b describe the same grouping with different numeric names
  • accuracy_score compares the two lists position by position
  • adjusted_rand_score judges which points share a group
Point 0A: 0 | B: 1Point 1A: 0 | B: 1Point 2A: 1 | B: 2Point 3A: 1 | B: 2Point 4A: 2 | B: 0
Which element of the first labeling is compared against which element of the second, and why does a matching grouping still produce mismatches?

Read the diagram position by position. Every position disagrees, so accuracy_score reports 0.0 even though the grouping is identical. The metric is not measuring whether the points are grouped correctly; it is measuring whether the same integer sits at the same position in both lists.

Predicting the Printed Scores

What do you think happens?

Both labelings describe the same grouping. What does accuracy_score print for labels_a and labels_b?

  • 1.0

  • 0.0

  • 0.6

  • It raises an error

Reveal answer
Answer:

0.0

Every position holds a different integer in the two lists (0 vs 1, 0 vs 1, 1 vs 2, 1 vs 2, 2 vs 0), so no position matches and the fraction of matching positions is 0.0.

What do you think happens?

What does adjusted_rand_score print for the same two labelings?

  • 1.0

  • 0.0

  • 0.2

  • It cannot be computed

Reveal answer
Answer:

1.0

adjusted_rand_score judges whether points share a group, and these two labelings group the points identically, so it reports perfect agreement.

Tracing the Comparison Script Step by Step

To locate the divergence, follow the script in order and compare each printed output with your prediction. The first line whose output disagrees with what you expected is the place to examine. The flowchart below lists the steps in execution order.

Build labels_aBuild labels_baccuracy_score callposition-by-position checkPrints 0.0diverges from agrouping-based expectationadjusted_rand_scorecallcompares shared groupsPrints 1.0thenthenfirst printed linethenthen
What sequence of steps does the comparison script run, and at which step does the printed score stop matching the learner's prediction?
Worked example

Finding the first line that disagrees with the prediction

You predicted that both metrics would report perfect agreement, because the two labelings describe the same grouping. Which printed line diverges from that prediction?

  1. 1
    Check the first printed line

    accuracy_score prints 0.0. The prediction was 1.0, so this line already disagrees.

  2. 2
    Locate the divergence

    The disagreement comes from the accuracy_score call, not from the data or the grouping. The labelings are correct; the assumption behind the call is what fails.

  3. 3
    Check the second printed line

    adjusted_rand_score prints 1.0, which matches the prediction. The grouping-based metric agrees with the expectation.

Result

The first divergence is the accuracy_score line. It rests on the assumption that identical integers must appear at identical positions, which is not a property of clusterings.

Why Position Matching Fails for Clusterings

accuracy_score requires the exact names to match. For classification this is a reasonable demand, because the predicted class is meant to be the true class. For clustering, the integers are arbitrary, so requiring them to match asks the wrong question. A metric that rewards identical integers will penalize a grouping that is correct but named differently.

Points 0 and 1label 0Points 0 and 1label 1Points 2 and 3label 1Points 2 and 3label 2Point 4label 2Point 4label 0same pointssame pointssame points
How can two label arrays with different numbers assigned to the same points describe identical clusters, and how does accuracy_score treat each one?

Each matched pair of groups holds exactly the same points, even though the numbers attached to them differ. A metric that asks only which points share a group sees identical clusterings here. accuracy_score asks which integer sits at each position, and sees none in agreement.

Choosing a Metric That Judges Grouping

The source names two suitable alternatives: adjusted_rand_score and normalized_mutual_info_score. Both are designed to compare a clustering with a reference grouping while ignoring the label names. When choosing between them, keep one question in mind: does the metric depend on which integer each point receives, or only on which points share a group? A metric that depends only on shared groups fits clustering evaluation.

Key point

adjusted_rand_score checks whether points share a group across the two labelings. Renaming the groups leaves that structure unchanged, so the score is not penalized for names.

Before
from sklearn.metrics import accuracy_score

labels_a = [0, 0, 1, 1, 2]
labels_b = [1, 1, 2, 2, 0]
print(accuracy_score(labels_a, labels_b))

accuracy_score reports 0.0 because no position holds the same integer in both lists

After
from sklearn.metrics import adjusted_rand_score

labels_a = [0, 0, 1, 1, 2]
labels_b = [1, 1, 2, 2, 0]
print(adjusted_rand_score(labels_a, labels_b))

adjusted_rand_score reports 1.0 because the grouping of the points is identical

Mistakes That Hide the Grouping Question

  • Common mistake

    Treating a low accuracy_score as proof that the clustering is poor

    What it looks like

    accuracy_score(labels_a, labels_b) returns 0.0 even though both lists group the five points identically.

    Why it fails

    accuracy_score rewards identical integers at identical positions. Renamed but identical groups score zero.

    Do this instead

    Use a metric that depends only on which points share a group, such as adjusted_rand_score.

  • Common mistake

    Assuming label 0 in one run means the same group as label 0 in another run

    Why it fails

    A cluster label is an arbitrary name. The same integer can refer to different groups in different runs.

    Do this instead

    Compare the points grouped together, not the integers attached to them.

  • Common mistake

    Stopping the trace at the final printed number instead of the first line that disagrees with the prediction

When No Reference Grouping Exists

Everything above assumes a reference grouping exists to compare against. Often it does not. The source treats evaluating clustering without ground truth as a distinct challenge, separate from comparing against known labels.

The lesson that carries over is this: whatever method you choose must judge the grouping, and it must not depend on arbitrary label names. This article does not cover the specific methods used when no reference exists.

Practice: Relabel and Predict

MEDIUM

Take labels_a = [0, 0, 1, 1, 2] and create a new labeling labels_c that groups the points in the same way but uses the names 2, 2, 0, 0, 1. Before running any code, predict the printed value of accuracy_score(labels_a, labels_c) and adjusted_rand_score(labels_a, labels_c). Then check your predictions and identify the first line whose output disagrees with them, if any.

Hints
  • Write the position-by-position pairs first: (0,2), (0,2), (1,0), (1,0), (2,1).
  • Ask whether any pair in that list matches exactly.
  • For adjusted_rand_score, ask whether the points in labels_a and labels_c share groups in the same way.

Key Takeaways

  • A cluster label is an arbitrary name; the meaningful content of a clustering is which points share a group.
  • accuracy_score compares labels position by position and requires the exact names to match, so it reports misleading results for a correct grouping with different names.
  • adjusted_rand_score and normalized_mutual_info_score judge the grouping rather than the label names, so they suit clustering evaluation.
  • To find a divergence, compare each script step with your prediction and locate the first line whose output disagrees.
  • Evaluating clustering without ground truth is a separate challenge, because metrics that compare against a reference need one to exist.

Related concepts

More concepts starting with C