├── .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 | " time | \n",
96 | " y | \n",
97 | " x1 | \n",
98 | " x2 | \n",
99 | " x3 | \n",
100 | " x4 | \n",
101 | " x5 | \n",
102 | " x6 | \n",
103 | " x7 | \n",
104 | " x8 | \n",
105 | " ... | \n",
106 | " x52 | \n",
107 | " x53 | \n",
108 | " x54 | \n",
109 | " x55 | \n",
110 | " x56 | \n",
111 | " x57 | \n",
112 | " x58 | \n",
113 | " x59 | \n",
114 | " x60 | \n",
115 | " x61 | \n",
116 | "
\n",
117 | " \n",
118 | " \n",
119 | " \n",
120 | " 0 | \n",
121 | " 5/1/99 0:00 | \n",
122 | " 0 | \n",
123 | " 0.376665 | \n",
124 | " -4.596435 | \n",
125 | " -4.095756 | \n",
126 | " 13.497687 | \n",
127 | " -0.118830 | \n",
128 | " -20.669883 | \n",
129 | " 0.000732 | \n",
130 | " -0.061114 | \n",
131 | " ... | \n",
132 | " 10.091721 | \n",
133 | " 0.053279 | \n",
134 | " -4.936434 | \n",
135 | " -24.590146 | \n",
136 | " 18.515436 | \n",
137 | " 3.473400 | \n",
138 | " 0.033444 | \n",
139 | " 0.953219 | \n",
140 | " 0.006076 | \n",
141 | " 0 | \n",
142 | "
\n",
143 | " \n",
144 | " 1 | \n",
145 | " 5/1/99 0:02 | \n",
146 | " 0 | \n",
147 | " 0.475720 | \n",
148 | " -4.542502 | \n",
149 | " -4.018359 | \n",
150 | " 16.230659 | \n",
151 | " -0.128733 | \n",
152 | " -18.758079 | \n",
153 | " 0.000732 | \n",
154 | " -0.061114 | \n",
155 | " ... | \n",
156 | " 10.095871 | \n",
157 | " 0.062801 | \n",
158 | " -4.937179 | \n",
159 | " -32.413266 | \n",
160 | " 22.760065 | \n",
161 | " 2.682933 | \n",
162 | " 0.033536 | \n",
163 | " 1.090502 | \n",
164 | " 0.006083 | \n",
165 | " 0 | \n",
166 | "
\n",
167 | " \n",
168 | " 2 | \n",
169 | " 5/1/99 0:04 | \n",
170 | " 0 | \n",
171 | " 0.363848 | \n",
172 | " -4.681394 | \n",
173 | " -4.353147 | \n",
174 | " 14.127998 | \n",
175 | " -0.138636 | \n",
176 | " -17.836632 | \n",
177 | " 0.010803 | \n",
178 | " -0.061114 | \n",
179 | " ... | \n",
180 | " 10.100265 | \n",
181 | " 0.072322 | \n",
182 | " -4.937924 | \n",
183 | " -34.183774 | \n",
184 | " 27.004663 | \n",
185 | " 3.537487 | \n",
186 | " 0.033629 | \n",
187 | " 1.840540 | \n",
188 | " 0.006090 | \n",
189 | " 0 | \n",
190 | "
\n",
191 | " \n",
192 | " 3 | \n",
193 | " 5/1/99 0:06 | \n",
194 | " 0 | \n",
195 | " 0.301590 | \n",
196 | " -4.758934 | \n",
197 | " -4.023612 | \n",
198 | " 13.161567 | \n",
199 | " -0.148142 | \n",
200 | " -18.517601 | \n",
201 | " 0.002075 | \n",
202 | " -0.061114 | \n",
203 | " ... | \n",
204 | " 10.104660 | \n",
205 | " 0.081600 | \n",
206 | " -4.938669 | \n",
207 | " -35.954281 | \n",
208 | " 21.672449 | \n",
209 | " 3.986095 | \n",
210 | " 0.033721 | \n",
211 | " 2.554880 | \n",
212 | " 0.006097 | \n",
213 | " 0 | \n",
214 | "
\n",
215 | " \n",
216 | " 4 | \n",
217 | " 5/1/99 0:08 | \n",
218 | " 0 | \n",
219 | " 0.265578 | \n",
220 | " -4.749928 | \n",
221 | " -4.333150 | \n",
222 | " 15.267340 | \n",
223 | " -0.155314 | \n",
224 | " -17.505913 | \n",
225 | " 0.000732 | \n",
226 | " -0.061114 | \n",
227 | " ... | \n",
228 | " 10.109054 | \n",
229 | " 0.091121 | \n",
230 | " -4.939414 | \n",
231 | " -37.724789 | \n",
232 | " 21.907251 | \n",
233 | " 3.601573 | \n",
234 | " 0.033777 | \n",
235 | " 1.410494 | \n",
236 | " 0.006105 | \n",
237 | " 0 | \n",
238 | "
\n",
239 | " \n",
240 | "
\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 | " time | \n",
372 | " y | \n",
373 | " x1 | \n",
374 | " x2 | \n",
375 | " x3 | \n",
376 | "
\n",
377 | " \n",
378 | " \n",
379 | " \n",
380 | " 256 | \n",
381 | " 5/1/99 8:32 | \n",
382 | " 0 | \n",
383 | " 1.016235 | \n",
384 | " -4.058394 | \n",
385 | " -1.097158 | \n",
386 | "
\n",
387 | " \n",
388 | " 257 | \n",
389 | " 5/1/99 8:34 | \n",
390 | " 0 | \n",
391 | " 1.005602 | \n",
392 | " -3.876199 | \n",
393 | " -1.074373 | \n",
394 | "
\n",
395 | " \n",
396 | " 258 | \n",
397 | " 5/1/99 8:36 | \n",
398 | " 0 | \n",
399 | " 0.933933 | \n",
400 | " -3.868467 | \n",
401 | " -1.249954 | \n",
402 | "
\n",
403 | " \n",
404 | " 259 | \n",
405 | " 5/1/99 8:38 | \n",
406 | " 1 | \n",
407 | " 0.892311 | \n",
408 | " -13.332664 | \n",
409 | " -10.006578 | \n",
410 | "
\n",
411 | " \n",
412 | " 260 | \n",
413 | " 5/1/99 10:50 | \n",
414 | " 0 | \n",
415 | " 0.020062 | \n",
416 | " -3.987897 | \n",
417 | " -1.248529 | \n",
418 | "
\n",
419 | " \n",
420 | "
\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 | " y | \n",
464 | " time | \n",
465 | " x1 | \n",
466 | " x2 | \n",
467 | " x3 | \n",
468 | "
\n",
469 | " \n",
470 | " \n",
471 | " \n",
472 | " 255 | \n",
473 | " 0.0 | \n",
474 | " 5/1/99 8:30 | \n",
475 | " 0.997107 | \n",
476 | " -3.865720 | \n",
477 | " -1.133779 | \n",
478 | "
\n",
479 | " \n",
480 | " 256 | \n",
481 | " 0.0 | \n",
482 | " 5/1/99 8:32 | \n",
483 | " 1.016235 | \n",
484 | " -4.058394 | \n",
485 | " -1.097158 | \n",
486 | "
\n",
487 | " \n",
488 | " 257 | \n",
489 | " 1.0 | \n",
490 | " 5/1/99 8:34 | \n",
491 | " 1.005602 | \n",
492 | " -3.876199 | \n",
493 | " -1.074373 | \n",
494 | "
\n",
495 | " \n",
496 | " 258 | \n",
497 | " 1.0 | \n",
498 | " 5/1/99 8:36 | \n",
499 | " 0.933933 | \n",
500 | " -3.868467 | \n",
501 | " -1.249954 | \n",
502 | "
\n",
503 | " \n",
504 | " 260 | \n",
505 | " 0.0 | \n",
506 | " 5/1/99 10:50 | \n",
507 | " 0.020062 | \n",
508 | " -3.987897 | \n",
509 | " -1.248529 | \n",
510 | "
\n",
511 | " \n",
512 | "
\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": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEWCAYAAABrDZDcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJzt3XmYFOW1+PHv6Z4ZZtgEBowKIogXEUQBcQOjuKCY5MYkbnFDJdGoMUYwJDHJjSZXbxJFXH563bckxg1NbmJcgguiA6ggREAWGUABQWCQfYaZ7j6/P6q6qe7p7unu6W2mz+d55pnu6uqqU28t5633raoWVcUYY0zp8hU6AGOMMYVlicAYY0qcJQJjjClxlgiMMabEWSIwxpgSZ4nAGGNKnCUCkzMislhExhQ6jlwRkatF5AsR2Ski1TmY/hMicov7+qsisszz2aEiMl9EdojIdSJSJSL/EJFtIvJ8tmPJJRFZLSKnFTqOUlZW6ADaMhFZDXwFCAI7gVeBa1V1ZyHjikdEbgYOUdWLczT9J4C1qvqr8DBVHZKLeRUDESkHpgLHqeq/cz0/VX0HONQz6KfADFUd7sZzCc62WK2qgVzHE0tEFPgPVV2R73mb1rMzgtb7T1XtDAwDhgM3FjiejIij3W0PItKsshNvWLrTwDnoVgKLM4gpG2V9UMy8DwKWZ5IE0i0P0w6pqv1l+AesBk7zvL8N+KfnfQdgCvAZ8AXwAFDl+fwsYAGwHagFxrnDDwD+DmwBVgBXeL5zM/Ac8EdgB87BYKTn858B69zPlgGnAuOARqAJ58zl3+64M4BbgRqgHjgkzjLdDPzZ8/4EYBawFVgDXAZc6U670Z3+P2LLxy2Lu4DP3b+7gA7uZ2OAtcANwEZgPXB5knLfB3jUHW8dcAvgdz+7zF2eO93yuyXBMB/wK+BTd55/BPZxp9EPUOB77rqbGTP/gcAud5ydwJvu8FHAB8A29/8oz3ealXWc5RoOfOiuu2eBZ4BbvGXkvn4T5yy0wZ3/0zHr93vueBOAJcCXwGvAQZ55KfBD4BNglTtsEDDdLaNlwHme8Z8A7gP+6cb3HjDA/WymO71d7vzPT7DernDj2QF8DIyIs50cA8zG2b7WA/cCFe5n4q7DjW4ZfwQc7n72NXeaO9xt4iee+X4DZz/birPtHpFsfyn0caUgx7JCB9CW/2I24D7AQuBuz+d34RzQewBdgH8Av3M/O8bdmMfiHJR6A4Pcz94G/henxjkM2BTeQHEOzA3uhu8HfgfMcT87FOfgfID7vp9nZ70ZzwHdHTYD50A3BKeZsJwkiQDo6+4wF7jjVgPD3M+ewD1oJSif3wJzgH2BXu4O+d/uZ2OAgDtOubtsu4HuCcr9b8CDQCd3eu8DP3A/u8yd1o/cZapKMGwCTpI9GOgMvAj8yVNuipMcOuFJ3p4YwuOUue974BxwL3HncYH7vjpRWcdMrwInKU10y+AcnAN7s0Tgmd73460n9/233OU7zJ3fr4BZns8V56Dfwy2PTjjbzuXu+COAzcAQz/rdgrPdlgFPAc/ETK9ZcvN8fi7OAfdonAP6IbiJiejt5CjgOHce/XASx/XuZ2cA84Bu7jQOA/Z3P1sPfNV93Z29SWYETuI4Fmd/udSdXweS7C+l9lfwANryn7tB7cQ5OCrwBtDN/UxwakgDPOMfz97a14PAnXGmeSBOba+LZ9jvgCfc1zcDr3s+GwzUu68PcTf602h+oIk6ULjDZgC/jbNMiRLBjcBfE5TFEyRPBLXA1zyfnQGsdl+Pwakll3k+34jT/h47n68Ae4g+s7oAeMt9fRnwWcx34g17A7jG8/5QnANv+ACkwMFJ1n14nHAiuAR4P2ac2cBlico6ZtwTcc6UxDNsFpkngldwzwzc9z6c5HqQ+16BUzyfnw+8ExPTg8BNnvX7iOezrwFLPe9bSgSvAT9Osh+dluCz68PbHHAKsBwnUfhixvsM+AHQNWb4/bgVDs+wZcBJJNlfSu2v3bUJF8C3VLULzo46COjpDu8FdATmichWEdmK05ncy/38QJyDY6wDgC2qusMz7FOcM4awDZ7Xu4FKESlTp6PuepyDwkYReUZEDmgh/jUtfO6VKOZUHICzHGGfusPC6jS6fXs3Tk091kE4Neb1nnJ9EOfMICzeMsUOixdPGU6iSTadRGKnF56md70lm94BwDp1j1Se72fqIOBuTxltwamcJIrnIODY8Pjudy4C9vOME7vdxVs/iaS07YjIQBF5SUQ2iMh24H9w9ylVfROnqeg+4AsReUhEurpfPRsnOX0qIm+LyPGe5bohZrkOxDkLyGR/aZcsEWSJqr6NU2ua4g7ajFPLHaKq3dy/fdTpWAZnJxwQZ1KfAz1EpItnWF+c0+pU4viLqp6AswMo8IfwR4m+EvN+F04CC/MeCBLFnGz6YZ+7MYX1dYelaw3OGUFPT7l21egrlOLFEjssXjwBnL6cZNNJJHZ64Wl611uy6a0HeouIxHw/U2twmsu6ef6qVHVWgnjWAG/HjN9ZVa9uRQyx8STadrzuB5biXIHUFfgFTgJzAla9R1WPwmliGwhMdod/oKpn4VQI/obTjxae760xy9VRVZ92v5dofykplgiy6y5grIgMU9UQ8DBwp4jsCyAivUXkDHfcR4HLReRUEfG5nw1S1TU4TQK/E5FKETkCp9PyqZZm7l5bfoqIdMDpR6jHaWYC5wDXL4WrVRYA3xWRchEZidNWHfYUcJqInCciZSJSLSLDPNM/OMl0nwZ+JSK9RKQn8Gvgzy0tUyxVXQ/8C7hDRLq6ZTdARE5Kc1JPAxNFpL+IdMapeT6rmV96+TIwUEQudMvmfJxmu5dS/P5snER0nfv97+C0x2fqAeBGERkCICL7iMi5ScZ/yY3/Enfdl4vI0SJyWIrza2n9PwL8RESOcq+aOkREYhMnOH1p24GdIjIIiCQiN55j3Ut3d+Fs40ERqRCRi0RkH1Vtcr8f3u4fBq5yvyci0klEvi4iXVrYX0qKJYIsUtVNOB2M/+UO+hlOh90c9zT3ddxrwVX1fZyOuTtxOo3fZm+N8gKcNujPgb/itNNOTyGEDsDvcc5GNuDUjn7hfha+yahORD5MMo3/wqm5fQn8BviLZ/k+wzn9vgGnqWEBcKT78aPAYPf0+29xpnsLMBfnSo+FOFfH3JLCMsUzHqdz9WM3zmnA/mlO4zHgTzhXvKzCORD8KMN4UNU6nKtTbgDqcK7z/4aqbk7x+43Ad3D6M77EabN/sRXx/BWndvuMu+0tAs5MMv4O4HTguzjb3Qb3+x1SnOXNwJPu+j8vzvSfx7lq6i84fWp/w+mojvUT4EJ3nIdxrp4K6+oO+xKn2ayOvWfglwCr3WW9CrjYne9cnKuV7nW/twKnjCH5/lJSJLpJ0hhjTKmxMwJjjClxlgiMMabEWSIwxpgSZ4nAGGNKXFE9bKpnz57ar1+/QodhjDFtxrx58zaraq+Wx0ysqBJBv379mDt3bqHDMMaYNkNEWnMHOmBNQ8YYU/IsERhjTImzRGCMMSWuqPoIjDHtR1NTE2vXrqWhoaHQobQLlZWV9OnTh/Ly8qxP2xKBMSYn1q5dS5cuXejXrx/RD1U16VJV6urqWLt2Lf3798/69K1pyBiTEw0NDVRXV1sSyAIRobq6OmdnV3ZGYIpWIBhi6vTlzKqtY9SAaiaNHUiZ3+oubYklgezJZVlaIjBFa+r05TxWs4qGphBLN2xHgMnjBhU6LGPaHatemaI1q7aOhqYQAA1NIWpq6wockWlrRIQbbrgh8n7KlCncfPPNeY3hsssuY9q0aXmdZ7osEZiiNWpANZXlziZaWe5j9IDqAkdk2poOHTrw4osvsnlzSr8P1EwgkOkP1rUt1jRkitaksQMRoKa2jtEDqpk4dmChQzI5lIs+obKyMq688kruvPNObr311qjPPv30UyZMmMCmTZvo1asXjz/+OH379uWyyy6jR48ezJ8/nxEjRtClSxdWrVrF+vXrWb58OVOnTmXOnDm88sor9O7dm3/84x+Ul5fz29/+ln/84x/U19czatQoHnzwwTbTR2JnBKZolfl9TB43iL/9cDSTxw2yjuJ2LtwntGDNVh6rWcWd05dnZbo//OEPeeqpp9i2bVvU8GuvvZbx48fz0UcfcdFFF3HddddFPlu+fDmvv/46d9xxBwC1tbX885//5P/+7/+4+OKLOfnkk1m4cCFVVVX885//jEzvgw8+YNGiRdTX1/PSS6n+XHXh2Z5ljCkKueoT6tq1K+PHj+eee+6JGj579mwuvPBCAC655BLefffdyGfnnnsufr8/8v7MM8+kvLycoUOHEgwGGTduHABDhw5l9erVALz11lsce+yxDB06lDfffJPFixdnJf58sERgjCkKuewTuv7663n00UfZtWtXwnG8zTidOnWK+qxDhw4A+Hw+ysvLI+P6fD4CgQANDQ1cc801TJs2jYULF3LFFVe0qTuqLREYY4rCpLED+d7o/gw7sBvfG90/q31CPXr04LzzzuPRRx+NDBs1ahTPPPMMAE899RQnnHBCxtMPH/R79uzJzp07i/4qoVjWWWyMKQrhPqHJOZr+DTfcwL333ht5f8899zBhwgRuv/32SGdxprp168YVV1zB0KFD6devH0cffXQ2Qs4bUdVCxxAxcuRItR+mMaZ9WLJkCYcddlihw2hX4pWpiMxT1ZGtma41DRljTImzRGCMMSXOEoExxpQ4SwTGGFPicpoIRGSiiCwWkUUi8rSIVOZyfsYYY9KXs0QgIr2B64CRqno44Ae+m6v5GWOMyUyum4bKgCoRKQM6Ap/neH7GGBPh9/sZNmwYRx55JCNGjGDWrFlZm3a/fv0yfqppscnZDWWquk5EpgCfAfXAv1T1X7HjiciVwJUAffv2zVU4xpgSVFVVxYIFCwB47bXXuPHGG3n77bejxgkGg1HPFSpFuWwa6g6cBfQHDgA6icjFseOp6kOqOlJVR/bq1StX4Rhjil0wAK//Bh4+1fkfzO5vAWzfvp3u3bsDMGPGDE4++WQuvPBChg4dCsCf//xnjjnmGIYNG8YPfvADgsEgAFdffTUjR45kyJAh3HTTTc2mW19fz7hx43j44YezGm8+5fIRE6cBq1R1E4CIvAiMAv6cw3kaY9qqt26F9+6Hpnr4YjEgcNqvWzXJ+vp6hg0bRkNDA+vXr+fNN9+MfPb++++zaNEi+vfvz5IlS3j22WepqamhvLyca665hqeeeorx48dz66230qNHD4LBIKeeeiofffQRRxxxBAA7d+7ku9/9LuPHj2f8+PGtirWQcpkIPgOOE5GOOE1DpwL2/AhjTHyrZjpJACBQD6veTj5+CrxNQ7Nnz2b8+PEsWrQIgGOOOYb+/fsD8MYbbzBv3rzIM4Lq6+vZd999AXjuued46KGHCAQCrF+/no8//jiSCM466yx++tOfctFFF7U61kLKZR/BeyIyDfgQCADzgYdyNT9jTBvX/0TnTCBQD2VV0P+krE7++OOPZ/PmzWzatAmIftS0qnLppZfyu9/9Luo7q1atYsqUKXzwwQd0796dyy67LOrx0qNHj+aVV17hwgsvbDO/RhZPTq8aUtWbVHWQqh6uqpeo6p5czs8Y04ad/Es47hroPdL5f/Ivsjr5pUuXEgwGqa5u/jsHp556KtOmTWPjxo0AbNmyhU8//ZTt27fTqVMn9tlnH7744gteeeWVqO/99re/pbq6mmuuuSarseabPYbaGFMc/GWt7hOIFe4jAKfW/+STT8a9Qmjw4MHccsstnH766YRCIcrLy7nvvvs47rjjGD58OEOGDOHggw9m9OjRzb571113MWHCBH76059y2223ZTX+fLHHUBtjcsIeQ5199hhqY4wxOWGJwBhjSpwlAmOMKXGWCIwxpsRZIjDGmBJnicAYY0qcJQJjTLtUV1fHsGHDGDZsGPvttx+9e/dm2LBhdOvWjcGDB2d9fjNmzOAb3/hGWt8ZM2YM8S6Zf+KJJ7j22muzFVqLLBEYY9ql6upqFixYwIIFC7jqqquYOHFi5L3P1/KhLxDI7tNPi5klAmNMyQkGg1xxxRUMGTKE008/nfp652F3Y8aM4Re/+AUnnXQSd999N5s2beLss8/m6KOP5uijj6ampgaAt99+O3K2MXz4cHbs2AE4TyM955xzGDRoEBdddBHhG3bfeOMNhg8fztChQ5kwYQJ79jR/2s7jjz/OwIEDOemkkyLzyRd7xIQxJj/GjMnu9GbMyPirn3zyCU8//TQPP/ww5513Hi+88AIXX+z8XMrWrVsjP15z4YUXMnHiRE444QQ+++wzzjjjDJYsWcKUKVO47777GD16NDt37qSy0vk59vnz57N48WIOOOAARo8eTU1NDSNHjuSyyy7jjTfeYODAgYwfP57777+f66+/PhLP+vXruemmm5g3bx777LMPJ598MsOHD8+8bNJkZwTGmJLTv3//yDOIjjrqKFavXh357Pzzz4+8fv3117n22msZNmwY3/zmN9m+fTs7duxg9OjRTJo0iXvuuYetW7dSVubUqY855hj69OmDz+dj2LBhrF69mmXLltG/f38GDhwIwKWXXsrMmTOj4nnvvfcYM2YMvXr1oqKiIiqGfLAzAmNMfrSiBp9tHTp0iLz2+/2RpiGIfjx1KBRi9uzZVFVVRX3/5z//OV//+td5+eWXOe6443j99dfjTjcQCJDq89wK+RhrOyMwxpgETj/9dO69997I+/CP3NTW1jJ06FB+9rOfMXLkSJYuXZpwGoMGDWL16tWsWLECgD/96U+cdFL0by0ce+yxzJgxg7q6Opqamnj++edzsDSJWSIwxpgE7rnnHubOncsRRxzB4MGDeeCBBwDn0dOHH344Rx55JFVVVZx55pkJp1FZWcnjjz/Oueeey9ChQ/H5fFx11VVR4+y///7cfPPNHH/88Zx22mmMGDEip8sVyx5DbYzJCXsMdfbZY6iNMcbkhCUCY4wpcZYIjDE5U0xNz21dLsvSEoExJicqKyupq6uzZJAFqkpdXV3kxrVss/sIjDE50adPH9auXcumTZsKHUq7UFlZSZ8+fXIybUsExpiMBIIhpk5fzqzaOkYNqGbS2IGU+fc2MpSXl9O/f/8CRmhSZYnAGJORqdOX81jNKhqaQizdsB0BJo8bVOiwTAasj8AYk5FZtXU0NIUAaGgKUVNbV+CITKYsERhjMjJqQDWV5c4hpLLcx+gB1QWOyGTKmoaMMRmZNHYgAtTU1jF6QDUTxw4sdEgmQ0kTgYj4gSdV9eI8xWOMaSPK/D4mjxvE5EIHYlotadOQqgaBXiJSkad4jDHG5FkqTUOrgRoR+TuwKzxQVafmKihjjDH5k0oi+Nz98wFdchuOMcaYfGsxEajqbwBEpIvzVnfmPCpjjDF50+LloyJyuIjMBxYBi0VknogMyX1oxhhj8iGV+wgeAiap6kGqehBwA/BwbsMyxhiTL6kkgk6q+lb4jarOADolHt0YY0xbkkpn8UoR+S/gT+77i4FVuQvJGGNMPqVyRjAB6AW86P71BC7PZVDGGGPyJ5U7i3+hqtdlMnER6QY8AhwOKDBBVWdnMi1jjDG5kTQRqGpQRI5qxfTvBl5V1XPcu5M7tmJaxhhjciCVPoL57l3FzxN9Z/GLyb4kIl2BE4HL3PEbgcaMIzXGGJMTqSSCHkAdcIpnmOL0FyRzMLAJeFxEjgTmAT9W1V3ekUTkSuBKgL59+6YYtjHGmGxJpY/gI1W9M8NpjwB+pKrvicjdwM+B//KOpKoP4dyrwMiRI+1Xro0xJs9SefroNzOc9lpgraq+576fhpMYjDHGFJFUmoZmici9wLNE9xF8mOxLqrpBRNaIyKGqugw4Ffi4VdEaY4zJulQSwSj3/289w5ToPoNEfgQ85V4xtBK7/8AYY4pOKk8fPTnTiavqAmBkpt83xhiTe6k8ffQrIvKoiLzivh8sIt/LfWjGGGPyIZVHTDwBvAYc4L5fDlyfq4CMMcbkVyqJoKeqPgeEAFQ1AARzGpUxxpi8SSUR7BKRapwOYkTkOGBbTqMyxhiTN6lcNTQJ+DswQERqcJ5Eek5OozLGGJM3qVw19KGInAQcCgiwTFWbch6ZMcaYvEjljCDcL7A4x7EYY4wpgFT6CIwxxrRjlgiMMabEpdQ0JCK9gYO846vqzFwFZYwxJn9aTAQi8gfgfJwHxoXvH1DAEoExxrQDqZwRfAs4VFX35DoYY4wx+ZdKH8FKoDzXgRhjjCmMVM4IdgMLROQNIHJWoKrX5SwqY4wxeZNKIvi7+2eMMaYdSuXO4ifdH5YZ6A6yO4uNMaYdSeWqoTHAk8BqnEdMHCgil9rlo8YY0z6k0jR0B3C6+7vDiMhA4GngqFwGZowxJj9SuWqoPJwEAFR1OXYVkTHGtBupnBHMFZFHgT+57y8C5uUuJGOMMfmUSiK4GvghcB1OH8FM4H9zGZQxxpj8SeWqoT3AVPfPGGNMO5MwEYjIc6p6nogsxP2ZSi9VPSKnkRljjMmLZGcEP3b/fyMfgRhjjCmMhFcNqep69+U1qvqp9w+4Jj/hGWOMybVULh8dG2fYmdkOxBhjTGEk6yO4GqfmP0BEPvJ81AWYlevAjDHG5EeyPoK/AK8AvwN+7hm+Q1W35DQqY4wxeZOsj2Cbqq4G7ga2ePoHmkTk2HwFaIwxJrdS6SO4H9jpeb/LHWaMMaYdSCURiKpG7iNQ1RAp/ui9McaY4pfST1WKyHUiUu7+/Rjn5yuNMca0A6kkgquAUcA6YC1wLHBlLoMyxhiTP6k8a2gj8N08xGKMMaYAUvmFsseJ/6yhCTmJyBhjTF6l0un7kud1JfBt4PPchGOMMSbfUmkaesH7XkSeBl5PdQYi4gfmAutU1R5gZ4wxRSaVzuJY/wH0TWP8HwNLMpiPMcaYPEilj2AH0X0EG4CfpTJxEekDfB24FZiUSYDGpCoQDDF1+nJm1dYxakA1k8YOpMyfSV3HmNKSNBGIiABDVPWzDKd/F/BTnAfVJZrHlbiXo/btm86JhsmbYADeuhVWzYT+J8LJvwR/8d1TOHX6ch6rWUVDU4ilG7YjwORxgwodljFFL2l1yb2j+K+ZTFhEvgFsVNWkP3Svqg+p6khVHdmrV69MZmVy7a1b4b37Yd1cmHM/vPU/hY4orlm1dTQ0hQBoaApRU1tX4IiMaRtSOW+eIyJHZzDt0cA3RWQ18Axwioj8OYPpmEJbNROa6p3XgXpY9XZh40lg1IBqKsudTbqy3MfoAdUFjsiYtiGV8/uTgR+IyKc4D5wTnJOFpL9ZrKo3AjcCiMgY4CeqenHrwjUF0f9E+GKxkwTKqqD/SYWOKK5JYwciQE1tHaMHVDNx7MBCh2RMm5BKIrBfIyt1J/8SEOdMoP9JcPIvCh1RXGV+H5PHDWJyoQMxpo1JJRHcoqqXeAeIyJ+ASxKM34yqzgBmpBWZKR7+Mjjt14WOwhiTI6n0EQzxvnFvEDsqN+EYY4zJt4SJQERudO8hOEJEtrt/O4CNwP/lLUJjjDE5leynKn+nql2A21W1q/vXRVWr3Y5gY4wx7UAqTUMviUgnABG5WESmishBOY7LGGNMnqT6m8W7ReRInLuEPwX+mNOojDHG5E0qiSDg3mF8FnC3qt5NkkdGGGOMaVtSuXx0h4jcCFwMnOheNVSe27CMMcbkSypnBOcDe4DvqeoGoDdwe06jMsYYkzep/DDNBmCq5/1nWB+BMca0Gy2eEYjId0TkExHZFr6XQES25yM4Y4wxuZdKH8FtwH+qqv3KmDHGtEOp9BF8YUnAGGPar1TOCOaKyLPA33A6jQFQ1RdzFpUxxpi8SSURdAV2A6d7hilgicAYY9qBVK4aujwfgRhjjCmMVK4a6iMifxWRjSLyhYi8ICJ98hGcMca0ViAY4rZXl/Kt+2q47dWlBIKhQodUdFJpGnoc+Atwrvv+YnfY2FwFZYwx2TJ1+nIeq1lFQ1OIpRu2I8DkcYMKHVZRSeWqoV6q+riqBty/J4BeOY7LGGOyYlZtHQ1NzllAQ1OImtq6AkdUfFJJBJvdx0/73b+LAStJY0ybMGpANZXlzqGustzH6AHVBY6o+KTSNDQBuBe4E+dqoVnuMGOMKXqTxg5EgJraOkYPqGbi2IGFDqnoiPOE6eIwcuRInTt3bqHDMMaYNkNE5qnqyNZMI5Wrhp4UkW6e991F5LHWzNQYY0zxSKWP4AhV3Rp+o6pfAsNzF5Ixxph8SiUR+ESke/iNiPQgtb4FY4wxbUAqB/Q7gFkiMg2ns/g84NacRmWMMSZvUnnExB9FZC5wCiDAd1T145xHZowxJi9SaRoC6AHsUtX/B2wSkf45jMkYY0wepXLV0E3Az4Ab3UHlwJ9zGZQxxpj8SeWM4NvAN4FdAKr6OdAll0EZY4zJn1QSQaM6d50pgIh0ym1Ixhhj8imVRPCciDwIdBORK4DXgUdyG5Yxxph8SeWqoSkiMhbYDhwK/FpVp+c8MmNMWgLBEFOnL2dWbR2jBlQzaexAyvypXg+Sf20t3vYspRvD3AP/dAD3CaQXqepTOY3MGJOWtvbc/bYWb3uWMP2KSFcRuVFE7hWR08VxLbAS56YyY0wRaWvP3W9r8bZnyc7D/oTTFLQQ+D7wL5xfKTtLVc/KQ2zGtEmF+mnEtvbc/bYWb3uWrGnoYFUdCiAijwCbgb6quiMvkRnTRhWqyaOtPXe/rcXbniVLBE3hF6oaFJFVlgSMaVm8Jo/JeZhvmd/H5HGDUppXMXTUphNvPhRDmRRKskRwpIhsd18LUOW+F0BVtWuyCYvIgcAfgf2AEPCQqt6dhZiNKWqjBlSzdMN2GppCRdvkYR21zZVymSRMBKrqb+W0A8ANqvqhiHQB5onIdHtgnWnv2kKTR6HOWopZKZdJzn5XQFXXA+vd1ztEZAnQG7BEYNq1YmvyiKctnLXkWymXSV5+YEZE+uH8qtl7cT67ErgSoG/fvvkIx5iS1xbOWvKtlMsk5z9eLyKdgbeBW1X1xWTj2o/XG2NMevLy4/WtISLlwAvAUy0lAWOMMYWRs6YhERHgUWCJqk7N1Xxao71cLtZelsMYUxi57CMYDVyiqEyfAAAf9UlEQVQCLBSRBe6wX6jqyzmcZ1ray+Vi7WU5ssUSozHpyeVVQ+/i3HNQtNrL5WLtZTmyxRKjMekp6WpSrp51ku9nzdgzW6LZw8yMSU9eLh8tVrm6XCzfNdJSvuwtnlK+HtxY02AmSjoR5OrGn3w31bSFG5jyyRJjtFI7MFrTYPpKOhHkitVIC8sSY7RSOzBan1n6LBHkgNVI245SqC2X2oHRKmLps0SQA1YjbTtKobZcagdGq4ilzxJBO5JK7bYUasDpKIXacqkdGK0ilj5LBO1IKrXbUqgBp6Ot1pbTSehlfh8Txw5EWU5NbR3K8pQrAFZxKA2WCLKo0DtNKrXbUqgBp6Ot1pbTTeiZVgCs4lAaLBFkUaF3mlRqt221BpwrbbUZId2EnmkFwCoOpcESQRYVeqdJpXbbVmrAhT67KnbpJvRMKwC5qjjY+i0ulgiyqNC17VRqt22lBlzos6til25Cz7QC0F7uvjfJ5fyHadJR6B+maW0tJRAMcef05VE7jXXIZeZb99WwYM3WyPthB3bjbz8cXcCITDbZ+s2ebPwwjZ0ReCSrpaRysM60tm21o+Ziz66O79+D215dasmylYqh0hEIhvDhPJpYsQclFgNLBB7J2vhzebAudN9CMYptkgiGlMctWbZaMVQ6pk5fzuL121CcZDB4/66tanIqhuTW1lki8EjWxp/Lg3Wh+xbSlY8dL/bs6lv31SQs/2w06SX7fns60BRDpWNWbR17Ak6TtAIhpVXlWQzJra2zROCRrGMslwfrXHTI5fLgVYgdL1n5tzaeKa8t45F3VxEIKQvXbUNV+dmZh6U0/bTLORiAt26FVTOh/4lw8i/BX5a3ZFMMlY5sxhAIhpg2b23Gya09JfnWsETgkayNP5eXXSabb6YbantrykpW/q2N58X56wiEnBpqMKS88OG6qESQ1SbDt26F9+6Hpnr4YjEgcNqv85Zci+Hy4XRiaGn7nzp9OXU790Tel/kkrcTSUrmXSqKwRJCiQl12mekBIvbg9e6KzWiWOltzXatMtPMlKv9cx5PVJsNVM50kABCoh1VvZzadDBXD5cPpxODd/pes38ac2jpCENkuZtXWEfRc+NijU0VayS223B+ftRqFyDZXKs1OJZ0I2kK2z/QAEXvw8ovw6Lsr2RNQ/r1mK3Nq63juquMzWt5kNbpslGm6O19ra7nfGd6bh99dSTAEfh+cPbx3ytNPOwn1P9E5EwjUQ1kV9D8ps+kUiVzvQ97tf09Amb92K6pEtovYcjv3qD5pzd/7fYDdjUEeq1kV2eaKoU8lH0o6EeQj27d2R8n0ABF78Hp3xeaoDrr5a7Zy5/TlGS1vshpdOmWaqGzS3fnSqWHGm+dPzjgUv08SJpLWNBk2m9+pN1KGOGcC/U+Ck3+R0nSKVa73Ie/2L0D4tqfwdjHtquNbVW7hcn981mp2Nwajpj2Ztpug01XSiSAf2b61O0omB4jYg4/z5En4aK1zyR44ySAXy5tOmSYqm1w+1uC8B2Y3q1VOHjco4+YSb5KIl2TiL+Ovk04nneUp9Bltrvah8LLVrNjM4P27EgwpfhE+jtkuYsstEAyldb9J+PsKkfXk3eaa7X+nHgyv/6ZZZ39b1/aXoBXyke1bu6NkcoCId/CZNHYgc2rrmL9ma05v4vGWaYcywYdz6WfsTpnsao9s1o4DwRBTXlvGi/PXsaOhiXp3frHzzIZ45Z7NA2XsgT8UUh6ftSorzX2ZytU+5C3LynIf3xvdn4ljBza7cz/e9zJpAk20zTXb/17/TdzO/raupBNBqgec1tS8juvfg4VrtxJU8Asc379HFpcgvrgHn3E+nrvq+BZ3JGjd8nrL1AeRGlzs2VCyqz2y2aE5dfpyHn5nZVSHYphAswNXomX3Dj/OXYdzVm1psUkrmwfK2ETTtbI8a819mfKu7+P79yAY0riJP13xynLiWKLOaBN9L5MySXmbi+nsXzbnJf4vcF5R9i+mo6QTQaorP93mHe9BQ1BEBNT9Ly3HFXswuu6UQ7jnzRVRB6dwXPEO1vEOPt5Tbb8I767YTNC9ZDL2gBZveSe6zRwtJYdwmU4Mhhj1+zcT1oZbutojWzd5xc4nTIDhfbs1S4aJ1rV3+MK1WxERAiFtsUlrYhbPbmIPjl0rneXwEWRS2fOM8i2m9t9Hwdj7s9Jcke5jVW57dWnW7v6OV5ap7IfH9e8R9QyjbDaBBoIhPtAhDGchleyhXiuYXj+Ix2pWoSFFfFLUF54kU9KJAFLb2BOd3if6rneDDT9PBSAQUmav3NLi/GM3+Dm1dc1q1t42Te9O0dAYYPaKzTQFQpT5oGuHMoIhZcpry3hi9urIcgAsWrct7gEt3vIq8XfCZGWQ7PruRFd7hKf3/Nw1bN7ViCpp3+TlNWpAdeSMDJwDZ68uHTh7eG8UOOeB2Sl1VHuHB5VIr2VLTVrexDh1+vJm83MmGH2TWeCkG5n6xspmZx8+nCa9cJmdPbw3763awqnrH+By/6t0lEYOr18Dj68GDSVtw4633sLl6m16Cm8zqRzY412yHHx5CS/OXwc4V2f95IxDkx4g4/UNnHBIT350yiGcePuMtJvZ/DHbXWvOdqdOX86Ta07n6tBWRvsXURM8nDuD5xAMhnhh/jq2NzS12ctMSz4ReO8q/WjtVmbXbiak4BchqMroQ3pyXP8ecU/vEx2MalZsjmyw3spovKaBeNdJL9mwI2qDD7frh98/P28tX+naIWqcdz7ZzORxcOHD7zF/7TbCM9+4s5EnZq+ma2V5VBKA5ge08I67bMP2ZjHXJDhATnltWaTpZcEap/yev2pUizX+8EHzXc8Zir66NOrgE4kzhZu8Hpy5kmBIIweacN/ACx+upaLMh4jQuUMZZ4/ozQ2nH8rU6cvj1l4TNeV5E5dfiCTQeP0gk8c1P7AkTVwxN5l9sHILj60ZFzn7iKwrnITaq3MFfbpXMWtlHccfXM23d9fScVcjAOU0wrq5oCGaPl/I3z5cR+3hE4HoM78pry3joZkrCbF3vR3bvzpS9kvWb8Pv86V14I13ybK3We7hd1by/qothCBh81ps38Dlx/dDgRNvn8GmHXui5rdo3VaOufV1vjO8N9ef9h/c8+YK/jjn06hxBGgKhvj9y0siyTRRc2WYt19JVenTvYqQwvptDexqEqZwPlOC50c9NC9cRqmWVbEp2UQQrhmEkwA4zzyZv2Zb1HjLvtjB5cf34/Lj+/GCW7MJhpSGxkCzzs7wwWz5FzviztMnQjCkBIKhSC3EmzS810l7xbZs1O1qZGdDU9SwFZt28K37ali0bhuxnDOTpqizk1hlPmm248LeB4Ipy+N2Ai//YkfU+PPXbOPO6ctbrPGHm6g+31rPl7ubCIQ06gylJbE1/UBIeeTdVfh9EmnK8S5LmU84d1SfyE4fm0ien7e2WbNNUGH2ys38/uUlzF5Zx2H7deGzul18uTtASJWOFX4G7tu5xQNLvPk9VrOKd1dsZvQhPfnJmrfxedqdu3xeQ0PT6ZEYvAIhZfPOxkiZLftiB2MOHMkBe1Y69yYgztkAUK57OGTnXCbPXBn5frgDdc2Xu/FWC+av2cayL3ZGbYsQjHwePqNLVqOOd8myN/6gEtm+vQnO26kbW07emnasQAg27tjDI++u4v1VWyLrIba8HnpnFX5pXpbe9R57t7J329m000myfnHKIVwBGHLAPoSUyEMRw0m0LV5mWrKJIFzzaOmg09AU4uF3VzG0d9fIBvnE7NW8v2pLs6YPv0ikNhPP7sYgD850akXhKxn8Et1pkMrPQwRDyu6YuHc3hqLaRmM1BkKRJFDmc3Yirx6dKgiqNttZwrMJhZSuleV06aAI8GGSeT04s5buHSs4bL+uhHTvqf1try5l2ry1bNnVGFXufoJMdtu4Z4WGMDV0LkH8UdP89rADot5fd8ohPOG59hucnT58Z2hNzEEoEFL+d0YtD85cydDeXTmmX4+oRLJlVyN3uLVA7/cWrN3Ov9duj5tAdzcGWb5xZ4s1wfBjl73qm0L8e+02Plq7jQHdB/Cdso+RQD1N0oG3mwYnLFtwknm4/BqaQtzWeA4vHtfTuTdBfLBhIQTqqdcKaoKHN/vu/DVbqarwN5vu7sZg5EAXq8zn1KxH/f7NyPqLTXxlfl+k0vDuis1s2NbQPHZ30t4yVpzt6Yjf/Iv/2LdTVIVlZ0Mg4f4UFghp0u0xdn5eG3fs4dwHZvH0Fcdx1+uf8OL8dWzZ1Rh3/KDCvp0rOKBbVVTTX/gMomtlOV0r4ewRvdvMfSBh7eeHacaMSWv0Reu2sXNPILN5xVHu91FR5mNXitP0iVBV4ae+MUioCNbBAd2qAPh8a/3egSIcsE8lABu2NaQdp4iwX9dKdjQ0JS3rA2Uj+8kW/ChBhA1azRrt1Sy+vj06Rt5/tmV3dKwePhE6VviTzrNzhzL2BEI0BUNR30t/GUFwvucTYb99KiNxqsKaL3enVHYDyjbTVXZTF6zis1CvpOPG8vmccu7TvYq1X+6mctc6Ood28mWoY7NybEm530cwpGmVQ+cOZQw+oCs+ET7bEn95fT6hY7mf3Xna3t3rM1KWyrpPtH437dizdzty9xnvtpqSGTPSG9/DfpimFbpWlWd1o+zVpQPb65uaDU+0gYVUo5LGgbKRrrKb7dqRdeyLp/k+LzZsb6BjeXQtsdwn9Olexcefb09pJ4kdR1VZvy3+wdqrq+zG79YB/ShdZRfEHMA27mhge30Tu5uCdCz3J2ziAqds9wRCSXfunXsCdHY70sPjZLItdKooo2tVOdvqm2gMhNiwzYlz8AFdWftlfcJkFas20DPteYeFQsrnW+s9B6RqoJpyvw+CyWvTsTqU+dKuIO3cE+Djz7fTtaqcL7bX05uNdPU52/Ia3dcZSaFLZVnUGVwupbsqW1r35X4fvbp0AJxKZNeqcsDpN4iqTKuyacee9BNBgbWfRJBmRt23McB1D81mwdrtLY+cgjKfUOaDhkD6B5PJZc9whP9VOoqPMg3x18BwpgTPz0pcYVVlQmOwedNPPH7P5Yhzeh/BHY3nMG/dzqTfCTdwZZK7Jpc9wwT/q1RJI/VawZOBMyPL743l7dAQpgacZqN9O1ew0W27jbsMcdqE4+lY4aO+KYQ/xb6J2Jg+8B/B7Y1nUx/0RS17mc85GKUSQ7HzLu8szzqIN95zFTezvzTgEx+V2sjfAkdye/CCookxU2U+4coTD27W9BtvvtVdOvL+L0/L2rzzof0kgjTd8+aKlJNAKhtZIKTN2t1TNcq3mI7iHNSqpJHR/kUZJ4JEsdankaAmlT0fuRyx/vPPuDE0G39FKOkOlsrUE8U2NXAuqhJ1SV7YDWXPcoX/ZcolxOGyClS5PXhB0iQAqR+Adzc6Ky2QRhXSWz6DQmvYRYgpRK+vTLeFVOT6oBcranllDaoSd/ucVPY8w6UWn1srKJcQZ/vfyUsiSDXGTAU8v5DX0nzva7iAhsYAlRVt5/DadiLNsneWbwQS71Te4SGEw+SznG1ks0JDGCRrIjXi2A6+dGRjh4hOTE2M8H2CT2j1sieKLYifKcHz4073O/53KRf3KpiYA0smB8RsHESzmbgzkek63rvsiwjhw4emVAapLu8o3+JIEgjrLPX4CeY0USWLMZtJM/x4Eu8096eu+XwbQ1zw8Bz++sMTsrNwedB2bn3LshWbnKaO8E413FfLBP+rTPRPazZ8mNQ2W9nZNDVwLo8GzmR+aACPBs7knuC3mVz2DH+t+C8mlz2Dn9TbVePtEOmaFRpCk+7dNMI7d7LpOVf+JI85o9iSVNQTrbtkMvlOrFmhIdRrBUDGiTuV8kok03W8d9lXMkJWNCuDRDGlurzOdhOdCTrQFLeMK2jkhYpfs7jD5bxQ8WsqiD7DS7d8EsWYjfUdyzvNatke2Ve88/1obfPLuItZySaC+ibnCBO7U51T9jZ+glHD/aKE3A28tTX2eMI14m83/jdTgufz47IXM954s3GQmho4lzrt2mx4sumlssNlEtuLoa9GdrQm9fFC8KuRzxKtu2SykShjE7e3KStV3vK60v8SNRU/SjkhZLqOvcsucZJ7onWY6vJODZzLQ4Fv0Kh7a9zlEopbxk9X3MIIWUEn2cMIWcGHHa6KWv50D+BTA+fyWOAMNmg3tmlHfBJqth9nqxLnnWa5hKjTLs3m29b6hnKaCERknIgsE5EVIvLzXM4rU7G132q2M9E/LWZnK+fD0CGt2vHjSVTrSbbxtlRTysZBKoifF0InRpa/SX1sCHVLOr1UdrhMYrsjcB4PBv6T+aEBPBj4T6YGz4t8lmjdJZONRBmbuDNpaog9mOzn25py0s90HceWFzjrNlwGidahd3nvDJ7DpLLn425/QfzcHryAh4Nfb7GMB8maSDISgc7SELX86R7Ag/gRgWp2sJ9vK1f4/8kk/3NZWd+xYqe5VvelK7vZz7eVy/2vZeWsI99y1kcgIn7gPmAssBb4QET+rqof52qemZgaOJezfTPZT5wbUsI1mHMab27WgZmNds5U+h6S9Rm01D6crL09HfE6cJMtfyr9HJnEluw7idZdsukn65jOJ295haXa35DpOo4tL4A67Ropg1TWYSr9E6mU8VI9kBGswHs/pXf5M+k3+47vHcrFSUzh/qTRjf8v6+s7dvlG+xcVtM8oG3LZWXwMsEJVVwKIyDPAWUBRJYJw7XeCvBq10WXrgBrLuyMFVfCLcw7p3YCS7Uj56qhMd/kLcYBNtO5a+k4u1mu6wuV1TtnbVLOdcgnlpNnRK155TQueFEnwqazDVLa/VMr4gsZf8ZfyWznCV4sfxS8atfwZbU9xnuybi/UdO00RbZa0jjigS9bmlw+5TAS9gTWe92uBY2NHEpErgSsB+vbtm8Nwok0YfRCP1TgPqMrnQSxe34MvZidItvFm8wqjbCrUAbZYavjpCpfXncFzmOiflrf4k5VXKuswW9tfIxWc0/Qb/ATjLn8m29OLwRMilxrH9iflUmyZPlV1EW9dNSov886WnD1iQkTOBc5Q1e+77y8BjlHVHyX6TqseMZGmQDDEH15ZwqPvro48fMsvUO6DplDi69B7dS7ny90Byv3CoP26EFI44ZCekWeL3Dndec6K3yfOM2YElm7YEbnRLPrmqXIWh/rhlxArOh3F2Gvu5PI/LnB+UjL8jB93vuHnr4R3nK/6FzNbh3BH0zk0JWmy6dmxjK0NwRZvlqoqE5pCzo1QXTqUsWnX3ruk9+1cQUhhV2MAEaFThZ8De3QkEAyBhlj4+U4Up8Opwg8NMf2dAlRV+Lng6D7MX7ONpRt2cOhXOjPyoO5Mm/sZXzY0v+i+Y4WfS47tG3nU9YWPvBf53oi+3Xhy9qdxr9Xv2bGMLbsDkXLbt0sHQqEQdbuaml2AVOl31nW4aBKVkABH9HZqeP9e5zxQ0C9Q4RcUaAxo1APcwst70TEHgsAfZ61mj6dMynzCoV/pxOZdTWzb3QSEaEjzaSdlPqFHx3K+PaI3PhFqVmxm/bZ6Nu2Mvrs99kY/H9CjUzmb3fXbscLPuUcdwDPvr4mK0auyTNgT0Kjtb7R/EbNDh3NX8By6duzA5l17F6DMJxy2fxdOGNCTgIZ46r01NDQGqazwEwop+3QsZ9/OHfD7YNkXO6lvClHmE7pXlXFgdScamwKsrKtnd2MQH3v3gTKf0K3Sj/iEzTud9Rm+cdAH9Oro45I9Tydszqwq99EUVOfx7JXlbN7ZSOwm5J1HuCw7uJPwlk+lHxqD0bH16FjO2Uf14YbTkz9qO9uy8YiJXCaC44GbVfUM9/2NAKr6u0TfyWciKJhgAN76n+gfL28Hv3mab4FgqNmvrSXa+VIZN53pZVsh552OthCnN8Zj+3Xng0+/ZOmGHQzarwt/+f6xbeomr1QVeyIoA5YDpwLrgA+AC1V1caLvlEQiMMaYLCrqh86pakBErgVeA/zAY8mSgDHGmMLI6XmSqr4MvJzLeRhjjGmd4mrgM8YYk3eWCIwxpsRZIjDGmBJnicAYY0pcUf1msYhsAj7N82x7ApvzPM+WFGNMYHGly+JKj8WVnnBcB6mm+ePUMYoqERSCiMxt7TW42VaMMYHFlS6LKz0WV3qyGZc1DRljTImzRGCMMSXOEgE8VOgA4ijGmMDiSpfFlR6LKz1Zi6vk+wiMMabU2RmBMcaUOEsExhhT4ko2EYjIOBFZJiIrROTnBZj/ahFZKCILRGSuO6yHiEwXkU/c/93d4SIi97ixfiQiI7IYx2MislFEFnmGpR2HiFzqjv+JiFyao7huFpF1bpktEJGveT670Y1rmYic4RmetfUsIgeKyFsiskREFovIj93hBS2vJHEVurwqReR9Efm3G9dv3OH9ReQ9d9mfFZEKd3gH9/0K9/N+LcWb5bieEJFVnvIa5g7P53bvF5H5IvKS+z4/ZaWqJfeH81jsWuBgoAL4NzA4zzGsBnrGDLsN+Ln7+ufAH9zXXwNewfnBqeOA97IYx4nACGBRpnEAPYCV7v/u7uvuOYjrZuAnccYd7K7DDkB/d936s72egf2BEe7rLji/tzG40OWVJK5Cl5cAnd3X5cB7bjk8B3zXHf4AcLX7+hrgAff1d4Fnk8Wbg7ieAM6JM34+t/tJwF+Al9z3eSmrUj0jOAZYoaorVbUReAY4q8AxgRPDk+7rJ4FveYb/UR1zgG4isn82ZqiqM4EtrYzjDGC6qm5R1S+B6cC4HMSVyFnAM6q6R1VXAStw1nFW17OqrlfVD93XO4AlOL/NXdDyShJXIvkqL1XVne7bcvdPgVOAae7w2PIKl+M04FQRkSTxZjuuRPKyHkWkD/B14BH3vZCnsirVRNAbWON5v5bkO04uKPAvEZknIle6w76iquvB2bmBfd3h+Y433TjyGd+17un5Y+EmmELE5Z6KD8epTRZNecXEBQUuL7epYwGwEedAWQtsVdXwjxx75xGZv/v5NqA6H3Gpari8bnXL604R6RAbV8z8sx3XXcBP2ftTyNXkqaxKNRFInGH5vo52tKqOAM4EfigiJyYZtxjihcRx5Cu++4EBwDBgPXBHIeISkc7AC8D1qro92agFjqvg5aWqQVUdBvTBqZkelmQeBYtLRA4HbgQGAUfjNPf8LF9xicg3gI2qOs87OMn0sxpTqSaCtcCBnvd9gM/zGYCqfu7+3wj8FWcn+SLc5OP+3+iOnu94040jL/Gp6hfuDhwCHmbvKW/e4hKRcpyD7VOq+qI7uODlFS+uYiivMFXdCszAaWPvJs5vmsfOIzJ/9/N9cJoH8xHXOLeJTVV1D/A4+S2v0cA3RWQ1TpPcKThnCPkpq9Z0bLTVP5yf6FyJ05kS7hQbksf5dwK6eF7PwmlbvJ3oTsfb3NdfJ7qz6v0sx9OP6E7ZtOLAqT2twukw6+6+7pGDuPb3vJ6I0xYKMIToDrKVOB2fWV3P7nL/EbgrZnhByytJXIUur15AN/d1FfAO8A3geaI7QK9xX/+Q6A7Q55LFm4O49veU513A7wu03Y9hb2dxXsoqaweTtvaHcyXAcpw2y1/med4Huyvr38Di8Pxx2vjeAD5x//fwbJj3ubEuBEZmMZancZoNmnBqE9/LJA5gAk7H1Arg8hzF9Sd3vh8Bfyf6QPdLN65lwJm5WM/ACTin2R8BC9y/rxW6vJLEVejyOgKY785/EfBrz/b/vrvszwMd3OGV7vsV7ucHtxRvluN60y2vRcCf2XtlUd62e3eaY9ibCPJSVvaICWOMKXGl2kdgjDHGZYnAGGNKnCUCY4wpcZYIjDGmxFkiMMaYEmeJwBSciATdpz0udp8IOUlEkm6bItJPRC7MQ2yPiMjgFsb5VqJxROQqERmf5jxniEjR/Vi6ab/KWh7FmJyrV+d2f0RkX5ynL+4D3JTkO/2AC91xc0ZVv5/CaN8CXgI+jvP9B7IelDFZZmcEpqio88iNK3EeliZuzf8dEfnQ/Rvljvp74KvumcTEJONFuOMsFZEn3QeLTRORju5np7rPgV/oPqCtgzs8UjsXkZ0icqt71jJHRL7izuebwO1uLANi5nmziPzEM60/iPMs/OUi8lV3eJWIPOPG9CzO3a7h758uIrPdZXpeRDqLyD7us+YPdcd5WkSuyOqKMCXFEoEpOqq6Emfb3BfnuT1j1XlA3/nAPe5oPwfeUdVhqnpnkvFiHQo8pKpHANuBa0SkEudZ9Oer6lCcM+Wr43y3EzBHVY8EZgJXqOosnLt2J7ux1LaweGWqegxwPXvPeK4Gdrsx3QocBSAiPYFfAae5yzUXmKSq24BrgSdE5Ls4z8B/uIX5GpOQJQJTrMJPUSwHHhaRhTi31Cdqr091vDWqWuO+/jPO4xkOBVap6nJ3+JM4P4wTqxGnCQhgHk7zVLrCD6rzfv9ENxZU9SOcRx+A81ybwUCN+8jkS4GD3PGm4zzu4D4gleYrYxKyPgJTdETkYCCIU8u/CfgCOBKn4tKQ4GsTUxwv9pkqiR7dG0+T7n0mS5DM9p89Cb4f71kvgvOs/AuafeB0ph8G1OM8/GxtBrEYA9gZgSkyItIL5ymL97oH3X2A9eo8SvkSnKdkAuzA+VnGsETjxeorIse7ry8A3gWWAv1E5BB3+CXA22mEHRtLumYCFwG4z8U/wh0+BxgdjktEOorIQPeziTi/RHYB8Jj7GGpjMmKJwBSDqvDlo8DrwL+A37if/S9wqYjMAQYCu9zhHwEBt+N2YpLxYi1xx/sIpyZ9v6o2AJcDz7tNSyGcZJSqZ4DJbmfzgBbHbu5+oLMb009xniaJqm4CLgOedj+bAwxyk8H3gRtU9R2cRPKrDOZrDIA9fdSUDnF+xvElVT28wKEYU1TsjMAYY0qcnREYY0yJszMCY4wpcZYIjDGmxFkiMMaYEmeJwBhjSpwlAmOMKXH/H3QRpwYhbQHYAAAAAElFTkSuQmCC\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": "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\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 |
--------------------------------------------------------------------------------