Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Clustering Metrics

API Reference

Signatures

sp.silhouette_score(X, labels)                          -> float
sp.davies_bouldin_score(X, labels)                      -> float
sp.calinski_harabasz_score(X, labels)                   -> float

sp.adjusted_rand_score(labels_true, labels_pred)        -> float
sp.normalized_mutual_info_score(labels_true, labels_pred) -> float
sp.fowlkes_mallows_score(labels_true, labels_pred)      -> float
sp.homogeneity_score(labels_true, labels_pred)          -> float
sp.completeness_score(labels_true, labels_pred)         -> float
sp.v_measure_score(labels_true, labels_pred)            -> float

Function summary

FunctionTypeRangeBestDescription
silhouette_scoreinternal$[-1, 1]$$\to 1$Mean silhouette over samples
davies_bouldin_scoreinternal$[0, \infty)$$\to 0$Mean cluster similarity ratio
calinski_harabasz_scoreinternal$[0, \infty)$$\to \infty$Variance ratio criterion
adjusted_rand_scoreexternal$[-1, 1]$$\to 1$Rand index adjusted for chance
normalized_mutual_info_scoreexternal$[0, 1]$$\to 1$MI normalised by mean entropy
fowlkes_mallows_scoreexternal$[0, 1]$$\to 1$Geometric mean of pairwise P/R
homogeneity_scoreexternal$[0, 1]$$\to 1$Each cluster contains one class
completeness_scoreexternal$[0, 1]$$\to 1$Each class lies in one cluster
v_measure_scoreexternal$[0, 1]$$\to 1$Harmonic mean of H and C

X is a 2D ndarray (n_samples, n_features) (the silhouette is parallelised with rayon).

Example
import seraplot as sp
import numpy as np

rng = np.random.default_rng(0)
X = np.vstack([
    rng.normal(loc=( 0,  0), scale=0.6, size=(100, 2)),
    rng.normal(loc=( 5,  5), scale=0.6, size=(100, 2)),
    rng.normal(loc=(-5,  5), scale=0.6, size=(100, 2)),
])
y_true = [0]*100 + [1]*100 + [2]*100

km = sp.KMeans(k=3, max_iter=100, tol=1e-4, mini_batch=False, batch_size=0, n_init=4)
labels = list(km.fit_predict(X))

print("silhouette        :", sp.silhouette_score(X, labels))
print("davies_bouldin    :", sp.davies_bouldin_score(X, labels))
print("calinski_harabasz :", sp.calinski_harabasz_score(X, labels))

print("ARI               :", sp.adjusted_rand_score(y_true, labels))
print("NMI               :", sp.normalized_mutual_info_score(y_true, labels))
print("FMI               :", sp.fowlkes_mallows_score(y_true, labels))
print("homogeneity       :", sp.homogeneity_score(y_true, labels))
print("completeness      :", sp.completeness_score(y_true, labels))
print("v_measure         :", sp.v_measure_score(y_true, labels))

Algorithmic Functioning

Silhouette — for each sample $i$, with $a_i$ the mean distance to the same-cluster points and $b_i$ the mean distance to the nearest other cluster:

$$s_i = \frac{b_i - a_i}{\max(a_i, b_i)}, \qquad S = \frac{1}{n}\sum_i s_i$$

Davies-Bouldin — for each cluster $k$ with intra-cluster dispersion $S_k$ and centroid distance $d_{kj}$:

$$\text{DB} = \frac{1}{K}\sum_k \max_{j \neq k} \frac{S_k + S_j}{d_{kj}}$$

Calinski-Harabasz — variance ratio between/within clusters, with $B$ between-cluster scatter and $W$ within-cluster scatter:

$$\text{CH} = \frac{\mathrm{tr}(B)}{\mathrm{tr}(W)} \cdot \frac{n - K}{K - 1}$$

Adjusted Rand Index — Rand index corrected for chance by subtracting the expected value:

$$\text{ARI} = \frac{\text{RI} - E[\text{RI}]}{\max(\text{RI}) - E[\text{RI}]}$$

NMI — normalised mutual information:

$$\text{NMI} = \frac{2 \cdot I(U; V)}{H(U) + H(V)}$$

Homogeneity / Completeness / V-measure — entropy-based duals:

$$h = 1 - \frac{H(C \mid K)}{H(C)}, \qquad c = 1 - \frac{H(K \mid C)}{H(K)}, \qquad V = \frac{2 h c}{h + c}$$

Fowlkes-Mallows — geometric mean of pairwise precision and recall computed from TP/FP/FN of the pair confusion matrix:

$$\text{FMI} = \sqrt{\frac{TP}{TP+FP} \cdot \frac{TP}{TP+FN}}$$

Référence API

Signatures

sp.silhouette_score(X, labels)                          -> float
sp.davies_bouldin_score(X, labels)                      -> float
sp.calinski_harabasz_score(X, labels)                   -> float

sp.adjusted_rand_score(labels_true, labels_pred)        -> float
sp.normalized_mutual_info_score(labels_true, labels_pred) -> float
sp.fowlkes_mallows_score(labels_true, labels_pred)      -> float
sp.homogeneity_score(labels_true, labels_pred)          -> float
sp.completeness_score(labels_true, labels_pred)         -> float
sp.v_measure_score(labels_true, labels_pred)            -> float

Résumé

FonctionTypePlageIdéalDescription
silhouette_scoreinterne$[-1, 1]$$\to 1$Silhouette moyenne
davies_bouldin_scoreinterne$[0, \infty)$$\to 0$Ratio de similarité moyen
calinski_harabasz_scoreinterne$[0, \infty)$$\to \infty$Critère de ratio de variance
adjusted_rand_scoreexterne$[-1, 1]$$\to 1$Index de Rand corrigé du hasard
normalized_mutual_info_scoreexterne$[0, 1]$$\to 1$MI normalisée par l'entropie
fowlkes_mallows_scoreexterne$[0, 1]$$\to 1$Moyenne géométrique de P/R par paires
homogeneity_scoreexterne$[0, 1]$$\to 1$Chaque cluster contient une classe
completeness_scoreexterne$[0, 1]$$\to 1$Chaque classe est dans un cluster
v_measure_scoreexterne$[0, 1]$$\to 1$Moyenne harmonique de H et C

X est un ndarray 2D (n_samples, n_features) (la silhouette est parallélisée avec rayon).

Exemple
import seraplot as sp
import numpy as np

rng = np.random.default_rng(0)
X = np.vstack([
    rng.normal(loc=( 0,  0), scale=0.6, size=(100, 2)),
    rng.normal(loc=( 5,  5), scale=0.6, size=(100, 2)),
    rng.normal(loc=(-5,  5), scale=0.6, size=(100, 2)),
])
y_true = [0]*100 + [1]*100 + [2]*100

km = sp.KMeans(k=3, max_iter=100, tol=1e-4, mini_batch=False, batch_size=0, n_init=4)
labels = list(km.fit_predict(X))

print("silhouette        :", sp.silhouette_score(X, labels))
print("davies_bouldin    :", sp.davies_bouldin_score(X, labels))
print("calinski_harabasz :", sp.calinski_harabasz_score(X, labels))

print("ARI               :", sp.adjusted_rand_score(y_true, labels))
print("NMI               :", sp.normalized_mutual_info_score(y_true, labels))
print("FMI               :", sp.fowlkes_mallows_score(y_true, labels))
print("homogeneity       :", sp.homogeneity_score(y_true, labels))
print("completeness      :", sp.completeness_score(y_true, labels))
print("v_measure         :", sp.v_measure_score(y_true, labels))

Fonctionnement algorithmique

Silhouette — pour chaque échantillon $i$, avec $a_i$ la distance moyenne aux points du même cluster et $b_i$ la distance moyenne au cluster voisin le plus proche :

$$s_i = \frac{b_i - a_i}{\max(a_i, b_i)}, \qquad S = \frac{1}{n}\sum_i s_i$$

Davies-Bouldin — pour chaque cluster $k$ avec dispersion intra $S_k$ et distance entre centroïdes $d_{kj}$ :

$$\text{DB} = \frac{1}{K}\sum_k \max_{j \neq k} \frac{S_k + S_j}{d_{kj}}$$

Calinski-Harabasz — ratio de variance inter/intra, avec $B$ dispersion inter-cluster et $W$ dispersion intra-cluster :

$$\text{CH} = \frac{\mathrm{tr}(B)}{\mathrm{tr}(W)} \cdot \frac{n - K}{K - 1}$$

Index de Rand ajusté — Rand corrigé en soustrayant la valeur attendue :

$$\text{ARI} = \frac{\text{RI} - E[\text{RI}]}{\max(\text{RI}) - E[\text{RI}]}$$

NMI — information mutuelle normalisée :

$$\text{NMI} = \frac{2 \cdot I(U; V)}{H(U) + H(V)}$$

Homogénéité / Complétude / V-mesure — duaux basés sur l'entropie :

$$h = 1 - \frac{H(C \mid K)}{H(C)}, \qquad c = 1 - \frac{H(K \mid C)}{H(K)}, \qquad V = \frac{2 h c}{h + c}$$

Fowlkes-Mallows — moyenne géométrique de la précision et du rappel par paires, calculées à partir de TP/FP/FN de la matrice de confusion par paires :

$$\text{FMI} = \sqrt{\frac{TP}{TP+FP} \cdot \frac{TP}{TP+FN}}$$