量子カーネル SVM で遊んでみる — Blueqat
目的
量子カーネル SVM で遊んでみる — Qiskit の内容を更に Blueqat でも実装してみようというもの。
データセット
毎回毎回同じであるが前回と同様に以下のデータセットを使いたい。
前回と同様に以下で訓練セット (train_data, train_labels)
とテストセット (test_data, test_labels)
が準備されているとする。
from sklearn.datasets import make_circles
X, Y = make_circles(n_samples=200, noise=0.05, factor=0.4)
A = X[np.where(Y==0)]
B = X[np.where(Y==1)]
A_label = np.zeros(A.shape[0], dtype=int)
B_label = np.ones(B.shape[0], dtype=int)
def make_train_test_sets(test_ratio=.3):
def split(arr, test_ratio):
sep = int(arr.shape[0]*(1-test_ratio))
return arr[:sep], arr[sep:]
A_label = np.zeros(A.shape[0], dtype=int)
B_label = np.ones(B.shape[0], dtype=int)
A_train, A_test = split(A, test_ratio)
B_train, B_test = split(B, test_ratio)
A_train_label, A_test_label = split(A_label, test_ratio)
B_train_label, B_test_label = split(B_label, test_ratio)
X_train = np.concatenate([A_train, B_train])
y_train = np.concatenate([A_train_label, B_train_label])
X_test = np.concatenate([A_test, B_test])
y_test = np.concatenate([A_test_label, B_test_label])
return X_train, y_train, X_test, y_test
train_data, train_labels, test_data, test_labels = make_train_test_sets()
今回やりたいこと
Qiskit に任せていた部分を独自実装する必要がある。つまり、以下の 2 点になる:
- Qiskit の ZZFeatureMap を Blueqat で実装する。
- 自作カーネルを計算する
calculate_kernel
を Blueqat で実装する。
ZZFeatureMap
を Blueqat で実装する
要するに以下の回路を実装すれば良い:
そのまま素直に実装できるが、比較のために Qiskit 版のインターフェイスに近づけておく。.bind_parameters()
のようなメソッドはないので、引数 x
でデータをリストで受け取ってそのまますぐに位相エンコーディングで回路に埋め込むことにした。
from blueqat import Circuit
def zz_feature_map(x, reps):
def sub_circuit(x):
n_qubit = len(x)
c = Circuit().h[:]
for i in range(n_qubit):
c.rz(2*x[i])[i]
for i in range(n_qubit - 1):
for j in range(i+1, n_qubit):
c.cx[i, j].rz(2*(np.pi-x[i])*(np.pi-x[j]))[j].cx[i, j]
return c
c = Circuit()
for _ in range(reps):
c += sub_circuit(x)
return c
今回、Qiskit 版の記事で書いたのと同じように rep=2
として扱いたいので、部分適用を用いてパラメータを予めバインドしておく:
from functools import partial
feature_map = partial(zz_feature_map, reps=2)
calculate_kernel
を Blueqat で実装する
自作カーネルを計算する おさらいする。zz_feature_map
による量子回路の部分を
を
こちらも Qiskit で行ったのと同様に素直に実装できる。numpy
バックエンドを用いれば良い。
def calculate_kernel(feature_map, x_data, y_data=None):
if y_data is None:
y_data = x_data
x_matrix, y_matrix = [], []
for x0, x1 in x_data:
c = feature_map([x0, x1])
sv = c.run(backend='numpy')
x_matrix.append(sv)
for y0, y1 in y_data:
c = feature_map([y0, y1])
sv = c.run(backend='numpy')
y_matrix.append(sv)
x_matrix, y_matrix = np.array(x_matrix), np.array(y_matrix)
kernel = np.abs(
y_matrix.conjugate() @ x_matrix.transpose()
)**2
return kernel
カーネルを計算して訓練する
冒頭のデータセット train_data
を使って calculate_kernel
で自作カーネルを計算して訓練する。
from sklearn.svm import SVC
train_kernel = calculate_kernel(feature_map, train_data)
model = SVC(kernel='precomputed')
model.fit(train_kernel, train_labels)
検証
テストカーネルも計算して、ラベルの推定結果を可視化する。
import matplotlib
test_kernel = calculate_kernel(feature_map, train_data, test_data)
pred = model.predict(test_kernel)
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111)
ax.set_aspect('equal')
ax.set_title("Predicted data classification")
ax.set_ylim(-2, 2)
ax.set_xlim(-2, 2)
for (x, y), pred_label in zip(test_data, pred):
c = 'C0' if pred_label == 0 else 'C3'
ax.add_patch(matplotlib.patches.Circle((x, y), radius=.01,
fill=True, linestyle='solid', linewidth=4.0,
color=c))
plt.grid()
plt.show()
今回も大体良さそうな結果になった。念の為スコアも確認する。
model.score(test_kernel, test_labels)
1.0
まとめ
Blueqat を用いる形でも量子カーネル SVM を行ってみた。Qiskit ではライブラリ実装の ZZFeatureMap
を使ったので「実際は中で凄いことをやっているんじゃないだろうか・・・」という気持ちがあったが、素直に論文の通りの回路を手で実装して同じ結果が得られると「な〜んだ」となる。「量子カーネル SVM」という響きは凄そうだが、特徴写像としての量子回路として先人が良さそうなものを見出してくれているのでそれを使って自作カーネル版のカーネル SVM を実行するだけであることが理解できた。
他の結論は 量子カーネル SVM で遊んでみる — Qiskit#まとめ と同じなので割愛する。不安なものは自分で納得いくまで実装したりして確認するのが良い。
参考文献
- [QSVM] Quantum feature maps and kernels, Qiskit Textbook
- [H-C-T-H-K-C-G] Vojtech Havlicek, Antonio D. Córcoles, Kristan Temme, Aram W. Harrow, Abhinav Kandala, Jerry M. Chow, Jay M. Gambetta, Supervised learning with quantum enhanced feature spaces, arXiv, 2018
- [QGSS2021] Kristan Temme, Quantum Feature Spaces and Kernels, Qiskit Global Summer School 2021
- [S-P] Maria Schuld, Francesco Petruccione, 量子コンピュータによる機械学習, 共立出版, 2020
- [S-K] Maria Schuld, Nathan Killoran, Quantum machine learning in feature Hilbert spaces, arXiv, 2018
- [S-B-S-W] Maria Schuld, Alex Bocharov, Krysta Svore, Nathan Wiebe, Circuit-centric quantum classifiers, arXiv, 2018
- [T-C-C-G] Francesco Tacchino, Alessandro Chiesa, Stefano Carretta, Dario Gerace Quantum computers as universal quantum simulators: state-of-art and perspectives, arXiv, 2019
- [PRML] C. M. Bishop, Pattern Recognition and Machine Learning, Springer, 2006
- [PML] S. Raschka, Python機械学習プログラミング, インプレス, 2020
- [カーネル法] 福水健次, カーネル法入門, 朝倉書店, 2010
- [sklearn.svm.SVC] sklearn.svm.SVC
Discussion