import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier


def abs_sum(y_true, y_pred):
    return sum(sum(abs(y_true - y_pred)))


def convert_to_prob(y):
    y_prob = []
    for label in y:
        row = []
        for i in range(4):
            if i == label:
                row.append(1)
            else:
                row.append(0)
        y_prob.append(row)
    return np.array(y_prob)


if __name__ == '__main__':
    df = pd.read_csv('data/train.csv')
    df_list = []
    for items in df.values:
        df_list.append([items[0]] + [float(i) for i in items[1].split(',')] + [items[2]])

    df = pd.DataFrame(np.array(df_list))
    df.columns = ['id'] + ['signal_'+str(i) for i in range(len(df_list[0])-2)] + ['label']

    x = df.drop(['id', 'label'], axis=1).to_numpy()
    y = df['label'].to_numpy()

    pca = PCA(n_components=0.95)
    x = pca.fit_transform(x)

    test_set_size = 0.1
    X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=test_set_size, random_state=3)

    knn = KNeighborsClassifier(n_neighbors=1, weights='distance').fit(X_train, y_train)
    y_pred_prob = knn.predict_proba(X_test)
    y_true_prob = convert_to_prob(y_test)
    loss = abs_sum(y_pred_prob, y_true_prob)
    print(loss)
