├── .gitignore ├── README.md ├── autoencoder_classifier.h5 └── autoencoder_classifier.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | data/ 2 | logs/ 3 | *.DS_Store 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Environments 88 | .env 89 | .venv 90 | env/ 91 | venv/ 92 | ENV/ 93 | env.bak/ 94 | venv.bak/ 95 | 96 | # Spyder project settings 97 | .spyderproject 98 | .spyproject 99 | 100 | # Rope project settings 101 | .ropeproject 102 | 103 | # mkdocs documentation 104 | /site 105 | 106 | # mypy 107 | .mypy_cache/ 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # autoencoder_classifier 2 | Autoencoder model for rare event classification 3 | -------------------------------------------------------------------------------- /autoencoder_classifier.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran2367/autoencoder_classifier/6377ebe747592066a7dbbd5bec300de8ec7249c4/autoencoder_classifier.h5 -------------------------------------------------------------------------------- /autoencoder_classifier.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Rare Event Binary Classification using Autoencoder\n", 8 | "\n", 9 | "Here we will show an implementation of building a binary classifier using Autoencoders. The purpose is to show the implementation steps. The Autoencoder tuning for performance improvement can be done.\n", 10 | "\n", 11 | "The dataset used here is taken from here,\n", 12 | "\n", 13 | "**Dataset: Rare Event Classification in Multivariate Time Series** https://arxiv.org/abs/1809.10717 (please cite this article, if using the dataset)." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stderr", 23 | "output_type": "stream", 24 | "text": [ 25 | "Using TensorFlow backend.\n" 26 | ] 27 | } 28 | ], 29 | "source": [ 30 | "%matplotlib inline\n", 31 | "import matplotlib.pyplot as plt\n", 32 | "import seaborn as sns\n", 33 | "\n", 34 | "import pandas as pd\n", 35 | "import numpy as np\n", 36 | "from pylab import rcParams\n", 37 | "\n", 38 | "import tensorflow as tf\n", 39 | "from keras.models import Model, load_model\n", 40 | "from keras.layers import Input, Dense\n", 41 | "from keras.callbacks import ModelCheckpoint, TensorBoard\n", 42 | "from keras import regularizers\n", 43 | "\n", 44 | "from sklearn.preprocessing import StandardScaler\n", 45 | "from sklearn.model_selection import train_test_split\n", 46 | "from sklearn.metrics import confusion_matrix, precision_recall_curve\n", 47 | "from sklearn.metrics import recall_score, classification_report, auc, roc_curve\n", 48 | "from sklearn.metrics import precision_recall_fscore_support, f1_score\n", 49 | "\n", 50 | "from numpy.random import seed\n", 51 | "seed(1)\n", 52 | "from tensorflow import set_random_seed\n", 53 | "set_random_seed(2)\n", 54 | "\n", 55 | "SEED = 123 #used to help randomly select the data points\n", 56 | "DATA_SPLIT_PCT = 0.2\n", 57 | "\n", 58 | "rcParams['figure.figsize'] = 8, 6\n", 59 | "LABELS = [\"Normal\",\"Break\"]" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "## Reading and preparing data" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/html": [ 77 | "
\n", 78 | "\n", 91 | "\n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | "
timeyx1x2x3x4x5x6x7x8...x52x53x54x55x56x57x58x59x60x61
05/1/99 0:0000.376665-4.596435-4.09575613.497687-0.118830-20.6698830.000732-0.061114...10.0917210.053279-4.936434-24.59014618.5154363.4734000.0334440.9532190.0060760
15/1/99 0:0200.475720-4.542502-4.01835916.230659-0.128733-18.7580790.000732-0.061114...10.0958710.062801-4.937179-32.41326622.7600652.6829330.0335361.0905020.0060830
25/1/99 0:0400.363848-4.681394-4.35314714.127998-0.138636-17.8366320.010803-0.061114...10.1002650.072322-4.937924-34.18377427.0046633.5374870.0336291.8405400.0060900
35/1/99 0:0600.301590-4.758934-4.02361213.161567-0.148142-18.5176010.002075-0.061114...10.1046600.081600-4.938669-35.95428121.6724493.9860950.0337212.5548800.0060970
45/1/99 0:0800.265578-4.749928-4.33315015.267340-0.155314-17.5059130.000732-0.061114...10.1090540.091121-4.939414-37.72478921.9072513.6015730.0337771.4104940.0061050
\n", 241 | "

5 rows × 63 columns

\n", 242 | "
" 243 | ], 244 | "text/plain": [ 245 | " time y x1 x2 x3 x4 x5 \\\n", 246 | "0 5/1/99 0:00 0 0.376665 -4.596435 -4.095756 13.497687 -0.118830 \n", 247 | "1 5/1/99 0:02 0 0.475720 -4.542502 -4.018359 16.230659 -0.128733 \n", 248 | "2 5/1/99 0:04 0 0.363848 -4.681394 -4.353147 14.127998 -0.138636 \n", 249 | "3 5/1/99 0:06 0 0.301590 -4.758934 -4.023612 13.161567 -0.148142 \n", 250 | "4 5/1/99 0:08 0 0.265578 -4.749928 -4.333150 15.267340 -0.155314 \n", 251 | "\n", 252 | " x6 x7 x8 ... x52 x53 x54 \\\n", 253 | "0 -20.669883 0.000732 -0.061114 ... 10.091721 0.053279 -4.936434 \n", 254 | "1 -18.758079 0.000732 -0.061114 ... 10.095871 0.062801 -4.937179 \n", 255 | "2 -17.836632 0.010803 -0.061114 ... 10.100265 0.072322 -4.937924 \n", 256 | "3 -18.517601 0.002075 -0.061114 ... 10.104660 0.081600 -4.938669 \n", 257 | "4 -17.505913 0.000732 -0.061114 ... 10.109054 0.091121 -4.939414 \n", 258 | "\n", 259 | " x55 x56 x57 x58 x59 x60 x61 \n", 260 | "0 -24.590146 18.515436 3.473400 0.033444 0.953219 0.006076 0 \n", 261 | "1 -32.413266 22.760065 2.682933 0.033536 1.090502 0.006083 0 \n", 262 | "2 -34.183774 27.004663 3.537487 0.033629 1.840540 0.006090 0 \n", 263 | "3 -35.954281 21.672449 3.986095 0.033721 2.554880 0.006097 0 \n", 264 | "4 -37.724789 21.907251 3.601573 0.033777 1.410494 0.006105 0 \n", 265 | "\n", 266 | "[5 rows x 63 columns]" 267 | ] 268 | }, 269 | "execution_count": 2, 270 | "metadata": {}, 271 | "output_type": "execute_result" 272 | } 273 | ], 274 | "source": [ 275 | "'''\n", 276 | "Download data here:\n", 277 | "https://docs.google.com/forms/d/e/1FAIpQLSdyUk3lfDl7I5KYK_pw285LCApc-_RcoC0Tf9cnDnZ_TWzPAw/viewform\n", 278 | "'''\n", 279 | "df = pd.read_csv(\"data/processminer-rare-event-mts - data.csv\") \n", 280 | "df.head(n=5) # visualize the data." 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": {}, 286 | "source": [ 287 | "### Shift the data\n", 288 | "\n", 289 | "This is a timeseries data in which we have to predict the event (y = 1) ahead in time. In this data, consecutive rows are 2 minutes apart. We will shift the labels in column `y` by 2 rows to do a 4 minute ahead prediction." 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 3, 295 | "metadata": {}, 296 | "outputs": [], 297 | "source": [ 298 | "sign = lambda x: (1, -1)[x < 0]\n", 299 | "\n", 300 | "def curve_shift(df, shift_by):\n", 301 | " '''\n", 302 | " This function will shift the binary labels in a dataframe.\n", 303 | " The curve shift will be with respect to the 1s. \n", 304 | " For example, if shift is -2, the following process\n", 305 | " will happen: if row n is labeled as 1, then\n", 306 | " - Make row (n+shift_by):(n+shift_by-1) = 1.\n", 307 | " - Remove row n.\n", 308 | " i.e. the labels will be shifted up to 2 rows up.\n", 309 | " \n", 310 | " Inputs:\n", 311 | " df A pandas dataframe with a binary labeled column. \n", 312 | " This labeled column should be named as 'y'.\n", 313 | " shift_by An integer denoting the number of rows to shift.\n", 314 | " \n", 315 | " Output\n", 316 | " df A dataframe with the binary labels shifted by shift.\n", 317 | " '''\n", 318 | "\n", 319 | " vector = df['y'].copy()\n", 320 | " for s in range(abs(shift_by)):\n", 321 | " tmp = vector.shift(sign(shift_by))\n", 322 | " tmp = tmp.fillna(0)\n", 323 | " vector += tmp\n", 324 | " labelcol = 'y'\n", 325 | " # Add vector to the df\n", 326 | " df.insert(loc=0, column=labelcol+'tmp', value=vector)\n", 327 | " # Remove the rows with labelcol == 1.\n", 328 | " df = df.drop(df[df[labelcol] == 1].index)\n", 329 | " # Drop labelcol and rename the tmp col as labelcol\n", 330 | " df = df.drop(labelcol, axis=1)\n", 331 | " df = df.rename(columns={labelcol+'tmp': labelcol})\n", 332 | " # Make the labelcol binary\n", 333 | " df.loc[df[labelcol] > 0, labelcol] = 1\n", 334 | "\n", 335 | " return df" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 4, 341 | "metadata": {}, 342 | "outputs": [ 343 | { 344 | "name": "stdout", 345 | "output_type": "stream", 346 | "text": [ 347 | "Before shifting\n" 348 | ] 349 | }, 350 | { 351 | "data": { 352 | "text/html": [ 353 | "
\n", 354 | "\n", 367 | "\n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | "
timeyx1x2x3
2565/1/99 8:3201.016235-4.058394-1.097158
2575/1/99 8:3401.005602-3.876199-1.074373
2585/1/99 8:3600.933933-3.868467-1.249954
2595/1/99 8:3810.892311-13.332664-10.006578
2605/1/99 10:5000.020062-3.987897-1.248529
\n", 421 | "
" 422 | ], 423 | "text/plain": [ 424 | " time y x1 x2 x3\n", 425 | "256 5/1/99 8:32 0 1.016235 -4.058394 -1.097158\n", 426 | "257 5/1/99 8:34 0 1.005602 -3.876199 -1.074373\n", 427 | "258 5/1/99 8:36 0 0.933933 -3.868467 -1.249954\n", 428 | "259 5/1/99 8:38 1 0.892311 -13.332664 -10.006578\n", 429 | "260 5/1/99 10:50 0 0.020062 -3.987897 -1.248529" 430 | ] 431 | }, 432 | "metadata": {}, 433 | "output_type": "display_data" 434 | }, 435 | { 436 | "name": "stdout", 437 | "output_type": "stream", 438 | "text": [ 439 | "After shifting\n" 440 | ] 441 | }, 442 | { 443 | "data": { 444 | "text/html": [ 445 | "
\n", 446 | "\n", 459 | "\n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | "
ytimex1x2x3
2550.05/1/99 8:300.997107-3.865720-1.133779
2560.05/1/99 8:321.016235-4.058394-1.097158
2571.05/1/99 8:341.005602-3.876199-1.074373
2581.05/1/99 8:360.933933-3.868467-1.249954
2600.05/1/99 10:500.020062-3.987897-1.248529
\n", 513 | "
" 514 | ], 515 | "text/plain": [ 516 | " y time x1 x2 x3\n", 517 | "255 0.0 5/1/99 8:30 0.997107 -3.865720 -1.133779\n", 518 | "256 0.0 5/1/99 8:32 1.016235 -4.058394 -1.097158\n", 519 | "257 1.0 5/1/99 8:34 1.005602 -3.876199 -1.074373\n", 520 | "258 1.0 5/1/99 8:36 0.933933 -3.868467 -1.249954\n", 521 | "260 0.0 5/1/99 10:50 0.020062 -3.987897 -1.248529" 522 | ] 523 | }, 524 | "metadata": {}, 525 | "output_type": "display_data" 526 | } 527 | ], 528 | "source": [ 529 | "'''\n", 530 | "Shift the data by 2 units, equal to 4 minutes.\n", 531 | "\n", 532 | "Test: Testing whether the shift happened correctly.\n", 533 | "'''\n", 534 | "print('Before shifting') # Positive labeled rows before shifting.\n", 535 | "one_indexes = df.index[df['y'] == 1]\n", 536 | "display(df.iloc[(one_indexes[0]-3):(one_indexes[0]+2), 0:5].head(n=5))\n", 537 | "\n", 538 | "# Shift the response column y by 2 rows to do a 4-min ahead prediction.\n", 539 | "df = curve_shift(df, shift_by = -2)\n", 540 | "\n", 541 | "print('After shifting') # Validating if the shift happened correctly.\n", 542 | "display(df.iloc[(one_indexes[0]-4):(one_indexes[0]+1), 0:5].head(n=5)) " 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | "execution_count": 5, 548 | "metadata": {}, 549 | "outputs": [], 550 | "source": [ 551 | "# Remove time column, and the categorical columns\n", 552 | "df = df.drop(['time', 'x28', 'x61'], axis=1)" 553 | ] 554 | }, 555 | { 556 | "cell_type": "markdown", 557 | "metadata": {}, 558 | "source": [ 559 | "### Divide the data into train, valid, and test" 560 | ] 561 | }, 562 | { 563 | "cell_type": "code", 564 | "execution_count": 6, 565 | "metadata": {}, 566 | "outputs": [], 567 | "source": [ 568 | "df_train, df_test = train_test_split(df, test_size=DATA_SPLIT_PCT, random_state=SEED)\n", 569 | "df_train, df_valid = train_test_split(df_train, test_size=DATA_SPLIT_PCT, random_state=SEED)" 570 | ] 571 | }, 572 | { 573 | "cell_type": "markdown", 574 | "metadata": {}, 575 | "source": [ 576 | "In the autoencoder, we will be encoding only the negatively labeled data. That is, we will take the part of data for which `y=0` and build an autoencoder. For that, we will divide the datasets as following." 577 | ] 578 | }, 579 | { 580 | "cell_type": "code", 581 | "execution_count": 7, 582 | "metadata": {}, 583 | "outputs": [], 584 | "source": [ 585 | "df_train_0 = df_train.loc[df['y'] == 0]\n", 586 | "df_train_1 = df_train.loc[df['y'] == 1]\n", 587 | "df_train_0_x = df_train_0.drop(['y'], axis=1)\n", 588 | "df_train_1_x = df_train_1.drop(['y'], axis=1)\n", 589 | "\n", 590 | "df_valid_0 = df_valid.loc[df['y'] == 0]\n", 591 | "df_valid_1 = df_valid.loc[df['y'] == 1]\n", 592 | "df_valid_0_x = df_valid_0.drop(['y'], axis=1)\n", 593 | "df_valid_1_x = df_valid_1.drop(['y'], axis=1)\n", 594 | "\n", 595 | "df_test_0 = df_test.loc[df['y'] == 0]\n", 596 | "df_test_1 = df_test.loc[df['y'] == 1]\n", 597 | "df_test_0_x = df_test_0.drop(['y'], axis=1)\n", 598 | "df_test_1_x = df_test_1.drop(['y'], axis=1)" 599 | ] 600 | }, 601 | { 602 | "cell_type": "markdown", 603 | "metadata": {}, 604 | "source": [ 605 | "### Standardize the data\n", 606 | "It is usually better to use a standardized data (transformed to Gaussian, mean 0 and sd 1) for autoencoders." 607 | ] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": 8, 612 | "metadata": {}, 613 | "outputs": [], 614 | "source": [ 615 | "scaler = StandardScaler().fit(df_train_0_x)\n", 616 | "df_train_0_x_rescaled = scaler.transform(df_train_0_x)\n", 617 | "df_valid_0_x_rescaled = scaler.transform(df_valid_0_x)\n", 618 | "df_valid_x_rescaled = scaler.transform(df_valid.drop(['y'], axis = 1))\n", 619 | "\n", 620 | "df_test_0_x_rescaled = scaler.transform(df_test_0_x)\n", 621 | "df_test_x_rescaled = scaler.transform(df_test.drop(['y'], axis = 1))" 622 | ] 623 | }, 624 | { 625 | "cell_type": "markdown", 626 | "metadata": {}, 627 | "source": [ 628 | "## Autoencoder training" 629 | ] 630 | }, 631 | { 632 | "cell_type": "markdown", 633 | "metadata": {}, 634 | "source": [ 635 | "First we will initialize the Autoencoder architecture. We are building a simple autoencoder. More complex architectures and other configurations should be explored." 636 | ] 637 | }, 638 | { 639 | "cell_type": "code", 640 | "execution_count": 106, 641 | "metadata": {}, 642 | "outputs": [ 643 | { 644 | "name": "stdout", 645 | "output_type": "stream", 646 | "text": [ 647 | "_________________________________________________________________\n", 648 | "Layer (type) Output Shape Param # \n", 649 | "=================================================================\n", 650 | "input_6 (InputLayer) (None, 59) 0 \n", 651 | "_________________________________________________________________\n", 652 | "dense_23 (Dense) (None, 32) 1920 \n", 653 | "_________________________________________________________________\n", 654 | "dense_24 (Dense) (None, 16) 528 \n", 655 | "_________________________________________________________________\n", 656 | "dense_25 (Dense) (None, 16) 272 \n", 657 | "_________________________________________________________________\n", 658 | "dense_26 (Dense) (None, 32) 544 \n", 659 | "_________________________________________________________________\n", 660 | "dense_27 (Dense) (None, 59) 1947 \n", 661 | "=================================================================\n", 662 | "Total params: 5,211\n", 663 | "Trainable params: 5,211\n", 664 | "Non-trainable params: 0\n", 665 | "_________________________________________________________________\n" 666 | ] 667 | } 668 | ], 669 | "source": [ 670 | "nb_epoch = 200\n", 671 | "batch_size = 128\n", 672 | "input_dim = df_train_0_x_rescaled.shape[1] #num of predictor variables, \n", 673 | "encoding_dim = 32\n", 674 | "hidden_dim = int(encoding_dim / 2)\n", 675 | "learning_rate = 1e-3\n", 676 | "\n", 677 | "input_layer = Input(shape=(input_dim, ))\n", 678 | "encoder = Dense(encoding_dim, activation=\"relu\", activity_regularizer=regularizers.l1(learning_rate))(input_layer)\n", 679 | "encoder = Dense(hidden_dim, activation=\"relu\")(encoder)\n", 680 | "decoder = Dense(hidden_dim, activation=\"relu\")(encoder)\n", 681 | "decoder = Dense(encoding_dim, activation=\"relu\")(decoder)\n", 682 | "decoder = Dense(input_dim, activation=\"linear\")(decoder)\n", 683 | "autoencoder = Model(inputs=input_layer, outputs=decoder)\n", 684 | "autoencoder.summary()" 685 | ] 686 | }, 687 | { 688 | "cell_type": "code", 689 | "execution_count": 107, 690 | "metadata": {}, 691 | "outputs": [ 692 | { 693 | "name": "stdout", 694 | "output_type": "stream", 695 | "text": [ 696 | "Train on 11541 samples, validate on 2883 samples\n", 697 | "Epoch 1/200\n", 698 | "11541/11541 [==============================] - 0s 26us/step - loss: 2.0636 - acc: 0.0358 - val_loss: 1.4716 - val_acc: 0.0555\n", 699 | "Epoch 2/200\n", 700 | "11541/11541 [==============================] - 0s 9us/step - loss: 1.1450 - acc: 0.0787 - val_loss: 0.9044 - val_acc: 0.0711\n", 701 | "Epoch 3/200\n", 702 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.7805 - acc: 0.0728 - val_loss: 0.6991 - val_acc: 0.0832\n", 703 | "Epoch 4/200\n", 704 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.6396 - acc: 0.0994 - val_loss: 0.6002 - val_acc: 0.1145\n", 705 | "Epoch 5/200\n", 706 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.5665 - acc: 0.1396 - val_loss: 0.5466 - val_acc: 0.1471\n", 707 | "Epoch 6/200\n", 708 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.5214 - acc: 0.1752 - val_loss: 0.5085 - val_acc: 0.1894\n", 709 | "Epoch 7/200\n", 710 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.4869 - acc: 0.2054 - val_loss: 0.4756 - val_acc: 0.2112\n", 711 | "Epoch 8/200\n", 712 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.4584 - acc: 0.2346 - val_loss: 0.4485 - val_acc: 0.2404\n", 713 | "Epoch 9/200\n", 714 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.4348 - acc: 0.2428 - val_loss: 0.4279 - val_acc: 0.2338\n", 715 | "Epoch 10/200\n", 716 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.4140 - acc: 0.2442 - val_loss: 0.4076 - val_acc: 0.2494\n", 717 | "Epoch 11/200\n", 718 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3968 - acc: 0.2470 - val_loss: 0.3919 - val_acc: 0.2366\n", 719 | "Epoch 12/200\n", 720 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3827 - acc: 0.2582 - val_loss: 0.3795 - val_acc: 0.2518\n", 721 | "Epoch 13/200\n", 722 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3715 - acc: 0.2651 - val_loss: 0.3683 - val_acc: 0.2636\n", 723 | "Epoch 14/200\n", 724 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3631 - acc: 0.2761 - val_loss: 0.3591 - val_acc: 0.2782\n", 725 | "Epoch 15/200\n", 726 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3529 - acc: 0.2878 - val_loss: 0.3506 - val_acc: 0.2969\n", 727 | "Epoch 16/200\n", 728 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3451 - acc: 0.2897 - val_loss: 0.3433 - val_acc: 0.2692\n", 729 | "Epoch 17/200\n", 730 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.3383 - acc: 0.2944 - val_loss: 0.3377 - val_acc: 0.2869\n", 731 | "Epoch 18/200\n", 732 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.3316 - acc: 0.3010 - val_loss: 0.3339 - val_acc: 0.3084\n", 733 | "Epoch 19/200\n", 734 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.3275 - acc: 0.3021 - val_loss: 0.3259 - val_acc: 0.3014\n", 735 | "Epoch 20/200\n", 736 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.3205 - acc: 0.3047 - val_loss: 0.3215 - val_acc: 0.2959\n", 737 | "Epoch 21/200\n", 738 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3155 - acc: 0.3092 - val_loss: 0.3146 - val_acc: 0.3032\n", 739 | "Epoch 22/200\n", 740 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.3106 - acc: 0.3194 - val_loss: 0.3126 - val_acc: 0.3104\n", 741 | "Epoch 23/200\n", 742 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.3064 - acc: 0.3144 - val_loss: 0.3107 - val_acc: 0.2973\n", 743 | "Epoch 24/200\n", 744 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3033 - acc: 0.3191 - val_loss: 0.3038 - val_acc: 0.3160\n", 745 | "Epoch 25/200\n", 746 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.3001 - acc: 0.3191 - val_loss: 0.3012 - val_acc: 0.3091\n", 747 | "Epoch 26/200\n", 748 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2950 - acc: 0.3260 - val_loss: 0.2994 - val_acc: 0.3247\n", 749 | "Epoch 27/200\n", 750 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2937 - acc: 0.3282 - val_loss: 0.2947 - val_acc: 0.3365\n", 751 | "Epoch 28/200\n", 752 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2898 - acc: 0.3379 - val_loss: 0.2938 - val_acc: 0.3313\n", 753 | "Epoch 29/200\n", 754 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2897 - acc: 0.3402 - val_loss: 0.2899 - val_acc: 0.3351\n", 755 | "Epoch 30/200\n", 756 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2848 - acc: 0.3399 - val_loss: 0.2901 - val_acc: 0.3441\n", 757 | "Epoch 31/200\n", 758 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2824 - acc: 0.3468 - val_loss: 0.2902 - val_acc: 0.3552\n", 759 | "Epoch 32/200\n", 760 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2814 - acc: 0.3528 - val_loss: 0.2846 - val_acc: 0.3552\n", 761 | "Epoch 33/200\n", 762 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2782 - acc: 0.3573 - val_loss: 0.2828 - val_acc: 0.3569\n", 763 | "Epoch 34/200\n", 764 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2753 - acc: 0.3670 - val_loss: 0.2804 - val_acc: 0.3535\n", 765 | "Epoch 35/200\n", 766 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2740 - acc: 0.3718 - val_loss: 0.2777 - val_acc: 0.3673\n", 767 | "Epoch 36/200\n", 768 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2726 - acc: 0.3707 - val_loss: 0.2742 - val_acc: 0.3711\n", 769 | "Epoch 37/200\n", 770 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2692 - acc: 0.3807 - val_loss: 0.2727 - val_acc: 0.3826\n", 771 | "Epoch 38/200\n", 772 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2746 - acc: 0.3850 - val_loss: 0.2746 - val_acc: 0.3933\n", 773 | "Epoch 39/200\n", 774 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2675 - acc: 0.3925 - val_loss: 0.2698 - val_acc: 0.3909\n", 775 | "Epoch 40/200\n", 776 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2659 - acc: 0.3897 - val_loss: 0.2686 - val_acc: 0.3913\n", 777 | "Epoch 41/200\n", 778 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2656 - acc: 0.3972 - val_loss: 0.2665 - val_acc: 0.3812\n", 779 | "Epoch 42/200\n", 780 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2647 - acc: 0.3988 - val_loss: 0.2690 - val_acc: 0.3871\n", 781 | "Epoch 43/200\n", 782 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2624 - acc: 0.3989 - val_loss: 0.2663 - val_acc: 0.4017\n", 783 | "Epoch 44/200\n", 784 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2600 - acc: 0.4007 - val_loss: 0.2635 - val_acc: 0.4096\n", 785 | "Epoch 45/200\n", 786 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2599 - acc: 0.4053 - val_loss: 0.2631 - val_acc: 0.3895\n", 787 | "Epoch 46/200\n", 788 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2589 - acc: 0.4056 - val_loss: 0.2625 - val_acc: 0.3972\n", 789 | "Epoch 47/200\n", 790 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2567 - acc: 0.4107 - val_loss: 0.2589 - val_acc: 0.4100\n", 791 | "Epoch 48/200\n", 792 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2551 - acc: 0.4125 - val_loss: 0.2598 - val_acc: 0.4062\n", 793 | "Epoch 49/200\n", 794 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2568 - acc: 0.4121 - val_loss: 0.2576 - val_acc: 0.4121\n", 795 | "Epoch 50/200\n", 796 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2537 - acc: 0.4160 - val_loss: 0.2619 - val_acc: 0.4121\n", 797 | "Epoch 51/200\n", 798 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2559 - acc: 0.4185 - val_loss: 0.2612 - val_acc: 0.4152\n", 799 | "Epoch 52/200\n", 800 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2549 - acc: 0.4191 - val_loss: 0.2556 - val_acc: 0.4180\n", 801 | "Epoch 53/200\n", 802 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2503 - acc: 0.4253 - val_loss: 0.2551 - val_acc: 0.4200\n", 803 | "Epoch 54/200\n", 804 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2518 - acc: 0.4233 - val_loss: 0.2534 - val_acc: 0.4214\n", 805 | "Epoch 55/200\n", 806 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2490 - acc: 0.4248 - val_loss: 0.2564 - val_acc: 0.4128\n", 807 | "Epoch 56/200\n", 808 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2489 - acc: 0.4239 - val_loss: 0.2508 - val_acc: 0.4273\n", 809 | "Epoch 57/200\n", 810 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2474 - acc: 0.4268 - val_loss: 0.2517 - val_acc: 0.4200\n", 811 | "Epoch 58/200\n", 812 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2495 - acc: 0.4282 - val_loss: 0.2527 - val_acc: 0.4114\n", 813 | "Epoch 59/200\n", 814 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2469 - acc: 0.4296 - val_loss: 0.2493 - val_acc: 0.4318\n", 815 | "Epoch 60/200\n" 816 | ] 817 | }, 818 | { 819 | "name": "stdout", 820 | "output_type": "stream", 821 | "text": [ 822 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2462 - acc: 0.4287 - val_loss: 0.2495 - val_acc: 0.4194\n", 823 | "Epoch 61/200\n", 824 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2464 - acc: 0.4270 - val_loss: 0.2530 - val_acc: 0.4266\n", 825 | "Epoch 62/200\n", 826 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2457 - acc: 0.4301 - val_loss: 0.2476 - val_acc: 0.4239\n", 827 | "Epoch 63/200\n", 828 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2447 - acc: 0.4319 - val_loss: 0.2498 - val_acc: 0.4339\n", 829 | "Epoch 64/200\n", 830 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2435 - acc: 0.4313 - val_loss: 0.2487 - val_acc: 0.4232\n", 831 | "Epoch 65/200\n", 832 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2455 - acc: 0.4287 - val_loss: 0.2452 - val_acc: 0.4391\n", 833 | "Epoch 66/200\n", 834 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2432 - acc: 0.4299 - val_loss: 0.2460 - val_acc: 0.4280\n", 835 | "Epoch 67/200\n", 836 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2415 - acc: 0.4347 - val_loss: 0.2461 - val_acc: 0.4145\n", 837 | "Epoch 68/200\n", 838 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2416 - acc: 0.4336 - val_loss: 0.2469 - val_acc: 0.4332\n", 839 | "Epoch 69/200\n", 840 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2426 - acc: 0.4355 - val_loss: 0.2436 - val_acc: 0.4273\n", 841 | "Epoch 70/200\n", 842 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2399 - acc: 0.4372 - val_loss: 0.2444 - val_acc: 0.4367\n", 843 | "Epoch 71/200\n", 844 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2406 - acc: 0.4367 - val_loss: 0.2422 - val_acc: 0.4336\n", 845 | "Epoch 72/200\n", 846 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2388 - acc: 0.4353 - val_loss: 0.2477 - val_acc: 0.4225\n", 847 | "Epoch 73/200\n", 848 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2405 - acc: 0.4333 - val_loss: 0.2474 - val_acc: 0.4225\n", 849 | "Epoch 74/200\n", 850 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2389 - acc: 0.4396 - val_loss: 0.2402 - val_acc: 0.4266\n", 851 | "Epoch 75/200\n", 852 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2395 - acc: 0.4332 - val_loss: 0.2432 - val_acc: 0.4426\n", 853 | "Epoch 76/200\n", 854 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2371 - acc: 0.4355 - val_loss: 0.2430 - val_acc: 0.4284\n", 855 | "Epoch 77/200\n", 856 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2384 - acc: 0.4349 - val_loss: 0.2409 - val_acc: 0.4374\n", 857 | "Epoch 78/200\n", 858 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2368 - acc: 0.4374 - val_loss: 0.2376 - val_acc: 0.4405\n", 859 | "Epoch 79/200\n", 860 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2352 - acc: 0.4366 - val_loss: 0.2415 - val_acc: 0.4429\n", 861 | "Epoch 80/200\n", 862 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2373 - acc: 0.4394 - val_loss: 0.2380 - val_acc: 0.4225\n", 863 | "Epoch 81/200\n", 864 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2343 - acc: 0.4401 - val_loss: 0.2369 - val_acc: 0.4492\n", 865 | "Epoch 82/200\n", 866 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2342 - acc: 0.4431 - val_loss: 0.2380 - val_acc: 0.4339\n", 867 | "Epoch 83/200\n", 868 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2335 - acc: 0.4422 - val_loss: 0.2367 - val_acc: 0.4440\n", 869 | "Epoch 84/200\n", 870 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2320 - acc: 0.4416 - val_loss: 0.2393 - val_acc: 0.4478\n", 871 | "Epoch 85/200\n", 872 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2356 - acc: 0.4349 - val_loss: 0.2351 - val_acc: 0.4429\n", 873 | "Epoch 86/200\n", 874 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2309 - acc: 0.4463 - val_loss: 0.2363 - val_acc: 0.4499\n", 875 | "Epoch 87/200\n", 876 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2333 - acc: 0.4470 - val_loss: 0.2393 - val_acc: 0.4353\n", 877 | "Epoch 88/200\n", 878 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2372 - acc: 0.4382 - val_loss: 0.2402 - val_acc: 0.4353\n", 879 | "Epoch 89/200\n", 880 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2317 - acc: 0.4461 - val_loss: 0.2340 - val_acc: 0.4350\n", 881 | "Epoch 90/200\n", 882 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2305 - acc: 0.4424 - val_loss: 0.2329 - val_acc: 0.4530\n", 883 | "Epoch 91/200\n", 884 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2311 - acc: 0.4444 - val_loss: 0.2355 - val_acc: 0.4468\n", 885 | "Epoch 92/200\n", 886 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2283 - acc: 0.4459 - val_loss: 0.2327 - val_acc: 0.4513\n", 887 | "Epoch 93/200\n", 888 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2294 - acc: 0.4426 - val_loss: 0.2406 - val_acc: 0.4325\n", 889 | "Epoch 94/200\n", 890 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2389 - acc: 0.4452 - val_loss: 0.2346 - val_acc: 0.4450\n", 891 | "Epoch 95/200\n", 892 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2296 - acc: 0.4482 - val_loss: 0.2359 - val_acc: 0.4409\n", 893 | "Epoch 96/200\n", 894 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2328 - acc: 0.4436 - val_loss: 0.2326 - val_acc: 0.4325\n", 895 | "Epoch 97/200\n", 896 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2280 - acc: 0.4508 - val_loss: 0.2335 - val_acc: 0.4502\n", 897 | "Epoch 98/200\n", 898 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2264 - acc: 0.4509 - val_loss: 0.2292 - val_acc: 0.4527\n", 899 | "Epoch 99/200\n", 900 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2271 - acc: 0.4486 - val_loss: 0.2321 - val_acc: 0.4527\n", 901 | "Epoch 100/200\n", 902 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2280 - acc: 0.4525 - val_loss: 0.2314 - val_acc: 0.4454\n", 903 | "Epoch 101/200\n", 904 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2265 - acc: 0.4518 - val_loss: 0.2322 - val_acc: 0.4475\n", 905 | "Epoch 102/200\n", 906 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2253 - acc: 0.4571 - val_loss: 0.2316 - val_acc: 0.4461\n", 907 | "Epoch 103/200\n", 908 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2280 - acc: 0.4552 - val_loss: 0.2335 - val_acc: 0.4471\n", 909 | "Epoch 104/200\n", 910 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2288 - acc: 0.4534 - val_loss: 0.2288 - val_acc: 0.4447\n", 911 | "Epoch 105/200\n", 912 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2263 - acc: 0.4567 - val_loss: 0.2315 - val_acc: 0.4617\n", 913 | "Epoch 106/200\n", 914 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2259 - acc: 0.4550 - val_loss: 0.2295 - val_acc: 0.4509\n", 915 | "Epoch 107/200\n", 916 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2235 - acc: 0.4549 - val_loss: 0.2287 - val_acc: 0.4346\n", 917 | "Epoch 108/200\n", 918 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2244 - acc: 0.4520 - val_loss: 0.2279 - val_acc: 0.4547\n", 919 | "Epoch 109/200\n", 920 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2236 - acc: 0.4565 - val_loss: 0.2261 - val_acc: 0.4533\n", 921 | "Epoch 110/200\n", 922 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2239 - acc: 0.4524 - val_loss: 0.2284 - val_acc: 0.4603\n", 923 | "Epoch 111/200\n", 924 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2279 - acc: 0.4580 - val_loss: 0.2262 - val_acc: 0.4468\n", 925 | "Epoch 112/200\n", 926 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2281 - acc: 0.4533 - val_loss: 0.2319 - val_acc: 0.4488\n", 927 | "Epoch 113/200\n", 928 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2251 - acc: 0.4572 - val_loss: 0.2285 - val_acc: 0.4669\n", 929 | "Epoch 114/200\n", 930 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2235 - acc: 0.4595 - val_loss: 0.2265 - val_acc: 0.4606\n", 931 | "Epoch 115/200\n", 932 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2235 - acc: 0.4621 - val_loss: 0.2275 - val_acc: 0.4506\n", 933 | "Epoch 116/200\n", 934 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2210 - acc: 0.4615 - val_loss: 0.2251 - val_acc: 0.4599\n", 935 | "Epoch 117/200\n", 936 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2216 - acc: 0.4634 - val_loss: 0.2268 - val_acc: 0.4575\n", 937 | "Epoch 118/200\n", 938 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2231 - acc: 0.4603 - val_loss: 0.2282 - val_acc: 0.4572\n", 939 | "Epoch 119/200\n" 940 | ] 941 | }, 942 | { 943 | "name": "stdout", 944 | "output_type": "stream", 945 | "text": [ 946 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2209 - acc: 0.4644 - val_loss: 0.2275 - val_acc: 0.4568\n", 947 | "Epoch 120/200\n", 948 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2220 - acc: 0.4630 - val_loss: 0.2244 - val_acc: 0.4655\n", 949 | "Epoch 121/200\n", 950 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2219 - acc: 0.4607 - val_loss: 0.2299 - val_acc: 0.4690\n", 951 | "Epoch 122/200\n", 952 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2270 - acc: 0.4611 - val_loss: 0.2259 - val_acc: 0.4631\n", 953 | "Epoch 123/200\n", 954 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2196 - acc: 0.4659 - val_loss: 0.2222 - val_acc: 0.4703\n", 955 | "Epoch 124/200\n", 956 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2199 - acc: 0.4631 - val_loss: 0.2292 - val_acc: 0.4530\n", 957 | "Epoch 125/200\n", 958 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2204 - acc: 0.4663 - val_loss: 0.2235 - val_acc: 0.4662\n", 959 | "Epoch 126/200\n", 960 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2195 - acc: 0.4658 - val_loss: 0.2254 - val_acc: 0.4475\n", 961 | "Epoch 127/200\n", 962 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2210 - acc: 0.4655 - val_loss: 0.2255 - val_acc: 0.4565\n", 963 | "Epoch 128/200\n", 964 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2218 - acc: 0.4681 - val_loss: 0.2266 - val_acc: 0.4672\n", 965 | "Epoch 129/200\n", 966 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2186 - acc: 0.4712 - val_loss: 0.2208 - val_acc: 0.4721\n", 967 | "Epoch 130/200\n", 968 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2183 - acc: 0.4686 - val_loss: 0.2193 - val_acc: 0.4679\n", 969 | "Epoch 131/200\n", 970 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2179 - acc: 0.4666 - val_loss: 0.2217 - val_acc: 0.4738\n", 971 | "Epoch 132/200\n", 972 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2188 - acc: 0.4715 - val_loss: 0.2222 - val_acc: 0.4624\n", 973 | "Epoch 133/200\n", 974 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2168 - acc: 0.4753 - val_loss: 0.2229 - val_acc: 0.4579\n", 975 | "Epoch 134/200\n", 976 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2186 - acc: 0.4714 - val_loss: 0.2262 - val_acc: 0.4554\n", 977 | "Epoch 135/200\n", 978 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2174 - acc: 0.4713 - val_loss: 0.2217 - val_acc: 0.4686\n", 979 | "Epoch 136/200\n", 980 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2168 - acc: 0.4696 - val_loss: 0.2213 - val_acc: 0.4599\n", 981 | "Epoch 137/200\n", 982 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2196 - acc: 0.4756 - val_loss: 0.2234 - val_acc: 0.4801\n", 983 | "Epoch 138/200\n", 984 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2177 - acc: 0.4715 - val_loss: 0.2218 - val_acc: 0.4665\n", 985 | "Epoch 139/200\n", 986 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2201 - acc: 0.4750 - val_loss: 0.2272 - val_acc: 0.4735\n", 987 | "Epoch 140/200\n", 988 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2165 - acc: 0.4755 - val_loss: 0.2184 - val_acc: 0.4672\n", 989 | "Epoch 141/200\n", 990 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2148 - acc: 0.4766 - val_loss: 0.2190 - val_acc: 0.4700\n", 991 | "Epoch 142/200\n", 992 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2172 - acc: 0.4708 - val_loss: 0.2207 - val_acc: 0.4672\n", 993 | "Epoch 143/200\n", 994 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2176 - acc: 0.4767 - val_loss: 0.2225 - val_acc: 0.4807\n", 995 | "Epoch 144/200\n", 996 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2164 - acc: 0.4766 - val_loss: 0.2193 - val_acc: 0.4821\n", 997 | "Epoch 145/200\n", 998 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2147 - acc: 0.4793 - val_loss: 0.2183 - val_acc: 0.4672\n", 999 | "Epoch 146/200\n", 1000 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2146 - acc: 0.4756 - val_loss: 0.2167 - val_acc: 0.4804\n", 1001 | "Epoch 147/200\n", 1002 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2148 - acc: 0.4791 - val_loss: 0.2216 - val_acc: 0.4835\n", 1003 | "Epoch 148/200\n", 1004 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2147 - acc: 0.4786 - val_loss: 0.2185 - val_acc: 0.4624\n", 1005 | "Epoch 149/200\n", 1006 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2142 - acc: 0.4787 - val_loss: 0.2172 - val_acc: 0.4974\n", 1007 | "Epoch 150/200\n", 1008 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2156 - acc: 0.4779 - val_loss: 0.2177 - val_acc: 0.4603\n", 1009 | "Epoch 151/200\n", 1010 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2162 - acc: 0.4803 - val_loss: 0.2174 - val_acc: 0.4676\n", 1011 | "Epoch 152/200\n", 1012 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2126 - acc: 0.4820 - val_loss: 0.2172 - val_acc: 0.4790\n", 1013 | "Epoch 153/200\n", 1014 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2129 - acc: 0.4832 - val_loss: 0.2199 - val_acc: 0.4939\n", 1015 | "Epoch 154/200\n", 1016 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2126 - acc: 0.4790 - val_loss: 0.2156 - val_acc: 0.4835\n", 1017 | "Epoch 155/200\n", 1018 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2139 - acc: 0.4848 - val_loss: 0.2180 - val_acc: 0.4665\n", 1019 | "Epoch 156/200\n", 1020 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2134 - acc: 0.4843 - val_loss: 0.2199 - val_acc: 0.4717\n", 1021 | "Epoch 157/200\n", 1022 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2156 - acc: 0.4785 - val_loss: 0.2191 - val_acc: 0.4901\n", 1023 | "Epoch 158/200\n", 1024 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2121 - acc: 0.4812 - val_loss: 0.2170 - val_acc: 0.4832\n", 1025 | "Epoch 159/200\n", 1026 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2150 - acc: 0.4834 - val_loss: 0.2177 - val_acc: 0.4915\n", 1027 | "Epoch 160/200\n", 1028 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2163 - acc: 0.4765 - val_loss: 0.2138 - val_acc: 0.4846\n", 1029 | "Epoch 161/200\n", 1030 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2113 - acc: 0.4810 - val_loss: 0.2168 - val_acc: 0.4710\n", 1031 | "Epoch 162/200\n", 1032 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2115 - acc: 0.4847 - val_loss: 0.2161 - val_acc: 0.4794\n", 1033 | "Epoch 163/200\n", 1034 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2128 - acc: 0.4832 - val_loss: 0.2170 - val_acc: 0.4832\n", 1035 | "Epoch 164/200\n", 1036 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2121 - acc: 0.4842 - val_loss: 0.2191 - val_acc: 0.4894\n", 1037 | "Epoch 165/200\n", 1038 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2127 - acc: 0.4861 - val_loss: 0.2157 - val_acc: 0.4735\n", 1039 | "Epoch 166/200\n", 1040 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2110 - acc: 0.4910 - val_loss: 0.2152 - val_acc: 0.5071\n", 1041 | "Epoch 167/200\n", 1042 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2097 - acc: 0.4922 - val_loss: 0.2136 - val_acc: 0.4762\n", 1043 | "Epoch 168/200\n", 1044 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2097 - acc: 0.4902 - val_loss: 0.2152 - val_acc: 0.4939\n", 1045 | "Epoch 169/200\n", 1046 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2097 - acc: 0.4890 - val_loss: 0.2152 - val_acc: 0.4984\n", 1047 | "Epoch 170/200\n", 1048 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2130 - acc: 0.4891 - val_loss: 0.2184 - val_acc: 0.4696\n", 1049 | "Epoch 171/200\n", 1050 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2122 - acc: 0.4867 - val_loss: 0.2181 - val_acc: 0.4551\n", 1051 | "Epoch 172/200\n", 1052 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2084 - acc: 0.4968 - val_loss: 0.2100 - val_acc: 0.4853\n", 1053 | "Epoch 173/200\n", 1054 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2097 - acc: 0.4891 - val_loss: 0.2113 - val_acc: 0.4894\n", 1055 | "Epoch 174/200\n", 1056 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2111 - acc: 0.4884 - val_loss: 0.2191 - val_acc: 0.4672\n", 1057 | "Epoch 175/200\n", 1058 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2125 - acc: 0.4869 - val_loss: 0.2144 - val_acc: 0.4860\n", 1059 | "Epoch 176/200\n", 1060 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2098 - acc: 0.4944 - val_loss: 0.2133 - val_acc: 0.4922\n", 1061 | "Epoch 177/200\n", 1062 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2187 - acc: 0.4934 - val_loss: 0.2169 - val_acc: 0.4835\n", 1063 | "Epoch 178/200\n" 1064 | ] 1065 | }, 1066 | { 1067 | "name": "stdout", 1068 | "output_type": "stream", 1069 | "text": [ 1070 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2229 - acc: 0.4890 - val_loss: 0.2238 - val_acc: 0.4710\n", 1071 | "Epoch 179/200\n", 1072 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2112 - acc: 0.4916 - val_loss: 0.2121 - val_acc: 0.4717\n", 1073 | "Epoch 180/200\n", 1074 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2125 - acc: 0.4888 - val_loss: 0.2131 - val_acc: 0.4918\n", 1075 | "Epoch 181/200\n", 1076 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2083 - acc: 0.4968 - val_loss: 0.2106 - val_acc: 0.4974\n", 1077 | "Epoch 182/200\n", 1078 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2070 - acc: 0.4958 - val_loss: 0.2091 - val_acc: 0.4925\n", 1079 | "Epoch 183/200\n", 1080 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2064 - acc: 0.4990 - val_loss: 0.2106 - val_acc: 0.4839\n", 1081 | "Epoch 184/200\n", 1082 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2066 - acc: 0.4987 - val_loss: 0.2108 - val_acc: 0.4929\n", 1083 | "Epoch 185/200\n", 1084 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2065 - acc: 0.4980 - val_loss: 0.2141 - val_acc: 0.4853\n", 1085 | "Epoch 186/200\n", 1086 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2076 - acc: 0.4947 - val_loss: 0.2136 - val_acc: 0.4776\n", 1087 | "Epoch 187/200\n", 1088 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2078 - acc: 0.4940 - val_loss: 0.2101 - val_acc: 0.4877\n", 1089 | "Epoch 188/200\n", 1090 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2074 - acc: 0.4951 - val_loss: 0.2130 - val_acc: 0.4846\n", 1091 | "Epoch 189/200\n", 1092 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2065 - acc: 0.4947 - val_loss: 0.2136 - val_acc: 0.4981\n", 1093 | "Epoch 190/200\n", 1094 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2083 - acc: 0.4997 - val_loss: 0.2113 - val_acc: 0.4880\n", 1095 | "Epoch 191/200\n", 1096 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2077 - acc: 0.4964 - val_loss: 0.2096 - val_acc: 0.4981\n", 1097 | "Epoch 192/200\n", 1098 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2064 - acc: 0.5042 - val_loss: 0.2086 - val_acc: 0.5064\n", 1099 | "Epoch 193/200\n", 1100 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2057 - acc: 0.5029 - val_loss: 0.2113 - val_acc: 0.4977\n", 1101 | "Epoch 194/200\n", 1102 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2064 - acc: 0.4980 - val_loss: 0.2120 - val_acc: 0.4925\n", 1103 | "Epoch 195/200\n", 1104 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2054 - acc: 0.5015 - val_loss: 0.2082 - val_acc: 0.4946\n", 1105 | "Epoch 196/200\n", 1106 | "11541/11541 [==============================] - 0s 8us/step - loss: 0.2077 - acc: 0.5014 - val_loss: 0.2116 - val_acc: 0.4998\n", 1107 | "Epoch 197/200\n", 1108 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2062 - acc: 0.4984 - val_loss: 0.2130 - val_acc: 0.5064\n", 1109 | "Epoch 198/200\n", 1110 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2054 - acc: 0.5000 - val_loss: 0.2143 - val_acc: 0.4887\n", 1111 | "Epoch 199/200\n", 1112 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2093 - acc: 0.4966 - val_loss: 0.2153 - val_acc: 0.5082\n", 1113 | "Epoch 200/200\n", 1114 | "11541/11541 [==============================] - 0s 9us/step - loss: 0.2056 - acc: 0.5007 - val_loss: 0.2107 - val_acc: 0.4964\n" 1115 | ] 1116 | } 1117 | ], 1118 | "source": [ 1119 | "autoencoder.compile(metrics=['accuracy'],\n", 1120 | " loss='mean_squared_error',\n", 1121 | " optimizer='adam')\n", 1122 | "\n", 1123 | "cp = ModelCheckpoint(filepath=\"autoencoder_classifier.h5\",\n", 1124 | " save_best_only=True,\n", 1125 | " verbose=0)\n", 1126 | "\n", 1127 | "tb = TensorBoard(log_dir='./logs',\n", 1128 | " histogram_freq=0,\n", 1129 | " write_graph=True,\n", 1130 | " write_images=True)\n", 1131 | "\n", 1132 | "history = autoencoder.fit(df_train_0_x_rescaled, df_train_0_x_rescaled,\n", 1133 | " epochs=nb_epoch,\n", 1134 | " batch_size=batch_size,\n", 1135 | " shuffle=True,\n", 1136 | " validation_data=(df_valid_0_x_rescaled, df_valid_0_x_rescaled),\n", 1137 | " verbose=1,\n", 1138 | " callbacks=[cp, tb]).history" 1139 | ] 1140 | }, 1141 | { 1142 | "cell_type": "code", 1143 | "execution_count": 108, 1144 | "metadata": {}, 1145 | "outputs": [], 1146 | "source": [ 1147 | "autoencoder = load_model('autoencoder_classifier.h5')" 1148 | ] 1149 | }, 1150 | { 1151 | "cell_type": "code", 1152 | "execution_count": 109, 1153 | "metadata": {}, 1154 | "outputs": [ 1155 | { 1156 | "data": { 1157 | "image/png": "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\n", 1158 | "text/plain": [ 1159 | "
" 1160 | ] 1161 | }, 1162 | "metadata": { 1163 | "needs_background": "light" 1164 | }, 1165 | "output_type": "display_data" 1166 | } 1167 | ], 1168 | "source": [ 1169 | "plt.plot(history['loss'], linewidth=2, label='Train')\n", 1170 | "plt.plot(history['val_loss'], linewidth=2, label='Valid')\n", 1171 | "plt.legend(loc='upper right')\n", 1172 | "plt.title('Model loss')\n", 1173 | "plt.ylabel('Loss')\n", 1174 | "plt.xlabel('Epoch')\n", 1175 | "plt.show()" 1176 | ] 1177 | }, 1178 | { 1179 | "cell_type": "code", 1180 | "execution_count": 110, 1181 | "metadata": {}, 1182 | "outputs": [ 1183 | { 1184 | "data": { 1185 | "image/png": "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\n", 1186 | "text/plain": [ 1187 | "
" 1188 | ] 1189 | }, 1190 | "metadata": { 1191 | "needs_background": "light" 1192 | }, 1193 | "output_type": "display_data" 1194 | } 1195 | ], 1196 | "source": [ 1197 | "valid_x_predictions = autoencoder.predict(df_valid_x_rescaled)\n", 1198 | "mse = np.mean(np.power(df_valid_x_rescaled - valid_x_predictions, 2), axis=1)\n", 1199 | "error_df = pd.DataFrame({'Reconstruction_error': mse,\n", 1200 | " 'True_class': df_valid['y']})\n", 1201 | "\n", 1202 | "precision_rt, recall_rt, threshold_rt = precision_recall_curve(error_df.True_class, error_df.Reconstruction_error)\n", 1203 | "plt.plot(threshold_rt, precision_rt[1:], label=\"Precision\",linewidth=5)\n", 1204 | "plt.plot(threshold_rt, recall_rt[1:], label=\"Recall\",linewidth=5)\n", 1205 | "plt.title('Precision and recall for different threshold values')\n", 1206 | "plt.xlabel('Threshold')\n", 1207 | "plt.ylabel('Precision/Recall')\n", 1208 | "plt.legend()\n", 1209 | "plt.show()" 1210 | ] 1211 | }, 1212 | { 1213 | "cell_type": "code", 1214 | "execution_count": 111, 1215 | "metadata": {}, 1216 | "outputs": [], 1217 | "source": [ 1218 | "test_x_predictions = autoencoder.predict(df_test_x_rescaled)\n", 1219 | "mse = np.mean(np.power(df_test_x_rescaled - test_x_predictions, 2), axis=1)\n", 1220 | "error_df_test = pd.DataFrame({'Reconstruction_error': mse,\n", 1221 | " 'True_class': df_test['y']})\n", 1222 | "error_df_test = error_df_test.reset_index()" 1223 | ] 1224 | }, 1225 | { 1226 | "cell_type": "code", 1227 | "execution_count": 120, 1228 | "metadata": {}, 1229 | "outputs": [ 1230 | { 1231 | "data": { 1232 | "image/png": "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\n", 1233 | "text/plain": [ 1234 | "
" 1235 | ] 1236 | }, 1237 | "metadata": { 1238 | "needs_background": "light" 1239 | }, 1240 | "output_type": "display_data" 1241 | } 1242 | ], 1243 | "source": [ 1244 | "threshold_fixed = 0.4\n", 1245 | "groups = error_df_test.groupby('True_class')\n", 1246 | "\n", 1247 | "fig, ax = plt.subplots()\n", 1248 | "\n", 1249 | "for name, group in groups:\n", 1250 | " ax.plot(group.index, group.Reconstruction_error, marker='o', ms=3.5, linestyle='',\n", 1251 | " label= \"Break\" if name == 1 else \"Normal\")\n", 1252 | "ax.hlines(threshold_fixed, ax.get_xlim()[0], ax.get_xlim()[1], colors=\"r\", zorder=100, label='Threshold')\n", 1253 | "ax.legend()\n", 1254 | "plt.title(\"Reconstruction error for different classes\")\n", 1255 | "plt.ylabel(\"Reconstruction error\")\n", 1256 | "plt.xlabel(\"Data point index\")\n", 1257 | "plt.show();" 1258 | ] 1259 | }, 1260 | { 1261 | "cell_type": "code", 1262 | "execution_count": 121, 1263 | "metadata": {}, 1264 | "outputs": [], 1265 | "source": [ 1266 | "pred_y = [1 if e > threshold_fixed else 0 for e in error_df.Reconstruction_error.values]\n" 1267 | ] 1268 | }, 1269 | { 1270 | "cell_type": "code", 1271 | "execution_count": 122, 1272 | "metadata": {}, 1273 | "outputs": [], 1274 | "source": [ 1275 | "predictions = pd.DataFrame({'true': error_df.True_class,\n", 1276 | " 'predicted': pred_y})" 1277 | ] 1278 | }, 1279 | { 1280 | "cell_type": "code", 1281 | "execution_count": 123, 1282 | "metadata": {}, 1283 | "outputs": [ 1284 | { 1285 | "data": { 1286 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAd4AAAHwCAYAAAAIOA6FAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJzt3XecJVWZ//HPlyFnEESSBEUxrCAgZhdFQUAFjGBCRHHNOfNTFnV1VzGtcVAUVlF0BUXEgJhdkSzCgoKAgCQRJDs7Qz+/P241Xsbpnp6ZrlvdU5+3r/vqe0+dqnPu2MwzzzmnTqWqkCRJo7FC1x2QJKlPDLySJI2QgVeSpBEy8EqSNEIGXkmSRsjAK0nSCBl41TtJVkvy7SQ3Jfn6MlzneUl+MJ1960qSxyb5Xdf9kPog3sermSrJc4E3ANsCtwDnAO+rql8s43VfALwaeFRVLVjmjs5wSQrYpqou7rovksx4NUMleQPwUeDfgI2AewOfAvaehstvAfy+D0F3KpKs2HUfpD4x8GrGSbIOcBjwyqo6rqpuq6r5VfXtqnpzU2eVJB9NclXz+miSVZpjuyS5Mskbk1yX5OokBzbH/hV4F/CcJLcmOSjJoUm+NNT+lklqPCAleVGSS5LckuTSJM8bKv/F0HmPSnJ6M4R9epJHDR37SZL3JPllc50fJNlggu8/3v+3DPV/nyR7Jvl9khuSvGOo/s5JfpXkr03dTyRZuTn2s6bab5rv+5yh6781yTXAF8bLmnPu07SxQ/N5kyTXJ9llmf6PlQQYeDUzPRJYFTh+kjrvBB4BbA9sB+wMHDJ0/F7AOsCmwEHAJ5OsV1XvZpBFH1tVa1bV5yfrSJI1gI8De1TVWsCjGAx5L1xvfeA7Td17AB8GvpPkHkPVngscCNwTWBl40yRN34vBn8GmDP6hcATwfGBH4LHAu5Js3dS9E3g9sAGDP7tdgVcAVNXjmjrbNd/32KHrr88g+z94uOGq+gPwVuDLSVYHvgB8sap+Mkl/JU2RgVcz0T2A6xczFPw84LCquq6q/gz8K/CCoePzm+Pzq+ok4Fbg/kvZnzHgwUlWq6qrq+r8RdTZC7ioqv6rqhZU1VeAC4GnDtX5QlX9vqruAL7G4B8NE5nPYD57PvBVBkH1Y1V1S9P++cBDAKrqzKo6tWn3MuCzwD9P4Tu9u6rmNf25m6o6ArgI+DWwMYN/6EiaBgZezUR/ATZYzNzjJsAfhz7/sSm76xoLBe7bgTWXtCNVdRvwHOBfgKuTfCfJtlPoz3ifNh36fM0S9OcvVXVn8348MF47dPyO8fOT3C/JiUmuSXIzg4x+kcPYQ/5cVX9bTJ0jgAcD/1lV8xZTV9IUGXg1E/0K+BuwzyR1rmIwTDru3k3Z0rgNWH3o872GD1bV96vqSQwyvwsZBKTF9We8T39ayj4tiU8z6Nc2VbU28A4gizln0tsZkqzJYHHb54FDm6F0SdPAwKsZp6puYjCv+clmUdHqSVZKskeS/2iqfQU4JMmGzSKldwFfmuiai3EO8Lgk924Wdr19/ECSjZI8rZnrncdgyPrORVzjJOB+SZ6bZMUkzwEeCJy4lH1aEmsBNwO3Ntn4yxc6fi2w9T+cNbmPAWdW1UsYzF1/Zpl7KQkw8GqGqqoPM7iH9xDgz8AVwKuAbzZV3gucAZwL/BY4qylbmrZOBo5trnUmdw+WKwBvZJDR3sBg7vQVi7jGX4CnNHX/ArwFeEpVXb80fVpCb2KwcOsWBtn4sQsdPxQ4qln1/OzFXSzJ3sCTGQyvw+D/hx3GV3NLWjZuoCFJ0giZ8UqSNEIGXkmSRsjAK0nSCBl4JUkaIQOvJEkjNGOfSjL/+ktcbq1Zb/P77tV1F6Rpcc1fL1jcpixLrY2/71faYOvW+ruszHglSRqhGZvxSpJ6YmxRm8Etv8x4JUkaITNeSVK3aqzrHoyUGa8kSSNkxitJ6tZYvzJeA68kqVPlULMkSWqLGa8kqVs9G2o245UkaYTMeCVJ3erZHK+BV5LULXeukiRJbTHjlSR1q2dDzWa8kiSNkBmvJKlbPbudyMArSeqUO1dJkqTWmPFKkrrVs6FmM15JkkbIjFeS1C3neCVJUlvMeCVJ3erZlpEGXklStxxqliRJbTHjlSR1y9uJJElSW8x4JUnd6tkcr4FXktQth5olSVq+Jdk8yY+TXJDk/CSvbcoPTfKnJOc0rz2Hznl7kouT/C7J7kPlT27KLk7ytsW1bcYrSepUVSf38S4A3lhVZyVZCzgzycnNsY9U1YeGKyd5ILAf8CBgE+CHSe7XHP4k8CTgSuD0JCdU1f9O1LCBV5LUO1V1NXB18/6WJBcAm05yyt7AV6tqHnBpkouBnZtjF1fVJQBJvtrUnTDwOtQsSepWjU3/awkk2RJ4KPDrpuhVSc5NcmSS9ZqyTYErhk67simbqHxCBl5JUrfGxqb9leTgJGcMvQ5eVNNJ1gS+Abyuqm4GPg3cB9ieQUZ8+HjVRZxek5RPyKFmSdJyp6rmAnMnq5NkJQZB98tVdVxz3rVDx48ATmw+XglsPnT6ZsBVzfuJyhfJjFeS1K0OhpqTBPg8cEFVfXiofOOhavsC5zXvTwD2S7JKkq2AbYDTgNOBbZJslWRlBguwTpisbTNeSVIfPRp4AfDbJOc0Ze8A9k+yPYPh4suAlwFU1flJvsZg0dQC4JXVLMdO8irg+8Ac4MiqOn+yhg28kqRudfBYwKr6BYuenz1pknPeB7xvEeUnTXbewgy8kqRu9WzLSOd4JUkaITNeSVK33KtZkiS1xYxXktQt53glSVJbzHglSd3q2RyvgVeS1K2eBV6HmiVJGiEzXklSp5qdF3vDjFeSpBEy45Ukdatnc7wGXklSt7yPV5IktcWMV5LUrZ4NNZvxSpI0Qma8kqRu9WyO18ArSeqWQ82SJKktZrySpG71bKjZjFeSpBEy45Ukdcs5XkmS1BYzXklSt3qW8Rp4JUndcnGVJElqixmvJKlbPRtqNuOVJGmEzHglSd3q2RyvgVeS1C2HmiVJUlvMeCVJ3erZULMZryRJI2TGK0nqVs/meA28kqRu9SzwOtQsSdIImfFKkrpV1XUPRsqMV5KkETLjlSR1yzleSZLUFjNeSVK3epbxGnglSd1y5ypJktQWM15JUrd6NtRsxitJ0giZ8UqSutWzDTQMvJKkbjnULEmS2mLGK0nqlhmvJElqixmvJKlbPdtAw8ArSepUjfVrVbNDzZIkjZAZrySpWy6ukiRJbTHjlSR1q2eLq8x4JUkaITNeSVK3eraq2cArSeqWi6skSVJbzHglSd0y45UkSW0x45UkdatcXCVJ0ug41CxJktpixrscufraP/OO93yI62+4kRUSnrn3Hrzg2fvwxv/3fi67/EoAbrn1VtZac02+cdQn+etNN/P6d76P8y78Pfvs8STe+cZXAHDH3/7GGw75N67809WssMIK7PKYh/P6l7+4y6+mnvvIJ97Lk3bfhev/fAO7POppAHz2yA9zn222BGCdddbmpptu5omPfTrrrbcunzv6o2z/0Adz7DHf5B1veW+HPdeUeB+vZqsV58zhza9+KQ+8/3257bbbefZBr+FRD3soh7/n7XfV+eB/HsGaa6wOwMorr8yrX/oCLrrkj1x8yR/vdq0D938GO++4HfPnz+eg17ydn//qdB77yIeN9PtI44495pscecQx/OenP3BX2cte/Ia73h/63rdw8823AjBv3jz+/X0fZ9sHbMO2D9hm5H2VFseh5uXIhhuszwPvf18A1lhjdbbeYnOu/fNf7jpeVXzvRz9jzyftAsDqq63KDts9mFVWXvlu11lt1VXZecftAFhppZV4wP3vy7V/vn40X0JahFP/5wz+euNfJzz+1H2ezPH//R0Abr/9Dk479SzmzZs3qu5pWdXY9L9msFYy3iRPn+x4VR3XRrv6uz9dfS0XXPQHHvKg+99VduZvzuMe663HFptvOuXr3HzLrfz0l7/m+c/au41uSsvsEY/aiev//BcuXWjURrOIQ83T4qmTHCvAwNui22+/g9e/87289TUvY8011rir/KSTf8KeT/rnKV9nwYI7ecuh/87znvk0Nt904za6Ki2zfZ+xF8d/4ztdd0OaslYCb1UduDTnJTkYOBjgU4e/l5e8cP9p7VcfzF+wgNe9873stdvjedIuj76rfMGCO/nhT/+Hrx358Slf69D/+Bj33mwTXvCcfdvoqrTM5syZw55PfSK77fLMrruiZVA9u52o9cVVSfYCHgSsOl5WVYctqm5VzQXmAsy//pJ+jT1Mg6riXe//KFtvsTkH7Hf30f5TzzibrbfYjHvdc8MpXevjc4/i1ltv57C3va6NrkrT4nG7PJKLL7qUq6+6tuuuSFPWauBN8hlgdeDxwOeAZwKntdlmn5197vl8+3unsM19tuQZB7wSgNe+7AAe96id+e4Pf8oeT9zlH87Z7RkHcOtttzN/wQJ+9PP/Ye5H3scaa6zO3KO+ylZbbM6zDnw1APs/46k882lPHuXXke7y6c99iEc9ZmfWv8e6nHX+j/ngBz7BV/7rG+zzjD3vWlQ17PRzf8iaa63ByiutxJP32pX9nv4Sfv+7P3TQc01JB3O8STYHjgbuBYwBc6vqY0nWB44FtgQuA55dVTcmCfAxYE/gduBFVXVWc60DgEOaS7+3qo6atO1qcauuJOdW1UOGfq4JHFdVuy3uXDNeLQ82v+9eXXdBmhbX/PWCtHXt2973wmn/+36Ndx49aX+TbAxsXFVnJVkLOBPYB3gRcENVfSDJ24D1quqtSfYEXs0g8D4c+FhVPbwJ1GcAOzFYw3QmsGNV3ThR223fTnRH8/P2JJsA84GtWm5TkjSbdHA7UVVdPZ6xVtUtwAXApsDewHjGehSDYExTfnQNnAqs2wTv3YGTq+qGJtieDEw6PNj2HO+JSdYFPgicxeBfA59ruU1J0mzSwlDz8GLdxtxmHdGi6m4JPBT4NbBRVV0Ng+Cc5J5NtU2BK4ZOu7Ipm6h8Qq0G3qp6T/P2G0lOBFatqpvabFOSpOHFupNppkC/Abyuqm4eTOUuuuqimpmkfEJtL66aA+zFYJJ6xaaMqvpwm+1KkmaRjm4nSrISg6D75aGNna5NsnGT7W4MXNeUXwlsPnT6ZsBVTfkuC5X/ZLJ2257j/TaDiep7AGsNvSRJ6kyzSvnzwAULJYMnAAc07w8AvjVU/sIMPAK4qRmS/j6wW5L1kqwH7NaUTajtOd7NquohLbchSZrNutky8tHAC4DfJjmnKXsH8AHga0kOAi4HntUcO4nBiuaLGdxOdCBAVd2Q5D3A6U29w6rqhskabjvwfjfJblX1g5bbkSTNVh081KCqfsGi52cBdl1E/QJeOcG1jgSOnGrbbQfeU4Hjk6zA4FaiMOj/2i23K0nSjNR24D0ceCTw22pzpw5J0uzVs6cTtb246iLgPIOuJEkDbWe8VwM/SfJd4K6nUns7kSRpnE8nml6XNq+Vm5ckSXfXs6Hm1gJvs3nGmlX15rbakCRptmkt8FbVnUl2aOv6kqTlhBnvtDonyQnA14HbxguHtuaSJKlX2g686wN/AZ4wVFaAgVeSNNDBBhpdavvpRAe2eX1JkmabVu/jTbJZkuOTXJfk2iTfSLJZm21KkmaZsZr+1wzW9gYaX2DwRIdNGDwY+NtNmSRJANRYTftrJms78G5YVV+oqgXN64vAhi23KUnSjNV24L0+yfOTzGlez2ew2EqSpAGHmqfVi4FnA9cw2D7ymU2ZJEm91Paq5suBp7XZhiRplnOv5mWX5F2THK6qek8b7UqSZqEZPjQ83drKeG9bRNkawEHAPQADrySpl1oJvFV1+Pj7JGsBrwUOBL4KHD7ReZKkHjLjnR5J1gfeADwPOArYoapubKs9SZJmg7bmeD8IPB2YC/xTVd3aRjuSpNmvyox3OrwRmAccArwzyXh5GCyuWruldiVJs41Dzcuuqtq+P1iSpFmp7ccCSpI0uZ5lvGamkiSNkBmvJKlTM/1pQtPNjFeSpBEy45UkdatnGa+BV5LUrX49I8GhZkmSRsmMV5LUKRdXSZKk1pjxSpK61bOM18ArSeqWi6skSVJbzHglSZ1ycZUkSWqNGa8kqVs9m+M18EqSOuVQsyRJao0ZrySpWz0bajbjlSRphMx4JUmdqp5lvAZeSVK3ehZ4HWqWJGmEzHglSZ3q21CzGa8kSSNkxitJ6pYZryRJaosZrySpU32b4zXwSpI61bfA61CzJEkjZMYrSeqUGa8kSWqNGa8kqVuVrnswUgZeSVKnHGqWJEmtMeOVJHWqxvo11GzGK0nSCJnxSpI61bc5XgOvJKlT1bNVzQ41S5I0Qma8kqRO9W2o2YxXkqQRMuOVJHXK24kkSVJrzHglSZ2q6roHo2XglSR1yqFmSZLUGjNeSVKnzHglSVJrDLySpE5VTf9rKpIcmeS6JOcNlR2a5E9Jzmleew4de3uSi5P8LsnuQ+VPbsouTvK2xbXrULMkqVMdDjV/EfgEcPRC5R+pqg8NFyR5ILAf8CBgE+CHSe7XHP4k8CTgSuD0JCdU1f9O1OgSZbxJ1mkalyRpVquqnwE3TLH63sBXq2peVV0KXAzs3LwurqpLqur/gK82dSe02MCb5JQkaydZD/gtcEySD06xo5IkTaoq0/5aRq9Kcm4zFL1eU7YpcMVQnSubsonKJzSVjHf9qroZeDpwVFVtD+y+mHMkSepMkoOTnDH0OniKp34auA+wPXA1cPj4JRdRtyYpn9BU5nhXTLIh8CzgXVOoL0nSlLXxdKKqmgvMXYrzrh1/n+QI4MTm45XA5kNVNwOuat5PVL5IU8l43wf8FLi8qk5LsjVw6RTOkyRpscYq0/5aWkk2Hvq4LzC+4vkEYL8kqyTZCtgGOA04HdgmyVZJVmawAOuEydpYbMZbVV9lMFk8/vkSFjNxLEnSTJfkK8AuwAZJrgTeDeySZHsGw8WXAS8DqKrzk3wN+F9gAfDKqrqzuc6rgO8Dc4Ajq+r8SdutxdzwlOT9wPuB24HvMBj3fn1VHbNU33SK5l9/Sc+2zdbyaPP77tV1F6Rpcc1fL2jtnp/fbbvHtP99f/8Lvztjt8OaylDzHs3iqqcA1zG4h+mtrfZKkqTl1JQWVzU/9wS+UlXXJzEblSRNi77t1TyVwPvdZjutO4FXJtkAmNdutyRJWj5NZXHVm5sNM26oqgVJ/sbgnl5JkpbZVPdWXl5Mda/m9YHHJFl1qKzVxVWSpH5wqHkhSQ4BdgO2ZbBcenfgFxh4JUlaYlNZ1fwc4PHA1VX1AmA7fKqRJGmazKQNNEZhKoH3juYm4QVJ1gKuAbZut1uSJC2fppK5np1kXeBI4AzgZuCsVnslSeqNaXia0KwylVXNL2vefjLJ94G1q8rAK0maFq5qbiR5yASHFiR5SFWd21KfJElabk2W8X5ykmMFPG6a+yJJ6qGZvhhquk0YeKvqsaPsiCRJfbDYVc1J/qVZXDX+eb0kB7fbLUlSX1Rl2l8z2VRuJ/qXqvrr+IequhF4eXtdkiT1SdX0v2ayqQTeOcMfkqwArNROdyRJWr5N5T7ek5N8BfgMg0VVLwd+2GqvJEm94eKqf/RmBsH29UCAHwCfbbNTAGts6qJpzX5jM33MS9LITWUDjTuBTzQvSZKm1UxfDDXdpjLHK0mSpolPGZIkdco53gkkWaWq5rXZGUlS//RtJcRUNtDYOclvgYuaz9sl+c/WeyZJ0nJoKhnvx4GnAN8EqKrfJHl8q72SJPVG34aap7K4aoWq+uNCZXe20RlJkpZ3U8l4r0iyM1BJ5gCvBn7fbrckSX3Rt9uJphJ4X85guPnewLUMdq1yr2ZJ0rQY67oDIzaVDTSuA/YbQV8kSVruLTbwJjmCRaz2riofDShJWmaFQ80LG34gwqrAvsAV7XRHkqTl21SGmo8d/pzkv4CTW+uRJKlXxnq2g8bSbBm5FbDFdHdEktRPYw41312SG/n7HO8KwA3A29rslCRJy6tJA2+SANsBf2qKxqp8wKgkafr0bXHVpDtXNUH2+Kq6s3kZdCVJWgZT2TLytCQ7tN4TSVIvjbXwmskmHGpOsmJVLQAeA7w0yR+A24AwSIYNxpIkLaHJ5nhPA3YA9hlRXyRJPdS3Od7JAm8AquoPI+qLJKmHZvrQ8HSbLPBumOQNEx2sqg+30B9JkpZrkwXeOcCa0LMxAEnSSJnx/t3VVXXYyHoiSVIPLHaOV5KkNrm46u92HVkvJEm9NdavuDvxBhpVdcMoOyJJUh8szdOJJEmaNn17OtFUtoyUJEnTxIxXktSpvj19x8ArSepU3+7jdahZkqQRMuOVJHVqLC6ukiRJLTHjlSR1qm+Lq8x4JUkaITNeSVKn+raq2cArSeqUezVLkqTWmPFKkjrlXs2SJKk1ZrySpE717XYiA68kqVMurpIkSa0x45Ukdapv9/Ga8UqSNEJmvJKkTrm4SpKkEXJxlSRJao0ZrySpUy6ukiRJrTHjlSR1yoxXkiS1xoxXktSpclWzJEmjM9bCayqSHJnkuiTnDZWtn+TkJBc1P9drypPk40kuTnJukh2GzjmgqX9RkgMW166BV5LUV18EnrxQ2duAU6pqG+CU5jPAHsA2zetg4NMwCNTAu4GHAzsD7x4P1hMx8EqSOtVVxltVPwNuWKh4b+Co5v1RwD5D5UfXwKnAukk2BnYHTq6qG6rqRuBk/jGY342BV5K03ElycJIzhl4HT/HUjarqaoDm5z2b8k2BK4bqXdmUTVQ+IRdXSZI61cZezVU1F5g7jZdc1BKwmqR8Qma8kqROjWX6X8vg2mYImebndU35lcDmQ/U2A66apHxCBl5Jkv7uBGB8ZfIBwLeGyl/YrG5+BHBTMxT9fWC3JOs1i6p2a8om5FCzJKlTXe1cleQrwC7ABkmuZLA6+QPA15IcBFwOPKupfhKwJ3AxcDtwIEBV3ZDkPcDpTb3DqmrhBVt3Y+CVJPVSVe0/waFdF1G3gFdOcJ0jgSOn2q6BV5LUqb7t1WzglSR1qo1VzTOZi6skSRohM15JUqeW8fafWceMV5KkETLjlSR1qm+Lq8x4JUkaITNeSVKn+raq2cArSerUWM9Cr0PNkiSNkBmvJKlTLq6SJEmtMeOVJHWqXzO8Bl5JUsccapYkSa0x45Ukdcq9miVJUmvMeCVJnerbBhoGXklSp/oVdh1qliRppMx4JUmd8nYiSZLUGjNeSVKnXFwlSdII9SvsOtQsSdJImfFKkjrl4ipJktQaM15JUqf6trjKjFeSpBEy45Ukdapf+a6BV5LUMRdXSZKk1pjxSpI6VT0bbDbjlSRphMx4JUmd6tscr4FXktQp7+OVJEmtMeOVJHWqX/muGa8kSSNlxitJ6lTf5ngNvD2xyiqr8KNTvsEqq6zMiivO4bjjTuKw9xzOZz/zIXbc8SEk4aKLLuGgl7ye2267vevuSlP22te8lBe/eH+qivPOu5CDXvIG5s2b13W3tAT6tqrZoeaemDdvHrvt/mx2ethu7PSw3dltt13YeecdeNObD2Wnh+3Gjjs9icuv+BOvePmBXXdVmrJNNrkXr3rli3n4I/Zk+4fuypw5c3jOs/fuulvSpMx4e2Q8k11ppRVZaaUVqSpuueXWu46vttqqVPVryEez34orrshqq63K/PnzWX211bj66mu67pKWkDtXTaMkBy2i7ANttqmJrbDCCpx+2vf505W/4ZRTfs7pp58NwBFzD+eKy8/m/ve7L5/81JEd91KauquuuoYPf+QzXPqH07jy8rO56eabOfmHP+u6W9Kk2h5qfmaS541/SPIpYMOW29QExsbGeNjOu7PV1g9jp52250EPvD8ALz34jWyx5Y5c+LuLeNazntZxL6WpW3fddXjaU3fnvvd7BJtvsQNrrLE6z33u07vulpbQWAuvmaztwPt04EVJ9k9yNPB/VfUPWfC4JAcnOSPJGWN33tZy1/rrpptu5mc/+xW77b7LXWVjY2N8/evfZt999+yuY9IS2nXXx3LpZZdz/fU3sGDBAo7/5nd55CN26rpb0qRaCbxJ1k+yPrAa8BLgLcDNwGFN+SJV1dyq2qmqdlphzhptdK23NthgfdZZZ20AVl11VZ7whMfw+9//gfvcZ8u76uy11xP53e8u7qiH0pK74vI/8fCH78Bqq60KwBMe/xguvPCijnulJVUt/G8ma2tx1ZkMNiPJ0M+9mlcBW7fUriaw8b024vOf/whz5sxhhRXCf//3iZx00in8+EfHsfbaa5HAuedewKte/fauuypN2Wmnn81xx32H00/7PgsWLOCcc87niM99uetuaQnN9KHh6ZaZuop15VU2m5kdk5bA2Az970taUgv+709p69oHbPmMaf8P5ajLvtFaf5dV67cTJXkw8EBg1fGyqjq67XYlSbND3/6B2mrgTfJuYBcGgfckYA/gF4CBV5LUS63fTgTsClxTVQcC2wGrtNymJGkWqRZeM1nbQ813VNVYkgVJ1gauw4VVkqQhPiRhep2RZF3gCAYrnW8FTmu5TUmSZqxWA29VvaJ5+5kk3wPWrqpz22xTkjS7zPT7bqdb23s1J8nzk7yrqi4D/ppk5zbblCRpJmt7cdWngEcC+zefbwE+2XKbkqRZpG97Nbc9x/vwqtohydkAVXVjkpVbblOSNIv0bXFV2xnv/CRzaFZ3J9mQmf+PEUmSWtN2xvtx4Hjgnknex+C+3kNablOSNIv0bXFV26uav5zkTAabaATYp6ouaLNNSZJmstYCb5IVgHOr6sHAhW21I0ma3fo2/9jaHG9VjQG/SXLvttqQJGm2aXuOd2Pg/CSnAbeNF1bV01puV5I0S8zUx9O2pe3A+68tX1+SNMv17XaithdX/XT8fZINgL9U3/5pI0nSkFbmeJM8IslPkhyX5KFJzgPOA65N8uQ22pQkzU7uXDU9PgG8A1gH+BGwR1WdmmRb4CvA91pqV5KkGa2twLtiVf0AIMlhVXUqQFVdmKSlJiVJs5EbaEyP4Uz/joWO9etPWJI0KRdXTY/tktzMYLeq1Zr3NJ9XbalNSZJmvFYCb1XNaeO6kqTlT1c3uyS5jMHjau+/jlzRAAAJ3UlEQVQEFlTVTknWB44FtgQuA57dPFkvwMeAPYHbgRdV1VlL027bTyeSJGkme3xVbV9VOzWf3wacUlXbAKc0nwH2ALZpXgcDn17aBg28kqROzbDbifYGjmreHwXsM1R+dA2cCqybZOOlacDAK0nqVLXwvyk3DT9IcmaSg5uyjarqaoDm5z2b8k2BK4bOvbIpW2JtbxkpSdLINYH04KGiuVU1d6Fqj66qq5LcEzg5yWRP0lvUvbBLNTlt4JUkdaqN24maILtwoF24zlXNz+uSHA/szGCHxY2r6upmKPm6pvqVwOZDp28GXLU0fXOoWZLUO0nWSLLW+HtgNwZbG58AHNBUOwD4VvP+BOCFGXgEcNP4kPSSMuOVJHWqo9uJNgKOb3ZTXBE4pqq+l+R04GtJDgIuB57V1D+Jwa1EFzO4nejApW3YwCtJ6p2qugTYbhHlfwF2XUR5Aa+cjrYNvJKkTrllpCRJI9S3hyS4uEqSpBEy45UkdWqso72au2LGK0nSCJnxSpI61a9818ArSepY31Y1O9QsSdIImfFKkjplxitJklpjxitJ6lRHezV3xsArSeqUQ82SJKk1ZrySpE65V7MkSWqNGa8kqVN9W1xlxitJ0giZ8UqSOtW3Vc0GXklSpxxqliRJrTHjlSR1qm9DzWa8kiSNkBmvJKlTfdtAw8ArSerUmIurJElSW8x4JUmd6ttQsxmvJEkjZMYrSepU3+Z4DbySpE451CxJklpjxitJ6lTfhprNeCVJGiEzXklSp5zjlSRJrTHjlSR1qm9zvAZeSVKnHGqWJEmtMeOVJHWqaqzrLoyUGa8kSSNkxitJ6tRYz+Z4DbySpE5Vz1Y1O9QsSdIImfFKkjrVt6FmM15JkkbIjFeS1Km+zfEaeCVJnerblpEONUuSNEJmvJKkTrlXsyRJao0ZrySpU31bXGXGK0nSCJnxSpI61bcNNAy8kqROOdQsSZJaY8YrSeqUG2hIkqTWmPFKkjrVtzleA68kqVN9W9XsULMkSSNkxitJ6lTfhprNeCVJGiEzXklSp/p2O5GBV5LUKR8LKEmSWmPGK0nqVN+Gms14JUkaITNeSVKnvJ1IkiS1xoxXktSpvq1qNvBKkjrlULMkSWqNGa8kqVNmvJIkqTVmvJKkTvUr34X0LcXX3yU5uKrmdt0PaVn5u6zZxKHmfju46w5I08TfZc0aBl5JkkbIwCtJ0ggZePvNOTEtL/xd1qzh4ipJkkbIjFeSpBEy8M5SSSrJ4UOf35Tk0BH34YtJnjnKNrX8S3JnknOS/CbJWUkeNY3XvizJBtN1PWlpGHhnr3nA05f2L5Ekbp6imeqOqtq+qrYD3g68f+EKSeaMvlvS9DDwzl4LGCwoef3CB5JskeSUJOc2P+/dlH8xyYeT/Bj49ySHJjkqyQ+aTODpSf4jyW+TfC/JSs1570pyepLzksxNkpF+U/XZ2sCNAEl2SfLjJMcAv23Knp/ktCZD/ux4QE7y6SRnJDk/yb8ufNEkqzW/4y8d5ZeRwMA7230SeF6SdRYq/wRwdFU9BPgy8PGhY/cDnlhVb2w+3wfYC9gb+BLw46r6J+COphzgE1X1sKp6MLAa8JRWvo00sFoTSC8EPge8Z+jYzsA7q+qBSR4APAd4dFVtD9wJPK+p986q2gl4CPDPSR4ydI01gW8Dx1TVEW1/GWlhBt5ZrKpuBo4GXrPQoUcCxzTv/wt4zNCxr1fVnUOfv1tV8xlkEHOA7zXlvwW2bN4/Psmvk/wWeALwoGn7EtI/Gh9q3hZ4MnD00CjLaVV1afN+V2BH4PQk5zSft26OPTvJWcDZDH5fHzh0/W8BX6iqo9v+ItKiOM83+30UOAv4wiR1hu8Zu22hY/MAqmosyfz6+/1lY8CKSVYFPgXsVFVXNAu4Vp2WnkuLUVW/atYxbNgUDf/+Bjiqqt4+fE6SrYA3AQ+rqhuTfJG7/87+EtgjyTHl/ZTqgBnvLFdVNwBfAw4aKv4fYL/m/fOAXyxDE+N/YV2fZE3AVcwamSTbMhiJ+csiDp8CPDPJPZu66yfZgsG88G3ATUk2AvZY6Lx3Ndf7VGsdlyZh4F0+HA4Mr25+DXBgknOBFwCvXdoLV9VfgSMYDD1/Ezh9GfopTcX4HO85wLHAAQtNjwBQVf8LHAL8oPldPxnYuKp+w2CI+XzgSAYZ7sJeB6ya5D/a+hLSRNy5SpKkETLjlSRphAy8kiSNkIFXkqQRMvBKkjRCBl5JkkbIwKvlytCTbc5L8vUkqy/DtXZJcmLz/mlJ3jZJ3XWTvGIp2jg0yZuWoP6tS9qGpJnFwKvlzfh2gw8G/g/4l+GDGVji3/uqOqGqPjBJlXWBJQ68kvrHwKvl2c+B+ybZMskFST7FYHvNzZPsluRXzfNev97sykWSJye5MMkvgKePXyjJi5J8onm/UZLjm+fF/qZ5XuwHgPs02fYHm3pvbp7qdO7wE3KSvDPJ75L8ELj/ojo+QRvDx9dsnjx1VvM0qb2b8jWSfKc557wkz2nKP5Dkf5u+fGja/oQlLTH3atZyKYPnDe/B3x/6cH/gwKp6RbP37yEMntJ0W5K3Am9odjE6gsGDIC5msGvSonwc+GlV7ds8hm5N4G3Ag5un5JBkN2AbBk/TCXBCkscx2MpwP+ChDP77Ows4c4ptDPsbsG9V3dx8n1OTnMDgoQJXVdVeTT/WSbI+sC+wbVVVknWn9qcoqQ0GXi1vVmu2GoRBxvt5YBPgj1V1alP+CAZPq/ll89CblYFfAdsCl1bVRQBJvgQcvIg2ngC8EKDZyvCmJOstVGe35nV283lNBoF4LeD4qrq9aeOECb7HP7Sx0PEA/9YE8zFgU2AjBlt7fijJvwMnVtXPm3+E/A34XJLvACdO0KakETDwanlzx3jWOa4Jrgs/1ebkqtp/oXrbc/cnOS2LAO+vqs8u1MbrpqmN5zF4Ys+OVTU/yWXAqlX1+yQ7AnsC70/yg6o6LMnODB6btx/wKgaBXVIHnONVH50KPDrJfQGSrJ7kfsCFwFZJ7tPU23+C808BXt6cOyfJ2sAtDLLZcd8HXjw0d7xp8xSdnwH7JlktyVrAU5egjWHrANc1QffxwBZN3U2A26vqS8CHgB2aPqxTVScxeDjA9kjqjBmveqeq/pzkRcBXkqzSFB/SZIsHA99Jcj2Dxyk+eBGXeC0wN8lBwJ3Ay5vnxv4yyXnAd6vqzUkeAPyqybhvBZ5fVWclORY4B/gjg+HwRfmHNhgMh4/7MvDtJGc017qwKf8n4INJxoD5zXlrAd/K4NnKAV6/BH9ckqaZTyeSJGmEHGqWJGmEDLySJI2QgVeSpBEy8EqSNEIGXkmSRsjAK0nSCBl4JUkaIQOvJEkj9P8BMTAcENH7N+4AAAAASUVORK5CYII=\n", 1287 | "text/plain": [ 1288 | "
" 1289 | ] 1290 | }, 1291 | "metadata": { 1292 | "needs_background": "light" 1293 | }, 1294 | "output_type": "display_data" 1295 | } 1296 | ], 1297 | "source": [ 1298 | "conf_matrix = confusion_matrix(error_df.True_class, pred_y)\n", 1299 | "plt.figure(figsize=(8, 8))\n", 1300 | "sns.heatmap(conf_matrix, xticklabels=LABELS, yticklabels=LABELS, annot=True, fmt=\"d\");\n", 1301 | "plt.title(\"Confusion matrix\")\n", 1302 | "plt.ylabel('True class')\n", 1303 | "plt.xlabel('Predicted class')\n", 1304 | "plt.show()" 1305 | ] 1306 | }, 1307 | { 1308 | "cell_type": "code", 1309 | "execution_count": null, 1310 | "metadata": {}, 1311 | "outputs": [], 1312 | "source": [ 1313 | "false_pos_rate, true_pos_rate, thresholds = roc_curve(error_df.True_class, error_df.Reconstruction_error)\n", 1314 | "roc_auc = auc(false_pos_rate, true_pos_rate,)\n", 1315 | "\n", 1316 | "plt.plot(false_pos_rate, true_pos_rate, linewidth=5, label='AUC = %0.3f'% roc_auc)\n", 1317 | "plt.plot([0,1],[0,1], linewidth=5)\n", 1318 | "\n", 1319 | "plt.xlim([-0.01, 1])\n", 1320 | "plt.ylim([0, 1.01])\n", 1321 | "plt.legend(loc='lower right')\n", 1322 | "plt.title('Receiver operating characteristic curve (ROC)')\n", 1323 | "plt.ylabel('True Positive Rate')\n", 1324 | "plt.xlabel('False Positive Rate')\n", 1325 | "plt.show()" 1326 | ] 1327 | } 1328 | ], 1329 | "metadata": { 1330 | "kernelspec": { 1331 | "display_name": "Python 3", 1332 | "language": "python", 1333 | "name": "python3" 1334 | }, 1335 | "language_info": { 1336 | "codemirror_mode": { 1337 | "name": "ipython", 1338 | "version": 3 1339 | }, 1340 | "file_extension": ".py", 1341 | "mimetype": "text/x-python", 1342 | "name": "python", 1343 | "nbconvert_exporter": "python", 1344 | "pygments_lexer": "ipython3", 1345 | "version": "3.7.1" 1346 | } 1347 | }, 1348 | "nbformat": 4, 1349 | "nbformat_minor": 2 1350 | } 1351 | --------------------------------------------------------------------------------