English
Languages
English
Bengali
French
Hindi
Italian
Japanese
Korean
Malayalam
Russian
Spanish
Tamil
Turkish
Vietnamese

Note

# Quantum Kernel Machine Learning¶

The general task of machine learning is to find and study patterns in data. For many datasets, the datapoints are better understood in a higher dimensional feature space, through the use of a kernel function: $$k(\vec{x}_i, \vec{x}_j) = \langle f(\vec{x}_i), f(\vec{x}_j) \rangle$$ where $$k$$ is the kernel function, $$\vec{x}_i, \vec{x}_j$$ are $$n$$ dimensional inputs, $$f$$ is a map from $$n$$-dimension to $$m$$-dimension space and $$\langle a,b \rangle$$ denotes the dot product. When considering finite data, a kernel function can be represented as a matrix: $$K_{ij} = k(\vec{x}_i,\vec{x}_j)$$.

In quantum kernel machine learning, a quantum feature map $$\phi(\vec{x})$$ is used to map a classical feature vector $$\vec{x}$$ to a quantum Hilbert space, $$| \phi(\vec{x})\rangle \langle \phi(\vec{x})|$$, such that $$K_{ij} = \left| \langle \phi^\dagger(\vec{x}_j)| \phi(\vec{x}_i) \rangle \right|^{2}$$. See Supervised learning with quantum enhanced feature spaces for more details.

In this notebook, we use qiskit to calculate a kernel matrix using a quantum feature map, then use this kernel matrix in scikit-learn classification and clustering algorithms.

:

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.algorithms.state_fidelities import ComputeUncompute
from qiskit.circuit.library import ZZFeatureMap
from qiskit.primitives import Sampler
from qiskit.utils import algorithm_globals
from qiskit_machine_learning.algorithms import QSVC
from qiskit_machine_learning.kernels import FidelityQuantumKernel

seed = 12345
algorithm_globals.random_seed = seed


## Classification¶

For our classification example, we will use the ad hoc dataset as described in Supervised learning with quantum enhanced feature spaces, and the scikit-learn support vector machine classification (svc) algorithm.

:

adhoc_dimension = 2
training_size=20,
test_size=5,
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(
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.show() With our training and testing datasets ready, we set up the FidelityQuantumKernel class to calculate a kernel matrix using the ZZFeatureMap. We use the reference implementation of the Sampler primitive and the ComputeUncompute fidelity that computes overlaps between states. These are the default values and if you don’t pass a Sampler or Fidelity instance, the same objects will be created automatically for you.

:

adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear")
sampler = Sampler()
fidelity = ComputeUncompute(sampler=sampler)


The scikit-learn SVC algorithm allows us to define a custom kernel in two ways: by providing the kernel as a callable function or by precomputing the kernel matrix. We can do either of these using the FidelityQuantumKernel class in qiskit.

The following code gives the kernel as a callable function:

:

adhoc_svc = SVC(kernel=adhoc_kernel.evaluate)

print(f"Callable kernel classification test score: {adhoc_score}")

Callable kernel classification test score: 1.0


The following code precomputes and plots the training and testing kernel matrices before providing them to the scikit-learn svc algorithm:

:

adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features)

fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs.imshow(
)
plt.show()

print(f"Precomputed kernel classification test score: {adhoc_score}") Precomputed kernel classification test score: 1.0


Qiskit Machine Learning also contains the QSVC class that extends the SVC class from scikit-learn, that can be used as follows:

:

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


## Clustering¶

For our clustering example, we will again use the ad hoc dataset as described in Supervised learning with quantum enhanced feature spaces, and the scikit-learn spectral clustering algorithm.

We will regenerate the dataset with a larger gap between the two classes, and as clustering is an unsupervised machine learning task, we don’t need a test sample.

:

adhoc_dimension = 2
training_size=25,
test_size=0,
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(
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.show() We again set up the FidelityQuantumKernel class to calculate a kernel matrix using the ZZFeatureMap, and the default values this time.

:

adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear")



The scikit-learn spectral clustering algorithm allows us to define a custom kernel in two ways: by providing the kernel as a callable function or by precomputing the kernel matrix. Using the FidelityQuantumKernel class in Qiskit Machine Learning, we can only use the latter.

The following code precomputes and plots the kernel matrices before providing it to the scikit-learn spectral clustering algorithm, and scoring the labels using normalized mutual information, since we a priori know the class labels.

:

adhoc_matrix = adhoc_kernel.evaluate(x_vec=train_features)

plt.figure(figsize=(5, 5))
plt.show()

cluster_score = normalized_mutual_info_score(cluster_labels, train_labels)

print(f"Clustering score: {cluster_score}") Clustering score: 0.7287008798015752


scikit-learn has other algorithms that can use a precomputed kernel matrix, here are a few:

:

import qiskit.tools.jupyter

%qiskit_version_table


### Version Information

Qiskit SoftwareVersion
qiskit-terra0.23.1
qiskit-aer0.11.2
qiskit-machine-learning0.5.0
System information
Python version3.8.16
Python compilerGCC 11.3.0
Python builddefault, Jan 11 2023 00:28:51
OSLinux
CPUs2
Memory (Gb)6.781219482421875
Tue Feb 07 03:48:02 2023 UTC