AI Hints
Home›Machine Learning Tutorial›Finding Groups
Machine Learning · Lesson 45 of 85

Hierarchical Clustering

A family tree of your data.

⏱ 2 min read▶ Video at 1:37:17🎓 Free
Watch this lesson in the Machine Learning courseWatch on YouTube ↗Full Machine Learning course

Think of how biologists organise life. Species join into families, families join into orders, and so on, in one great tree. Hierarchical clustering does the same for your data. It gives you a whole family tree, and lets you cut it at whatever level you like.

Hierarchical Clustering
From the video: Hierarchical Clustering
  • Species, families, orders
  • A tree of your data
  • Cut it at any level

Reading a dendrogram

The method starts with every point as its own group. Then it repeatedly merges the two closest groups, until only one remains. A chart called a dendrogram shows the entire history. Run it. Each join shows two groups merging, and its height shows how far apart they were. Look for the long vertical stems, where a big jump happens. Cutting across there gives you natural groups. Here, there are three clear branches.

dendrogram.pypython
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.datasets import make_blobs

X, _ = make_blobs(n_samples=40, centers=3, cluster_std=0.8, random_state=2)

plt.figure(figsize=(10, 4.5))
dendrogram(linkage(X, method="ward"), no_labels=True, color_threshold=8)
plt.ylabel("Distance when merged")
plt.tight_layout()
plt.savefig("dendrogram.png", dpi=120)
print("Merges performed:", len(X) - 1)
Output
Merges performed: 39

Linkage matters

How do we measure the distance between two groups? This choice is called linkage. Ward merges the pair that adds the least variance. Average uses the mean distance. And single uses the closest two points. We compare each to the true groups. An adjusted rand score of one means a perfect match. Run it. Ward and average match the truth almost perfectly, while single linkage does badly, because it chains groups together. Ward is usually the safest default.

linkage.pypython
import numpy as np
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_blobs
from sklearn.metrics import adjusted_rand_score

X, truth = make_blobs(n_samples=300, centers=3, cluster_std=0.8, random_state=2)

for link in ["ward", "average", "single"]:
    labels = AgglomerativeClustering(n_clusters=3, linkage=link).fit_predict(X)
    print(f"{link:<8} match with truth {adjusted_rand_score(truth, labels):.3f}")
Output
ward     match with truth 0.990
average  match with truth 0.990
single   match with truth 0.560

Summary

Hierarchical clustering gives you the whole tree, with no need to choose a number first. But it gets very slow on big data. And it still struggles with strange shapes. Next, an algorithm that finds groups of any shape, and also knows when to say, this point belongs nowhere.

Key takeaways
  • Merge the closest groups, repeatedly
  • Dendrograms show the whole tree
  • Ward linkage is a safe default
Next up: DBSCAN — clusters of any shape