1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

qiskit_machine_learningでQSVM

Last updated at Posted at 2021-10-17

はじめに

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)

image.png

少し見にくいですが、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並の使い勝手になると期待しています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?