{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 6-量子アニーリングによる機械学習 (QBoost)" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "view-in-github" }, "source": [ "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/OpenJij/OpenJijTutorial/blob/master/source/ja/006-Machine_Learning_by_QA.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このチュートリアルでは、量子アニーリングの最適化の応用の一例として機械学習を取り上げます。 \n", "前半では、PyQUBOとOpenjijを利用したクラスタリングを行います。 \n", "後半では、PyQUBOとD-Waveのサンプラーを用いたQboostというアンサンブル学習を行います。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## クラスタリング\n", "\n", "クラスタリングとは与えられたデータを$n$個のクラスターに分けるというタスクです($n$は外部から与えられているとします)。簡単のため、今回はクラスター数が2を考えましょう。\n", "\n", "### 必要なライブラリのインポート\n", "\n", "機械学習のライブラリであるscikit-learnなどをインポートします。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# ライブラリのインポート\n", "import numpy as np\n", "from matplotlib import pyplot as plt\n", "from sklearn import cluster\n", "import pandas as pd\n", "from scipy.spatial import distance_matrix \n", "from pyqubo import Array, Constraint, Placeholder, solve_qubo\n", "import openjij as oj\n", "from sklearn.model_selection import train_test_split" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 人工データの生成\n", "\n", "今回は人工的に二次元平面上の明らかに線形分離可能なデータを生成しましょう。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "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" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# データセットの可視化\n", "df1.plot(kind='scatter', x=\"x\", y=\"y\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "今回は、以下のハミルトニアンを最小化することでクラスタリングを行います。\n", "\n", "$$\n", "H = - \\sum_{i, j} \\frac{1}{2}d_{i,j} (1 - \\sigma _i \\sigma_j)\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$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": [ "### PyQUBOによるクラスタリング\n", "\n", "まずは、PyQUBOで上のハミルトニアンを定式化します。そして`solve_qubo`を用いてシミュレーテッドアニーリング(SA)を行います。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def clustering_pyqubo(df):\n", " # 距離行列の作成\n", " d_ij = distance_matrix(df, df)\n", " # スピン変数の設定\n", " spin = Array.create(\"spin\", shape= len(df), vartype=\"SPIN\")\n", " # 全ハミルトニアンの設定\n", " H = - 0.5* sum(\n", " [d_ij[i,j]* (1 - spin[i]* spin[j]) for i in range(len(df)) for j in range(len(df))]\n", " )\n", " # コンパイル\n", " model = H.compile()\n", " # QUBOに変換\n", " qubo, offset = model.to_qubo()\n", " # SAで解を求める\n", " raw_solution = solve_qubo(qubo, num_reads=10)\n", " # 解を見やすい形にデコード\n", " decoded_solution, broken, energy= model.decode_solution(raw_solution, vartype=\"SPIN\")\n", " # ラベルを抽出\n", " labels = [decoded_solution[\"spin\"][idx] for idx in range(len(df))]\n", " return labels, energy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "実行をおよび解の確認を行います。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "label [0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0]\n", "energy -13861.844537404875\n" ] } ], "source": [ "labels, energy =clustering_pyqubo(df1[[\"x\", \"y\"]])\n", "print(\"label\", labels)\n", "print(\"energy\", energy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "可視化をしてみましょう。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "for idx, label in enumerate(labels):\n", " if label:\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": [ "### Openjijのソルバーを用いたクラスタリング\n", "\n", "次はQUBOの定式化にPyQUBOを用いて、ソルバー部分をOpenJijにしてクラスタリングを行います。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def clustering_openjij(df):\n", " # 距離行列の作成\n", " d_ij = distance_matrix(df, df)\n", " # スピン変数の設定\n", " spin = Array.create(\"spin\", shape= len(df), vartype=\"SPIN\")\n", " # 全ハミルトニアンの設定\n", " H = - 0.5* sum(\n", " [d_ij[i,j]* (1 - spin[i]* spin[j]) for i in range(len(df)) for j in range(len(df))]\n", " )\n", " # コンパイル\n", " model = H.compile()\n", " # QUBOに変換\n", " qubo, offset = model.to_qubo()\n", " # OpenJijのSAをサンプラーに設定\n", " sampler = oj.SASampler(num_reads=10, num_sweeps=100)\n", " # サンプラーで解を求める\n", " response = sampler.sample_qubo(qubo)\n", " # 生データの抽出\n", " raw_solution = dict(zip(response.indices, response.states[np.argmin(response.energies)]))\n", " # 解を見やすい形にデコード\n", " decoded_solution, broken, energy= model.decode_solution(raw_solution, vartype=\"SPIN\")\n", " # ラベルを抽出\n", " labels = [int(decoded_solution[\"spin\"][idx] ) for idx in range(len(df))]\n", " return labels, sum(response.energies)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "実行および解の確認を行います。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "label [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1]\n", "energy -138618.44537404884\n" ] } ], "source": [ "labels, energy =clustering_openjij(df1[[\"x\", \"y\"]])\n", "print(\"label\", labels)\n", "print(\"energy\", energy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "こちらも、可視化をしてみましょう。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "for idx, label in enumerate(labels):\n", " if label:\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": [ "PyQUBOのSAのときと同様の結果を得ることができました。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## QBoost\n", "\n", "QBoostは量子アニーリングを用いたアンサンブル学習の一つです。アンサンブル学習は弱い予測器を多数用意して、その予測器の各予測結果の組み合わせて最終的な予測結果を得ます。 \n", "QBoostでは、与えられた学習データに対して最適な学習器の組み合わせを、量子アニーリングを用いて最適化を行います。今回は分類問題を扱います。 \n", "\n", "$D$個の学習データの集合を$\\{\\vec x^{(d)}\\}(d=1, ..., D)$、対応するラベルを$\\{y^{(d)}\\}(d=1, ..., D), y^{(d)}\\in \\{-1, 1\\}$とします。また、$N$個の弱学習器の(関数の)集合を$\\{C_i\\}(i=1, ..., N)$とします。あるデータ$\\vec x^{(d)}$ に対して、$C_i(\\vec x^{(d)})\\in \\{-1, 1\\}$です。このとき、最終的な分類のラベルは以下のようになります。\n", "\n", "$${\\rm sgn}\\left( \\sum_{i=1}^{N} w_i C_i({\\vec x}^{(d)})\\right)$$\n", "\n", "ここで$w_i\\in\\{0, 1\\} (i=1, ..., N)$とします。これは各予測器の重み(予測器を最終的な予測に採用するか採用しないかのbool値)です。 \n", "QBoostではこの$w_i$を、弱学習器の個数を刈り込みつつ最終的な予測が教師データに一致するように組み合わせの最適化を行います。\n", "この問題におけるハミルトニアンは、以下のようになります。\n", "\n", "$$H(\\vec w) = \\sum_{d=1}^{D} \\left( \\frac{1}{N}\\sum_{i=1}^{N} w_i C_i(\\vec x^{(d)})-y^{(d)} \\right)^2 + \\lambda \\sum _i^N w_i$$\n", "\n", "このハミルトニアンの第一項目は、弱分類器と正解ラベルの差を表しています。第二項目は最終的な分類器に採用する弱分類器の個数の程度を表しています。$\\lambda$は第二項の弱分類器の個数がハミルトニアンにどのくらい影響するかを調節する正則化パラメータにです。 \n", "第一項をコスト(目的関数)、第二項を制約として、このハミルトニアンの最適化を行います。量子アニーリングで最小化することにより、学習データに最も適合するような弱分類器の組み合わせを得ることができます。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### スクリプト\n", "\n", "それでは実際にQBoostを試してみましょう。学習データにはscikit-learnの癌識別のデータセットを使用します。簡単のために、学習に用いるのは\"0\"と\"1\"の2つの文字種のみとします。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# ライブラリをインポート\n", "import pandas as pd \n", "from scipy import stats \n", "from sklearn import datasets\n", "from sklearn import metrics" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# データのロード\n", "cancerdata = datasets.load_breast_cancer()\n", "# 学習用データと検証用データの個数の設定\n", "num_train = 450" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "今回はデモンストレーションのために、ノイズとなる特徴量がある場合を考えます。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(569, 60)\n" ] } ], "source": [ "data_noisy = np.concatenate((cancerdata.data, np.random.rand(cancerdata.data.shape[0], 30)), axis=1)\n", "print(data_noisy.shape)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# labelを{0, 1}から{-1, 1}に変換\n", "labels = (cancerdata.target-0.5) * 2" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# データセットを学習用と検証用に分割\n", "X_train = data_noisy[:num_train, :]\n", "X_test = data_noisy[num_train:, :]\n", "y_train = labels[:num_train]\n", "y_test = labels[num_train:]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# 弱学習器の結果から\n", "def aggre_mean(Y_list):\n", " return ((np.mean(Y_list, axis=0)>0)-0.5) * 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 弱学習器の作成\n", "\n", "scikit-learnで弱分類器を作成します。今回は弱分類器としてdecision stumpを用いましょう。decision stumpとは、一層の決定木のことです。今回は弱分類器として用いるので、分割に用いる特徴量はランダムに選ぶこととします(一層のランダムフォレストを行うという理解で良いでしょう)。" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# 必要なライブラリのインポート\n", "from sklearn.tree import DecisionTreeClassifier as DTC\n", "\n", "# 弱分類機の個数の設定\n", "num_clf = 32\n", "# bootstrap samplingで、一つのサンプルに対して取り出すサンブル個数\n", "sample_train = 40\n", "# モデルの設定\n", "models = [DTC(splitter=\"random\",max_depth=1) for i in range(num_clf)]\n", "for model in models:\n", " # ランダムに抽出\n", " train_idx = np.random.choice(np.arange(X_train.shape[0]), sample_train)\n", " # 説明変数と目的変数から決定木を作成\n", " model.fit(X=X_train[train_idx], y=y_train[train_idx])\n", "y_pred_list_train = []\n", "for model in models:\n", " # 作成したモデルを用いて予測を実行\n", " y_pred_list_train.append(model.predict(X_train))\n", "y_pred_list_train = np.asanyarray(y_pred_list_train)\n", "y_pred_train =np.sign(y_pred_list_train)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "すべての弱学習器を最終的な分類器としたときの精度を見てみましょう。以後、この組み合わせをbaselineとします。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.9495798319327731\n" ] } ], "source": [ "y_pred_list_test = []\n", "for model in models:\n", " # 検証データで実行\n", " y_pred_list_test.append(model.predict(X_test))\n", " \n", "y_pred_list_test = np.array(y_pred_list_test)\n", "y_pred_test = np.sign(np.sum(y_pred_list_test,axis=0))\n", "# 予測結果の精度のスコア計算\n", "acc_test_base = metrics.accuracy_score(y_true=y_test, y_pred=y_pred_test)\n", "print(acc_test_base)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "# QBoostを行うクラスを定義\n", "class QBoost():\n", " def __init__(self, y_train, ys_pred):\n", " self.num_clf = ys_pred.shape[0]\n", " # バイナリ変数を定義\n", " self.Ws = Array.create(\"weight\", shape = self.num_clf, vartype=\"BINARY\")\n", " # 正規化項の大きさ(ハイパーパラメータ)をPyQUBOのPlaceholderで定義\n", " self.param_lamda = Placeholder(\"norm\")\n", " # 弱分類器の組み合わせのハミルトニアンをセット\n", " self.H_clf = sum( [ (1/self.num_clf * sum([W*C for W, C in zip(self.Ws, y_clf)])- y_true)**2 for y_true, y_clf in zip(y_train, ys_pred.T)\n", " ])\n", " # 正規化項のハミルトニアンを制約としてセット\n", " self.H_norm = Constraint(sum([W for W in self.Ws]), \"norm\")\n", " # 全ハミルトニアンをセット\n", " self.H = self.H_clf + self.H_norm * self.param_lamda\n", " # モデルをコンパイル\n", " self.model = self.H.compile()\n", " # QUBOに変換する関数を定義\n", " def to_qubo(self, norm_param=1):\n", " # ハイパーパラメータの大きさを設定\n", " self.feed_dict = {'norm': norm_param}\n", " return self.model.to_qubo(feed_dict=self.feed_dict)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "qboost = QBoost(y_train=y_train, ys_pred=y_pred_list_train)\n", "# lambda=3としてQUBO作成\n", "qubo = qboost.to_qubo(3)[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### D-Waveサンプラーを用いてQBoostを実行" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "# 必要なライブラリをインポート\n", "from dwave.system.samplers import DWaveSampler\n", "from dwave.system.composites import EmbeddingComposite" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dw = DWaveSampler(endpoint='https://cloud.dwavesys.com/sapi/', \n", " token='xxxx', \n", " solver='DW_2000Q_VFYC_6')\n", "sampler = EmbeddingComposite(dw)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# D-Waveサンプラーで計算\n", "sampleset = sampler.sample_qubo(qubo, num_reads=100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 結果の確認\n", "print(sampleset)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 各計算結果をPyQUBOでdecode\n", "decoded_solutions = []\n", "brokens = []\n", "energies =[]\n", "\n", "decoded_sol = qboost.model.decode_dimod_response(sampleset, feed_dict=qboost.feed_dict)\n", "for d_sol, broken, energy in decoded_sol:\n", " decoded_solutions.append(d_sol)\n", " brokens.append(broken)\n", " energies.append(energy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "D-Waveで得られた弱分類器の組み合わせを使った場合の、学習データ/検証データでの精度を確認しましょう。" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "accs_train_Dwaves = []\n", "accs_test_Dwaves = []\n", "for decoded_solution in decoded_solutions:\n", " idx_clf_DWave=[]\n", " for key, val in decoded_solution[\"weight\"].items():\n", " if val == 1:\n", " idx_clf_DWave.append(int(key))\n", " y_pred_train_DWave = np.sign(np.sum(y_pred_list_train[idx_clf_DWave, :], axis=0))\n", " y_pred_test_DWave = np.sign(np.sum(y_pred_list_test[idx_clf_DWave, :], axis=0))\n", " acc_train_DWave = metrics.accuracy_score(y_true=y_train, y_pred=y_pred_train_DWave)\n", " acc_test_DWave= metrics.accuracy_score(y_true=y_test, y_pred=y_pred_test_DWave)\n", " accs_train_Dwaves.append(acc_train_DWave)\n", " accs_test_Dwaves.append(acc_test_DWave)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "横軸をエネルギー、縦軸を精度のグラフを作成しましょう。" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "image/svg+xml": [ "\r\n", "\r\n", "\r\n", "\r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", "\r\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(12, 8))\n", "plt.scatter(energies, accs_train_Dwaves, label=\"train\" )\n", "plt.scatter(energies, accs_test_Dwaves, label=\"test\")\n", "plt.xlabel(\"energy: D-wave\")\n", "plt.ylabel(\"accuracy\")\n", "plt.title(\"relationship between energy and accuracy\")\n", "plt.grid()\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "base accuracy is 0.9411764705882353\n", "max accuracy of QBoost is 0.957983193277311\n", "average accuracy of QBoost is 0.9398183515830576\n" ] } ], "source": [ "print(\"base accuracy is {}\".format(acc_test_base))\n", "print(\"max accuracy of QBoost is {}\".format(max(accs_test_Dwaves)))\n", "print(\"average accuracy of QBoost is {}\".format(np.mean(np.asarray(accs_test_Dwaves))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "D-Waveによるサンプリングは短時間で数百サンプリング以上が実行できます。精度が最大になる結果を使えば、baselineよりも高精度の分類器を作成することが可能です。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.8.5" } }, "nbformat": 4, "nbformat_minor": 2 }