# 1.パッケージのインストールやライブラリのインポート { display-mode: "form" }
# TYTANパッケージをインストール
!pip install -U git+https://github.com/tytansdk/tytan
from tytan import *
import numpy as np
import pandas as pd
from sklearn import datasets # サンプルデータセット
from sklearn.model_selection import train_test_split # データ分割用
from matplotlib import pyplot as plt # グラフ描画用
from sklearn.tree import DecisionTreeClassifier as DTC # 決定木
from sklearn.tree import plot_tree # 決定木の可視化
from sklearn.metrics import accuracy_score # 精度計算用
from sklearn import metrics # 精度計算用
# Titanicデータセットを取得
# X: 性別、年齢などのデータ y: 正解データ
# Data obtained from http://hbiostat.org/data courtesy of the Vanderbilt University Department of Biostatistics.
# X, y = datasets.fetch_openml(data_id=40945, return_X_y=True, as_frame=True)
df = pd.read_csv('https://hbiostat.org/data/repo/titanic3.csv')
X = df.drop(columns='survived')
y = df['survived']
# データの確認
X # 性別、年齢などのデータ
y # 正解データ 1: 生還 0: 死亡
# 前処理
# データがないところを中央値などで埋める
X["age"] = X["age"].fillna(X["age"].median())
X["fare"] = X["fare"].fillna(X["fare"].median())
X["embarked"] = X["embarked"].fillna("S")
X["sex"] = pd.get_dummies(X["sex"], drop_first=True)
X = pd.concat([X, pd.get_dummies(X["embarked"], prefix="embarked")], axis=1).drop(columns=["embarked"])
# 今回使わないデータを削除
feature_columns =["name", "sibsp", "parch", "ticket","fare", "cabin", "boat", "body", "home.dest"]
X = X.drop(columns=feature_columns, axis=1)
print(X.columns)
X = X.values
y = y.values
y = y.astype(int)
# 正解値を平均値計算の都合により {0, 1}から{-1, 1}に変換
y = (y - 0.5) * 2
X # 性別、年齢などのデータ
y # 正解データ 1: 生還 -1: 死亡
seed=0
np.random.seed(seed)
# データを学習用とテスト用に7:3に分割
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=seed)
print("X: ", X.shape, X.dtype)
print("y: ", y.shape, y.dtype)
print("train_X: ", train_X.shape, train_X.dtype)
print("train_y: ", train_y.shape, train_y.dtype)
print("test_X: ", test_X.shape, test_X.dtype)
print("test_y: ", test_y.shape, test_y.dtype)
# パラメータ設定
param_lambda = 3 # 正則化調整パラメータ
num_random = 100 # ランダムデータの数
num_learner = 100 # 学習器の数
# 決定木の深さを指定してモデルを構築
models = [DTC(max_depth=3) for i in range(num_learner)]
y_pred_list_train = []
y_pred_list_test = []
for model in models:
# データをランダムに抽出
train_idx = np.random.choice(np.arange(train_X.shape[0]), num_random)
# 決定木作成
model.fit(X=train_X[train_idx], y=train_y[train_idx])
# 予測
y_pred_list_train.append(model.predict(train_X))
y_pred_list_test.append(model.predict(test_X))
y_pred_list_train = np.asanyarray(y_pred_list_train)
y_pred_list_test = np.array(y_pred_list_test)
# 決定木の可視化(代表で1つ)
plt.figure(figsize=(10, 7))
plot_tree(models[0], filled=True, class_names=['Class 0', 'Class 1'])
plt.show()
# 予測、精度確認
# 多数決で正解値を決定(重みはすべて1)
y_pred_test = np.sign(np.sum(y_pred_list_test.astype(int), axis=0))
# 予測結果の精度のスコア計算
acc_test_base = metrics.accuracy_score(y_true=test_y, y_pred=y_pred_test)
print("Base Model: {}".format(acc_test_base))
# 2.ルールの式(QUBO形式)を書く { display-mode: "form" }
# 学習器の数分、量子ビットを用意
q = symbols_list(num_learner, 'q{}')
#+++++++++++++++++++++++++++++++++
# QBoostの定式化
#+++++++++++++++++++++++++++++++++
# 初期化
H_clf = 0
H_norm = 0
H = 0
for i in range(len(train_y)):
temp_sum = 0
for j in range(len(q)):
temp_sum += q[j] * y_pred_list_train[j, i]
temp_sum = (1/num_learner * temp_sum - train_y[i]) ** 2
H_clf += temp_sum
# 正則化項
for j in range(len(q)):
H_norm += q[j]
H = H_clf + param_lambda * H_norm
# 3.TYTANを使ったコンパイルとサンプリング { display-mode: "form" }
qubo, offset = Compile(H).get_qubo()
# solver = sampler.SASampler(seed=0)
solver = sampler.ArminSampler(seed=1)
result = solver.run(qubo, shots=100)
for r in result:
print(r)
# 4.結果の表示 { display-mode: "form" }
accs_train = []
accs_test = []
decoded_solutions = np.array([record[0] for record in np.array(result)])
for decoded_solution in decoded_solutions:
idx_clf = []
for key, val in decoded_solution.items():
if val == 1:
idx = int(key.split('q')[1].split(']')[0])
idx_clf.append(idx)
np.set_printoptions(threshold=np.inf)
# 重み付き多数決(アンサンブル)
y_pred_train = np.sign(np.sum(y_pred_list_train[idx_clf, :], axis=0))
y_pred_test = np.sign(np.sum(y_pred_list_test[idx_clf, :], axis=0))
acc_train = metrics.accuracy_score(y_true=train_y, y_pred=y_pred_train)
acc_test = metrics.accuracy_score(y_true=test_y, y_pred=y_pred_test)
accs_train.append(acc_train)
accs_test.append(acc_test)
# ベースとなるモデルとQBoostの精度を確認
print("Base Model: {}".format(acc_test_base))
print("QBoost : {}".format(max(accs_test)))
accs_test