{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Comparison of the K-Means and MiniBatchKMeans clustering algorithms\n\nWe want to compare the performance of the MiniBatchKMeans and KMeans:\nthe MiniBatchKMeans is faster, but gives slightly different results (see\n`mini_batch_kmeans`).\n\nWe will cluster a set of data, first with KMeans and then with\nMiniBatchKMeans, and plot the results.\nWe will also plot the points that are labelled differently between the two\nalgorithms.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Authors: The scikit-learn developers\n# SPDX-License-Identifier: BSD-3-Clause"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Generate the data\n\nWe start by generating the blobs of data to be clustered.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\n\nfrom sklearn.datasets import make_blobs\n\nnp.random.seed(0)\n\nbatch_size = 45\ncenters = [[1, 1], [-1, -1], [1, -1]]\nn_clusters = len(centers)\nX, labels_true = make_blobs(n_samples=3000, centers=centers, cluster_std=0.7)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Compute clustering with KMeans\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import time\n\nfrom sklearn.cluster import KMeans\n\nk_means = KMeans(init=\"k-means++\", n_clusters=3, n_init=10)\nt0 = time.time()\nk_means.fit(X)\nt_batch = time.time() - t0"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Compute clustering with MiniBatchKMeans\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.cluster import MiniBatchKMeans\n\nmbk = MiniBatchKMeans(\n    init=\"k-means++\",\n    n_clusters=3,\n    batch_size=batch_size,\n    n_init=10,\n    max_no_improvement=10,\n    verbose=0,\n)\nt0 = time.time()\nmbk.fit(X)\nt_mini_batch = time.time() - t0"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Establishing parity between clusters\n\nWe want to have the same color for the same cluster from both the\nMiniBatchKMeans and the KMeans algorithm. Let's pair the cluster centers per\nclosest one.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from sklearn.metrics.pairwise import pairwise_distances_argmin\n\nk_means_cluster_centers = k_means.cluster_centers_\norder = pairwise_distances_argmin(k_means.cluster_centers_, mbk.cluster_centers_)\nmbk_means_cluster_centers = mbk.cluster_centers_[order]\n\nk_means_labels = pairwise_distances_argmin(X, k_means_cluster_centers)\nmbk_means_labels = pairwise_distances_argmin(X, mbk_means_cluster_centers)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Plotting the results\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\n\nfig = plt.figure(figsize=(8, 3))\nfig.subplots_adjust(left=0.02, right=0.98, bottom=0.05, top=0.9)\ncolors = [\"#4EACC5\", \"#FF9C34\", \"#4E9A06\"]\n\n# KMeans\nax = fig.add_subplot(1, 3, 1)\nfor k, col in zip(range(n_clusters), colors):\n    my_members = k_means_labels == k\n    cluster_center = k_means_cluster_centers[k]\n    ax.plot(X[my_members, 0], X[my_members, 1], \"w\", markerfacecolor=col, marker=\".\")\n    ax.plot(\n        cluster_center[0],\n        cluster_center[1],\n        \"o\",\n        markerfacecolor=col,\n        markeredgecolor=\"k\",\n        markersize=6,\n    )\nax.set_title(\"KMeans\")\nax.set_xticks(())\nax.set_yticks(())\nplt.text(-3.5, 1.8, \"train time: %.2fs\\ninertia: %f\" % (t_batch, k_means.inertia_))\n\n# MiniBatchKMeans\nax = fig.add_subplot(1, 3, 2)\nfor k, col in zip(range(n_clusters), colors):\n    my_members = mbk_means_labels == k\n    cluster_center = mbk_means_cluster_centers[k]\n    ax.plot(X[my_members, 0], X[my_members, 1], \"w\", markerfacecolor=col, marker=\".\")\n    ax.plot(\n        cluster_center[0],\n        cluster_center[1],\n        \"o\",\n        markerfacecolor=col,\n        markeredgecolor=\"k\",\n        markersize=6,\n    )\nax.set_title(\"MiniBatchKMeans\")\nax.set_xticks(())\nax.set_yticks(())\nplt.text(-3.5, 1.8, \"train time: %.2fs\\ninertia: %f\" % (t_mini_batch, mbk.inertia_))\n\n# Initialize the different array to all False\ndifferent = mbk_means_labels == 4\nax = fig.add_subplot(1, 3, 3)\n\nfor k in range(n_clusters):\n    different += (k_means_labels == k) != (mbk_means_labels == k)\n\nidentical = np.logical_not(different)\nax.plot(X[identical, 0], X[identical, 1], \"w\", markerfacecolor=\"#bbbbbb\", marker=\".\")\nax.plot(X[different, 0], X[different, 1], \"w\", markerfacecolor=\"m\", marker=\".\")\nax.set_title(\"Difference\")\nax.set_xticks(())\nax.set_yticks(())\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
}