§ この記事の目的
機械学習の理論を量子コンピューティングに応用した技術の一つである**量子SVM(量子サポートベクターマシン)**について、基本的な動作確認を行います。
今回は、量子コンピューティング技術の最先端をリードするIBM社がリリースする、量子コンピューティングSDKのQiskit(キスキット)を使用します。
IBM Qiskitチュートリアル
https://qiskit.org/documentation/locale/ja_JP/index.html
§ 古典機械学習の線形・非線形の分類について
ここでは、量子コンピューティングを応用した機械学習を量子機械学習と呼び、従来の機械学習を古典機械学習と呼びます。
サポートベクターマシンは古典機械学習分野の理論及び手法の一つで、教師あり学習を基盤とし、2クラス分類(または二値分類)などに使用されます。
その仕組みとして、基本理論では様々なデータが分散・存在する特徴量空間において超平面を求め、超平面で仕切ることでデータを2分割し、2クラス分類を実現します。このような分類方法を線形分離と呼びます。線形分離は以下の線形識別関数で表されます。
f(x)=wTx+bf(\mathbf{x})=\mathbf{w}^T\mathbf{x}+bf(x)=wTx+b
ただし、wは係数ベクトル、xは入力ベクトル、bはバイアス項です。
さらに、tit_iti をi番目のデータが値+1を取るクラスに分類されるか、あるいは値-1を取るクラスに分類されるかを決める正解ラベルとすると、クラス分類方程式は以下のように書き表すことができます。
ti(wTxi+b)≧1t_i(\mathbf{w}^T\mathbf{x_i}+b) \geqq 1ti(wTxi+b)≧1
下図(Wikipediaより)は、超平面により白丸と黒丸の2クラスに分類を行った様子です。
2次元空間では分離面が直線になります(赤線)。3次元以上の空間では平面となるため、超平面と呼びます。また、破線と赤線との距離をマージンと呼びます。
サポートベクターマシンでは、上図のマージンを以下の式を用いて最大化することを目的とします。すなわち、マージンを最大化するには、ラグランジュ未定乗数をαi\alpha_iαi とし、以下の評価関数LLL を最大化する相対問題に置き換えることができます。
L(α)=αT1−12αTHαL(\alpha)=\alpha^T\mathbf{1}-\frac{1}{2}\alpha^TH\alphaL(α)=αT1−21αTHα
制約条件:0≦αi≦C,αTt=0制約条件:0 \leqq \alpha_i \leqq C, \quad \alpha^T\mathbf{t} = 0制約条件:0≦αi≦C,αTt=0
ここで、Cはソフトマージン識別器におけるパラメータです。
さらに、応用理論として、カーネル関数を用いた特徴量の高次元への写像を行うことで、線形分離では分離ができなかったデータを分離できるようにする方法を非線形分離と言います。
詳しくは触れませんが、カーネル関数は以下のように書き、その下の羅列のようなカーネル関数が考案されています。
K(xi,xj)... 式(1)K(\mathbf{x_i}, \mathbf{x_j}) \quad ... \; 式(1)K(xi,xj)...式(1)
- 線形カーネル
- シグモイドカーネル
- 多項式カーネル
- ガウスカーネル
- 動径基底関数(RBF)カーネル
カーネル関数による写像と非線形分離についてのイメージ図を以下に示します。
非線形分類問題においては、式(1)のカーネル関数を用いて、以下の双対問題を解く問題に帰着できます。
L(α)=∑i=1Nαi−12∑i=1N∑j=1NαiαjtitjK(xi,xj)L(\alpha) = \sum_{i=1}^{N}\alpha_i - \frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}\alpha_i\alpha_j t_i t_j K(x_i, x_j)L(α)=∑i=1Nαi−21∑i=1N∑j=1NαiαjtitjK(xi,xj)
制約条件:0≦αi≦C,αTt=0制約条件:0 \leqq \alpha_i \leqq C, \quad \alpha^T\mathbf{t} = 0制約条件:0≦αi≦C,αTt=0
評価関数Lを最大化します。
以上を応用することで、サポートベクターマシンは線形・非線形問わずクラス分類を行うことができます。
§ 量子SVMの理論と線形・非線形の分類について
量子SVMは、基本的には量子コンピュータ上で従来の機械学習の理論を用いて、同様にクラス分類を行うための理論です。
量子SVMでも、古典SVMと同じように非線形分離の場合に、カーネル関数を使用する理論が提唱されています。これについての論文は、以下からご参照下さい。
Supervised learning with quantum enhanced feature spaces
https://arxiv.org/pdf/1804.11326.pdf
量子SVMではカーネル関数を以下のように定義します。
K(xi,xj)=∣〈ϕ(xi)∣ϕ(xj)〉∣2... 式(2)K(\mathbf{x_i}, \mathbf{x_j}) = |〈\phi(x_i)|\phi(x_j)〉|^2 \quad ... \; 式(2)K(xi,xj)=∣〈ϕ(xi)∣ϕ(xj)〉∣2...式(2)
式(2)の絶対値の中身は|Φ(x)〉の内積となっています。
ここで、|Φ(x)〉は何らかの量子状態を意味し、以下のようにユニタリ発展を用いてこの状態を生成します。
U(x)∣0〉=∣ϕ(x)〉U(x)|0〉=|\phi(x)〉U(x)∣0〉=∣ϕ(x)〉
上記の仕様はQiskitにも実装されています。
Qiskitのチュートリアルで、量子SVMについては以下からご参照下さい。
量子サポート・ベクター・マシン (QSVM) [Qiskitチュートリアル]
§ 実行環境
今回の実行環境は以下です。なお、当記事執筆時点(2021/03/03)のバージョンであり、Qiskitの機能変更やバージョンアップにより環境が動作しなくなる可能性もありますのでご了承お願い致します。
- Ubuntu Server 20.04 LTS 64bit
- Qiskit
qiskit 0.23.6
qiskit-aer 0.7.5
qiskit-aqua 0.8.2
qiskit-ibmq-provider 0.11.1
qiskit-ignis 0.5.2
qiskit-terra 0.16.4
- Python 3.9.2
Qiskitについては、以下のコマンドでインストールを実行して下さい。
pip install qiskit
pip install qiskit-aqua[cvx]
§ 線形の場合の2クラス分類の実装と動作確認(AND回路)
最も簡単な線形2クラス分類の例を見てみましょう。
下図(図1.線形分離の場合)をご覧下さい。
x-y平面上に青色と赤色でクラス分けされた◆(ダイヤ)マークがあります。
ここで青色をAクラス、赤色をBクラスとします。
青色◆は座標が(0,0)で、残りの3つの赤色◆は座標がそれぞれ(0,1),(1,0),(1,1)です。
これはAND回路そのものと言えます。
真理表で表すと以下のようになります。
真理値0をAクラス、真理値1をBクラスに割り当てれば、AND回路を2クラスに分類することができます。
サポートベクターマシンを使用してこのAND回路のクラス分類を行うにはどうすれば良いでしょうか。
サポートベクターマシン理論によれば、クラス分類を行うには超平面を定義することでした。そこで、上図の破線のように超平面(2次元の場合は分離線)を求めることで分類が可能であることがわかります。AND回路は線形分離が可能な例となります。
では、Qiskitを用いて分類器を実装してみます。
1. 教師データ(訓練データ)の作成
教師データの変数名をtrain_input、正解ラベル変数名をtrain_labelとし、教師データと正解ラベルが含まれる訓練データセットを用意します。
訓練データセットはPythonの辞書型で作成します。「図1.線形分離の場合」に従い、青色をAクラス、赤色をBクラスとします。それぞれの座標から以下のように作成します。
# 教師データ
train_input = {
'A':[
[0, 0],
],
'B':[
[1, 0],
[0, 1],
[1, 1],
]
}
# 正解ラベル
train_label = {
'A':[
[0, 0],
],
'B':[
[1, 0],
[0, 1],
[1, 1],
]
}
今回はデータ数が少ないことと、辞書型で作成する必要があるため、train_input及びtrain_labelは同じ内容となっています。
2. テストデータの作成
テストデータは配列型を用意します。
今回はx-y平面上の4点の教師データを学習した上で、改めてこれら4点のテストを行うため、テストデータは4つです。
具体的には以下とします。
# テストデータ
test_input = [
[0, 0],
[1, 0],
[0, 1],
[1, 1],
]
3. QSVMのプログラミングと実行
QSVMの主計算部分のプログラミングは以下となります。
from qiskit.circuit.library import ZZFeatureMap
from qiskit import BasicAer
from qiskit.aqua.algorithms import QSVM
from qiskit.aqua import QuantumInstance
random_seed = 10598
shots = 1024
backend = BasicAer.get_backend('qasm_simulator') # s1
feature_map = ZZFeatureMap(feature_dimension=2, reps=2)
qsvm = QSVM(feature_map, train_input, train_label, test_input) # s2
qsvm.random_seed = random_seed
quantum_instance = QuantumInstance(backend, shots=shots, seed_simulator=random_seed, seed_transpiler=random_seed)
result = qsvm.run(quantum_instance) # s3
print('正解率', result['testing_accuracy'])
print('クラス分類結果', result['predicted_classes'])
要点のみ解説します。
s1
量子コンピュータとして、qasmシミュレータを設定します。
s2
QSVMを定義します。入力データとして、train_input, train_label, test_inputを設定します。
s3
実際に計算を実行する部分です。
データが少ないため、処理の実行時間は瞬時に実行されました。
4. 結果の確認
処理結果を確認します。
処理結果はresult変数に格納されます。ここでは、正解率とテストデータのクラス分類結果を表示しました。
正解率1.0、つまり100%で正解することができました。
また、クラスの分類結果についても、想定通りのクラスに分類できたことがわかります。
以上から線形の場合の2クラス分類の動作確認を取ることができました。
続いて、非線形の場合の動作確認を行います。
§ 非線形の場合の2クラス分類の実装と動作確認(XOR回路)
AND回路は線形分離が可能な例でしたが、ここでは線形分離が不可能な例を見てみます。
下図(図2.非線形分離の場合)をご覧下さい。
x-y平面のクラス分け状況を見てみると、
青色◆は2つあり、それぞれの座標は(0,0),(1,1)となっています。
また、赤色◆も2つで、それぞれの座標は(1,0),(0,1)です。
これはXOR回路となります。
真理表で表すと以下のようになります。
先程と同様に、真理値0をAクラス、真理値1をBクラスに割り当てます。
図を見てわかる通り、直線で2クラスに分類することはできません。図の破線(分離線)ように曲線を用いないと2クラスに分類することが不可能です。
このように、XOR回路は線形分離が不可能な例となります。
では、量子SVMでこのような非線形の分類が可能なのか、実装して動作確認してみます。
1. 教師データ(訓練データ)の作成
線形の場合と同様に、教師データの変数名をtrain_input、正解ラベル変数名をtrain_labelとし、教師データと正解ラベルが含まれる訓練データセットを用意します。
訓練データセットはPythonの辞書型で作成します。「図2.非線形分離の場合」に従い、青色をAクラス、赤色をBクラスとします。それぞれの座標から以下のように作成します。
# 教師データ
train_input = {
'A':[
[0, 0],
[1, 1],
],
'B':[
[1, 0],
[0, 1],
]
}
# 正解ラベル
train_label = {
'A':[
[0, 0],
[1, 1],
],
'B':[
[1, 0],
[0, 1],
]
}
同様の理由で、辞書型で作成する必要があるため、train_input及びtrain_labelは同じ内容となっています。
2. テストデータの作成
# テストデータ
test_input = [
[0, 0],
[1, 0],
[0, 1],
[1, 1],
]
3. QSVMのプログラミングと実行
プログラムは線形の場合と同じ内容になります。
線形の場合は想定通り正解を得られましたが、非線形の場合も想定通り結果が得られるかどうかを確認します。
4. 結果の確認
処理結果は以下となりました。
こちらも正解率1.0、つまり100%で正解することができました。
また、クラスの分類結果についても、想定通りのクラス分類ができました。
以上から線形の場合と非線形の場合のどちらにおいても、2クラス分類の動作確認を取ることができました。