From fa50e6885a0d377e4df4beb163c6bec2159feda0 Mon Sep 17 00:00:00 2001 From: Lars Buitinck <L.J.Buitinck@uva.nl> Date: Tue, 13 Sep 2011 16:50:30 +0200 Subject: [PATCH] rename ari_score adjusted_rand_score --- doc/modules/classes.rst | 2 +- doc/modules/clustering.rst | 12 ++++++------ .../plot_adjusted_for_chance_measures.py | 2 +- examples/cluster/plot_affinity_propagation.py | 3 ++- examples/cluster/plot_dbscan.py | 3 ++- examples/cluster/plot_kmeans_digits.py | 11 +++++++---- examples/document_clustering.py | 3 ++- sklearn/metrics/__init__.py | 2 +- sklearn/metrics/cluster.py | 17 +++++++++-------- sklearn/metrics/tests/test_cluster.py | 11 ++++++----- 10 files changed, 37 insertions(+), 29 deletions(-) diff --git a/doc/modules/classes.rst b/doc/modules/classes.rst index f3d492a657..42dfd4bffa 100644 --- a/doc/modules/classes.rst +++ b/doc/modules/classes.rst @@ -295,7 +295,7 @@ Clustering metrics :toctree: generated/ :template: function.rst - metrics.ari_score + metrics.adjusted_rand_score metrics.homogeneity_completeness_v_measure metrics.homogeneity_score metrics.completeness_score diff --git a/doc/modules/clustering.rst b/doc/modules/clustering.rst index 656ffc3ca4..1923283568 100644 --- a/doc/modules/clustering.rst +++ b/doc/modules/clustering.rst @@ -358,34 +358,34 @@ chance normalization**:: >>> labels_true = [0, 0, 0, 1, 1, 1] >>> labels_pred = [0, 0, 1, 1, 2, 2] - >>> metrics.ari_score(labels_true, labels_pred) # doctest: +ELLIPSIS + >>> metrics.adjusted_rand_score(labels_true, labels_pred) # doctest: +ELLIPSIS 0.24... One can permute 0 and 1 in the predicted labels and rename `2` by `3` and get the same score:: >>> labels_pred = [1, 1, 0, 0, 3, 3] - >>> metrics.ari_score(labels_true, labels_pred) # doctest: +ELLIPSIS + >>> metrics.adjusted_rand_score(labels_true, labels_pred) # doctest: +ELLIPSIS 0.24... -Furthermore, :func:`ari_score` is **symmetric**: swapping the argument +Furthermore, :func:`adjusted_rand_score` is **symmetric**: swapping the argument does not change the score. It can thus be used as a **consensus measure**:: - >>> metrics.ari_score(labels_pred, labels_true) # doctest: +ELLIPSIS + >>> metrics.adjusted_rand_score(labels_pred, labels_true) # doctest: +ELLIPSIS 0.24... Perfect labeling is scored 1.0:: >>> labels_pred = labels_true[:] - >>> metrics.ari_score(labels_true, labels_pred) + >>> metrics.adjusted_rand_score(labels_true, labels_pred) 1.0 Bad (e.g. independent labelings) have negative or close to 0.0 scores:: >>> labels_true = [0, 1, 2, 0, 3, 4, 5, 1] >>> labels_pred = [1, 1, 0, 0, 2, 2, 2, 2] - >>> metrics.ari_score(labels_true, labels_pred) # doctest: +ELLIPSIS + >>> metrics.adjusted_rand_score(labels_true, labels_pred) # doctest: +ELLIPSIS -0.12... diff --git a/examples/cluster/plot_adjusted_for_chance_measures.py b/examples/cluster/plot_adjusted_for_chance_measures.py index 2ac81f21c4..bed0dcc875 100644 --- a/examples/cluster/plot_adjusted_for_chance_measures.py +++ b/examples/cluster/plot_adjusted_for_chance_measures.py @@ -56,7 +56,7 @@ def uniform_labelings_scores(score_func, n_samples, n_clusters_range, return scores score_funcs = [ - metrics.ari_score, + metrics.adjusted_rand_score, metrics.v_measure_score, ] diff --git a/examples/cluster/plot_affinity_propagation.py b/examples/cluster/plot_affinity_propagation.py index eb0b7c6664..a059a9aece 100644 --- a/examples/cluster/plot_affinity_propagation.py +++ b/examples/cluster/plot_affinity_propagation.py @@ -38,7 +38,8 @@ print 'Estimated number of clusters: %d' % n_clusters_ print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels) print "Completeness: %0.3f" % metrics.completeness_score(labels_true, labels) print "V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels) -print "Adjusted Rand Index: %0.3f" % metrics.ari_score(labels_true, labels) +print "Adjusted Rand Index: %0.3f" % \ + metrics.adjusted_rand_score(labels_true, labels) ############################################################################## # Plot result diff --git a/examples/cluster/plot_dbscan.py b/examples/cluster/plot_dbscan.py index 0bff8ce1c8..5b806ed5df 100644 --- a/examples/cluster/plot_dbscan.py +++ b/examples/cluster/plot_dbscan.py @@ -39,7 +39,8 @@ print 'Estimated number of clusters: %d' % n_clusters_ print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels) print "Completeness: %0.3f" % metrics.completeness_score(labels_true, labels) print "V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels) -print "Adjusted Rand Index: %0.3f" % metrics.ari_score(labels_true, labels) +print "Adjusted Rand Index: %0.3f" % \ + metrics.adjusted_rand_score(labels_true, labels) ############################################################################## # Plot result diff --git a/examples/cluster/plot_kmeans_digits.py b/examples/cluster/plot_kmeans_digits.py index 11f60cf9a6..6d96456e87 100644 --- a/examples/cluster/plot_kmeans_digits.py +++ b/examples/cluster/plot_kmeans_digits.py @@ -44,7 +44,8 @@ print "Inertia: %f" % km.inertia_ print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels, km.labels_) print "Completeness: %0.3f" % metrics.completeness_score(labels, km.labels_) print "V-measure: %0.3f" % metrics.v_measure_score(labels, km.labels_) -print "Adjusted Rand Index: %0.3f" % metrics.ari_score(labels, km.labels_) +print "Adjusted Rand Index: %0.3f" % \ + metrics.adjusted_rand_score(labels, km.labels_) print print "Raw k-means with random centroid init..." @@ -55,7 +56,8 @@ print "Inertia: %f" % km.inertia_ print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels, km.labels_) print "Completeness: %0.3f" % metrics.completeness_score(labels, km.labels_) print "V-measure: %0.3f" % metrics.v_measure_score(labels, km.labels_) -print "Adjusted Rand Index: %0.3f" % metrics.ari_score(labels, km.labels_) +print "Adjusted Rand Index: %0.3f" % \ + metrics.adjusted_rand_score(labels, km.labels_) print print "Raw k-means with PCA-based centroid init..." @@ -69,7 +71,8 @@ print "Inertia: %f" % km.inertia_ print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels, km.labels_) print "Completeness: %0.3f" % metrics.completeness_score(labels, km.labels_) print "V-measure: %0.3f" % metrics.v_measure_score(labels, km.labels_) -print "Adjusted Rand Index: %0.3f" % metrics.ari_score(labels, km.labels_) +print "Adjusted Rand Index: %0.3f" % \ + metrics.adjusted_rand_score(labels, km.labels_) print # Plot k-means++ form on a 2D plot using PCA @@ -80,7 +83,7 @@ kmeans = KMeans(init='k-means++', k=n_digits, n_init=10).fit(reduced_data) print "done in %0.3fs" % (time() - t0) # Step size of the mesh. Decrease to increase the quality of the VQ. -h = .02# point in the mesh [x_min, m_max]x[y_min, y_max]. +h = .02 # point in the mesh [x_min, m_max]x[y_min, y_max]. # Plot the decision boundary. For that, we will asign a color to each x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1 diff --git a/examples/document_clustering.py b/examples/document_clustering.py index 3c30fce678..5459995ffb 100644 --- a/examples/document_clustering.py +++ b/examples/document_clustering.py @@ -85,5 +85,6 @@ print print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels, mbkm.labels_) print "Completeness: %0.3f" % metrics.completeness_score(labels, mbkm.labels_) print "V-measure: %0.3f" % metrics.v_measure_score(labels, mbkm.labels_) -print "Adjusted Rand-Index: %.3f" % metrics.ari_score(labels, mbkm.labels_) +print "Adjusted Rand-Index: %.3f" % \ + metrics.adjusted_rand_score(labels, mbkm.labels_) print diff --git a/sklearn/metrics/__init__.py b/sklearn/metrics/__init__.py index bcf3f7fd5e..4ed164bef2 100644 --- a/sklearn/metrics/__init__.py +++ b/sklearn/metrics/__init__.py @@ -9,7 +9,7 @@ from .metrics import confusion_matrix, roc_curve, auc, precision_score, \ precision_recall_curve, explained_variance_score, r2_score, \ zero_one, mean_square_error, hinge_loss -from .cluster import ari_score +from .cluster import adjusted_rand_score from .cluster import homogeneity_completeness_v_measure from .cluster import homogeneity_score from .cluster import completeness_score diff --git a/sklearn/metrics/cluster.py b/sklearn/metrics/cluster.py index 454340ad9c..96bc80be6c 100644 --- a/sklearn/metrics/cluster.py +++ b/sklearn/metrics/cluster.py @@ -12,6 +12,7 @@ from scipy import comb import numpy as np + # the exact version if faster for k == 2: use it by default globally in # this module instead of the float approximate variant def comb2(n): @@ -39,7 +40,7 @@ def check_clusterings(labels_true, labels_pred): # clustering measures -def ari_score(labels_true, labels_pred): +def adjusted_rand_score(labels_true, labels_pred): """Rand index adjusted for chance The Rand Index computes a similarity measure between two clusterings @@ -59,7 +60,7 @@ def ari_score(labels_true, labels_pred): ARI is a symmetric measure:: - ari_score(a, b) == ari_score(b, a) + adjusted_rand_score(a, b) == adjusted_rand_score(b, a) Parameters ---------- @@ -80,28 +81,28 @@ def ari_score(labels_true, labels_pred): Perfectly maching labelings have a score of 1 even - >>> from sklearn.metrics.cluster import ari_score - >>> ari_score([0, 0, 1, 1], [0, 0, 1, 1]) + >>> from sklearn.metrics.cluster import adjusted_rand_score + >>> adjusted_rand_score([0, 0, 1, 1], [0, 0, 1, 1]) 1.0 - >>> ari_score([0, 0, 1, 1], [1, 1, 0, 0]) + >>> adjusted_rand_score([0, 0, 1, 1], [1, 1, 0, 0]) 1.0 Labelings that assign all classes members to the same clusters are complete be not always pure, hence penalized:: - >>> ari_score([0, 0, 1, 2], [0, 0, 1, 1]) # doctest: +ELLIPSIS + >>> adjusted_rand_score([0, 0, 1, 2], [0, 0, 1, 1]) # doctest: +ELLIPSIS 0.57... ARI is symmetric, so labelings that have pure clusters with members coming from the same classes but unnecessary splits are penalized:: - >>> ari_score([0, 0, 1, 1], [0, 0, 1, 2]) # doctest: +ELLIPSIS + >>> adjusted_rand_score([0, 0, 1, 1], [0, 0, 1, 2]) # doctest: +ELLIPSIS 0.57... If classes members are completely split across different clusters, the assignment is totally incomplete, hence the ARI is very low:: - >>> ari_score([0, 0, 0, 0], [0, 1, 2, 3]) + >>> adjusted_rand_score([0, 0, 0, 0], [0, 1, 2, 3]) 0.0 References diff --git a/sklearn/metrics/tests/test_cluster.py b/sklearn/metrics/tests/test_cluster.py index 6966e51723..35a4982ca7 100644 --- a/sklearn/metrics/tests/test_cluster.py +++ b/sklearn/metrics/tests/test_cluster.py @@ -1,6 +1,6 @@ import numpy as np -from sklearn.metrics.cluster import ari_score +from sklearn.metrics.cluster import adjusted_rand_score from sklearn.metrics.cluster import homogeneity_score from sklearn.metrics.cluster import completeness_score from sklearn.metrics.cluster import v_measure_score @@ -12,12 +12,13 @@ from numpy.testing import assert_array_almost_equal score_funcs = [ - ari_score, + adjusted_rand_score, homogeneity_score, completeness_score, v_measure_score, ] + def assert_raise_message(exception, message, callable, *args, **kwargs): """Helper function to test error messages in exceptions""" try: @@ -97,8 +98,8 @@ def test_non_consicutive_labels(): assert_almost_equal(c, 0.42, 2) assert_almost_equal(v, 0.52, 2) - ari_1 = ari_score([0, 0, 0, 1, 1, 1], [0, 1, 0, 1, 2, 2]) - ari_2 = ari_score([0, 0, 0, 1, 1, 1], [0, 4, 0, 4, 2, 2]) + ari_1 = adjusted_rand_score([0, 0, 0, 1, 1, 1], [0, 1, 0, 1, 2, 2]) + ari_2 = adjusted_rand_score([0, 0, 0, 1, 1, 1], [0, 4, 0, 4, 2, 2]) assert_almost_equal(ari_1, 0.24, 2) assert_almost_equal(ari_2, 0.24, 2) @@ -123,7 +124,7 @@ def test_adjustment_for_chance(): n_runs = 10 scores = uniform_labelings_scores( - ari_score, n_samples, n_clusters_range, n_runs) + adjusted_rand_score, n_samples, n_clusters_range, n_runs) max_abs_scores = np.abs(scores).max(axis=1) assert_array_almost_equal(max_abs_scores, [0.02, 0.03, 0.03, 0.02], 2) -- GitLab