はじめに
Qiskitのライブラリ qiskit_machine_learning
を使って簡単にQSVMが出来ます。
実はqiskit.aquaにあった機能です。が、aquaは廃止になりました。
にもかかわらず、未だに検索するとqiskit.aquaによる実装がたくさん出てきて困りますので
ここにqiskit_machine_learningによる実装を書いておきます。
以下のチュートリアルを参考に、QSVMを実装してみます。
https://qiskit.org/documentation/machine-learning/tutorials/03_quantum_kernel.html
qiskit による実装
# !pip install qiskit_machine_learning
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
# from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True)
# pick inputs and labels from the first two classes only,
# corresponding to the first 100 samples
X = X[:100,0:2]
y = y[:100]
# scaling the inputs is important since the embedding we use is periodic
scaler = StandardScaler().fit(X)
X_scaled = scaler.transform(X)
# scaling the labels to -1, 1 is important for the SVM and the
# definition of a hinge loss
y_scaled = 2 * (y - 0.5)
train_features, test_features, train_labels, test_labels = train_test_split(X_scaled, y_scaled, train_size=80, test_size=20)
n_qubits = 2
adhoc_feature_map = ZZFeatureMap(feature_dimension=n_qubits,
reps=1, entanglement='linear')
adhoc_backend = QuantumInstance(BasicAer.get_backend('statevector_simulator'), shots=1,
seed_simulator=seed, seed_transpiler=seed)
adhoc_kernel = QuantumKernel(feature_map=adhoc_feature_map, quantum_instance=adhoc_backend)
ZZ Feature map を見てみます。
print(adhoc_feature_map)
少し見にくいですが、H→RZ→CNOT(0,1)→RZ→CNOT(0,1)となっています。
CNOT(0,1)→RZ→CNOT(0,1) は、RZZと等価です。
QSVMの学習・予測の実行時間と、予測精度をみてみます。
import time
qsvc = QSVC(quantum_kernel=adhoc_kernel)
start = time.time()
qsvc.fit(train_features, train_labels)#train
qsvc_score = qsvc.score(test_features, test_labels) #predict
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
print(f'QSVC classification test score: {qsvc_score}')
elapsed_time:1.3650000095367432[sec]
QSVC classification test score: 0.45
予測精度は全くだめです。
ZZ feature map はこの問題に適さないということです。
(参考) PennyLane での実装
PennyLaneでも同じことをやってみます。
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pennylane as qml
from pennylane.operation import Tensor
from pennylane import numpy as np
import matplotlib.pyplot as plt
def my_feature_map(a):
for i in range(n_qubits):
qml.Hadamard(wires=i)
qml.RZ(2*a[i], wires=i)
qml.IsingZZ(2*(np.pi-a[0])*(np.pi-a[1]),wires=[0,1])
dev_kernel = qml.device("lightning.qubit", wires=n_qubits)
# |00...0><0.....00|
projector = np.zeros((2**n_qubits, 2**n_qubits))
projector[0, 0] = 1
@qml.qnode(dev_kernel)
def kernel(x1, x2):
"""The quantum kernel."""
#S(x)
my_feature_map(x1)
#S^{\dagger}(x')
qml.adjoint(my_feature_map)(x2)
return qml.expval(qml.Hermitian(projector, wires=range(n_qubits)))
def kernel_matrix(A, B):
"""Compute the matrix whose entries are the kernel
evaluated on pairwise data from sets A and B."""
return np.array([[kernel(a, b) for b in B] for a in A])
svm = SVC(kernel=kernel_matrix)
start = time.time()
svm.fit(train_features, train_labels)
predictions = svm.predict(test_features)
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
accuracy_score(predictions, test_labels)
elapsed_time:15.84500002861023[sec]
0.45
予測精度は当然同じ結果になりますが、実行時間が10倍程度かかっています。
PennyLaneは勾配降下が必要な機械学習には強いですが、QSVMではその必要性がないので、別に早くはないと考えられます。
所感
QSVMのライブラリについては、Qiskitのほうが整備されており、使いやすい。
PennyLaneもQSVM関係の機能が地味に増えたりしていますので、今後はQiskit並の使い勝手になると期待しています。