Nota
Esta página fue generada a partir de `docs/tutorials/03_quantum_kernel.ipynb`__.
Machine Learning con Kernel Cuántico¶
La tarea general del machine learning es encontrar y estudiar patrones en los datos. Para muchos conjuntos de datos, los puntos de datos se comprenden mejor en un espacio de características de mayor dimensión, mediante el uso de una función de kernel: \(k(\vec{x}_i, \vec{x}_j) = \langle f(\vec{x}_i), f(\vec{x}_j) \rangle\) donde \(k\) es la función de kernel, \(\vec{x}_i, \vec{x}_j\) son entradas \(n\) dimensionales, \(f\) es un mapa del espacio de dimensión \(n\) al espacio de dimensión \(m\) y \(\langle a,b \rangle\) denota el producto punto. Cuando se consideran datos finitos, una función de kernel se puede representar como una matriz: \(K_{ij} = k(\vec{x}_i,\vec{x}_j)\).
En machine learning con kernel cuántico, se utiliza un mapa cuántico de características \(\phi(\vec{x})\) para asignar un vector clásico de características \(\vec{x}\) a un espacio cuántico de Hilbert, \(| \phi(\vec{x})\rangle \langle \phi(\vec{x})|\), tal que \(K_{ij} = \left| \langle \phi^\dagger(\vec{x}_j)| \phi(\vec{x}_i) \rangle \right|^{2}\). Consulta Supervised learning with quantum enhanced feature spaces para obtener más detalles.
En este cuaderno, usamos qiskit
para calcular una matriz de kernel usando un mapa cuántico de características, luego usamos esta matriz de kernel en algoritmos de clasificación y agrupamiento de scikit-learn
.
[1]:
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
from qiskit_machine_learning.datasets import ad_hoc_data
seed = 12345
algorithm_globals.random_seed = seed
Clasificación¶
Para nuestro ejemplo de clasificación, usaremos el dataset ad hoc como se describe en Supervised learning with quantum enhanced feature spaces, y el algoritmo de clasificación support vector machine (svc
) de scikit-learn
.
[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()

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.
[3]:
adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear")
sampler = Sampler()
fidelity = ComputeUncompute(sampler=sampler)
adhoc_kernel = FidelityQuantumKernel(fidelity=fidelity, feature_map=adhoc_feature_map)
El algoritmo SVC
de scikit-learn
nos permite definir un `kernel personalizado<https://scikit-learn.org/stable/modules/svm.html#custom-kernels>`__ de dos formas: proporcionando el kernel como una función invocable o precalculando la matriz del kernel. Podemos hacer cualquiera de estos usando la clase FidelityQuantumKernel
en qiskit
.
El siguiente código da el kernel como una función invocable:
[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
El siguiente código precalcula y grafica las matrices del kernel de entrenamiento y prueba antes de proporcionarlas al algoritmo svc
de scikit-learn
:
[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 Machine Learning también contiene la clase QSVC
que amplía la clase SVC
de scikit-learn, que se puede usar de la siguiente manera:
[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
Agrupación (Clustering)¶
Para nuestro ejemplo de agrupamiento, usaremos nuevamente el dataset ad hoc como se describe en Supervised learning with quantum enhanced feature spaces, y el algoritmo de agrupación spectral
de scikit-learn
.
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.
[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()

Nuevamente, configuramos la clase FidelityQuantumKernel
para calcular una matriz del kernel usando ZZFeatureMap, y los valores predeterminados en esta ocasión.
[8]:
adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear")
adhoc_kernel = FidelityQuantumKernel(feature_map=adhoc_feature_map)
El algoritmo de agrupamiento espectral de scikit-learn nos permite definir un kernel personalizado de dos maneras: proporcionando el kernel como una función invocable o precalculando la matriz del kernel. Usando la clase FidelityQuantumKernel
en Qiskit Machine Learning, solo podemos usar este último.
El siguiente código precalcula y grafica las matrices del kernel antes de proporcionarlo al algoritmo de agrupamiento espectral de scikit-learn y puntuar las etiquetas utilizando información mutua normalizada, ya que conocemos las etiquetas de clase a priori.
[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
tiene otros algoritmos que pueden usar una matriz de kernel precalculada, aquí hay algunos:
[10]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.22.0 |
qiskit-aer | 0.11.0 |
qiskit-ignis | 0.7.0 |
qiskit | 0.33.0 |
qiskit-machine-learning | 0.5.0 |
System information | |
Python version | 3.7.9 |
Python compiler | MSC v.1916 64 bit (AMD64) |
Python build | default, Aug 31 2020 17:10:11 |
OS | Windows |
CPUs | 4 |
Memory (Gb) | 31.837730407714844 |
Mon Oct 10 12:01:53 2022 GMT Daylight Time |
This code is a part of Qiskit
© Copyright IBM 2017, 2022.
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.