{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f5c4abc0",
   "metadata": {},
   "source": [
    "# Intel® Extension for Scikit-learn TSNE example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "23512089",
   "metadata": {},
   "outputs": [],
   "source": [
    "from timeit import default_timer as timer\n",
    "from sklearn import metrics\n",
    "from sklearn.datasets import make_blobs\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b6e359f6",
   "metadata": {},
   "source": [
    "### Generate the data \n",
    "Generate isotropic Gaussian blobs for clustering.\n",
    "<br/>\n",
    "With the number of samples: 20k<br/> \n",
    "Number of features: 100 <br/>\n",
    "Number of blobs: 4 <br/>\n",
    "Source: <br/>    \n",
    "https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_blobs.html\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "27b99b44",
   "metadata": {},
   "outputs": [],
   "source": [
    "x, y = make_blobs(n_samples=20000, centers=4, n_features=100, random_state=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0341cac9",
   "metadata": {},
   "source": [
    "### Patch original Scikit-learn with Intel® Extension for Scikit-learn\n",
    "Intel® Extension for Scikit-learn (previously known as daal4py) contains drop-in replacement functionality for the stock Scikit-learn package. You can take advantage of the performance optimizations of Intel® Extension for Scikit-learn by adding just two lines of code before the usual Scikit-learn imports:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "244c5bc9",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Intel(R) Extension for Scikit-learn* enabled (https://github.com/intel/scikit-learn-intelex)\n"
     ]
    }
   ],
   "source": [
    "from sklearnex import patch_sklearn\n",
    "patch_sklearn()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6bb14ac8",
   "metadata": {},
   "source": [
    "Intel® Extension for Scikit-learn patching affects performance of specific Scikit-learn functionality. Refer to the [list of supported algorithms and parameters](https://intel.github.io/scikit-learn-intelex/algorithms.html) for details. In cases when unsupported parameters are used, the package fallbacks into original Scikit-learn. If the patching does not cover your scenarios, [submit an issue on GitHub](https://github.com/intel/scikit-learn-intelex/issues)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "693b4e26",
   "metadata": {},
   "source": [
    "Training TSNE algorithm with Intel® Extension for Scikit-learn for generated dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e9b8f06b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Intel® extension for Scikit-learn time: 12.63 s\n",
      "Intel® Extension for scikit-learn. Divergence: 4.289110606110757\n"
     ]
    }
   ],
   "source": [
    "from sklearn.manifold import TSNE\n",
    "\n",
    "params = {\n",
    "    'n_components': 2,\n",
    "    'random_state': 42\n",
    "}\n",
    "start = timer()\n",
    "tsne = TSNE(**params)\n",
    "embedding_intelex = tsne.fit_transform(x)\n",
    "time_opt = timer() - start\n",
    "\n",
    "print(f\"Intel® extension for Scikit-learn time: {time_opt:.2f} s\")\n",
    "print(f\"Intel® Extension for scikit-learn. Divergence: {tsne.kl_divergence_}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd8e7b0b",
   "metadata": {},
   "source": [
    "  ### Train the same algorithm with original Scikit-learn\n",
    "In order to cancel optimizations, we use *unpatch_sklearn* and reimport the class TSNE."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5bb884d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearnex import unpatch_sklearn\n",
    "unpatch_sklearn()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8cfa0dba",
   "metadata": {},
   "source": [
    "Training algorithm with original Scikit-learn library for generated dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ae421d8e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Original Scikit-learn time: 37.66 s\n",
      "Original Scikit-learn. Divergence: 4.2955403327941895\n"
     ]
    }
   ],
   "source": [
    "from sklearn.manifold import TSNE\n",
    "\n",
    "params = {\n",
    "    'n_components': 2,\n",
    "    'random_state': 42\n",
    "}\n",
    "start = timer()\n",
    "tsne = TSNE(**params)\n",
    "embedding_original = tsne.fit_transform(x)\n",
    "time_original = timer() - start\n",
    "\n",
    "print(f\"Original Scikit-learn time: {time_original:.2f} s\")\n",
    "print(f\"Original Scikit-learn. Divergence: {tsne.kl_divergence_}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8358d7c2",
   "metadata": {},
   "source": [
    "### Plot embeddings original scikit-learn and Intel® extension"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "43ab1a96",
   "metadata": {},
   "outputs": [],
   "source": [
    "colors = [int(m) for m in y]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "35147d24",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 27280 characters]\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 28776 characters]\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for emb, title in zip([embedding_intelex, embedding_original], \n",
    "                      ['Intel® Extension for scikit-learn', 'Original scikit-learn']):\n",
    "    plt.scatter(emb[:, 0], emb[:, 1], c=colors)\n",
    "    plt.title(title)\n",
    "    plt.xlabel('x')\n",
    "    plt.ylabel('y')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ffd79e96",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Speedup for this run: 3.0'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"Speedup for this run: {(time_original/time_opt):.1f}\""
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
