from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute
from qiskit import Aer
from qiskit.aqua.utils import split_dataset_to_data_and_labels
from qiskit.tools.visualization import plot_bloch_multivector
from qiskit.aqua import QuantumInstance
from qiskit.aqua.algorithms import QSVM
from qiskit.circuit.library import ZZFeatureMap

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn.svm import SVC
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.decomposition import PCA

Titanic_DF = pd.read_csv('titanic.csv')
Titanic_DF = Titanic_DF.drop(['PassengerId','Name','Cabin','Ticket'],axis=1)

lb_make = preprocessing.LabelEncoder()
Titanic_DF['Sex'] = lb_make.fit_transform(Titanic_DF['Sex'])
Titanic_DF['Embarked'] = lb_make.fit_transform(Titanic_DF['Embarked'])

le_name_mapping = dict(zip(lb_make.classes_, lb_make.transform(lb_make.classes_)))

pd.DataFrame(Titanic_DF).fillna(inplace=True, method='backfill')

FeatureNames = [x for x in list(Titanic_DF.columns) if x not in ['Name','Survived']]
Data = Titanic_DF[FeatureNames].values
Labels = Titanic_DF['Survived'].values

Titanic_DF.info()

Titanic_DF

feature_dim=2
class_labels = [r'0', r'1']

sample_train, sample_test, label_train, label_test = train_test_split(Data, Labels, test_size=0.3, random_state=12)

std_scale = StandardScaler().fit(sample_train, label_train)
sample_train = std_scale.transform(sample_train)
sample_test = std_scale.transform(sample_test)

pca = PCA(n_components=feature_dim).fit(sample_train)
sample_train = pca.transform(sample_train)
sample_test = pca.transform(sample_test)

samples = np.append(sample_train, sample_test, axis=0)
minmax_scale = MinMaxScaler((-1, 1)).fit(samples)
sample_train = minmax_scale.transform(sample_train)
sample_test = minmax_scale.transform(sample_test)

sample_test

def QuantumFormat(sample_train, sample_test, label_train, label_test, training_size, test_size, class_labels):
    training_input = {key: (sample_train[label_train == k, :])[:training_size] for k, key in enumerate(class_labels)}
    test_input = {key: (sample_test[label_test == k, :])[:test_size] for k, key in enumerate(class_labels)}
    return training_input, test_input

training_input, test_input = QuantumFormat(sample_train, sample_test, label_train, label_test, 10, 10, class_labels)
datapoints, class_to_label = split_dataset_to_data_and_labels(test_input)

training_input, test_input


# QSVM
feature_map = ZZFeatureMap(feature_dimension=feature_dim, reps=2, entanglement='linear')
qsvm = QSVM(feature_map, training_input, test_input, None)
backend = Aer.get_backend('qasm_simulator')
quantum_instance = QuantumInstance(backend, shots=1024)
result = qsvm.run(quantum_instance)
print("kernel matrix during the training:")
kernel_matrix = result['kernel_matrix_training']
img = plt.imshow(np.asmatrix(kernel_matrix),interpolation='nearest',origin='upper',cmap='bone_r')
plt.show()


# Classical SVM
svc = SVC(probability=True, gamma='auto')
svc.fit(sample_train, label_train)
kernel_matrix2=sklearn.metrics.pairwise.rbf_kernel(sample_train, sample_train)
img = plt.imshow(np.asmatrix(kernel_matrix2[0:10,0:10]),interpolation='nearest',origin='upper',cmap='bone_r')
plt.show()

# Error Rate
label_predict=svc.predict(sample_test)
print('Error rate: ' + str(sum(label_predict==label_test)/len(label_predict)))

