import torch import torch.nn as nn import torch.optim as optim import numpy as np import pandas as pd from sklearn.utils.multiclass import unique_labels from matplotlib import pyplot as plt from sklearn.metrics import * class Net(nn.Module): def __init__(self, input_shape): super().__init__() self.fc1 = nn.Linear(input_shape, 8) self.fc2 = nn.Linear(8, 4) def forward(self, x): x = torch.sigmoid(self.fc1(x)) return self.fc2(x) def get_argmax(array): max = 0 index = 0 for i in range(len(array)): if array[i] > max: max = array[i] index = i one_hot = [0, 0, 0, 0] one_hot[index] = 1 return one_hot def plot_confusion_matrix(y_true, y_pred, classes, cmap=plt.cm.Blues): """ This function prints and plots the confusion matrix. Normalization can be applied by setting `normalize=True`. """ title = "Confusion Matrix" # Compute confusion matrix cm = confusion_matrix(y_true, y_pred) # Only use the labels that appear in the data classes = classes[unique_labels(y_true, y_pred)] print(cm) fig, ax = plt.subplots() im = ax.imshow(cm, interpolation='nearest', cmap=cmap) ax.figure.colorbar(im, ax=ax) # We want to show all ticks... ax.set(xticks=np.arange(cm.shape[1]), yticks=np.arange(cm.shape[0]), # ... and label them with the respective list entries xticklabels=classes, yticklabels=classes, title=title, ylabel='True label', xlabel='Predicted label') # Rotate the tick labels and set their alignment. plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor") # Loop over data dimensions and create text annotations. fmt = '.2f' if normalize else 'd' thresh = cm.max() / 2. for i in range(cm.shape[0]): for j in range(cm.shape[1]): ax.text(j, i, format(cm[i, j], fmt), ha="center", va="center", color="white" if cm[i, j] > thresh else "black") fig.tight_layout() return ax def get_trainset(batch_size, dataset, k, n0, x_columns, y_columns): inp = dataset[x_columns] out = dataset[y_columns] col = "day" x = [] y = [] input_shape = 0 output_shape = 0 for player in out["playerID"].unique(): XPlayer = inp[inp["playerID"] == player] YPlayer = out[out["playerID"] == player] for day in YPlayer[col][n0 - 1:]: prev = day - k xprev = XPlayer[XPlayer[col] == prev].drop(columns=[col, "playerID"]).to_numpy() if xprev.shape[0] != 1: continue else: xprev = xprev[0, :] yt = YPlayer[YPlayer[col] == day].drop(columns=[col, "playerID"]).to_numpy()[0, :] if input_shape == 0: input_shape = xprev.shape[0] else: if input_shape != xprev.shape[0]: print("INCONSISTENT INPUT DIMENSION") exit(2) if output_shape == 0: output_shape = yt.shape[0] else: if output_shape != yt.shape[0]: print("INCONSISTENT OUTPUT DIMENSION") exit(2) x.append(xprev) y.append(yt) randn_1 = np.random.randint(1, 5200) x = torch.FloatTensor(x) y = torch.LongTensor(y) if batch_size: x = x.narrow(0, randn_1, 125) y = y.narrow(0, randn_1, 125) return x, y def time_series_sigmoid_classification(steps, dataset, k, n0, x_columns, y_columns, labels): net = Net(4) optimizer = optim.Adam(net.parameters(), lr=.03) loss = nn.CrossEntropyLoss() x, y = get_trainset(False, dataset, k, n0, x_columns, y_columns) accuracy(net, x, y) for step in range(steps): optimizer.zero_grad() x, y = get_trainset(True, dataset, k, n0, x_columns, y_columns) pred = net(x) net_loss = loss(pred, torch.max(y, 1)[1]) net_loss.backward() optimizer.step() print("Loss at Step {}: {}".format(step, net_loss)) x, y = get_trainset(False, dataset, k, n0, x_columns, y_columns) accuracy(net, x, y) def accuracy(net, x, y): pred = net(x) pred = pred.detach().numpy() for row in range(len(pred)): pred[row] = get_argmax(pred[row]) total = len(pred) correct = 0 for i in range(len(pred)): equal = True for j in range(len(pred[i])): if pred[i][j] != y[i][j]: equal = False if equal: correct += 1 accuracy = (correct / total) * 100 print("Accuracy for set: {}%".format(accuracy)) torch.save(net, "model_higher_lr.ckpt") return pred, y def cm_plot(classes, dataset, k, n0, x_columns, y_columns): model = torch.load('model.ckpt') x, y = get_trainset(True, dataset, k, n0, x_columns, y_columns) pred = model(x) pred = pred.detach().numpy() for row in range(len(pred)): pred[row] = get_argmax(pred[row]) print('F1: {}'.format(f1_score(y, pred > .5, average='micro'))) plot_confusion_matrix(y, pred, classes) def main(): filename = "personal.csv" df = pd.read_csv(filename) x = ["day", "playerID", "fatigueSliding", "fatigueNorm", "sleepHoursSliding", "sleepQuality"] y = ["day", "playerID", "BestOutOfMyselfAbsolutely", "BestOutOfMyselfSomewhat", "BestOutOfMyselfNotAtAll", "BestOutOfMyselfUnknown"] # time_series_sigmoid_classification(50, df, 0, 30, x, y, y) cm_plot( ["BestOutOfMyselfAbsolutely", "BestOutOfMyselfSomewhat", "BestOutOfMyselfNotAtAll", "BestOutOfMyselfUnknown"], df, 0, 30, x, y) if __name__ == '__main__': main()