{ "cells": [ { "cell_type": "markdown", "id": "ae397d48", "metadata": {}, "source": [ "# Constants" ] }, { "cell_type": "code", "execution_count": 1, "id": "3827a09b", "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true' # this is required\n", "os.environ['CUDA_VISIBLE_DEVICES'] = '1' # set to '0' for GPU0, '1' for GPU1 or '2' for GPU2. Check \"gpustat\" in a terminal." ] }, { "cell_type": "code", "execution_count": 2, "id": "654f2682", "metadata": {}, "outputs": [], "source": [ "glob_path = '/opt/iui-datarelease3-sose2021/*.csv'\n", "\n", "pickle_file = '../data.pickle'\n", "\n", "cenario = 'SYY'\n", "\n", "win_sz = 50\n", "stride_sz = 25 " ] }, { "cell_type": "code", "execution_count": 3, "id": "6cc88c90", "metadata": {}, "outputs": [], "source": [ "from matplotlib import pyplot as plt\n", "\n", "def pplot(dd):\n", " x = dd.shape[0]\n", " fix = int(x/3)+1\n", " fiy = 3\n", " fig, axs = plt.subplots(fix, fiy, figsize=(3*fiy, 9*fix))\n", " \n", " for i in range(x):\n", " axs[int(i/3)][i%3].plot(dd[i])" ] }, { "cell_type": "markdown", "id": "3c47f127", "metadata": {}, "source": [ "# Loading Data" ] }, { "cell_type": "code", "execution_count": 4, "id": "9dc8d47e", "metadata": { "tags": [] }, "outputs": [], "source": [ "from glob import glob\n", "import pandas as pd\n", "from tqdm import tqdm\n", "\n", "def dl_from_blob(filename, user_filter=None):\n", " \n", " dic_data = []\n", " \n", " for p in tqdm(glob(glob_path)):\n", " path = p\n", " filename = path.split('/')[-1].split('.')[0]\n", " splitname = filename.split('_')\n", " user = int(splitname[0][1:])\n", " if (user_filter):\n", " if (user != user_filter):\n", " continue\n", " scenario = splitname[1][len('Scenario'):]\n", " heightnorm = splitname[2][len('HeightNormalization'):] == 'True'\n", " armnorm = splitname[3][len('ArmNormalization'):] == 'True'\n", " rep = int(splitname[4][len('Repetition'):])\n", " session = int(splitname[5][len('Session'):])\n", " data = pd.read_csv(path)\n", " dic_data.append(\n", " {\n", " 'filename': path,\n", " 'user': user,\n", " 'scenario': scenario,\n", " 'heightnorm': heightnorm,\n", " 'armnorm': armnorm,\n", " 'rep': rep,\n", " 'session': session,\n", " 'data': data \n", " }\n", " )\n", " return dic_data" ] }, { "cell_type": "code", "execution_count": 5, "id": "1294685f", "metadata": {}, "outputs": [], "source": [ "import pickle\n", "\n", "def save_pickle(f, structure):\n", " _p = open(f, 'wb')\n", " pickle.dump(structure, _p)\n", " _p.close()" ] }, { "cell_type": "code", "execution_count": 6, "id": "5e418dc4", "metadata": {}, "outputs": [], "source": [ "def load_pickles(f) -> list:\n", " _p = open(pickle_file, 'rb')\n", " _d = pickle.load(_p)\n", " _p.close()\n", " \n", " return _d" ] }, { "cell_type": "code", "execution_count": 7, "id": "7938c466", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading data...\n", "../data.pickle found...\n", "768\n", "CPU times: user 615 ms, sys: 2.24 s, total: 2.85 s\n", "Wall time: 2.85 s\n" ] } ], "source": [ "%%time\n", "\n", "def load_data() -> list:\n", " if os.path.isfile(pickle_file):\n", " print(f'{pickle_file} found...')\n", " return load_pickles(pickle_file)\n", " print(f'Didn\\'t find {pickle_file}...')\n", " all_data = dl_from_blob(glob_path)\n", " print(f'Creating {pickle_file}...')\n", " save_pickle(pickle_file, all_data)\n", " return all_data\n", "\n", "print(\"Loading data...\")\n", "dic_data = load_data()\n", "print(len(dic_data))" ] }, { "cell_type": "code", "execution_count": 8, "id": "e3f38b64", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Categorized Data\n", "cdata = dict() \n", "# Sorting, HeightNorm, ArmNorm\n", "cdata['SYY'] = list() \n", "cdata['SYN'] = list() \n", "cdata['SNY'] = list() \n", "cdata['SNN'] = list() \n", "\n", "# Jenga, HeightNorm, ArmNorm\n", "cdata['JYY'] = list() \n", "cdata['JYN'] = list() \n", "cdata['JNY'] = list() \n", "cdata['JNN'] = list() \n", "for d in dic_data:\n", " if d['scenario'] == 'Sorting':\n", " if d['heightnorm']:\n", " if d['armnorm']:\n", " cdata['SYY'].append(d)\n", " else:\n", " cdata['SYN'].append(d)\n", " else:\n", " if d['armnorm']:\n", " cdata['SNY'].append(d)\n", " else:\n", " cdata['SNN'].append(d)\n", " elif d['scenario'] == 'Jenga':\n", " if d['heightnorm']:\n", " if d['armnorm']:\n", " cdata['JYY'].append(d)\n", " else:\n", " cdata['JYN'].append(d)\n", " else:\n", " if d['armnorm']:\n", " cdata['JNY'].append(d)\n", " else:\n", " cdata['JNN'].append(d)\n", "\n", "# for k,v in cdata.items():\n", "# print(k,': ',len(v))\n", "# test_entry = pickle.loads(pickle.dumps(cdata['SYY'][17]))\n", "# test_entry['data']" ] }, { "cell_type": "markdown", "id": "83953c92", "metadata": {}, "source": [ "# Preprocessing" ] }, { "cell_type": "code", "execution_count": 9, "id": "583e8c34", "metadata": { "tags": [] }, "outputs": [], "source": [ "def drop(entry) -> pd.DataFrame:\n", " droptable = ['participantID', 'FrameID', 'Scenario', 'HeightNormalization', 'ArmNormalization', 'Repetition', 'Session', 'Unnamed: 0']\n", " centry = pickle.loads(pickle.dumps(entry))\n", " return centry['data'].drop(droptable, axis=1)" ] }, { "cell_type": "code", "execution_count": 10, "id": "b8a05286", "metadata": { "tags": [] }, "outputs": [], "source": [ "def floatize(entry) -> pd.DataFrame:\n", " centry = pickle.loads(pickle.dumps(entry))\n", " centry['data']['LeftHandTrackingAccuracy'] = (entry['data']['LeftHandTrackingAccuracy'] == 'High') * 1.0\n", " centry['data']['RightHandTrackingAccuracy'] = (entry['data']['RightHandTrackingAccuracy'] == 'High') * 1.0\n", " return centry['data']" ] }, { "cell_type": "code", "execution_count": 11, "id": "fbe90e8d", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "right_Hand_ident='right_Hand'\n", "left_Hand_ident='left_hand'\n", "\n", "def rem_low_acc(entry) -> pd.DataFrame:\n", " centry = pickle.loads(pickle.dumps(entry))\n", " right_Hand_cols = [c for c in centry['data'] if right_Hand_ident in c]\n", " left_Hand_cols = [c for c in centry['data'] if left_Hand_ident in c]\n", " \n", " centry['data'].loc[centry['data']['RightHandTrackingAccuracy'] == 0.0, right_Hand_cols] = np.nan\n", " centry['data'].loc[centry['data']['LeftHandTrackingAccuracy'] == 0.0, left_Hand_cols] = np.nan\n", " return centry['data']" ] }, { "cell_type": "code", "execution_count": 12, "id": "26059dd4", "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", "\n", "stride = 150\n", "def pad(entry) -> pd.DataFrame:\n", " centry = pickle.loads(pickle.dumps(entry))\n", " cols = centry['data'].columns\n", " pentry = pad_sequences(centry['data'].T.to_numpy(),\n", " maxlen=(int(centry['data'].shape[0]/stride)+1)*stride,\n", " dtype='float64',\n", " padding='pre', \n", " truncating='post',\n", " value=np.nan\n", " ) \n", " pdentry = pd.DataFrame(pentry.T, columns=cols)\n", " pdentry.loc[0] = [0 for _ in cols]\n", " return pdentry" ] }, { "cell_type": "code", "execution_count": 13, "id": "2f2181f0", "metadata": {}, "outputs": [], "source": [ "def interpol(entry) -> pd.DataFrame:\n", " centry = pickle.loads(pickle.dumps(entry))\n", " return centry['data'].interpolate(method='linear', axis=0)" ] }, { "cell_type": "code", "execution_count": 14, "id": "276ecf82", "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.preprocessing import timeseries_dataset_from_array\n", "\n", "def slicing(entry):\n", " centry = pickle.loads(pickle.dumps(entry))\n", " return timeseries_dataset_from_array(\n", " data=centry['data'], \n", " targets=[centry['user'] for _ in range(centry['data'].shape[0])], \n", " sequence_length=win_sz,\n", " sequence_stride=stride_sz, \n", " batch_size=8, \n", " seed=177013\n", " )" ] }, { "cell_type": "code", "execution_count": 15, "id": "dab70ad9", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 96/96 [00:15<00:00, 6.14it/s]\n" ] } ], "source": [ "classes = 16 # dynamic\n", "\n", "def preproc(data):\n", " res_list = list()\n", " \n", " for e in tqdm(data):\n", " res_list.append(preproc_entry(e))\n", " \n", " return res_list\n", " \n", "def preproc_entry(entry):\n", " entry2 = pickle.loads(pickle.dumps(entry))\n", " entry2['data'] = drop(entry2)\n", " \n", " entry3 = pickle.loads(pickle.dumps(entry2))\n", " entry3['data'] = floatize(entry3)\n", " \n", " entry4 = pickle.loads(pickle.dumps(entry3))\n", " entry4['data'] = rem_low_acc(entry4)\n", " \n", " entry5 = pickle.loads(pickle.dumps(entry4))\n", " entry5['data'] = pad(entry5)\n", " \n", " entry6 = pickle.loads(pickle.dumps(entry5))\n", " entry6['data'] = interpol(entry6)\n", " \n", " entry7 = pickle.loads(pickle.dumps(entry6))\n", " entry7['data'] = slicing(entry7)\n", " \n", " return entry7\n", "\n", "pdata = preproc(cdata[cenario])" ] }, { "cell_type": "markdown", "id": "ddba89b9", "metadata": {}, "source": [ "# Building Model" ] }, { "cell_type": "code", "execution_count": 16, "id": "61c34fed", "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf\n", "from tensorflow.keras.models import Sequential\n", "from tensorflow.keras.layers import Dense, Flatten, BatchNormalization, Dropout, Conv2D, MaxPooling2D\n", "\n", "def build_model(train):\n", " s = train[0].shape\n", "\n", " model = Sequential()\n", " ncount = s[0]*s[1]\n", " \n", " model.add(Flatten(input_shape=s))\n", " \n", " model.add(BatchNormalization())\n", " \n", " model.add(Dropout(0.1))\n", " \n", " for i in range(1,6):\n", " model.add(Dense(int(ncount/pow(3,i)), activation='relu'))\n", " model.add(Dropout(0.1))\n", " \n", " model.add(Dense(classes, activation='softmax'))\n", "\n", " model.compile(\n", " optimizer=tf.keras.optimizers.Adam(0.001),\n", " loss=\"categorical_crossentropy\", \n", " metrics=[\"acc\"],\n", " )\n", "\n", " return model" ] }, { "cell_type": "code", "execution_count": 17, "id": "47058299", "metadata": {}, "outputs": [], "source": [ "checkpoint_file = './goat.weights'\n", "\n", "def train_model(X_train, y_train):\n", " model = build_model(X_train)\n", " \n", " model.summary()\n", "\n", " history = model.fit(X_train, \n", " y_train,\n", " epochs=30,\n", " batch_size=128,\n", " shuffle=True,\n", " verbose=0,\n", " )\n", " return model, history" ] }, { "cell_type": "code", "execution_count": 18, "id": "6c99e0bc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(48, 48)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import LabelEncoder, LabelBinarizer\n", "\n", "train = np.array([x['data'] for x in pdata if x['session'] == 1])\n", "test = np.array([x['data'] for x in pdata if x['session'] == 2])\n", "\n", "len(train), len(test)" ] }, { "cell_type": "code", "execution_count": 19, "id": "727b89e0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 8.86 s, sys: 3.63 s, total: 12.5 s\n", "Wall time: 4.7 s\n" ] } ], "source": [ "%%time\n", "X_train = list()\n", "y_train = list()\n", "\n", "train = list()\n", "test = list()\n", "\n", "for x in pdata:\n", " if x['session'] == 1:\n", " train.append(\n", " {\n", " 'label': x['user'],\n", " 'data': list()\n", " })\n", " for y in x['data'].unbatch().as_numpy_iterator():\n", " X_train.append(y[0])\n", " y_train.append(y[1])\n", " \n", " train[-1]['data'].append(y[0])\n", " if x['session'] == 2:\n", " test.append(\n", " {\n", " 'label': x['user'],\n", " 'data': list()\n", " })\n", " for y in x['data'].unbatch().as_numpy_iterator():\n", " test[-1]['data'].append(y[0])\n", "\n", "X_train = np.array(X_train)\n", "y_train = np.array(y_train)" ] }, { "cell_type": "code", "execution_count": 20, "id": "ba64dca4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(5832, 50, 338)\n", "(5832, 16)\n" ] } ], "source": [ "lb = LabelBinarizer()\n", "yy_train = lb.fit_transform(y_train)\n", "\n", "for e in test:\n", " e['label'] = lb.transform([e['label']])\n", " e['data'] = np.array(e['data'])\n", " \n", "for e in train:\n", " e['label'] = lb.transform([e['label']])\n", " e['data'] = np.array(e['data'])\n", "\n", "print(X_train.shape)\n", "print(yy_train.shape)\n" ] }, { "cell_type": "code", "execution_count": 21, "id": "399176de", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 4: 53 (53, 50, 338)\n", "14: 35 (35, 50, 338)\n", "12: 65 (65, 50, 338)\n", " 8: 149 (149, 50, 338)\n", " 1: 53 (53, 50, 338)\n", " 3: 107 (107, 50, 338)\n", "11: 53 (53, 50, 338)\n", " 3: 125 (125, 50, 338)\n", " 1: 41 (41, 50, 338)\n", "13: 71 (71, 50, 338)\n", "15: 59 (59, 50, 338)\n", " 3: 77 (77, 50, 338)\n", "10: 119 (119, 50, 338)\n", " 6: 47 (47, 50, 338)\n", "14: 41 (41, 50, 338)\n", " 5: 167 (167, 50, 338)\n", " 8: 89 (89, 50, 338)\n", "14: 41 (41, 50, 338)\n", " 9: 71 (71, 50, 338)\n", "10: 77 (77, 50, 338)\n", " 8: 77 (77, 50, 338)\n", "16: 77 (77, 50, 338)\n", "16: 77 (77, 50, 338)\n", " 2: 59 (59, 50, 338)\n", " 9: 77 (77, 50, 338)\n", "15: 77 (77, 50, 338)\n", " 5: 101 (101, 50, 338)\n", "16: 71 (71, 50, 338)\n", "15: 71 (71, 50, 338)\n", "12: 95 (95, 50, 338)\n", " 6: 71 (71, 50, 338)\n", " 2: 53 (53, 50, 338)\n", "12: 845 (845, 50, 338)\n", " 7: 65 (65, 50, 338)\n", " 2: 65 (65, 50, 338)\n", "13: 95 (95, 50, 338)\n", " 5: 125 (125, 50, 338)\n", "11: 65 (65, 50, 338)\n", " 7: 59 (59, 50, 338)\n", "10: 77 (77, 50, 338)\n", " 6: 59 (59, 50, 338)\n", " 7: 53 (53, 50, 338)\n", " 1: 101 (101, 50, 338)\n", "13: 71 (71, 50, 338)\n", "11: 59 (59, 50, 338)\n", " 4: 77 (77, 50, 338)\n", " 9: 29 (29, 50, 338)\n", " 4: 107 (107, 50, 338)\n" ] } ], "source": [ "for e in test:\n", " print(f\"{lb.inverse_transform(e['label'])[0]:2d}: {len(e['data']):3d} {e['data'].shape}\")" ] }, { "cell_type": "code", "execution_count": 22, "id": "75af2444", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model: \"sequential\"\n", "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "flatten (Flatten) (None, 16900) 0 \n", "_________________________________________________________________\n", "batch_normalization (BatchNo (None, 16900) 67600 \n", "_________________________________________________________________\n", "dropout (Dropout) (None, 16900) 0 \n", "_________________________________________________________________\n", "dense (Dense) (None, 5633) 95203333 \n", "_________________________________________________________________\n", "dropout_1 (Dropout) (None, 5633) 0 \n", "_________________________________________________________________\n", "dense_1 (Dense) (None, 1877) 10575018 \n", "_________________________________________________________________\n", "dropout_2 (Dropout) (None, 1877) 0 \n", "_________________________________________________________________\n", "dense_2 (Dense) (None, 625) 1173750 \n", "_________________________________________________________________\n", "dropout_3 (Dropout) (None, 625) 0 \n", "_________________________________________________________________\n", "dense_3 (Dense) (None, 208) 130208 \n", "_________________________________________________________________\n", "dropout_4 (Dropout) (None, 208) 0 \n", "_________________________________________________________________\n", "dense_4 (Dense) (None, 69) 14421 \n", "_________________________________________________________________\n", "dropout_5 (Dropout) (None, 69) 0 \n", "_________________________________________________________________\n", "dense_5 (Dense) (None, 16) 1120 \n", "=================================================================\n", "Total params: 107,165,450\n", "Trainable params: 107,131,650\n", "Non-trainable params: 33,800\n", "_________________________________________________________________\n", "CPU times: user 32.2 s, sys: 9.61 s, total: 41.8 s\n", "Wall time: 18 s\n" ] } ], "source": [ "%%time\n", "model, history = train_model(np.array(X_train), np.array(yy_train))" ] }, { "cell_type": "code", "execution_count": 23, "id": "1a63ecda", "metadata": {}, "outputs": [], "source": [ "def predict(model, entry):\n", " p_dict = dict()\n", " predictions = model.predict_classes(entry['data'])\n", " \n", " for p in predictions:\n", " if p in p_dict:\n", " p_dict[p] += 1\n", " else:\n", " p_dict[p] = 1\n", " prediction = max(p_dict, key=p_dict.get)\n", " return prediction\n" ] }, { "cell_type": "code", "execution_count": 24, "id": "aae03bc6", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/opt/jupyterhub/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py:455: UserWarning: `model.predict_classes()` is deprecated and will be removed after 2021-01-01. Please use instead:* `np.argmax(model.predict(x), axis=-1)`, if your model does multi-class classification (e.g. if it uses a `softmax` last-layer activation).* `(model.predict(x) > 0.5).astype(\"int32\")`, if your model does binary classification (e.g. if it uses a `sigmoid` last-layer activation).\n", " warnings.warn('`model.predict_classes()` is deprecated and '\n" ] } ], "source": [ "ltest = [lb.inverse_transform(e['label'])[0] for e in test]\n", "ptest = [predict(model, e) for e in test]\n", "\n", "# for e in test:\n", "# print(f\"Label: {lb.inverse_transform(e['label'])[0]:2d}\")\n", "# print(f\"Prediction: {predict(model, e):2d}\\n_______________\")" ] }, { "cell_type": "code", "execution_count": 25, "id": "888494f1", "metadata": {}, "outputs": [], "source": [ "ltrain = [lb.inverse_transform(e['label'])[0] for e in train]\n", "ptrain = [predict(model, e) for e in train]\n", "# for e in train:\n", "# print(f\"Label: {lb.inverse_transform(e['label'])[0]:2d}\")\n", "# print(f\"Prediction: {predict(model, e):2d}\\n_______________\")" ] }, { "cell_type": "code", "execution_count": 26, "id": "03dfed1a", "metadata": {}, "outputs": [ { "data": { "image/png": "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xdNaxZ49e9L2xX3sscc8rxH12p00yBUYERERkevqy2MHREREJAf5vTtJlRgREZEhyu+VmL7c7E5EREQk66glRkREZIjye0uMKjEiIiJDVF6evztkVIkRyWFeXva8YsUKT3JeeOEFT3Jk4A4dOuRJzsyZMz3JkeylSoyIiMgQ5ffuJH+3I4mIiMiAmVnahj5kPWxmPzKzH5vZmusst8DMnJmV3GidqsSIiIhIRplZgK7nKH4emAp8ycymXmO50cDvAIf7sl5VYkRERIYoD1tiPgP82DnX6JxrB14GvniN5X4f+Drwf/qy/arEiIiIDFHprMSYWbmZ1XYbyrtFFQJnu43/JDmt+7ZMByY456r6uv06sVdERERumnNuB7BjIO81szzgOeDJ/rwvZ1piDh48yNy5c3nwwQfZsWNAn+GQzPEySznZn5WunKlTp7JhwwY2btzIQw89dM1lpk+fTmVlJRUVFTz11FMATJkyhbVr16aG7du3c/fddw94O7SPsiMnEomwZs0aVq9ezb59+66af+DAAdatW0dFRQWbN2/m3LlzADQ2NlJRUZEa3n///ZvaDj9+dpmWl5eXtuEGzgETuo1/OjntstHArwDfNbPTwGeBN250cm9OtMTE43E2bdrErl27CIfDLFy4kLKyMu68807lZEmWcrI/K105Zsbjjz/O9u3bicVirFmzhkgkwvnz51PL3H777Tz88MNs27aNS5cuMXr0aABOnDjBli1bALjlllvYtGkTx48fH9TyZFOWH3MSiQQvvvgiq1atoqCggI0bN1JcXExh4S96EmbOnElZWRkAdXV17N69m5UrV1JYWMiGDRsIBAK0trZSUVHBPffcQyAQGNQyZUNOunh4ifURYLKZFdFVeXkc+PLlmc65fwbGdtuu7wIrnXO111tpTrTERCIRJk6cyIQJExg2bBjz5s2jurpaOVmUpZzsz0pXzh133EFzczMtLS3E43Fqa2uvak25//77eeedd7h06RIAH3300VXrmT59Og0NDXR0dAxqebIpy485jY2NhMNhQqEQ+fn5lJaWUldX12OZkSNHpl63tbWlfliHDx+eqrB0dHTc1A+uHz+7XOKc6wS+BrwF/BB4xTnXYGabzOwLA11vTlRiotEo48aNS42Hw2Gi0ahysihLOdmfla6cMWPGEIvFUuOxWIwxY8b0WCYUChEKhVi5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Ya/bbmYLgYedc8uS40uBUufc166x7BLga8B/cM61XS8zU91J/9PMPglwRQXmTuBHGcoUERGR7HQOmNBt/NPJaT2Y2Rzg94Av3KgCAxmqxDjnKp1zP7vG9B8DVZnIFBERkax1BJhsZkVmNgx4HHij+wJmVgx8g64KzId9WelgXGK9cRAyRURE5ApendjrnOukq4voLeCHwCvOuQYz22RmX0guthX4JPCqmR0zszd6WV1KRk7sNbNIb7MAXWsmIiIyxDjn3gTevGJaZbfXc/q7zoxdnQTMBa68XaIBNRnKFBERkX7w+7OTMlWJ2Qd80jl37MoZZvbdDGWKiIhIP6gScw3OuV7vBeOc+3ImMkVERGRoych9YtIkazdMcpdX9+zItft15KIcvQeJZD9Pm0bOnz+ftt/acePGed6sk6nuJBEREclyfu9OyqqnWIuIiIj0lVpiREREhii1xIiIiIgMAlViRERExJfUnSQiIjJEqTspSxw8eJC5c+fy4IMPsmPHDuVkYZbfcqZOncqGDRvYuHEjDz300DWXmT59OpWVlVRUVPDUU08BMGXKFNauXZsatm/fzt133z3g7QD/fXa5mBOJRFizZg2rV69m3759V80/cOAA69ato6Kigs2bN3PuXNcDehsbG6moqEgN77///k1thx8/u2zI8TLLyzLdLK+enZQxzrlsHfqss7PTzZ492505c8a1tbW5Rx55xJ08ebI/qxiSOV5m+SXn6aefdk8//bRbsWKF+/DDD926devcV7/6VXf27Fm3YcOG1Pynn37aVVRUuDNnzrhnn33WPf30027VqlU95j/99NPu2WefdT/72c/cM88802O6l2VSzsByampqUsN7773n7rvvPvf666+7gwcPutmzZ7tXX321xzLV1dWp188//7x77LHHXE1NjXv77bfdu+++62pqatybb77pZsyYkRqvqanxtExDNcfLrDTkePpb29zc7NI1eL3tzrncaImJRCJMnDiRCRMmMGzYMObNm0d1dbVysijLbzl33HEHzc3NtLS0EI/Hqa2tvao15f777+edd97h0qVLAHz00UdXrWf69Ok0NDTQ0dExsALhv88uF3MaGxsJh8OEQiHy8/MpLS2lrq6uxzIjR45MvW5ra0v9z3T48OEEAgEAOjo6bup/rH787LIhx8ssL8uUDn5vifGsEmNmoUytOxqN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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "from sklearn.metrics import confusion_matrix\n", "import seaborn as sn\n", "\n", "set_digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}\n", "\n", "train_cm = confusion_matrix(ltrain, ptrain, normalize='true')\n", "test_cm = confusion_matrix(ltest, ptest, normalize='true')\n", "\n", "df_cm = pd.DataFrame(test_cm, index=set_digits, columns=set_digits)\n", "plt.figure(figsize = (10,7))\n", "sn_plot = sn.heatmap(df_cm, annot=True, cmap=\"Greys\")\n", "plt.ylabel(\"True Label\")\n", "plt.xlabel(\"Predicted Label\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "9ad253a7", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }