GitHub
deepbox/metrics

Clustering Metrics

Evaluate clustering quality using internal metrics (no ground truth needed — silhouette, Davies-Bouldin, Calinski-Harabasz) and external metrics (require ground truth labels — adjusted Rand, mutual information, V-measure). Internal metrics measure cluster separation and compactness; external metrics measure agreement with known labels.
silhouetteScore
silhouetteScore(X: Tensor, labels: Tensor): number

Measures how similar each point is to its own cluster vs. other clusters. Range: [−1, 1]. Higher is better. 1 = well-clustered, 0 = overlapping, −1 = misassigned.

silhouetteSamples
silhouetteSamples(X: Tensor, labels: Tensor): Tensor

Per-sample silhouette values. Useful for identifying poorly assigned samples.

daviesBouldinScore
daviesBouldinScore(X: Tensor, labels: Tensor): number

Average similarity between each cluster and its most similar cluster. Lower is better. 0 = perfect separation.

calinskiHarabaszScore
calinskiHarabaszScore(X: Tensor, labels: Tensor): number

Ratio of between-cluster dispersion to within-cluster dispersion. Higher is better. Also known as Variance Ratio Criterion.

adjustedRandScore
adjustedRandScore(labelsTrue: Tensor, labelsPred: Tensor): number

Similarity between two clusterings, adjusted for chance. Range: [−1, 1]. 1 = perfect match, 0 = random. Requires ground truth labels.

adjustedMutualInfoScore
adjustedMutualInfoScore(labelsTrue: Tensor, labelsPred: Tensor): number

Adjusted mutual information between two label assignments. Adjusted for chance. Range: [0, 1].

normalizedMutualInfoScore
normalizedMutualInfoScore(labelsTrue: Tensor, labelsPred: Tensor): number

Normalized mutual information between two label assignments. Range: [0, 1]. 1 = perfect correlation.

fowlkesMallowsScore
fowlkesMallowsScore(labelsTrue: Tensor, labelsPred: Tensor): number

Geometric mean of pairwise precision and recall. Range: [0, 1]. Higher is better.

homogeneityScore
homogeneityScore(labelsTrue: Tensor, labelsPred: Tensor): number

Whether each cluster contains only members of a single class. Range: [0, 1].

completenessScore
completenessScore(labelsTrue: Tensor, labelsPred: Tensor): number

Whether all members of a given class are assigned to the same cluster. Range: [0, 1].

vMeasureScore
vMeasureScore(labelsTrue: Tensor, labelsPred: Tensor): number

Harmonic mean of homogeneity and completeness. Range: [0, 1].

Silhouette Coefficient

s(i) = (b(i) − a(i)) / max(a(i), b(i))

Where:

  • a(i) = Mean distance to points in same cluster
  • b(i) = Mean distance to nearest other cluster

Davies-Bouldin Index

DB = (1/k) Σᵢ maxⱼ≠ᵢ (σᵢ + σⱼ) / d(cᵢ, cⱼ)

Where:

  • σᵢ = Average distance of cluster i members to centroid
  • d(cᵢ,cⱼ) = Distance between centroids

Calinski-Harabasz Index

CH = [B / (k−1)] / [W / (n−k)]

Where:

  • B = Between-cluster dispersion
  • W = Within-cluster dispersion

V-Measure

V = 2 · h · c / (h + c)

Where:

  • h = Homogeneity
  • c = Completeness
clustering-metrics.ts
import { silhouetteScore, daviesBouldinScore, adjustedRandScore } from "deepbox/metrics";import { tensor } from "deepbox/ndarray";const X = tensor([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]]);const labels = tensor([0, 0, 1, 1, 0, 1]);silhouetteScore(X, labels);    // Higher = better separationdaviesBouldinScore(X, labels); // Lower = better separation// With ground truthconst trueLabels = tensor([0, 0, 1, 1, 0, 1]);const predLabels = tensor([0, 0, 1, 1, 0, 2]);adjustedRandScore(trueLabels, predLabels);