OpenJij/OpenJij

View on GitHub
docs/tutorial/en/machine_learning/clustering.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Clustering with Annealing\n",
    "\n",
    "This tutorial will cover clustering using PyQUBO and Openjij as an example for an application of annealing."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clustering\n",
    "Assuming $n$ is given externally, we divide the given data into $n$ clusters. Let us consider 2 clusters in this case."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Clustering Hamiltonian\n",
    "Clustering can be done by minimizing the following Hamiltonian:\n",
    "\n",
    "$$\n",
    "H = - \\sum_{i, j} \\frac{1}{2}d_{i,j} (1 - \\sigma _i \\sigma_j)\n",
    "$$\n",
    "\n",
    "$i, j$ is the sample number, $d_{i,j}$ is the distance between the two samples, and $\\sigma_i=\\{-1,1\\}$ is a spin variable that indicates which of the two clusters it belongs to.\n",
    "Each term of this Hamiltonian sum is:\n",
    "\n",
    "- 0 when $\\sigma_i = \\sigma_j $\n",
    "- $d_{i,j}$  when $\\sigma_i \\neq \\sigma_j $\n",
    "\n",
    "With the negative on the right-hand side of the Hamiltonian, the entire Hamiltonian comes down to the question to choose the pair of $\\{\\sigma _1, \\sigma _2 \\ldots \\}$ that maximizes the distance between samples belonging to different classes."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Import Libraries\n",
    "We use JijModeling for modeling and JijModeling Transpiler for QUBO generation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import jijmodeling as jm\n",
    "import numpy as np\n",
    "import openjij as oj\n",
    "import pandas as pd\n",
    "from jijmodeling.transpiler.pyqubo.to_pyqubo import to_pyqubo\n",
    "from matplotlib import pyplot as plt\n",
    "from scipy.spatial import distance_matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Clustering with JijModeling and OpenJij\n",
    "\n",
    "First, we formulate the above Hamiltonian using JijModeling.\n",
    "Since JijModeling cannot handle the spin variable $\\sigma_i$, we rewrite it using the relation $\\sigma_i = 2x_i - 1$ so that it can be written in the binary variable $x_i$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$$\\begin{alignat*}{4}\\text{Problem} & \\text{: clustering} \\\\\\min & \\quad \\left( -0.5 \\right) \\cdot \\sum_{ i = 0 }^{ N - 1 } \\sum_{ j = 0 }^{ N - 1 } d_{i,j} \\cdot \\left( 1 - \\left( 2 \\cdot x_{i} - 1 \\right) \\cdot \\left( 2 \\cdot x_{j} - 1 \\right) \\right) \\\\& x_{i_{0}} \\in \\{0, 1\\}\\end{alignat*}$$"
      ],
      "text/plain": [
       "<jijmodeling.problem.problem.Problem at 0x12af4cbb0>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "problem = jm.Problem(\"clustering\")\n",
    "d = jm.Placeholder(\"d\", dim=2)\n",
    "N = d.shape[0].set_latex(\"N\")\n",
    "x = jm.Binary(\"x\", shape=(N))\n",
    "i = jm.Element(\"i\", (0, N))\n",
    "j = jm.Element(\"j\", (0, N))\n",
    "problem += (\n",
    "    -1 / 2 * jm.Sum([i, j], d[i, j] * (1 - (2 * x[i] - 1) * (2 * x[j] - 1)))\n",
    ")\n",
    "problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generating Artificial Data\n",
    "Let us artificially generate data that is linearly separable on a 2D plane."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = []\n",
    "label = []\n",
    "for i in range(100):\n",
    "    # Generate random numbers in [0, 1]\n",
    "    p = np.random.uniform(0, 1)\n",
    "    # Class 1 when a condition is satisfied, -1 when it is not.\n",
    "    cls =1 if p>0.5 else -1\n",
    "    # Create random numbers that follow a normal distribution\n",
    "    data.append(np.random.normal(0, 0.5, 2) + np.array([cls, cls]))\n",
    "    label.append(cls)\n",
    "# Format as a DataFrame\n",
    "df1 = pd.DataFrame(data, columns=[\"x\", \"y\"], index=range(len(data)))\n",
    "df1[\"label\"] = label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot: xlabel='x', ylabel='y'>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Visualize dataset\n",
    "df1.plot(kind='scatter', x=\"x\", y=\"y\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "instance_data = {\"d\": distance_matrix(df1, df1)}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Solving the Clustering Problem using OpenJij\n",
    "With the mathematical model and data, let us start solving the problem by Openjij.\n",
    "Here we use JijModeling Transpiler."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "pyq_obj, pyq_cache = to_pyqubo(problem, instance_data, {})\n",
    "qubo, constant = pyq_obj.compile().to_qubo()\n",
    "sampler = oj.SASampler()\n",
    "response = sampler.sample_qubo(qubo)\n",
    "result = pyq_cache.decode(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiIAAAGdCAYAAAAvwBgXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAArq0lEQVR4nO3dX4xU9d3H8c+wDStGdn1QQGBHF7E3xoY2+KfFYHYTot6YJZvl6QNeoPEhxqJxxV5AL+RpouFCnroNpf65KDRpQBueQRovmijZRRI1JhoubIMpdQnr8EfUOKtcLHZ2novTs+yf+XPOzDnn9/ud834lm5HZYebsnMXzmd/v+/v+cpVKpSIAAAAD5pk+AAAAkF0EEQAAYAxBBAAAGEMQAQAAxhBEAACAMQQRAABgDEEEAAAYQxABAADG/MD0AdQzOTmpc+fOaeHChcrlcqYPBwAABFCpVPTtt99q+fLlmjev/piH1UHk3Llzyufzpg8DAAA0YWxsTF1dXXUfY3UQWbhwoSTvB+no6DB8NAAAIIjx8XHl8/mp63g9VgcRfzqmo6ODIAIAgGOClFVQrAoAAIwhiAAAAGMIIgAAwBiCCAAAMIYgAgAAjCGIAAAAYwgiAADAGIIIAAAwxuqGZgAANK1clk6ckM6fl5Ytk9atk9raTB8VZiGIAADSp1CQnn5a+vzzq/d1dUm//a3U32/uuDAHUzMAgHQpFKSBgZkhRJKKRe/+QsHMcaEqgggAID3KZW8kpFKZ+z3/vsFB73GwAkEEAJAeJ07MHQmZrlKRxsa8x8EKBBEAQHqcPx/t4xA7gggAID2WLYv2cYgdQQQAkB7r1nmrY3K56t/P5aR83nscrEAQAQCkR1ubt0RXmhtG/D8PDdFPxCIEEQBAuvT3S4cPSytWzLy/q8u7nz4iVqGhGQAgffr7pb4+Oqs6gCACAEintjapp8f0UaABpmYAAIAxBBEAAGAMQQQAABhDEAEAAMYQRAAAgDEEEQAAYAxBBAAAGEMQAQAAxsQaRHbv3q277rpLCxcu1JIlS7RhwwZ9+umncb4kACAu5bI0MiIdOuTdlsumjwgpEGsQOX78uLZt26YPPvhAb7/9tr7//nvdf//9unz5cpwvCwCIWqEgdXdLvb3S5s3ebXe3d38SCEGplatUKpWkXuzSpUtasmSJjh8/rvvuu6/h48fHx9XZ2alSqaSOjo4EjhAAMEehIA0MSLMvF/5utnFvJFcoSE8/LX3++dX7urq8XXbZwM5KYa7fidaIlEolSdKiRYuSfFkAQLPKZS8EVPvM6t83OBjfCIUfgqaHEEkqFr37kxqRQWwSCyKTk5MaHBzUvffeqzvuuKPqYyYmJjQ+Pj7jCwBg0IkTc0PAdJWKNDbmPS5qpkMQEpFYENm2bZs++eQTvf766zUfs3v3bnV2dk595fP5pA4PAFDN+fPRPi4MkyEIiUkkiDz55JN66623NDw8rK6urpqP27lzp0ql0tTX2NhYEocHAKhl2bJoHxeGyRCExPwgzievVCp66qmndOTIEY2MjGjlypV1H9/e3q729vY4DwkAUE+57I0wnD/vhYu1a73C0GKx+hRJLud9f9266I/FZAhCYmINItu2bdPBgwd19OhRLVy4UBcuXJAkdXZ2asGCBXG+NAAgrFqrUzZtkvbs8ULH9DDir5oZGpLa2qI/nnXrzIUgJCbWqZmXX35ZpVJJPT09WrZs2dTXG2+8EefLAgDCqrc6Zc8e6Ze/lFasmPm9rq54l+62tXlLdKWroccXdwhCYhLtIxIWfUQAIAHlstecrFZhqD/ycPq09N57V6dt1q1LJgRUG6nJ570QQh8RK4W5fsc6NQMAcEDQ1SnvvSf19CR2WFP6+6W+vpm1K0mFINvNrulx8H0hiABA1rmwOqWtzUwIsllKOs6y+y4AZB2rU9yToo6zBBEAyDp/dcrsglBfLufVZLA6xQ4p6zhLEAGArGN1iltS1nGWIAIA8GoKDh9OfokuwnOhpicEilUBAB5Wp7ghZTU9BBEAwFWsTrFfyjrOMjUDAGhduSyNjEiHDnm3jhRKOillNT0EEQBAawoFrzNrb6+0ebN3293t1BJS56SopocW7wCA5vn9LGZfSvxP5o5dFJ1jaWfVMNdvgggAoDlB96gZHbXi4ojkhLl+MzUDAGhOyvpZwAxWzQBAlrUytG9TPwtLpyjQGEEEALKq1U3TbOlnUe3nWLxYevhhry8KocRq1IgAQBZFUWTq14g06mcRZ41IrZ9jOgd3pHUdNSIAgNqi2jTNdD+Lej/HdJ9/7tyOtFlCEAGArImyyNRkP4tGP8dsDu1ImyXUiABA1kRdZGpqj5owRbDTwxUt7K1CEAGArImjyNTEHjXNFME6siNtljA1AwBZ42+aNruuw5fLSfm8/ZumNfo5qnFkR9osIYgAQNaYLjKNSr2fYzZXwlUGEUQAIIvSsmlarZ9jOpfCVQbRRwQAsiwtHUn9n+PoUelPf5K+/PLq9/J5L4S4Eq5SgE3vAADZZVu4su14EhDm+s2qGQBAuphYwVNLq230M4AgAgBRyuCn34ay+p7Uaj9fLHr3u1SLEyOKVQEgKoWCt/dKb6+0ebN3292d7dbiWX1PomqjnwEEEQCIgv/pd3bLcf/Tb9ovvNVk+T2Jso1+yhFEAKBVfPqdK+vvSdRt9FOMIAIAreLT71xRvyflsjQyIh065N3aHmDiaKOfUgQRAGgVn37nivI9cbHOJC1t9BNAEAGAVmX102+9UYqo3hNX60zS0kY/AQQRAGhVFj/9NhqliOI9cb3OJC1t9GNGEAGAVgX59Pvf/y39+c9u1Dc0EmSUIooRgTTU3vT3S2fOSMPD0sGD3u3oKCFkGoIIAESh1qffRYu8r1273KlvqCfMKEWrIwJpqb3xO71u2uTdMh0zA3vNAECUpncR/cc/vAAymz8i4OLw/MiIF6YaGR6+2ma92c6qzbwWrMBeMwBgiv/pt1z2Rj6qqVS8MDI4KPX1ufUJuZlRimb3fvHrTIrF6iMwuZz3/TTV3mQQUzMAEIe46xtM9dVIcoUQK08ygSACAHGIs77BZF+NqFYIBQ1SrDxJPYIIAMQhrpED0301ohilCBukWHmSahSrAkAc/BqRRvUNo6PBpxb856w15dPMczarUPBWz0w/lnzeCyH1AoIfpGa/Jy4X8GKOMNdvgggAxMW/6EozL7zNXnRtW0USdjWMTUEKsQpz/WZqBgDiEnV9g219NcL2x0hDgzJEjuW7ABCn/n5viW4zfTRmc31PG9uCFKxAEAGAuDXbR2M21/tquB6kEAumZgDAFa731cji5oBoiCACAC5xua+G60EKsWDVDAC4qNn9W2zQ7NJfOIPluwAAu7kcpNAQm94BAOwWVQEvnEeNCAAAMIYgAgAAjCGIAAAAYwgiAADAGIpVAQDJYbUMZiGIAACSUa1/SFeX1+SM/iGZxdQMACB+hYI0MDB3991i0bu/UDBzXDCOIAIACK9clkZGpEOHvNtyuf5jn366+kZ9/n2Dg/WfA6lFEAEAhFMoSN3dUm+vtHmzd9vdXXtU48SJuSMh01Uq0tiY97gkhQlTiA1BBAAQXDNTLOfPB3vuoI+LQtgwhdgQRAAAV9UbJWh2imXZsmCvHfRxraJexSoEEQCAp9EoQbNTLOvWeatjcrnqfy+X83bfXbcuip+iPupVrEMQAQAEGyVodoqlrc1boivNDSP+n4eGkuknYmu9SoYRRAAg64KOEixZEuz5qk2x9PdLhw9LK1bMvL+ry7s/qT4iNtarZBwNzQAg64KOEkhecCgWq4eWXM77fq0plv5+qa/PbGdV2+pVQBABgMwL+un/iy+8KZaBAS90TA8jQadY2tqknp5mj7R1fr1Ks2EKkWNqBgCyLswogS1TLM2yqV4FkqRcpVItEtphfHxcnZ2dKpVK6ujoMH04AJBO5bK3OqbRKMHo6NULtOub11Xb9yaf90KI7WHKAWGu3wQRAMDVVTNS9SmXJEc7kgo5rocpi4W5flMjAgDNSNtFzJ9yqbY7bpKjBEnu0Du9XiVt59MhsdaIvPvuu3rooYe0fPly5XI5vfnmm3G+HAAkI63twfv7pTNnpOFh6eBB73Z0NNkQYqLjaVrPpyNiDSKXL1/W6tWrtW/fvjhfBgCSk/b24P4owaZN3m1SowKmOp6m/Xw6ILEakVwupyNHjmjDhg2B/w41IgCs4hd11uq5Ua2oE8GMjHgjEY0MD0e3/JfzGZsw12+W7wJAULQHj4+JjqecTytYVaw6MTGhiYmJqT+Pj48bPBoAmIX24PEx0fGU82kFq0ZEdu/erc7OzqmvfD5v+pAA4Crag8fHxA69nE8rWBVEdu7cqVKpNPU15u9tAAA2sGk7+7Qx0fGU82kFq4JIe3u7Ojo6ZnwBgDVoDx6vpNvHcz6tEGsQ+e6773Ty5EmdPHlSkjQ6OqqTJ0/q7Nmzcb4sAMTH9b1WpiuXvdUqhw55t7WWxgZ9XBSS7mWSpvPpqFiX746MjKi3ynKsLVu26MCBAw3/Pst3AVjL9U6cQTuYJtnp1CTXz6dl2GsGAOLk+kXLb+I1+3//s/eVCfo42Mfw7yhBBADi4voIQdAmXqdPS6tW0ezLRRb8jtLQDADikIZ24EGbeP3+9zT7cpGDv6MEEQAIwtReKFEL2pzrn/+M9vkaSbIgNq0c/R0liABAEGlpBx60OdeqVdE+Xz3sfhsNR39HCSIAEERa2oEHbeL1i18k0+zLwakEazn6O0oQAYAg0tIOPGgTr/nz42/25ehUgrUc/R0liABAEGlqBx60iVfczb4cnUqwlqO/o1btvgsA1vJHEgYGvP+hT/8U72I78P5+qa+vca+JoI9rhqNTCdZy9HeUIAIAQfkjBNV6NAwNhR8hMN0Yra1N6umJ7nFhOTqVYLWof0cTQEMzAAgrigBhQdMp48plaelS6auvqn+fpmnNc6izKiMiABBWqyMEtVqn+ytFstI6/ejR2iFE8t4fC6cSnBDXKFYMGBEBgCQFbbGe9lGARu+DJN1wg3TxYrrfh5SixTsAxKXVDqCsFPE0eh8kb7Qk7e8DmJoBkDDTBZqtiKKuw/RKEVPv/+zXPXIk2N9jxUzqEUQAJMflAs2o6jpMrhQx9f5Xe915AQfkWTGTetSIAEhGrQu539/A5gLNKOs6/OcqFqt3FI2rRsTU+1/rdYNYvNgbEYl6xMblUTlHUCMCwC6ut/KOsq4jaIv1KC+Mpt7/eq8bxMMPRx8Qkthgj52EQyGIAIif6wWaUdd1xN06fTZT73+QgtR6+vqiOxYpmQ322Ek4NIIIgPiZLtBsVRx1Hf390pkz0vCwdPCgdzs6Gs/0iKn3v5Xni3pPlCRGhdhJuCkUqwKIn4utvKfXESxZ4o1enDtXv64jyIXTRH2Cqfe/meeLa3oqzKhQrUZg9c5do6CTy3lBp6/PnnoUW2plKhYrlUoVSZVSqWT6UAC04l//qlS6uiqVXK5S8f63PPMrl6tU8nnvcTb4v//zjnf6Md5ww9VjnX3suZz3d5p53q6uYH+3Fabe/0avK1UqbW0z/5zPx/N+HDxY+ximfx08WP3vNzp3w8PBnn94OPqfrRkx/y6GuX4zNQMgfiYKNJtVa3j966+920WLZt4ftK7D5LC9qfe/0evmctLrryczPdXKqFCQc+fS9KNtU0iRRJ+YMCICpEy1T2FxfAL+17+8T54HD3q3QT/p+5/ga32azeW877/zTrjnDvK8SYwIJfX+2/K60zU7KhT03L3zjhsjIgn9Loa5ftNHBECy4p6XbqVp18iIt8qhkeHhcBuKxfW8zbCls6qJegR/JECaWctRr5dK0HP3zjvSI48k3x8mrIR+F9l9F4C94twVtNXup3ENr9s0bG9qV1YbdoP1l01XC6pDQ9V/N4Keky++8MLuwIAXOqoFHRumH236Xfw3akQApEMUyzPjWl3i4qqhtAq7bDrMuUu6P0wzLPxdZGoGQDpEMeQcV/t1U23d0bpmzp0N01C1JPS7SIt3ANkTxZBzXKtLXFo1hJmaOXf+NNSmTd6tTefVwt9FggiAdIhqyLnV4fVa+4y4MGyP6tJ27vyfZ/nymfevWGHk56FYFUA6rFvnXRgaDTkH6X7a3+91wAw7vN5oxU6zzwvz0njuZo+IGEKNCID0aGZ5ZtSvPft/qUm8NhBGAr+r1IgAyCZTQ+hJbKgGRMHC31WmZgCki4kh9Cg2VKvG5tUXaMzG8xfX72oLCCIA0ifp5llxNIlqpUMszLP1/NHQDABSKOomUbZtSoZwbD5/NDQLh2JVAE6IskmU/1y1hs9pfmY3288fDc0AIIWibBIVZg4f9rH9/NHQDABSKqoVOxbO4SMEF86fZQ3aKFYFgKhEsWLHwjl8hODK+bOoQRs1IgBgEzbIcxvnTxI1IgDgLgvn8BEC5y80gggA2MayOXyExPkLhakZALCVjZ05EVyGz1+Y6zfFqgBgq6Q7xCJanL9AmJoBAADGMCICALbI8FB+ILw/qUQQAQAb2LpJmi14f1KLqRkAMM3mTdJswPuTaqyaAQCTbN8kzTTeHyfR0AwAXGH7Jmmm8f6kHkEEAExyYZM0k3h/Uo8gAgAmubJJmim8P6lHEAEAk9at82ocZu9L4svlpHzee1wW8f6kHkEEAExik7T6eH9SjyACAKbV2yTtz3+WFi2SDh2SRka8VSRZwyZyqcbyXQCwxezOoZcuSdu308TLR2dVZ4S5fhNEAMBGfhOv2f+L9qcjGAmAxegjAgAuK5e9dubVPif69w0OZnOaBqlDEAEA29DECxlCEAEA29DECxlCEAEA29DECxlCEAEA29DECxlCEAEA29DEK3rlsteHJcv9WCxFEAEAG9HEKzqFgtTdLfX2Sps3e7fd3d79MI4+IgBgM5p4tYZ+LEbQ0AwAgHLZG/motRQ6l/NGmEZHCXcRo6EZAAD0Y3HCD0wfAOpjVBYAmkQ/FicQRCxWKHhdntnvCgCaQD8WJzA1Yym/vmr2qGKx6N1PsTcANEA/FicQRCzEflcAEAH6sTghkSCyb98+dXd365prrtE999yjDz/8MImXdRb1VQAQEfqxWC/2IPLGG29o+/bt2rVrlz7++GOtXr1aDzzwgL744ou4X9pZ1FcBQIT6+6UzZ6ThYengQe92dJQQYonYg8hvfvMbbd26VY8++qhuv/12vfLKK7r22mv1hz/8Ie6Xdhb1VQAQsbY2qadH2rTJu2U6xhqxBpErV67oo48+0vr166++4Lx5Wr9+vd5///05j5+YmND4+PiMryyivgoAkBWxBpEvv/xS5XJZS5cunXH/0qVLdeHChTmP3717tzo7O6e+8vl8nIdnLeqrAABZYdWqmZ07d6pUKk19jY2NmT4kY6ivAgBkQawNzW688Ua1tbXp4sWLM+6/ePGibrrppjmPb29vV3t7e5yH5JT+fqmvj86qAID0inVEZP78+VqzZo2OHTs2dd/k5KSOHTumn/3sZ3G+dGpQXwUASLPYW7xv375dW7Zs0Z133qm7775bQ0NDunz5sh599NG4XxoAAFgu9iDy85//XJcuXdJzzz2nCxcu6Mc//rH++te/zilgBQAA2ZOrVKo1ErfD+Pi4Ojs7VSqV1NHRYfpwAABAAGGu31atmgEAANkS+9QM0IxymdVCAJAFBBFYp1Dwdh+evvFfV5fX5I3+KQCQLkzNwCqFgjQwMHf34WLRu79QMHNcAFpQLksjI9KhQ95tuWz6iGARggisUS57IyHVyqf9+wYH+X8Y4JRCQerulnp7pc2bvdvubj5VYApBBNY4cWLuSMh0lYo0NuY9DoADGOJEAAQRWOP8+WgfB8AghjgREEEE1li2LNrHATCIIU4ERBCBNdat81bH5HLVv5/LSfm89zgAlmOIEwERRGCNtjZvia40N4z4fx4aop8I4ASGOBEQQQRW6e+XDh+WVqyYeX9Xl3c/fUQARzDEiYBoaAbr9PdLfX10VgWc5g9xDgx4oWN60SpDnJiGIAIrtbVJPT2mjwJAS/whzmqtkoeGGOKEJIIIACBODHGiAYIIACBeDHGiDopVAQCAMQQRAABgDEEEAAAYQxABAADGEEQAAIAxBBEAAGAMQQQAABhDEAEAAMYQRAAAgDEEEQAAYAwt3mGFcpmtKAAgiwgiMK5QqL45529/y+acAJB2TM3AqEJBGhiYGUIkqVj07i8UzBwXACAZBBEYUy57IyGVytzv+fcNDnqPAwCkE0EExpw4MXckZLpKRRob8x4HAEgnggiMOX8+2scBANxDEIExy5ZF+zgAgHsIIjBm3TpvdUwuV/37uZyUz3uPAwCkE0EExrS1eUt0pblhxP/z0BD9RAAgzQgiMKq/Xzp8WFqxYub9XV3e/bP7iJTL0siIdOiQd8uKGgBwGw3NYFx/v9TX17izKo3PACB9GBFxWFpGB4K0d6fxGQCkE0HEUYWC1N0t9fZKmzd7t93d7l2Qg/wcND4DgPQiiDgoLaMDQX8OGp8BQHoRRByTltGBMD8Hjc8AIL0IIo5Jy+hAmJ+DxmcAkF4EEcekZXQgzM9B4zMASC+CiGPSMjoQ5ueg8VljaVlBBSB7CCKOScvoQNifI2zjsyzww8czz3iBzfUVVACyKVepVCsXtMP4+Lg6OztVKpXU0dFh+nCs4a82kWYWe/oXdVcuzM38HEF6jmRBteZu07n2uwAgXcJcvwkijqp2IcrnvSkKly48afk5kuQHuEb/cnM5b8RodDSbYQ2AOQSRjEjL6EBafo4klMvetEu9FUezDQ9LPT1xHREAzBXm+s1eMw5ra0vHBSYtP0cSGi17rsb2FVQAso1iVcAhzYQK21dQAcg2RkQAh4QJFX6NiO0rqABkG0EELaG+I1n+sudisX6xKv1VALiCqRk0LS07ALukXnO36VaskP7nf6SJCRqcAbAbq2bQlFpLSNPevyLOEaAwz11t2fPixdLDD0v/8R/Sa695oya+ri4vwKTxnACwD8t3EatGS0jT2r+i2sW/3gW+1WDRKDxUe/6jR7MZEAHYhSCCWI2MeNMwjaSpf0XYEaAwwSKq0aWsBkQA9glz/c5sjQibhDUvLTsAB1Uue6GiWmT37xscvPo75AeL2YGgWPTun15DE/a562nUY6RSkcbGvMcBgC0yGUQosmyNyzsANxNAw1zgwwaLKMND1gIigHTIXBAJ82kV1bm6A3CzATTMBT5ssIgyPLgcEAFkV6aCSJTD4FlWbwmprf0rWgmgYS7wYYNFlOHB1YAIINsyFUSYQ49Of79XRLlixcz7u7rsW5nRagANc4EPGiz+/ndvamjt2ujCg4sBEQAyFUSYQ49Wf7905oy3OubgQe92dNSuECK1HkDDXOAbhRbf8897U0OrVkmbNgV77iBcCogAIGUsiDCHHj1/59xNm7xbGz9tRxFAg17gg3Y+9RWL0p490i9/GV14cCUgAoCUsT4ifp+FWvt00GchPaY3+7p4UXrmmcZ/J0jfk6BNyqr1EanF/707fVp67z327QHgPhqa1eEXLUozwwidJ9OjWghoa6tdAxJXAPVDy7Fj3lRMI42CEBsMAnAFDc3qYA493WqtjqkXQiTpf//Xu8hH2eDOn7a6/fZgj683NUTvGwBp9QPTB2BCf7/U18eny7SptzrGN3tkpKtL+q//krZvD7fPSxj/+Eewx9WqTarVAt5fekyABuCyzE3NIJ3KZWnv3mC1IC+9JC1d6l34v/xS+s//jG+TuFohYvZr1ZoaYv8YAC4Kc/3O5IgI0iVMYajkhZBNm65e5Gv1F8nlvP4ifX3NXeSDjND4r1VriW6Ypcdp2WAQQLYQROC0ICMOs/lTIHFf5Bs9v+/Xv6496tLM0mOKWgG4hCASEy4G8Qs64uDzpzH8LqVBL/LHjjV3/oI+/w9/WPt7YXvfVBsdirLeJQv4twskK3OrZpLACodkBB1xkKp3KQ16kX/++ebOXxQN9MK0l2dDx9bxbxdIXmxB5IUXXtDatWt17bXX6vrrr4/rZazDxSA5YVrxV1ueHbQdu9Tc+YtiE7qg7eUlNnRsFf92ATNiCyJXrlzRxo0b9cQTT8T1EtZhd99kBR1xeOml6i3O29q8otUgUzvNnL+oNqEL0vuGDR1bw79dwJzYgsivf/1rPfPMM/rRj34U10tYh4tBsoKOODz1VO027Hv2BH+9Zs5fVA30Gu0fw4aOreHfLmCOVcWqExMTmpiYmPrz+Pi4waMJj4tBsvwRh4EBL3RUa9lfa8QhbKHrdGHPX1QN9PxOrdWwoWNr+LcLmGNVseru3bvV2dk59ZXP500fUihcDOJRLntt16u1X292xCFMoetszZy/uHcpjqIeJcv4twuYEyqI7NixQ7lcru7XqVOnmj6YnTt3qlQqTX2NjY01/VwmcDGIXpBVDNOnLf70J68mZPduadGi2nP6zXyytfn8RVWPklX82wXMCTU18+yzz+qRRx6p+5hbb7216YNpb29Xe3t703/ftFamCjBXmD1W2tqkr7+WduwI1kMj7CdbF86fPzpUrY/I0BB9ROrh3y5gTux7zRw4cECDg4P65ptvQv9dV/eaqdZUKp/nYhBG2D1WaoWWWnvG+M9fLAarE3Hp/NGQq3n82wWiEeb6HVsQOXv2rL7++mv95S9/0YsvvqgT/y43v+2223TdddcFeg5Xg4jExaBVIyPeNEwjw8Pee9vMxnB+eJHmfgKuVLzW6z/8Iecva/i3C7TOik3vnnvuOf3xj3+c+vNPfvITSdLw8LB6MrA7V70VDmkS1/+0w6xiaHbPGKYyUE1W/u0CtogtiBw4cEAHDhyI6+lhgTj3NQmziqGVpZdRLa0Ni0/dAOCxqo8I3BGmkLQZ/iqGWjUc0zewC9pkqla4SfoTcNIb0xF6ANjMqj4icEMS7bDDLEd1aell0vuZsIkbANsRRFKiXtOvZh5XT1LtsIM2K3Olh0bS+5mwiRsAFxBEUiDop96oPh0n2Q670R4r0x8XxZ4ucUpyPxM2cQPgCmpEHBe0ViPKmo6k22EHreEwVXgaVFIBrlyW9u5tbiURACSNERGHBf3Ue+VKtJ+Oba7JiHtPl1YEDWZ//3vz02b+qNczzwR7PJu4ATCNIOKwoEP9v/99tFMCLtVktFoPE6VGAc73/PPNTZvVqgmph03cAJhGEHFY0E+z//xntM8n2V+TYeNqkXoBrpowRaX1RseqsWklEYBsI4g4LOin2VWron0+X9BC0qTZvFqkVoCrJsy0WaPRselsGrUCgNg3vWuFy3vNJKHRxm1+06/Tp70w0uhxs/dicVHYzfJM8ZuMHTvmTcU0Mjxcv6j00CFv5CcINnFrHU3igPrCXL8ZEXFY0FqN+fPdqOmIQpJLZFvhF9XefnuwxzeaNgs6mvXSS3aMWrnMxmk/wGUEEccFrdWwvaYjKkn2OIlCVEuh165tHCTb2qRf/CIdgdMUm6f9AFcxNZMSQYeK0z6kPDLifUJtpNFUR1KCTq81mkpy7ed2kSvTfoANwly/aWiWEkGbfqV9i/Mwm+XZwJ9eGxjwjm36MYeZNnNtJMhFYab90vxvDIgaUzNIFVd6nEwXxbRZ0t1us4iwB8SDIILUcbEeptWl0DZ3u00Lwh4QD2pEkFppr4eZzS+klKpP8dgawlwRVT0PkAUs3wVk974zcXBxJMglLk77AS5gRARImayNBCWtUPDa6U8vXKVJHDBTmOs3QQQAQiLsAfWxfBeIGReibEv7MnggSQSRGrjQJM+V97za0HxXl1c/wNA8AIRDsWoV7CWRPFfec1p8A0C0qBGZxb/QzH5XWAIZH1fec1p8A0AwLN9tUrnsDblXi2b+fYOD3uMQDZfec1d29gUAlxBEpuFCkzyX3nNafANA9Agi03ChSZ5L7zktvgEgegSRabjQJM+l95z9XAAgegSRabjQJM+l95wW3wAQPYLINFxokufae85+LgAQLYLILFxokufae97fL505Iw0PSwcPerejo/YdJwC4gD4iNbjS5TNNeM8BIB3YayYC7CWRPN5zAMgeggjQJEZwAKB1BBGgCWx8BwDRoFgVCCnIxnflsjQyIh065N3a0KIeAGxEsSoQQpCN7xYtkq65xgsmPkZLAGQJm94BAYUduQiyN85XX80MIdLM0RIAwFUEEWRWoeCNbvT2Sps3e7fd3fXDQrN73ti2kzAA2IIggkwKUudRTSt73ti0kzAA2IIggswpl70VL9WqoxqNXDTaGycIG3YSBgBbEESQOUHqPGqNXNTbGycoG3YSbgUrggBEiSCCzAk6IlHrcfX2xrnhBjd2Em5WM3U1AFAPQQSZE3REot7jqm18d+aM9Npr3vdd2Ek4rGbragCgHvqIIHP8XiDFYvU6kVzOG90YHW0uNFTruprPeyHE1T4iQfqntPKeAUgX+ogAddSr84hi5KLaaMnoqLshRGqtrgYA6mGvGQSWpk3e/DqPavvFRDFykbadhFutqwGAWggiCCSNm7z190t9fekJV3GKoq4GAKqhRgQN+UWKs39T/GmMw4fdDSMIJu66GgDpQo0IItNK8y8b0QOjOXHX1QDILoII6kpTkSI9MFpTr38Ko2IAmkWNCOpKS5FireklvwcGF9JgqKsBEDWCCOpKQ5Fio+mlXM6bXurr44IaRNpWBAEwi6kZ1NVokzcX2panaXoJANKGIIK60lCkmJbpJQBII4IIGnK9SDEN00sAkFb0EUFgrnZWpQcGACQrzPWbYlUE5mqRoj+9NDDghY7pYcSV6SUASCumZpAJrk8vAUBaZXJExNUpBrSGHhgAYJ/MBZE0bt6G4FydXgKAtMrU1IzfXXN2Twm/uyatvgEASFZmgkjaNm8DACANMhNE6K4JAIB9MhNE6K4JAIB9MhNE6K4JAIB9MhNE0rB5GwAAaZOZIJKGzdsAAEibzAQRie6aAADYJnMNzeiuCQCAPTIXRCS6awIAYIvYpmbOnDmjxx57TCtXrtSCBQu0atUq7dq1S1euXInrJQEAgGNiGxE5deqUJicn9eqrr+q2227TJ598oq1bt+ry5cvas2dPXC8LAAAckqtUqjU9j8eLL76ol19+WZ999lmgx4+Pj6uzs1OlUkkdHR0xHx0AAIhCmOt3ojUipVJJixYtqvn9iYkJTUxMTP15fHw8icMCAACGJLZ89/Tp09q7d68ef/zxmo/ZvXu3Ojs7p77y+XxShwcAAAwIHUR27NihXC5X9+vUqVMz/k6xWNSDDz6ojRs3auvWrTWfe+fOnSqVSlNfY2Nj4X8iAADgjNA1IpcuXdJXX31V9zG33nqr5s+fL0k6d+6cenp69NOf/lQHDhzQvHnBsw81IgAAuCfWGpHFixdr8eLFgR5bLBbV29urNWvWaP/+/aFCCAAASL/YilWLxaJ6enp0yy23aM+ePbp06dLU92666aa4XhYAADgktiDy9ttv6/Tp0zp9+rS6urpmfC/obJD/OFbPAADgDv+6HeR6n2gfkbA+//xzVs4AAOCosbGxOYMRs1kdRCYnJ3Xu3DktXLhQuVzO9OGEMj4+rnw+r7GxMQptLcZ5cgPnyQ2cJzckcZ4qlYq+/fZbLV++vGF9qNWb3s2bN69hkrJdR0cH/yAdwHlyA+fJDZwnN8R9njo7OwM9jmUsAADAGIIIAAAwhiASk/b2du3atUvt7e2mDwV1cJ7cwHlyA+fJDbadJ6uLVQEAQLoxIgIAAIwhiAAAAGMIIgAAwBiCCAAAMIYgErMzZ87oscce08qVK7VgwQKtWrVKu3bt0pUrV0wfGmZ54YUXtHbtWl177bW6/vrrTR8O/m3fvn3q7u7WNddco3vuuUcffvih6UPCLO+++64eeughLV++XLlcTm+++abpQ8Isu3fv1l133aWFCxdqyZIl2rBhgz799FPThyWJIBK7U6dOaXJyUq+++qr+9re/6aWXXtIrr7yiX/3qV6YPDbNcuXJFGzdu1BNPPGH6UPBvb7zxhrZv365du3bp448/1urVq/XAAw/oiy++MH1omOby5ctavXq19u3bZ/pQUMPx48e1bds2ffDBB3r77bf1/fff6/7779fly5dNHxrLd0148cUX9fLLL+uzzz4zfSio4sCBAxocHNQ333xj+lAy75577tFdd92l3/3ud5K8/afy+byeeuop7dixw/DRoZpcLqcjR45ow4YNpg8FdVy6dElLlizR8ePHdd999xk9FkZEDCiVSlq0aJHpwwCsduXKFX300Udav3791H3z5s3T+vXr9f777xs8MsB9pVJJkqy4FhFEEnb69Gnt3btXjz/+uOlDAaz25Zdfqlwua+nSpTPuX7p0qS5cuGDoqAD3TU5OanBwUPfee6/uuOMO04dDEGnWjh07lMvl6n6dOnVqxt8pFot68MEHtXHjRm3dutXQkWdLM+cJANJs27Zt+uSTT/T666+bPhRJ0g9MH4Crnn32WT3yyCN1H3PrrbdO/fe5c+fU29urtWvX6rXXXov56OALe55gjxtvvFFtbW26ePHijPsvXryom266ydBRAW578skn9dZbb+ndd99VV1eX6cORRBBp2uLFi7V48eJAjy0Wi+rt7dWaNWu0f/9+zZvHQFRSwpwn2GX+/Plas2aNjh07NlX4ODk5qWPHjunJJ580e3CAYyqVip566ikdOXJEIyMjWrlypelDmkIQiVmxWFRPT49uueUW7dmzR5cuXZr6Hp/q7HL27Fl9/fXXOnv2rMrlsk6ePClJuu2223TdddeZPbiM2r59u7Zs2aI777xTd999t4aGhnT58mU9+uijpg8N03z33Xc6ffr01J9HR0d18uRJLVq0SDfffLPBI4Nv27ZtOnjwoI4ePaqFCxdO1Vl1dnZqwYIFZg+ugljt37+/IqnqF+yyZcuWqudpeHjY9KFl2t69eys333xzZf78+ZW777678sEHH5g+JMwyPDxc9d/Oli1bTB8a/q3WdWj//v2mD61CHxEAAGAMxQoAAMAYgggAADCGIAIAAIwhiAAAAGMIIgAAwBiCCAAAMIYgAgAAjCGIAAAAYwgiAADAGIIIAAAwhiACAACMIYgAAABj/h8CTdMP2t48bwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# visualize\n",
    "for idx in range(0, len(instance_data['d'])):\n",
    "    if idx in result.record.solution[\"x\"][0][0][0]:\n",
    "        plt.scatter(df1.loc[idx][\"x\"], df1.loc[idx][\"y\"], color=\"b\")\n",
    "    else:\n",
    "        plt.scatter(df1.loc[idx][\"x\"], df1.loc[idx][\"y\"], color=\"r\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We see that they are classified into red and blue classes."
   ]
  }
 ],
 "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"
  },
  "vscode": {
   "interpreter": {
    "hash": "2e8d7574d7ec71e14cb1575cf43673432d6fae464c836a7b3733d4f6c20243fb"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}