注釈
このページは docs/tutorials/03_quantum_kernel.ipynb から生成されました。
量子カーネル法機械学習¶
機械学習の一般的タスクはデータからパターンを発見したり学習することです。多くのデータセットに対し、データポイントはカーネル関数: \(k(\vec{x}_i, \vec{x}_j) = \langle f(\vec{x}_i), f(\vec{x}_j) \rangle\) を用いて高次元特徴空間で理解することができます。ここで、\(k\) はカーネル関数、\(\vec{x}_i, \vec{x}_j\) は n 次元のインプット、\(f\) は \(n\)-次元空間から \(m\)-次元空間への写像、\(\langle a,b \rangle\) は内積を表します。有限のデータに対して、カーネル関数は行列 \(K_{ij} = k(\vec{x}_i,\vec{x}_j)\) で表現することができます。
量子カーネル法機械学習において、量子特徴マップ \(\phi(\vec{x})\) は古典特徴ベクトル \(\vec{x}\) を \(K_{ij} = \left| \langle \phi^\dagger(\vec{x}_j)| \phi(\vec{x}_i) \rangle \right|^{2}\) なる量子ヒルベルト空間 \(| \phi(\vec{x})\rangle \langle \phi(\vec{x})|\) にマップする際に使用されます。詳細は Supervised learning with quantum enhanced feature spaces を参照してください。
このノートブックでは、量子特徴マップを使ってカーネル行列を計算するために qiskit
を使用し、 scikit-learn
の分類とクラスタリングアルゴリズムでこのカーネル行列を使用します。
[3]:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
from sklearn.cluster import SpectralClustering
from sklearn.metrics import normalized_mutual_info_score
from qiskit import BasicAer
from qiskit.circuit.library import ZZFeatureMap
from qiskit.utils import QuantumInstance, algorithm_globals
from qiskit_machine_learning.algorithms import QSVC
from qiskit_machine_learning.kernels import QuantumKernel
from qiskit_machine_learning.datasets import ad_hoc_data
seed = 12345
algorithm_globals.random_seed = seed
分類¶
分類の例では、Supervised learning with quantum enhanced feature spaces で説明されている アドホック・データセット と scikit-learn
の サポートベクターマシン (svc) 分類アルゴリズムを使用します。
[2]:
adhoc_dimension = 2
train_features, train_labels, test_features, test_labels, adhoc_total = ad_hoc_data(
training_size=20,
test_size=5,
n=adhoc_dimension,
gap=0.3,
plot_data=False,
one_hot=False,
include_sample_total=True,
)
plt.figure(figsize=(5, 5))
plt.ylim(0, 2 * np.pi)
plt.xlim(0, 2 * np.pi)
plt.imshow(
np.asmatrix(adhoc_total).T,
interpolation="nearest",
origin="lower",
cmap="RdBu",
extent=[0, 2 * np.pi, 0, 2 * np.pi],
)
plt.scatter(
train_features[np.where(train_labels[:] == 0), 0],
train_features[np.where(train_labels[:] == 0), 1],
marker="s",
facecolors="w",
edgecolors="b",
label="A train",
)
plt.scatter(
train_features[np.where(train_labels[:] == 1), 0],
train_features[np.where(train_labels[:] == 1), 1],
marker="o",
facecolors="w",
edgecolors="r",
label="B train",
)
plt.scatter(
test_features[np.where(test_labels[:] == 0), 0],
test_features[np.where(test_labels[:] == 0), 1],
marker="s",
facecolors="b",
edgecolors="w",
label="A test",
)
plt.scatter(
test_features[np.where(test_labels[:] == 1), 0],
test_features[np.where(test_labels[:] == 1), 1],
marker="o",
facecolors="r",
edgecolors="w",
label="B test",
)
plt.legend(bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0.0)
plt.title("Ad hoc dataset for classification")
plt.show()

学習用とテスト用のデータセットの準備ができたら、ZZFeatureMap を使用してカーネル行列を計算するための QuantumKernel
クラスを設定します。そして BasicAer
qasm_simulator
で 1024 回のショットを実行します。
[3]:
adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear")
adhoc_backend = QuantumInstance(
BasicAer.get_backend("qasm_simulator"), shots=1024, seed_simulator=seed, seed_transpiler=seed
)
adhoc_kernel = QuantumKernel(feature_map=adhoc_feature_map, quantum_instance=adhoc_backend)
scikit-learn
の svc
アルゴリズムでは、custom kernel を次の2つの方法で定義することができます: 呼び出し可能な関数としてカーネルを提供するか、カーネル行列を予測することです。 qiskit
の QuantumKernel
クラスを使用して、どちらかを行うことができます。
次のコードは、カーネルを呼び出し可能な関数として提供します。
[4]:
adhoc_svc = SVC(kernel=adhoc_kernel.evaluate)
adhoc_svc.fit(train_features, train_labels)
adhoc_score = adhoc_svc.score(test_features, test_labels)
print(f"Callable kernel classification test score: {adhoc_score}")
Callable kernel classification test score: 1.0
以下のコードは、scikit-learn
svc
アルゴリズムにそれらを提供する前に、カーネル行列の学習とテストを事前計算してプロットします。
[5]:
adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features)
adhoc_matrix_test = adhoc_kernel.evaluate(x_vec=test_features, y_vec=train_features)
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].imshow(
np.asmatrix(adhoc_matrix_train), interpolation="nearest", origin="upper", cmap="Blues"
)
axs[0].set_title("Ad hoc training kernel matrix")
axs[1].imshow(np.asmatrix(adhoc_matrix_test), interpolation="nearest", origin="upper", cmap="Reds")
axs[1].set_title("Ad hoc testing kernel matrix")
plt.show()
adhoc_svc = SVC(kernel="precomputed")
adhoc_svc.fit(adhoc_matrix_train, train_labels)
adhoc_score = adhoc_svc.score(adhoc_matrix_test, test_labels)
print(f"Precomputed kernel classification test score: {adhoc_score}")

Precomputed kernel classification test score: 1.0
qiskit
には、sklearn svc
クラスを拡張した qsvc
クラスも含まれており、次のように使用できます。
[6]:
qsvc = QSVC(quantum_kernel=adhoc_kernel)
qsvc.fit(train_features, train_labels)
qsvc_score = qsvc.score(test_features, test_labels)
print(f"QSVC classification test score: {qsvc_score}")
QSVC classification test score: 1.0
クラスタリング¶
クラスタリングの例では、Supervised learning, with quantum enhanced feature spaces で説明されている アドホック・データセット と scikit-learn
の spectral
クラスタリング・アルゴリズムを再度使用します。
2 つのクラス間に大きなギャップがあるデータ・セットを再生成します。クラスタリングは教師なし機械学習タスクであるため、テスト・サンプルは必要ありません。
[7]:
adhoc_dimension = 2
train_features, train_labels, test_features, test_labels, adhoc_total = ad_hoc_data(
training_size=25,
test_size=0,
n=adhoc_dimension,
gap=0.6,
plot_data=False,
one_hot=False,
include_sample_total=True,
)
plt.figure(figsize=(5, 5))
plt.ylim(0, 2 * np.pi)
plt.xlim(0, 2 * np.pi)
plt.imshow(
np.asmatrix(adhoc_total).T,
interpolation="nearest",
origin="lower",
cmap="RdBu",
extent=[0, 2 * np.pi, 0, 2 * np.pi],
)
plt.scatter(
train_features[np.where(train_labels[:] == 0), 0],
train_features[np.where(train_labels[:] == 0), 1],
marker="s",
facecolors="w",
edgecolors="b",
label="A",
)
plt.scatter(
train_features[np.where(train_labels[:] == 1), 0],
train_features[np.where(train_labels[:] == 1), 1],
marker="o",
facecolors="w",
edgecolors="r",
label="B",
)
plt.legend(bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0.0)
plt.title("Ad hoc dataset for clustering")
plt.show()

再度、 ZZFeatureMap を使用してカーネル行列を計算するために QuantumKernel
クラスを設定し、BasicAerの qasm_simulator
を1024ショットに設定します。
[8]:
adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear")
adhoc_backend = QuantumInstance(
BasicAer.get_backend("qasm_simulator"), shots=1024, seed_simulator=seed, seed_transpiler=seed
)
adhoc_kernel = QuantumKernel(feature_map=adhoc_feature_map, quantum_instance=adhoc_backend)
scikit-learnのスペクトラル・クラスタリング・アルゴリズムでは、[カスタム・カーネル] を2つの方法で定義することができます。つまり、カーネルを呼び出し可能な関数として提供するか、カーネル行列を予測することです。 QiskitのQuantumKernelクラスを使用する場合、後者のみを使用できます。
クラス・ラベルを前もって知っているので、以下のコードは、scikit-learnのスペクトラル・クラスタリング・アルゴリズムに投入し正規化相互情報量でラベルをスコアリングする前に、カーネル行列を事前計算してプロットします。
[9]:
adhoc_matrix = adhoc_kernel.evaluate(x_vec=train_features)
plt.figure(figsize=(5, 5))
plt.imshow(np.asmatrix(adhoc_matrix), interpolation="nearest", origin="upper", cmap="Greens")
plt.title("Ad hoc clustering kernel matrix")
plt.show()
adhoc_spectral = SpectralClustering(2, affinity="precomputed")
cluster_labels = adhoc_spectral.fit_predict(adhoc_matrix)
cluster_score = normalized_mutual_info_score(cluster_labels, train_labels)
print(f"Clustering score: {cluster_score}")

Clustering score: 0.7287008798015754
scikit-learn
には、事前計算されたカーネル行列を使用できる次のような他のアルゴリズムがあります:
[1]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.19.0 |
qiskit-aer | 0.8.2 |
qiskit-ignis | 0.6.0 |
qiskit-aqua | 0.9.2 |
qiskit | 0.27.0 |
qiskit-machine-learning | 0.3.0 |
System information | |
Python | 3.7.9 (default, Aug 31 2020, 17:10:11) [MSC v.1916 64 bit (AMD64)] |
OS | Windows |
CPUs | 4 |
Memory (Gb) | 31.837730407714844 |
Fri Dec 03 15:08:20 2021 GMT Standard Time |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.