OpenJij/OpenJij

View on GitHub
docs/tutorial/en/006-Machine_Learning_by_QA.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6-Machine Learning (QBoost) with Quantum Annealing"
   ]
  },
  {
   "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/en/006-Machine_Learning_by_QA.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this section, we describe an application of machine learning (ML) with quantum annealing (QA) optimization.\n",
    "\n",
    "In the first, we show application for clustering task using JijModeling and OpenJij.  \n",
    "In the second, we execute an ensemble study called QBoost with PyQUBO and D-Wave sampler."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clustering\n",
    "\n",
    "Clustering is the task of dividing given set of data into $n$ clusters ($n$ is our input). For the sake of simplicity, let us consider the number of cluster $n$ is 2 in this time."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Clustering Hamiltonian\n",
    "We demonstrate clustering by minimizing the following Hamiltonians.\n",
    "\n",
    "$$\n",
    "H = - \\sum_{i, j} \\frac{1}{2}d_{i,j} (1 - \\sigma _i \\sigma_j)\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Where $i, j$ is sample No., $d_{i, j}$ is a distance between $i$ and $j$, $\\sigma_i=\\{-1,1\\}$ is spin variable that indicates whether $i$ belong to one of the two clusters.\n",
    "\n",
    "Each term of this Hamiltonian sum behaves as follows.\n",
    "\n",
    "- 0 for $\\sigma_i  = \\sigma_j $\n",
    "- $d_{i,j}$ for $\\sigma_i  \\neq \\sigma_j $  \n",
    "\n",
    "Note that minus of R.H.S., Hamiltonian means the problem is \"Choosing pairs of $\\{\\sigma _1, \\sigma _2 \\ldots \\}$ that maximizes the distance between the samples of different classes\"."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### Importing the required libraries\n",
    "\n",
    "We import several libraries for clustering."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import libraries\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import pandas as pd\n",
    "from scipy.spatial import distance_matrix\n",
    "\n",
    "import openjij as oj\n",
    "import jijmodeling as jm\n",
    "from jijmodeling.transpiler.pyqubo.to_pyqubo import to_pyqubo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Clustering with JijModeling and OpenJij\n",
    "\n",
    "At first, we formulate the mathematical model in JijModeling. We cannot use spin variable in JijModeling, so we change spin variable $\\sigma_i$ to binary variable $x_i$ by using the relationship $\\sigma_i = 2x_i - 1$."
   ]
  },
  {
   "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 }^{ d_{\\mathrm{shape}(0)} - 1 } \\sum_{ j = 0 }^{ d_{\\mathrm{shape}(0)} - 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 0x7f1c10470820>"
      ]
     },
     "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]\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": [
    "### Make artificial data\n",
    "\n",
    "Next, we create instance data for the clustering problem.\n",
    "\n",
    "In this case, let us generate linearly separable data in a two-dimensional plane artificially. Our clustering algorithm is unsupervised learning algorithm, so we do not need to prepare answer data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = []\n",
    "label = []\n",
    "N = 100\n",
    "for i in range(N):\n",
    "    # generate 0 to 1 random number\n",
    "    p = np.random.uniform(0, 1)\n",
    "    # set class 1 when certain condition are met, and -1 when it are not met\n",
    "    cls = 1 if p > 0.5 else -1\n",
    "    # create random numbers following a normal distribution\n",
    "    data.append(np.random.normal(0, 0.5, 2) + np.array([cls, cls]))\n",
    "    label.append(cls)\n",
    "# formatted as a DataFrame\n",
    "df1 = pd.DataFrame(data, columns=[\"x\", \"y\"], index=range(len(data)))\n",
    "df1[\"label\"] = label"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us see the data of the clustering problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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kRT1o1NjY6ORZDZs2NB17L333jN/93d/Zz72sY+ZwsJC88UvfjEiGHnR3Llzo15n9+uSZFatWmWMMaatrc3cdNNNpqSkxPTr18+MHDnSzJ8/v+uXsheleo3GfDCN/B//8R/NsGHDTEFBgbnhhhvMvn37st/4JJ08edJUVVWZgQMHmqKiInPHHXdEhLie79dDhw6ZqVOnmiFDhpiCggJTXl5u7r//fhMOh126guhqamrMZZddZvr3728qKyvNK6+80vW566+/3sydOzfi/F/96lfm4x//uOnfv7/55Cc/af77v/87yy1OXSrXuHjx4q5zhw0bZm6++Wbz2muvudDq5HVOl+750Xldc+fONddff32vx4wfP97079/fjB49OuJn04tSvcYf/OAH5vLLLzcDBgwwQ4YMMdOmTTMvvviiO41PUqx7YvfXxomfycCHXxwAAMAqzK4CAABWIuQAAAArEXIAAICVCDkAAMBKhBwAAGAlQg4AALASIQcAAFiJkAMAAKxEyAEAAFYi5AAAACsRcgAAgJUIOQB8KxQKafjw4fr+97/fdezll19W//79tX79ehdbBsAL2KATgK/9+te/1qxZs/Tyyy9r7NixGj9+vG655Rb96Ec/crtpAFxGyAHgewsXLtQLL7yga665Rrt379aOHTtUUFDgdrMAuIyQA8D33nvvPV155ZU6fPiwdu7cqXHjxrndJAAeQE0OAN97++23dfToUXV0dOjAgQNuNweAR9CTA8DXzp49q8rKSo0fP15jx47Vj3/8Y+3evVtDhw51u2kAXEbIAeBr999/v55++mm9/vrrGjhwoK6//noFg0E9//zzbjcNgMsYrgLgWxs3btSPf/xjPfHEEyoqKlJeXp6eeOIJ/f73v9dPf/pTt5sHwGX05AAAACvRkwMAAKxEyAEAAFYi5AAAACsRcgAAgJUIOQAAwEqEHAAAYCVCDgAAsBIhBwAAWImQAwAArETIAQAAViLkAAAAK/1/roggElY7kdwAAAAASUVORK5CYII=",
      "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\")\n",
    "plt.show()"
   ]
  },
  {
   "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 by using OpenJij\n",
    "We create mathematical model and instance data, so let us solve the clustering problem by using openjij."
   ]
  },
  {
   "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": "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XXDBBdq1a1f/z7p160JqYe2q2ce77rpL//7v/67Vq1dr8+bN+qM/+iPNmTNHn332WYgtrc3ll1+urVu36umnn9ZTTz2l5557Ttdcc03Fxy1YsGDQsbzrrrsiaG1ljzzyiBYvXqylS5fqlVde0WmnnaY5c+bo/fffL7r9z3/+c82bN09XX321Xn31Vc2dO1dz587Vr3/964hb7p3ffZScqpoDj9c777wTYYv9+/jjj3Xaaafp/vvv97R9V1eXvv71r6u9vV1btmzRokWL9Hd/93f6yU9+EnJLa+N3P11vvvnmoOM5fvz4kFpYm2effVYLFy7Uiy++qKefflqff/65zj//fH388cclHxPYd9KgpLvuustMmTKl5N8//PBDc/jhh5vHHnus/77XX3/dSDKbNm2KoolVe/jhh01zc7Onba+44grT0dERanvC4HUfDx06ZCZOnGjuvvvu/vs+/PBD09jYaNatWxdiC6v3m9/8xkgyv/zlL/vv+9GPfmQymYzp7u4u+bhzzz3X3HjjjRG00L+zzjrLLFy4sP/3QqFgJk+ebJYvX150+0suucR8/etfH3Tf2Wefbb71rW+F2s5a+N1HP99TG0kyTzzxRNlt/uEf/sF8+ctfHnTfpZdeaubMmRNiy4LlZT83btxoJJnf/e53kbQpaO+//76RZJ599tmS2wT1naTHpIze3l6NGTOm5N9ffvllff7555o9e3b/fSeffLKOPfZYbdq0KYomRqazs1Pjx4/XSSedpOuuu0579+6Nu0mB6erqUk9Pz6Dj2NzcrLPPPtva47hp0yYdffTROvPMM/vvmz17tkaMGKHNmzeXfex///d/a+zYsTrllFN022236ZNPPgm7uRUdPHhQL7/88qBjMGLECM2ePbvkMdi0adOg7SVpzpw51h6zavZRkj766CMdd9xxymaz6ujo0NatW6NobmSSdhxrdfrpp2vSpEn6i7/4C/3sZz+Luzme9fb2SlLZc2JQx9LqRfzitG3bNt13331asWJFyW16eno0cuTIYXkMEyZMsHbcsBoXXHCBcrmcpkyZorffflu33367/vIv/1KbNm1SQ0ND3M2rmXusJkyYMOh+m49jT0/PsC7gww47TGPGjCnb5vnz5+u4447T5MmT9atf/Ur/+I//qDfffFP5fD7sJpf1wQcfqFAoFD0Gb7zxRtHH9PT0JOqY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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for idx in range(0, N):\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 can see the data is clearly separated by blue and red class."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## QBoost\n",
    "\n",
    "QBoost is a one of the ensemble learning using QA. Ensemble learning involves preparing a number of weak predictors and combining the results of each of these predictors to obtain the final prediction result.\n",
    "\n",
    "QBoost uses QA to optimize the best combination of learners for a given training data. We handle classification problem in this time.\n",
    "\n",
    "We define that the set of $D$ training data are $\\{\\vec x^{(d)}\\}(d=1, ..., D)$, corresponding label are $\\{y^{(d)}\\}(d=1, ..., D), y^{(d)}\\in \\{-1, 1\\}$ and the (function) set of $N$ weak learner is $\\{C_i\\}(i=1, ..., N)$. For some data $\\vec x^{(d)}$, $C_i(\\vec x^{(d)})\\in \\{-1, 1\\}$. \n",
    "\n",
    "Based on the definitions above, the classification labels are as follows.\n",
    "\n",
    "$${\\rm sgn}\\left( \\sum_{i=1}^{N} w_i C_i({\\vec x}^{(d)})\\right)$$\n",
    "\n",
    "Where $w_i\\in\\{0, 1\\} (i=1, ..., N)$, is a weight of each predictor (bool value to adopt or not adopt the predictor for the final prediction).QBoost optimizes the combination of $w_i$ so that prediction matches the training data while erasing the number of weak learners.\n",
    "\n",
    "Hamiltonian in this problem is as follows.\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",
    "The first term represents the difference between weak classifier and the correct label. The second term represents a degree of the number of weak classifier to be employed in the final classifier. $\\lambda$ is the regularization parameter that adjust how much the number of weak classifiers affects the total Hamiltonian.\n",
    "\n",
    "We optimize this Hamiltonian by recognizing the first term as a cost (objective function) and the second term as a constraint.Minimizing with QA allows us to obtain a combination of weak classifiers that best fits the training data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Preparation of dataset\n",
    "\n",
    "Let us try QBoost. We use the cancer identification dataset from scikit-learn for training data. For simplicity, we will only use two character types for training: \"0\" and \"1\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import libraries\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": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load data\n",
    "cancerdata = datasets.load_breast_cancer()\n",
    "# set the number of training data & test data\n",
    "num_train = 450"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this time, we consider that feature of noise exists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(569, 60)\n"
     ]
    }
   ],
   "source": [
    "data_noisy = np.concatenate(\n",
    "    (cancerdata.data, np.random.rand(cancerdata.data.shape[0], 30)), axis=1\n",
    ")\n",
    "print(data_noisy.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "# convert from label {0, 1} to {-1, 1}\n",
    "labels = (cancerdata.target - 0.5) * 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "# divide dataset to training and test\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": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from the result of weak learnor\n",
    "def aggre_mean(Y_list):\n",
    "    return ((np.mean(Y_list, axis=0) > 0) - 0.5) * 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating Set of Weak Learner\n",
    "\n",
    "We make weak learner with scikit-learn. In this time, we choose decision stump. Decision stump is a single-layer decision tree. As it will be used as a weak classifier, the features to be used for segmentation are selected randomly (it's a good understanding that we execute single-layer of random forest)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import required libraries\n",
    "from sklearn.tree import DecisionTreeClassifier as DTC\n",
    "\n",
    "# set the number of weak classifier\n",
    "num_clf = 32\n",
    "# set the number of ensembles to be taken out for one sample in bootstrap sampling\n",
    "sample_train = 40\n",
    "# set model\n",
    "models = [DTC(splitter=\"random\", max_depth=1) for i in range(num_clf)]\n",
    "for model in models:\n",
    "    # extract randomly\n",
    "    train_idx = np.random.choice(np.arange(X_train.shape[0]), sample_train)\n",
    "    # make decision tree with variables\n",
    "    model.fit(X=X_train[train_idx], y=y_train[train_idx])\n",
    "y_pred_list_train = []\n",
    "for model in models:\n",
    "    # execute prediction with model\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": [
    "We look accuracy of all weak learner as the final classifier. Henceforth, we refer to this combination as baseline."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9411764705882353\n"
     ]
    }
   ],
   "source": [
    "y_pred_list_test = []\n",
    "for model in models:\n",
    "    # execute with test data\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",
    "# compute score of prediction accuracy\n",
    "acc_test_base = metrics.accuracy_score(y_true=y_test, y_pred=y_pred_test)\n",
    "print(acc_test_base)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Execute QBoost with OpenJij"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us creater QBoost model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [],
   "source": [
    "# set class of QBoost\n",
    "class QBoost:\n",
    "    def __init__(self, y_train, ys_pred):\n",
    "        self.instance_data = {\"y\": y_train, \"C\": ys_pred}\n",
    "        self.qboost_Hamiltonian()\n",
    "        self.pyq_obj, self.pyq_cache = to_pyqubo(\n",
    "            self.problem, self.instance_data, {}\n",
    "        )\n",
    "\n",
    "    def qboost_Hamiltonian(self):\n",
    "        problem = jm.Problem(\"QBoost\")\n",
    "        C = jm.Placeholder(\"C\", dim=2)\n",
    "        y = jm.Placeholder(\"y\", dim=1)\n",
    "        N = C.shape[0].set_latex(\"N\")\n",
    "        D = C.shape[1].set_latex(\"D\")\n",
    "        w = jm.Binary(\"w\", shape=(N))\n",
    "        i = jm.Element(\"i\", (0, N))\n",
    "        d = jm.Element(\"d\", (0, D))\n",
    "        obj = jm.Sum(\n",
    "            d,\n",
    "            (1 / N * jm.Sum(i, w[i] * C[i, d]) - y[d])\n",
    "            * (1 / N * jm.Sum(i, w[i] * C[i, d]) - y[d]),\n",
    "        )\n",
    "        constraint = jm.Constraint(\"constraint\", jm.Sum(i, w[i]))\n",
    "        problem += obj\n",
    "        problem += constraint\n",
    "        self.problem = problem\n",
    "\n",
    "    def sampling(self, qubo, **kwargs):\n",
    "        sampler = oj.SASampler(**kwargs)\n",
    "        response = sampler.sample_qubo(qubo)\n",
    "        return response\n",
    "\n",
    "    def decode(self, response):\n",
    "        return self.pyq_cache.decode(response)\n",
    "\n",
    "    # set function for converting to QUBO\n",
    "    def to_qubo(self, norm_param=1):\n",
    "        # set value of hyperparameter\n",
    "        self.multiplier = {\"constraint\": norm_param}\n",
    "        model = self.pyq_obj.compile()\n",
    "        return model.to_qubo(feed_dict=self.multiplier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$$\\begin{alignat*}{4}\\text{Problem} & \\text{: QBoost} \\\\\\min & \\quad \\sum_{ d = 0 }^{ D - 1 } \\left( \\frac{ 1 }{ N } \\cdot \\sum_{ i = 0 }^{ N - 1 } w_{i} \\cdot C_{i,d} - y_{d} \\right) \\cdot \\left( \\frac{ 1 }{ N } \\cdot \\sum_{ i = 0 }^{ N - 1 } w_{i} \\cdot C_{i,d} - y_{d} \\right) \\\\\\text{s.t.} & \\\\& \\text{constraint} :\\\\ &\\quad \\quad \\sum_{ i = 0 }^{ N - 1 } w_{i} = 0,\\\\[8pt]& w_{i_{0}} \\in \\{0, 1\\}\\end{alignat*}$$"
      ],
      "text/plain": [
       "<jijmodeling.problem.problem.Problem at 0x7f2e3d14a7f0>"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "qboost = QBoost(y_train=y_train, ys_pred=y_pred_list_train)\n",
    "qboost.problem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "# make QUBO with lambda=3\n",
    "qubo = qboost.to_qubo(1)[0]\n",
    "response = qboost.sampling(qubo, num_reads=100, num_sweeps=10)\n",
    "result = qboost.decode(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us check the accuracy in the training/validation data when using a combination of weak classifiers obtained by D-Wave."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "accs_train_Dwaves = []\n",
    "accs_test_Dwaves = []\n",
    "\n",
    "for solution in result.record.solution[\"w\"]:\n",
    "    idx_clf_DWave = solution[0][0]\n",
    "    y_pred_train_DWave = np.sign(\n",
    "        np.sum(y_pred_list_train[idx_clf_DWave, :], axis=0)\n",
    "    )\n",
    "    y_pred_test_DWave = np.sign(\n",
    "        np.sum(y_pred_list_test[idx_clf_DWave, :], axis=0)\n",
    "    )\n",
    "    acc_train_DWave = metrics.accuracy_score(\n",
    "        y_true=y_train, y_pred=y_pred_train_DWave\n",
    "    )\n",
    "    acc_test_DWave = metrics.accuracy_score(\n",
    "        y_true=y_test, y_pred=y_pred_test_DWave\n",
    "    )\n",
    "    accs_train_Dwaves.append(acc_train_DWave)\n",
    "    accs_test_Dwaves.append(acc_test_DWave)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [],
   "source": [
    "energies = result.evaluation.energy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We make a graph with energy on the horizontal axis and accuracy on the vertical axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA/IAAAK9CAYAAACHG1c1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAACSi0lEQVR4nOzde3yT5f3/8XdS2obSA8fSggxKcWJFQVAYyMEph1oGivsOh1OQbagMpo7fpuJQqCfUKV+ZBzxszA3m1HlgsGEV8QAKUiagw6JflYIOSgtUWw6WluT+/REbCU3aJL1zuJPX8/Hgoblz5b4/1+e+riSf3nfu22YYhiEAAAAAAGAJ9mgHAAAAAAAAAkchDwAAAACAhVDIAwAAAABgIRTyAAAAAABYCIU8AAAAAAAWQiEPAAAAAICFUMgDAAAAAGAhFPIAAAAAAFgIhTwAAAAAABZCIQ8Aceqqq65Sr169TF3nU089JZvNpl27dpm63mAtWLBANptNBw4caLFtr169dNVVV5m27auuukrp6emmrQ8wSzjmPAAgNlHIAwCauPvuu7VixYpoh5EwHn30UT311FPRDgMAAFgEhTwAoAl/hfyVV16pr7/+Wj179ox8UCH6+OOP9eSTT0Y7jGZRyAMAgGBQyAOARRw5ciTaISgpKUkOh0M2my3aoQQsNTVVycnJ0Q4DMSQW5hIC43K5VFdXF+0wACDmUMgDQAxq/A14WVmZLr/8cnXo0EHDhw/3PL98+XINGjRIbdu2VceOHfXjH/9YX3zxRYvrvf/++zVs2DB16tRJbdu21aBBg/T88897tbHZbDpy5Ij+/Oc/y2azyWazeX5j7u838o8++qjOOOMMpaamqlu3bpo1a5a++uorrzbnn3+++vXrp7KyMn3/+99XWlqaunfvrvvuu69JnA899JDOOOMMpaWlqUOHDjrnnHP09NNPN2n31Vdf6aqrrlL79u2VlZWl6dOn6+jRo15tTv6NfGMf1q1bp2uuuUadOnVSZmampk6dqi+//LLFHDbauXOnxo0bp3bt2qlbt266/fbbZRiGVxuXy6UHH3xQZ5xxhhwOh7p27aprrrnGazu9evXShx9+qLfeesuT7/PPP19fffWVkpKS9Pvf/97T9sCBA7Lb7erUqZPXtmbOnKmcnByvbW/atEmFhYXKyspSWlqaRo0apXfeeadJP/bs2aOf/vSn6tq1q1JTU3XGGWdo6dKlXm3efPNN2Ww2Pffcc7rrrrt0yimnyOFw6MILL9Snn34aUL7CsZ1A+tjcXHK5XFqwYIG6deumtLQ0ff/731dZWZnXmNm5c6dsNpv+93//t8n2N2zYIJvNpr/97W9++11fX6/bbrtNgwYNUlZWltq1a6cRI0bojTfe8Gq3a9cu2Ww23X///XriiSeUn5+v1NRUnXvuudq8eXOT9a5YsUL9+vWTw+FQv3799NJLL/mN4WT/+Mc/NH78eHXr1k2pqanKz8/XHXfcIafT2aTtpk2bVFRUpA4dOqhdu3Y666yztHjxYq82H330kSZPnqwuXbqobdu2Ou200/Tb3/7W87y/3+437psT2Ww2zZ49W3/961897yklJSWSAnv/arR8+XINHjzY8x4ycuRIvfrqq5KkadOmqXPnzmpoaGjyurFjx+q0005rPoEAEAPaRDsAAIB/P/rRj3Tqqafq7rvv9hRud911l2699VZNnjxZP//5z7V//3499NBDGjlypLZu3ar27dv7Xd/ixYs1ceJE/eQnP1F9fb2eeeYZ/ehHP9I///lPjR8/XpK0bNky/fznP9fgwYN19dVXS5Ly8/P9rnPBggUqLi7W6NGjNXPmTH388cdasmSJNm/erHfeecfraPiXX36pwsJCXXrppZo8ebKef/553XTTTTrzzDN10UUXSZKefPJJXXfddfqf//kfXX/99aqrq9MHH3ygTZs26fLLL/fa9uTJk5WXl6eFCxdqy5Yt+sMf/qDs7Gzde++9LeZ29uzZat++vRYsWOCJeffu3Z5isjlOp1OFhYX63ve+p/vuu08lJSWaP3++jh8/rttvv93T7pprrtFTTz2l6dOn67rrrlN5ebkefvhhbd261ZObBx98UL/85S+Vnp7uKX66du2q9u3bq1+/flq3bp2uu+46SdLbb78tm82m6upqlZWV6YwzzpAkrV+/XiNGjPBs9/XXX9dFF12kQYMGaf78+bLb7frTn/6kCy64QOvXr9fgwYMlSZWVlfre977nKZ66dOmil19+WT/72c9UW1urG264wavf99xzj+x2u37961+rpqZG9913n37yk59o06ZNzeYrHNsJtI+NfM2luXPn6r777tOECRM0btw4vf/++xo3bpzXEeDevXvrvPPO01//+lf96le/8lrnX//6V2VkZOjiiy/22/fa2lr94Q9/0JQpUzRjxgwdOnRIf/zjHzVu3DiVlpZqwIABXu2ffvppHTp0SNdcc41sNpvuu+8+XXrppdq5c6dnLr366qv64Q9/qIKCAi1cuFAHDx7U9OnTdcoppzS7Hxo99dRTSk9P15w5c5Senq7XX39dt912m2pra/W73/3O027NmjX6wQ9+oNzcXF1//fXKycnRjh079M9//lPXX3+9JOmDDz7QiBEjlJycrKuvvlq9evXSZ599plWrVumuu+4KKJ6Tvf7663ruuec0e/Zsde7c2fNHgEDevySpuLhYCxYs0LBhw3T77bcrJSVFmzZt0uuvv66xY8fqyiuv1F/+8he98sor+sEPfuB53b59+/T6669r/vz5IcUNABFlAABizvz58w1JxpQpU7yW79q1y0hKSjLuuusur+X/+c9/jDZt2ngtnzZtmtGzZ0+vdkePHvV6XF9fb/Tr18+44IILvJa3a9fOmDZtWpO4/vSnPxmSjPLycsMwDKOqqspISUkxxo4dazidTk+7hx9+2JBkLF261LNs1KhRhiTjL3/5i2fZsWPHjJycHOOHP/yhZ9nFF19snHHGGT6y8q3G/Pz0pz/1Wj5p0iSjU6dOXst69uzp1ZfGPgwaNMior6/3LL/vvvsMScY//vGPZrc9bdo0Q5Lxy1/+0rPM5XIZ48ePN1JSUoz9+/cbhmEY69evNyQZf/3rX71eX1JS0mT5GWecYYwaNarJtmbNmmV07drV83jOnDnGyJEjjezsbGPJkiWGYRjGwYMHDZvNZixevNgTy6mnnmqMGzfOcLlcntcePXrUyMvLM8aMGeNZ9rOf/czIzc01Dhw44LXdH//4x0ZWVpZnvLzxxhuGJOP00083jh075mm3ePFiQ5Lxn//8p9mcmb2dYProby7t27fPaNOmjXHJJZd4LV+wYIEhyWvMPP7444YkY8eOHZ5l9fX1RufOnX3OkxMdP37cqy+GYRhffvml0bVrV6/xW15ebkgyOnXqZFRXV3uW/+Mf/zAkGatWrfIsGzBggJGbm2t89dVXnmWvvvqqIanJnPfl5PcBwzCMa665xkhLSzPq6uo8cefl5Rk9e/Y0vvzyS6+2J+Z85MiRRkZGhrF7926/bXy9FxnGt/vmRJIMu91ufPjhhy3G7ev965NPPjHsdrsxadIkr/ekE2NyOp3GKaecYlx22WVezy9atMiw2WzGzp07m2wbAGINp9YDQAy79tprvR6/+OKLcrlcmjx5sg4cOOD5l5OTo1NPPbXJ6bona9u2ref/v/zyS9XU1GjEiBHasmVLSPG99tprqq+v1w033CC7/duPlBkzZigzM1P/+te/vNqnp6friiuu8DxOSUnR4MGDtXPnTs+y9u3b67///a/P04lPdnJ+RowYoYMHD6q2trbF11599dVeZwvMnDlTbdq00erVq1t8reQ+ot+o8UhzfX29XnvtNUnS3//+d2VlZWnMmDFe+2rQoEFKT09vcV819qeyslIff/yxJPeR95EjR2rEiBFav369JPdResMwPEfkt23bpk8++USXX365Dh486NnukSNHdOGFF2rdunVyuVwyDEMvvPCCJkyYIMMwvGIcN26campqmoyL6dOnKyUlxSs+SV7772Th2E6gfTzRyWNl7dq1On78uH7xi194Lf/lL3/ZpA+TJ0+Ww+HQX//6V8+yV155RQcOHPAaz74kJSV5+uJyuVRdXa3jx4/rnHPO8TnvLrvsMnXo0MFv3ysqKrRt2zZNmzZNWVlZnnZjxoxRQUFBs7E0OvF94NChQzpw4IBGjBiho0eP6qOPPpIkbd26VeXl5brhhhuanOXTeMbK/v37tW7dOv30pz/Vd77zHZ9tQjFq1CiffQnk/WvFihVyuVy67bbbvN6TTozJbrfrJz/5iVauXKlDhw55nv/rX/+qYcOGKS8vL+TYASBSOLUeAGLYyV8oP/nkExmGoVNPPdVn+5Yu6vbPf/5Td955p7Zt26Zjx455lof6pXv37t2S1OQ3pSkpKerdu7fn+UannHJKk2116NBBH3zwgefxTTfdpNdee02DBw9Wnz59NHbsWF1++eU677zzmmz/5OKhsQD68ssvlZmZ2WzsJ+cwPT1dubm5TX7/74vdblfv3r29ln33u9+VJM/rP/nkE9XU1Cg7O9vnOqqqqlrcTmMRt379ep1yyinaunWr7rzzTnXp0kX333+/57nMzEz179/fs13J/Ttgf2pqatTQ0KCvvvpKTzzxhJ544omAYmwu3/7s37/f9O0E2scTC+KT51Lj2OzTp4/X8o4dO3q9TnL/cWnChAl6+umndccdd0hyF33du3fXBRdc4DeGRn/+85/1wAMP6KOPPvL6XbavgrGlvjfG7es94LTTTgvoj3Iffvih5s2bp9dff73JH71qamokSZ999pkkqV+/fn7X0/jHhebahMJfIR3I+9dnn30mu93e4h81pk6dqnvvvVcvvfSSpk6dqo8//ljvvfeeHnvsMXM6AQBhRiEPADHsxCNQkvuIns1m08svv6ykpKQm7dPT0/2ua/369Zo4caJGjhypRx99VLm5uUpOTtaf/vQnnxeSCwdfMUvyunDb6aefro8//lj//Oc/VVJSohdeeEGPPvqobrvtNhUXFwe9vmhxuVzKzs72Oop7oi5durS4jm7duikvL0/r1q1Tr169ZBiGhg4dqi5duuj666/X7t27tX79eg0bNsxz9LHxSPTvfve7Jr+/bpSenq6DBw9Kkq644gq/BfFZZ53l9TiUfDfGY+Z2Au3jiU6eS8GaOnWq/v73v2vDhg0688wztXLlSv3iF79octT3ZMuXL9dVV12lSy65RL/5zW+UnZ2tpKQkLVy40FMsnyjcY/qrr77SqFGjlJmZqdtvv135+flyOBzasmWLbrrppiZnMpjB3x8KfV1cT/K9r8x+/yooKNCgQYO0fPlyTZ06VcuXL1dKSoomT54c9LoAIBoo5AHAQvLz82UYhvLy8jxHgAP1wgsvyOFw6JVXXlFqaqpn+Z/+9KcmbQM9Qt94P/mPP/7Y6wh1fX29ysvLNXr06KBibNSuXTtddtlluuyyy1RfX69LL71Ud911l+bOnSuHwxHSOk/2ySef6Pvf/77n8eHDh1VRUaGioqIWX+tyubRz506vffB///d/kuS5MFd+fr5ee+01nXfeeS0Wkc3le8SIEVq3bp3y8vI0YMAAZWRkqH///srKylJJSYm2bNni9QeOxgsTZmZmNpv/Ll26KCMjQ06nM+T9FIhwbCfQPjancex++umnXkeADx486PMMg8LCQnXp0kV//etfNWTIEB09elRXXnlli9t5/vnn1bt3b7344ote+znUC6o1xt14VsKJGn+C0Zw333xTBw8e1IsvvqiRI0d6lpeXl3u1a8zx9u3b/ea4cc5v37692W126NChyV0sJDU5Y6c5gb5/5efny+VyqayszO8feRpNnTpVc+bMUUVFhZ5++mmNHz++ydkYABCr+I08AFjIpZdeqqSkJBUXFzc5QmcYhucoqy9JSUmy2WxeR8F27dqlFStWNGnbrl07n1+8TzZ69GilpKTo97//vVc8f/zjH1VTU+N1JelAndyHlJQUFRQUyDAMn7eLCtUTTzzhtb4lS5bo+PHjnqvnt+Thhx/2/L9hGHr44YeVnJysCy+8UJL7d9VOp9NzKvaJjh8/7pXf5vI9YsQI7dq1S88++6znVHu73a5hw4Zp0aJFamho8Lpi/aBBg5Sfn6/7779fhw8fbrK+/fv3S3KPhx/+8Id64YUXfBZije1aKxzbCbSPzbnwwgvVpk0bLVmyxGv5ifv1RG3atNGUKVP03HPP6amnntKZZ57Z5EwCXxqPsJ84PzZt2qSNGze2+FpfcnNzNWDAAP35z3/2nAYvua8wX1ZWFlI89fX1evTRR73aDRw4UHl5eXrwwQebjM3G13bp0kUjR47U0qVL9fnnn/tsI7mL65qaGq+f0FRUVAR1y7xA378uueQS2e123X777U3OLjj5PXPKlCmy2Wy6/vrrtXPnzhavdwAAsYQj8gBgIfn5+brzzjs1d+5c7dq1S5dccokyMjJUXl6ul156SVdffbV+/etf+3zt+PHjtWjRIhUWFuryyy9XVVWVHnnkEfXp08frC7bkLpRee+01LVq0yHN695AhQ5qss0uXLpo7d66Ki4tVWFioiRMn6uOPP9ajjz6qc889N6QvxmPHjlVOTo7OO+88de3aVTt27NDDDz+s8ePHKyMjI+j1+VNfX68LL7xQkydP9sQ8fPhwTZw4scXXOhwOlZSUaNq0aRoyZIhefvll/etf/9Itt9ziOWV+1KhRuuaaa7Rw4UJt27ZNY8eOVXJysj755BP9/e9/1+LFi/U///M/ktz5XrJkie6880716dNH2dnZnt9eNxbpH3/8se6++25PDCNHjtTLL7/sudd4I7vdrj/84Q+66KKLdMYZZ2j69Onq3r279uzZozfeeEOZmZlatWqVJPdt3t544w0NGTJEM2bMUEFBgaqrq7Vlyxa99tprqq6uNiXXZm8nmD7607VrV11//fV64IEHNHHiRBUWFur999/Xyy+/rM6dO/s8S2Lq1Kn6/e9/rzfeeCOgWxxK0g9+8AO9+OKLmjRpksaPH6/y8nI99thjKigo8PlHiEAsXLhQ48eP1/Dhw/XTn/5U1dXVeuihh3TGGWe0uM5hw4apQ4cOmjZtmq677jrZbDYtW7asSZFrt9u1ZMkSTZgwQQMGDND06dOVm5urjz76SB9++KFeeeUVSdLvf/97DR8+XAMHDtTVV1+tvLw87dq1S//617+0bds2SdKPf/xj3XTTTZo0aZKuu+46HT16VEuWLNF3v/vdgC+0Gej7V58+ffTb3/5Wd9xxh0aMGKFLL71Uqamp2rx5s7p166aFCxd62nbp0kWFhYX6+9//rvbt24f0h0cAiJrIXSAfABCoxtsyNd7K7GQvvPCCMXz4cKNdu3ZGu3btjL59+xqzZs0yPv74Y08bX7d8+uMf/2iceuqpRmpqqtG3b1/jT3/6k89bQH300UfGyJEjjbZt23rdiuvk2881evjhh42+ffsaycnJRteuXY2ZM2c2uWXVqFGjfN5W7uQ4H3/8cWPkyJFGp06djNTUVCM/P9/4zW9+Y9TU1LSYH1/x+bv93FtvvWVcffXVRocOHYz09HTjJz/5iXHw4MEm8fmKt127dsZnn31mjB071khLSzO6du1qzJ8/v8ntrgzDMJ544glj0KBBRtu2bY2MjAzjzDPPNG688UZj7969njb79u0zxo8fb2RkZBiSmtyKLjs725BkVFZWepa9/fbbhiRjxIgRPuPcunWrcemll3ry2LNnT2Py5MnG2rVrvdpVVlYas2bNMnr06GEkJycbOTk5xoUXXmg88cQTnjaNt4X7+9//7vXaxlum/elPf2oxb+HYTiB9bG4uHT9+3Lj11luNnJwco23btsYFF1xg7Nixw+jUqZNx7bXX+uzHGWecYdjtduO///1vi302DPctz+6++26jZ8+eRmpqqnH22Wcb//znP5uM+8Y+/u53v2uyDknG/PnzvZa98MILxumnn26kpqYaBQUFxosvvuj3Nm8ne+edd4zvfe97Rtu2bY1u3boZN954o/HKK68Ykow33njDq+3bb79tjBkzxsjIyDDatWtnnHXWWcZDDz3k1Wb79u3GpEmTjPbt2xsOh8M47bTTjFtvvdWrzauvvmr069fPSElJMU477TRj+fLlfm8/N2vWLJ9xB/r+ZRiGsXTpUuPss882UlNTjQ4dOhijRo0y1qxZ06Tdc889Z0gyrr766hbzBgCxxGYYMXBFIAAAIuSpp57S9OnTtXnzZp1zzjnRDgcx5quvvlKHDh1055136re//W2T588++2x17NhRa9eujUJ0MNs//vEPXXLJJVq3bp3XT1QAINbxG3kAAJCQvv766ybLHnzwQUnS+eef3+S5f//739q2bZum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XnrpJb3++uvKy8sLvpMAYkaS3ab5EwokuQu7EzU+nj+hwHKFHti3AAAAoQipkPfl1FNP1T333NPkaH1L5syZoyeffFJ//vOftWPHDs2cOVNHjhzxXMV+6tSpXhfD27Rpk1588UXt3LlT69evV2FhoVwul2688UZPm1mzZmn58uV6+umnlZGRoX379mnfvn36+uuvzeksgIgr7JerJVcMVE6W98Uuc7IcWnLFQBX2y41SZGgt9i0AAEBwQjq13u/K2rTR3r17g3rNZZddpv379+u2227Tvn37NGDAAJWUlKhr166SpM8//1x2+7d/b6irq9O8efO0c+dOpaenq6ioSMuWLVP79u09bZYsWSJJOv/887229ac//UlXXXVVSH0DEH2F/XI1piBHpeXVqjpUp+wMhwbndeRobRxg3wIAAAQupEJ+5cqVXo8Nw1BFRYUefvhhnXfeeUGvb/bs2Zo9e7bP5958802vx6NGjVJZWVmz64vihfgBhFmS3aah+Z2iHQbCgH0LAAAQmJAK+UsuucTrsc1mU5cuXXTBBRfogQceMCMuAAAAAADgQ0iFvMvlMjsOAAAAAAAQANMudgcAAAAAAMIvpEL+hz/8oe69994my++77z796Ec/anVQAAAAAADAt5AK+XXr1qmoqKjJ8osuukjr1q1rdVAAAAAAAMC3kAr5w4cPKyUlpcny5ORk1dbWtjooAAAAAADgW0iF/Jlnnqlnn322yfJnnnlGBQUFrQ4KAAAAAAD4FtJV62+99VZdeuml+uyzz3TBBRdIktauXau//e1v+vvf/25qgAAAAAAA4FshFfITJkzQihUrdPfdd+v5559X27ZtddZZZ+m1117TqFGjzI4RAAAAAAB8I6RCXpLGjx+v8ePHmxkL4pjTZai0vFpVh+qUneHQ4LyOSrLboh2WpUU7p762H63tMpYSF+MBAAAkopAK+c2bN8vlcmnIkCFeyzdt2qSkpCSdc845pgSH+FCyvULFq8pUUVPnWZab5dD8CQUq7JcbxcisK9o59bf928afFpXtMpYSE+MBAAAkqpAudjdr1ix98cUXTZbv2bNHs2bNanVQiB8l2ys0c/kWry/akrSvpk4zl29RyfaKKEVmXdHOaXPb/9Wz26KyXcZS4mE8AACARBZSIV9WVqaBAwc2WX722WerrKys1UEhPjhdhopXlcnw8Vzj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",
      "text/plain": [
       "<Figure size 1200x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "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\")\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": 95,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "base accuracy is 0.9411764705882353\n",
      "max accuracy of QBoost is 0.9495798319327731\n",
      "average accuracy of QBoost is 0.9284033613445378\n"
     ]
    }
   ],
   "source": [
    "print(\"base accuracy is {}\".format(acc_test_base))\n",
    "print(\"max accuracy of QBoost is {}\".format(max(accs_test_Dwaves)))\n",
    "print(\n",
    "    \"average accuracy of QBoost is {}\".format(\n",
    "        np.mean(np.asarray(accs_test_Dwaves))\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.10"
  },
  "vscode": {
   "interpreter": {
    "hash": "2e8d7574d7ec71e14cb1575cf43673432d6fae464c836a7b3733d4f6c20243fb"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}