{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Various Agglomerative Clustering on a 2D embedding of digits\n\nAn illustration of various linkage option for agglomerative clustering on\na 2D embedding of the digits dataset.\n\nThe goal of this example is to show intuitively how the metrics behave, and\nnot to find good clusters for the digits. This is why the example works on a\n2D embedding.\n\nWhat this example shows us is the behavior \"rich getting richer\" of\nagglomerative clustering that tends to create uneven cluster sizes.\n\nThis behavior is pronounced for the average linkage strategy,\nthat ends up with a couple of clusters with few datapoints.\n\nThe case of single linkage is even more pathologic with a very\nlarge cluster covering most digits, an intermediate size (clean)\ncluster with most zero digits and all other clusters being drawn\nfrom noise points around the fringes.\n\nThe other linkage strategies lead to more evenly distributed\nclusters that are therefore likely to be less sensible to a\nrandom resampling of the dataset.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Authors: The scikit-learn developers\n# SPDX-License-Identifier: BSD-3-Clause\n\nfrom time import time\n\nimport numpy as np\nfrom matplotlib import pyplot as plt\n\nfrom sklearn import datasets, manifold\n\ndigits = datasets.load_digits()\nX, y = digits.data, digits.target\nn_samples, n_features = X.shape\n\nnp.random.seed(0)\n\n\n# ----------------------------------------------------------------------\n# Visualize the clustering\ndef plot_clustering(X_red, labels, title=None):\n    x_min, x_max = np.min(X_red, axis=0), np.max(X_red, axis=0)\n    X_red = (X_red - x_min) / (x_max - x_min)\n\n    plt.figure(figsize=(6, 4))\n    for digit in digits.target_names:\n        plt.scatter(\n            *X_red[y == digit].T,\n            marker=f\"${digit}$\",\n            s=50,\n            c=plt.cm.nipy_spectral(labels[y == digit] / 10),\n            alpha=0.5,\n        )\n\n    plt.xticks([])\n    plt.yticks([])\n    if title is not None:\n        plt.title(title, size=17)\n    plt.axis(\"off\")\n    plt.tight_layout(rect=[0, 0.03, 1, 0.95])\n\n\n# ----------------------------------------------------------------------\n# 2D embedding of the digits dataset\nprint(\"Computing embedding\")\nX_red = manifold.SpectralEmbedding(n_components=2).fit_transform(X)\nprint(\"Done.\")\n\nfrom sklearn.cluster import AgglomerativeClustering\n\nfor linkage in (\"ward\", \"average\", \"complete\", \"single\"):\n    clustering = AgglomerativeClustering(linkage=linkage, n_clusters=10)\n    t0 = time()\n    clustering.fit(X_red)\n    print(\"%s :\\t%.2fs\" % (linkage, time() - t0))\n\n    plot_clustering(X_red, clustering.labels_, \"%s linkage\" % linkage)\n\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.14"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}