OpenJij/OpenJij

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

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# アニーリングを用いたクラスタリング\n",
    "\n",
    "このチュートリアルでは、アニーリングの応用の一例としてPyQUBOとOpenjijを利用したクラスタリングを取り上げます。  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## クラスタリング\n",
    "\n",
    "クラスタリングとは与えられたデータを$n$個のクラスターに分けるというタスクです($n$は外部から与えられているとします)。簡単のため、今回はクラスター数が2を考えましょう。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### クラスタリングのハミルトニアン\n",
    "今回は、以下のハミルトニアンを最小化することでクラスタリングを行います。\n",
    "\n",
    "$$\n",
    "H = - \\sum_{i, j} \\frac{1}{2}d_{i,j} (1 - \\sigma _i \\sigma_j)\n",
    "$$\n",
    "\n",
    "$i, j$はサンプルの番号、$d_{i,j}$は2つのサンプル間の距離、$\\sigma_i=\\{-1,1\\}$は2つのクラスターのどちらかに属しているかを表すスピン変数です。  \n",
    "このハミルトニアンの和の各項は   \n",
    "\n",
    "- $\\sigma_i  = \\sigma_j $のとき、0\n",
    "- $\\sigma_i  \\neq \\sigma_j $のとき、$d_{i,j}$  \n",
    "\n",
    "となります。右辺のマイナスに注意すると、ハミルトニアン全体では「異なるクラスに属しているサンプル同士の距離を最大にする$\\{\\sigma _1, \\sigma _2 \\ldots \\}$の組を選びなさい」という問題に帰着することがわかります。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  JijModelingとOpenJijを用いたクラスタリング\n",
    "\n",
    "### 変数定義\n",
    "\n",
    "JijModelingを用いて、上述のハミルトニアンを定式化しましょう。\n",
    "そのために必要となる変数を定義します。\n",
    "JijModelingでは、スピン変数$\\sigma_i$を扱えないため、バイナリ変数$x_i$で書けるように、$\\sigma_i = 2x_i - 1$という関係を用いて書き直します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import jijmodeling as jm\n",
    "\n",
    "d = jm.Placeholder(\"d\", ndim=2)\n",
    "N = d.len_at(0, latex=\"N\")\n",
    "x = jm.BinaryVar(\"x\", shape=(N, ))\n",
    "i = jm.Element(\"i\", belong_to=(0, N))\n",
    "j = jm.Element(\"j\", belong_to=(0, N))\n",
    "sigma_i = 2 * x[i] - 1\n",
    "sigma_j = 2 * x[j] - 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 目的関数の実装\n",
    "\n",
    "先ほどのハミルトニアンを実装します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem = jm.Problem(\"Clustering\")\n",
    "problem += - jm.sum([i, j], d[i, j]*(1-sigma_i*sigma_j))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "実装された数理モデルを、Jupyter Notebookで表示してみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$$\\begin{array}{cccc}\\text{Problem:} & \\text{Clustering} & & \\\\& & \\min \\quad \\displaystyle - \\sum_{i = 0}^{N - 1} \\sum_{j = 0}^{N - 1} d_{i, j} \\cdot \\left(- \\left(2 \\cdot x_{i} - 1\\right) \\cdot \\left(2 \\cdot x_{j} - 1\\right) + 1\\right) & \\\\\\text{{where}} & & & \\\\& x & 1\\text{-dim binary variable}\\\\\\end{array}$$"
      ],
      "text/plain": [
       "<jijmodeling.Problem at 0x3bce1c0>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### インスタンスの作成\n",
    "\n",
    "今回は人工的に二次元平面上の明らかに線形分離可能なデータを生成しましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from scipy.spatial import distance_matrix\n",
    "\n",
    "data = []\n",
    "label = []\n",
    "for i in range(100):\n",
    "    # [0, 1]の乱数を生成\n",
    "    p = np.random.uniform(0, 1)\n",
    "    # ある条件を満たすときをクラス1、満たさないときを-1\n",
    "    cls =1 if p>0.5 else -1\n",
    "    # ある座標を中心とする正規分布に従う乱数を作成\n",
    "    data.append(np.random.normal(0, 0.5, 2) + np.array([cls, cls]))\n",
    "    label.append(cls)\n",
    "# DataFrameとして整形\n",
    "df1 = pd.DataFrame(data, columns=[\"x\", \"y\"], index=range(len(data)))\n",
    "df1[\"label\"] = label\n",
    "instance_data = {'d': distance_matrix(df1, df1)}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "生成されたデータを可視化してみます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='x', ylabel='y'>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# データセットの可視化\n",
    "df1.plot(kind='scatter', x=\"x\", y=\"y\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### JijModeling TranspilerによるPyQUBOへの変換\n",
    "\n",
    "ここまで行われてきた実装は、全てJijModelingによるものでした。\n",
    "これをPyQUBOに変換することで、OpenJijはもちろん、他のソルバーを用いた組合せ最適化計算を行うことが可能になります。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "import jijmodeling_transpiler as jmt\n",
    "\n",
    "# compile\n",
    "compiled_model = jmt.core.compile_model(problem, instance_data, {})\n",
    "# get qubo model\n",
    "pubo_builder = jmt.core.pubo.transpile_to_pubo(compiled_model=compiled_model, relax_method=jmt.core.pubo.RelaxationMethod.AugmentedLagrangian)\n",
    "qubo, const = pubo_builder.get_qubo_dict(multipliers={})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### OpenJijによる求解\n",
    "\n",
    "Openjijを用いて、最適化問題を解いてみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "import openjij as oj\n",
    "\n",
    "# set sampler\n",
    "sampler = oj.SASampler()\n",
    "# solve problem\n",
    "result = sampler.sample_qubo(qubo, num_reads=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "計算結果をデコードします。\n",
    "また得られた解の中から目的関数値が最小のものを選び出し、それを可視化してみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'y')"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# decode a result to JijModeling sampleset\n",
    "sampleset = jmt.core.pubo.decode_from_openjij(result, pubo_builder, compiled_model)\n",
    "objectives = [objective for objective in sampleset.evaluation.objective]\n",
    "lowest_index = np.argmin(objectives)\n",
    "# visualize solution\n",
    "for idx in range(0, len(instance_data['d'])):\n",
    "    if idx in sampleset.record.solution[\"x\"][lowest_index][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\")\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "赤と青の2つのクラスに分類できていることがわかります。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.5 ('.venv': venv)",
   "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.5"
  },
  "vscode": {
   "interpreter": {
    "hash": "8e4ef42922154d6c53cb4e5074b09fe7c3d2526e8e95a3a7b0551dc780a36e7a"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}