Hierarchical Agglomerative Clustering (HAC) algorithm.
Classes
Node in the hierarchical clustering tree (dendrogram).
Methods
is_leaf
(self) -> bool
Hierarchical Agglomerative Clustering.
Builds a hierarchy of clusters by progressively merging the most similar clusters. This implementation uses a bottom-up (agglomerative) approach, starting with each point as its own cluster and merging them based on a linkage criterion.
Constructor
__init__( self, n_clusters: int = 2, linkage: str = 'ward', distance: str = 'euclidean', )
Overview
The algorithm constructs a dendrogram (tree of merges):
- Initialize each data point as a singleton cluster
- Compute the pairwise distance matrix between all clusters
- Find the two closest clusters according to the linkage criterion
- Merge them into a single cluster and record the merge distance
- Repeat steps 2--4 until only one cluster remains
-
Cut the dendrogram at the level that yields
n_clustersclusters
Theory
The linkage criterion determines the distance between sets of observations as a function of the pairwise distances between observations:
- Single Linkage:
- Complete Linkage:
- Average Linkage (UPGMA):
- Ward Linkage minimizes the increase in total within-cluster variance:
\Delta(A, B) = \sqrt{\frac{|A| \cdot |B|}{|A| + |B|}} \| \bar{A} - \bar{B} \|_2
Parameters
n_clusters
int
= 2
The number of clusters to find.
linkage
{"ward", "complete", "average", "single"}
= "ward"
Which linkage criterion to use.
distance
{"euclidean", "manhattan"}
= "euclidean"
Metric used to compute the linkage. If linkage is "ward", only "euclidean" is accepted.
Attributes
labels_
np.ndarray of shape (n_samples,)
Cluster labels for each point.
children_
np.ndarray of shape (n_samples-1, 2)
The children of each non-leaf node. Each row represents a merge.
distances_
np.ndarray of shape (n_samples-1,)
The distances between nodes which were merged.
n_clusters_
int
The number of clusters found by the algorithm.
Notes
Complexity:
- Training: O(n^3) time complexity and O(n^2) memory.
When to use AgglomerativeClusterer:
- When you need a full hierarchy or dendrogram of clusters
- Exploratory analysis to understand data structure at multiple scales
- Small to medium datasets (quadratic memory limits scalability)
- When cluster shapes are non-globular and linkage choice matters
References
Mullner2011
Mullner, D. (2011).
Modern hierarchical, agglomerative clustering algorithms.
arXiv preprint arXiv:1109.2378.
Ward1963
Ward, J. H. (1963).
Hierarchical grouping to optimize an objective function.
Journal of the American Statistical Association, 58(301), pp. 236-244.
Agglomerative clustering with Ward linkage:
python
>>> import numpy as np
>>> from tuiml.algorithms.clustering import AgglomerativeClusterer
>>> X = np.array([[1, 2], [1, 4], [1, 0],
... [4, 2], [4, 4], [4, 0]])
>>> hc = AgglomerativeClusterer(n_clusters=2, linkage='ward')
>>> hc.fit(X)
>>> hc.labels_
array([0, 0, 0, 1, 1, 1])