├── Labels.xlsx ├── README.md ├── rClassify Trained Models.ipynb └── rClassify preprocessing Demo.ipynb /Labels.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitrj/rClassify/1d3e3ebf4e43d4fc05a07e0fcc8ed0c84ac26df0/Labels.xlsx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Retinopathy-Detection 2 | 3 | ## Dataset Description: 4 | Over 200 Images of retina, obtained by Fundus imaging were acquired and analyzed. 100 of them were normal and tagged as 0, and 100 were affected by diabetic retinopathy and tagged as 1. 5 | 6 | ## Preprocessing 7 | The images were preprocessed to highlight the sites of microaneurysm and suppress all other features. 8 | 9 | ## Regression Analysis 10 | These images were then used to train machine learning models based on SVM, Random Forest, Decision Tree and K Nearest Neighbors. The train and test data were split into 60-40, 70-30 and 80-20 combinations of train and test ratios. The best model was the random forest model obtained by training over 70% of data. 11 | 12 | ## Dataset is subject to privacy concerns. 13 | Will be shared soon. 14 | -------------------------------------------------------------------------------- /rClassify Trained Models.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Imports" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import matplotlib.pyplot as plt\n", 17 | "import numpy as np\n", 18 | "import pandas as pd\n", 19 | "\n", 20 | "import cv2\n", 21 | "from scipy.ndimage.filters import gaussian_filter\n", 22 | "\n", 23 | "from sklearn.model_selection import train_test_split\n", 24 | "from sklearn.metrics import classification_report\n", 25 | "from pandas_ml import ConfusionMatrix\n", 26 | "\n", 27 | "from sklearn.svm import SVC\n", 28 | "from sklearn.ensemble import RandomForestClassifier\n", 29 | "from sklearn.tree import DecisionTreeClassifier\n", 30 | "from sklearn.neighbors import KNeighborsClassifier" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "## Read Dataset" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 2, 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "data": { 47 | "text/html": [ 48 | "
\n", 49 | "\n", 62 | "\n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | "
Image_IDLabel
0002c21358ce60
1005b95c288520
20097f532ac9f0
300cc2b75cddd0
400f6c1be5a330
\n", 98 | "
" 99 | ], 100 | "text/plain": [ 101 | " Image_ID Label\n", 102 | "0 002c21358ce6 0\n", 103 | "1 005b95c28852 0\n", 104 | "2 0097f532ac9f 0\n", 105 | "3 00cc2b75cddd 0\n", 106 | "4 00f6c1be5a33 0" 107 | ] 108 | }, 109 | "execution_count": 2, 110 | "metadata": {}, 111 | "output_type": "execute_result" 112 | } 113 | ], 114 | "source": [ 115 | "df = pd.read_excel(\"Labels.xlsx\")\n", 116 | "df.head()" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 3, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/html": [ 127 | "
\n", 128 | "\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 | "
Label
count200.000000
mean0.500000
std0.501255
min0.000000
25%0.000000
50%0.500000
75%1.000000
max1.000000
\n", 183 | "
" 184 | ], 185 | "text/plain": [ 186 | " Label\n", 187 | "count 200.000000\n", 188 | "mean 0.500000\n", 189 | "std 0.501255\n", 190 | "min 0.000000\n", 191 | "25% 0.000000\n", 192 | "50% 0.500000\n", 193 | "75% 1.000000\n", 194 | "max 1.000000" 195 | ] 196 | }, 197 | "execution_count": 3, 198 | "metadata": {}, 199 | "output_type": "execute_result" 200 | } 201 | ], 202 | "source": [ 203 | "df.describe()" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "## Function to read, preprocess and flatten images" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 4, 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [ 219 | "def read_preprocess(name):\n", 220 | " path = 'ImageData/' + name + '.png'\n", 221 | " frame = cv2.imread(path)\n", 222 | " imG = cv2.equalizeHist(frame[:,:,1])\n", 223 | " blG = gaussian_filter(np.max(imG) - imG, sigma=50) \n", 224 | " fG = ( blG < np.mean(blG) )* (np.max(imG) - imG)\n", 225 | " pifG = (fG/np.mean(fG))**2\n", 226 | " pifG = (pifG * (255/np.max(pifG))).astype(int)\n", 227 | " frame[:,:,1] = pifG\n", 228 | " fr = cv2.resize(frame,(256,256), interpolation = cv2.INTER_AREA)\n", 229 | " fg = fr[:,:,1]\n", 230 | " fg1 = np.max(fg**2) - fg**2\n", 231 | " fg2 = (fg1>245) * fg1\n", 232 | " fg3 = (fg2>=248) * 255\n", 233 | " \n", 234 | " return (fg3.reshape(256*256))/255 " 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 5, 245 | "metadata": {}, 246 | "outputs": [], 247 | "source": [ 248 | "def CR(Ypred,Ytrue):\n", 249 | " rep = classification_report(y_pred = Ypred ,y_true=Ytrue,)\n", 250 | " det = np.array( [ [float(x.strip()) for x in rep.split('\\n')[2].split(' ')[3:6] ], [float(x.strip()) for x in rep.split('\\n')[3].split(' ')[3:6] ]])\n", 251 | " dd = pd.DataFrame()\n", 252 | " dd['Precision'] = det.T[0]\n", 253 | " dd['Recall'] = det.T[1]\n", 254 | " dd['f1_score'] = det.T[2]\n", 255 | " return dd" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "## Feature Matrix" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": 6, 268 | "metadata": {}, 269 | "outputs": [], 270 | "source": [ 271 | "X = np.zeros((len(df['Image_ID']),(256*256)))" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 7, 277 | "metadata": {}, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "pocessing 0\n", 284 | "pocessing 1\n", 285 | "pocessing 2\n", 286 | "pocessing 3\n", 287 | "pocessing 4\n", 288 | "pocessing 5\n", 289 | "pocessing 6\n", 290 | "pocessing 7\n", 291 | "pocessing 8\n", 292 | "pocessing 9\n", 293 | "pocessing 10\n", 294 | "pocessing 11\n", 295 | "pocessing 12\n", 296 | "pocessing 13\n", 297 | "pocessing 14\n", 298 | "pocessing 15\n", 299 | "pocessing 16\n", 300 | "pocessing 17\n", 301 | "pocessing 18\n", 302 | "pocessing 19\n", 303 | "pocessing 20\n", 304 | "pocessing 21\n", 305 | "pocessing 22\n", 306 | "pocessing 23\n", 307 | "pocessing 24\n", 308 | "pocessing 25\n", 309 | "pocessing 26\n", 310 | "pocessing 27\n", 311 | "pocessing 28\n", 312 | "pocessing 29\n", 313 | "pocessing 30\n", 314 | "pocessing 31\n", 315 | "pocessing 32\n", 316 | "pocessing 33\n", 317 | "pocessing 34\n", 318 | "pocessing 35\n", 319 | "pocessing 36\n", 320 | "pocessing 37\n", 321 | "pocessing 38\n", 322 | "pocessing 39\n", 323 | "pocessing 40\n", 324 | "pocessing 41\n", 325 | "pocessing 42\n", 326 | "pocessing 43\n", 327 | "pocessing 44\n", 328 | "pocessing 45\n", 329 | "pocessing 46\n", 330 | "pocessing 47\n", 331 | "pocessing 48\n", 332 | "pocessing 49\n", 333 | "pocessing 50\n", 334 | "pocessing 51\n", 335 | "pocessing 52\n", 336 | "pocessing 53\n", 337 | "pocessing 54\n", 338 | "pocessing 55\n", 339 | "pocessing 56\n", 340 | "pocessing 57\n", 341 | "pocessing 58\n", 342 | "pocessing 59\n", 343 | "pocessing 60\n", 344 | "pocessing 61\n", 345 | "pocessing 62\n", 346 | "pocessing 63\n", 347 | "pocessing 64\n", 348 | "pocessing 65\n", 349 | "pocessing 66\n", 350 | "pocessing 67\n", 351 | "pocessing 68\n", 352 | "pocessing 69\n", 353 | "pocessing 70\n", 354 | "pocessing 71\n", 355 | "pocessing 72\n", 356 | "pocessing 73\n", 357 | "pocessing 74\n", 358 | "pocessing 75\n", 359 | "pocessing 76\n", 360 | "pocessing 77\n", 361 | "pocessing 78\n", 362 | "pocessing 79\n", 363 | "pocessing 80\n", 364 | "pocessing 81\n", 365 | "pocessing 82\n", 366 | "pocessing 83\n", 367 | "pocessing 84\n", 368 | "pocessing 85\n", 369 | "pocessing 86\n", 370 | "pocessing 87\n", 371 | "pocessing 88\n", 372 | "pocessing 89\n", 373 | "pocessing 90\n", 374 | "pocessing 91\n", 375 | "pocessing 92\n", 376 | "pocessing 93\n", 377 | "pocessing 94\n", 378 | "pocessing 95\n", 379 | "pocessing 96\n", 380 | "pocessing 97\n", 381 | "pocessing 98\n", 382 | "pocessing 99\n", 383 | "pocessing 100\n", 384 | "pocessing 101\n", 385 | "pocessing 102\n", 386 | "pocessing 103\n", 387 | "pocessing 104\n", 388 | "pocessing 105\n", 389 | "pocessing 106\n", 390 | "pocessing 107\n", 391 | "pocessing 108\n", 392 | "pocessing 109\n", 393 | "pocessing 110\n", 394 | "pocessing 111\n", 395 | "pocessing 112\n", 396 | "pocessing 113\n", 397 | "pocessing 114\n", 398 | "pocessing 115\n", 399 | "pocessing 116\n", 400 | "pocessing 117\n", 401 | "pocessing 118\n", 402 | "pocessing 119\n", 403 | "pocessing 120\n", 404 | "pocessing 121\n", 405 | "pocessing 122\n", 406 | "pocessing 123\n", 407 | "pocessing 124\n", 408 | "pocessing 125\n", 409 | "pocessing 126\n", 410 | "pocessing 127\n", 411 | "pocessing 128\n", 412 | "pocessing 129\n", 413 | "pocessing 130\n", 414 | "pocessing 131\n", 415 | "pocessing 132\n", 416 | "pocessing 133\n", 417 | "pocessing 134\n", 418 | "pocessing 135\n", 419 | "pocessing 136\n", 420 | "pocessing 137\n", 421 | "pocessing 138\n", 422 | "pocessing 139\n", 423 | "pocessing 140\n", 424 | "pocessing 141\n", 425 | "pocessing 142\n", 426 | "pocessing 143\n", 427 | "pocessing 144\n", 428 | "pocessing 145\n", 429 | "pocessing 146\n", 430 | "pocessing 147\n", 431 | "pocessing 148\n", 432 | "pocessing 149\n", 433 | "pocessing 150\n", 434 | "pocessing 151\n", 435 | "pocessing 152\n", 436 | "pocessing 153\n", 437 | "pocessing 154\n", 438 | "pocessing 155\n", 439 | "pocessing 156\n", 440 | "pocessing 157\n", 441 | "pocessing 158\n", 442 | "pocessing 159\n", 443 | "pocessing 160\n", 444 | "pocessing 161\n", 445 | "pocessing 162\n", 446 | "pocessing 163\n", 447 | "pocessing 164\n", 448 | "pocessing 165\n", 449 | "pocessing 166\n", 450 | "pocessing 167\n", 451 | "pocessing 168\n", 452 | "pocessing 169\n", 453 | "pocessing 170\n", 454 | "pocessing 171\n", 455 | "pocessing 172\n", 456 | "pocessing 173\n", 457 | "pocessing 174\n", 458 | "pocessing 175\n", 459 | "pocessing 176\n", 460 | "pocessing 177\n", 461 | "pocessing 178\n", 462 | "pocessing 179\n", 463 | "pocessing 180\n", 464 | "pocessing 181\n", 465 | "pocessing 182\n", 466 | "pocessing 183\n", 467 | "pocessing 184\n", 468 | "pocessing 185\n", 469 | "pocessing 186\n", 470 | "pocessing 187\n", 471 | "pocessing 188\n", 472 | "pocessing 189\n", 473 | "pocessing 190\n", 474 | "pocessing 191\n", 475 | "pocessing 192\n", 476 | "pocessing 193\n", 477 | "pocessing 194\n", 478 | "pocessing 195\n", 479 | "pocessing 196\n", 480 | "pocessing 197\n", 481 | "pocessing 198\n", 482 | "pocessing 199\n" 483 | ] 484 | } 485 | ], 486 | "source": [ 487 | "for i in range(len(df['Image_ID'])):\n", 488 | " print(\"pocessing\", i)\n", 489 | " X[i] = read_preprocess(df['Image_ID'][i])" 490 | ] 491 | }, 492 | { 493 | "cell_type": "markdown", 494 | "metadata": {}, 495 | "source": [ 496 | "## Labels" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": 8, 502 | "metadata": {}, 503 | "outputs": [], 504 | "source": [ 505 | "y = np.array(df['Label'])" 506 | ] 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "metadata": {}, 511 | "source": [ 512 | "## Train : Test = 60:40" 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "execution_count": 9, 518 | "metadata": {}, 519 | "outputs": [], 520 | "source": [ 521 | "Xtr, Xt, ytr, yt = train_test_split(X,y, test_size = 0.4, train_size = 0.6)" 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "### SVM Classifier" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "execution_count": 10, 534 | "metadata": {}, 535 | "outputs": [], 536 | "source": [ 537 | "clf_SVM = SVC(gamma = 'auto')" 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": 11, 543 | "metadata": {}, 544 | "outputs": [ 545 | { 546 | "data": { 547 | "text/plain": [ 548 | "SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,\n", 549 | " decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',\n", 550 | " max_iter=-1, probability=False, random_state=None, shrinking=True,\n", 551 | " tol=0.001, verbose=False)" 552 | ] 553 | }, 554 | "execution_count": 11, 555 | "metadata": {}, 556 | "output_type": "execute_result" 557 | } 558 | ], 559 | "source": [ 560 | "clf_SVM.fit(Xtr,ytr)" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": 12, 566 | "metadata": {}, 567 | "outputs": [], 568 | "source": [ 569 | "yp_SVM = clf_SVM.predict(Xt)" 570 | ] 571 | }, 572 | { 573 | "cell_type": "code", 574 | "execution_count": 13, 575 | "metadata": {}, 576 | "outputs": [ 577 | { 578 | "data": { 579 | "text/html": [ 580 | "
\n", 581 | "\n", 594 | "\n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | "
PrecisionRecallf1_score
00.680.690.68
10.740.730.74
\n", 618 | "
" 619 | ], 620 | "text/plain": [ 621 | " Precision Recall f1_score\n", 622 | "0 0.68 0.69 0.68\n", 623 | "1 0.74 0.73 0.74" 624 | ] 625 | }, 626 | "execution_count": 13, 627 | "metadata": {}, 628 | "output_type": "execute_result" 629 | } 630 | ], 631 | "source": [ 632 | "cr_SVM = CR(yp_SVM,yt)\n", 633 | "cr_SVM" 634 | ] 635 | }, 636 | { 637 | "cell_type": "markdown", 638 | "metadata": {}, 639 | "source": [ 640 | "### Random Forest" 641 | ] 642 | }, 643 | { 644 | "cell_type": "code", 645 | "execution_count": 14, 646 | "metadata": {}, 647 | "outputs": [], 648 | "source": [ 649 | "clf_RF = RandomForestClassifier(n_estimators=100, max_depth=40,random_state=0)" 650 | ] 651 | }, 652 | { 653 | "cell_type": "code", 654 | "execution_count": 15, 655 | "metadata": {}, 656 | "outputs": [ 657 | { 658 | "data": { 659 | "text/plain": [ 660 | "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", 661 | " max_depth=40, max_features='auto', max_leaf_nodes=None,\n", 662 | " min_impurity_decrease=0.0, min_impurity_split=None,\n", 663 | " min_samples_leaf=1, min_samples_split=2,\n", 664 | " min_weight_fraction_leaf=0.0, n_estimators=100, n_jobs=None,\n", 665 | " oob_score=False, random_state=0, verbose=0, warm_start=False)" 666 | ] 667 | }, 668 | "execution_count": 15, 669 | "metadata": {}, 670 | "output_type": "execute_result" 671 | } 672 | ], 673 | "source": [ 674 | "clf_RF.fit(Xtr,ytr)" 675 | ] 676 | }, 677 | { 678 | "cell_type": "code", 679 | "execution_count": 16, 680 | "metadata": {}, 681 | "outputs": [], 682 | "source": [ 683 | "yp_RF = clf_RF.predict(Xt)" 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "execution_count": 17, 689 | "metadata": {}, 690 | "outputs": [ 691 | { 692 | "data": { 693 | "text/html": [ 694 | "
\n", 695 | "\n", 708 | "\n", 709 | " \n", 710 | " \n", 711 | " \n", 712 | " \n", 713 | " \n", 714 | " \n", 715 | " \n", 716 | " \n", 717 | " \n", 718 | " \n", 719 | " \n", 720 | " \n", 721 | " \n", 722 | " \n", 723 | " \n", 724 | " \n", 725 | " \n", 726 | " \n", 727 | " \n", 728 | " \n", 729 | " \n", 730 | " \n", 731 | "
PrecisionRecallf1_score
00.830.690.76
10.780.890.83
\n", 732 | "
" 733 | ], 734 | "text/plain": [ 735 | " Precision Recall f1_score\n", 736 | "0 0.83 0.69 0.76\n", 737 | "1 0.78 0.89 0.83" 738 | ] 739 | }, 740 | "execution_count": 17, 741 | "metadata": {}, 742 | "output_type": "execute_result" 743 | } 744 | ], 745 | "source": [ 746 | "cr_RF = CR(yp_RF,yt)\n", 747 | "cr_RF" 748 | ] 749 | }, 750 | { 751 | "cell_type": "markdown", 752 | "metadata": {}, 753 | "source": [ 754 | "### Decision Tree" 755 | ] 756 | }, 757 | { 758 | "cell_type": "code", 759 | "execution_count": 18, 760 | "metadata": {}, 761 | "outputs": [], 762 | "source": [ 763 | "clf_DT = DecisionTreeClassifier()" 764 | ] 765 | }, 766 | { 767 | "cell_type": "code", 768 | "execution_count": 19, 769 | "metadata": {}, 770 | "outputs": [ 771 | { 772 | "data": { 773 | "text/plain": [ 774 | "DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,\n", 775 | " max_features=None, max_leaf_nodes=None,\n", 776 | " min_impurity_decrease=0.0, min_impurity_split=None,\n", 777 | " min_samples_leaf=1, min_samples_split=2,\n", 778 | " min_weight_fraction_leaf=0.0, presort=False, random_state=None,\n", 779 | " splitter='best')" 780 | ] 781 | }, 782 | "execution_count": 19, 783 | "metadata": {}, 784 | "output_type": "execute_result" 785 | } 786 | ], 787 | "source": [ 788 | "clf_DT.fit(Xtr,ytr)" 789 | ] 790 | }, 791 | { 792 | "cell_type": "code", 793 | "execution_count": 20, 794 | "metadata": {}, 795 | "outputs": [], 796 | "source": [ 797 | "yp_DT = clf_DT.predict(Xt)" 798 | ] 799 | }, 800 | { 801 | "cell_type": "code", 802 | "execution_count": 21, 803 | "metadata": {}, 804 | "outputs": [ 805 | { 806 | "data": { 807 | "text/html": [ 808 | "
\n", 809 | "\n", 822 | "\n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | "
PrecisionRecallf1_score
00.700.640.67
10.720.770.75
\n", 846 | "
" 847 | ], 848 | "text/plain": [ 849 | " Precision Recall f1_score\n", 850 | "0 0.70 0.64 0.67\n", 851 | "1 0.72 0.77 0.75" 852 | ] 853 | }, 854 | "execution_count": 21, 855 | "metadata": {}, 856 | "output_type": "execute_result" 857 | } 858 | ], 859 | "source": [ 860 | "cr_DT = CR(yp_DT,yt)\n", 861 | "cr_DT" 862 | ] 863 | }, 864 | { 865 | "cell_type": "markdown", 866 | "metadata": {}, 867 | "source": [ 868 | "### K Nearest Neighbors" 869 | ] 870 | }, 871 | { 872 | "cell_type": "code", 873 | "execution_count": 22, 874 | "metadata": {}, 875 | "outputs": [], 876 | "source": [ 877 | "clf_KNN = KNeighborsClassifier(n_neighbors=3)" 878 | ] 879 | }, 880 | { 881 | "cell_type": "code", 882 | "execution_count": 23, 883 | "metadata": {}, 884 | "outputs": [ 885 | { 886 | "data": { 887 | "text/plain": [ 888 | "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n", 889 | " metric_params=None, n_jobs=None, n_neighbors=3, p=2,\n", 890 | " weights='uniform')" 891 | ] 892 | }, 893 | "execution_count": 23, 894 | "metadata": {}, 895 | "output_type": "execute_result" 896 | } 897 | ], 898 | "source": [ 899 | "clf_KNN.fit(Xtr,ytr)" 900 | ] 901 | }, 902 | { 903 | "cell_type": "code", 904 | "execution_count": 24, 905 | "metadata": {}, 906 | "outputs": [], 907 | "source": [ 908 | "yp_KNN = clf_KNN.predict(Xt)" 909 | ] 910 | }, 911 | { 912 | "cell_type": "code", 913 | "execution_count": 25, 914 | "metadata": {}, 915 | "outputs": [ 916 | { 917 | "data": { 918 | "text/html": [ 919 | "
\n", 920 | "\n", 933 | "\n", 934 | " \n", 935 | " \n", 936 | " \n", 937 | " \n", 938 | " \n", 939 | " \n", 940 | " \n", 941 | " \n", 942 | " \n", 943 | " \n", 944 | " \n", 945 | " \n", 946 | " \n", 947 | " \n", 948 | " \n", 949 | " \n", 950 | " \n", 951 | " \n", 952 | " \n", 953 | " \n", 954 | " \n", 955 | " \n", 956 | "
PrecisionRecallf1_score
00.640.830.72
10.820.610.70
\n", 957 | "
" 958 | ], 959 | "text/plain": [ 960 | " Precision Recall f1_score\n", 961 | "0 0.64 0.83 0.72\n", 962 | "1 0.82 0.61 0.70" 963 | ] 964 | }, 965 | "execution_count": 25, 966 | "metadata": {}, 967 | "output_type": "execute_result" 968 | } 969 | ], 970 | "source": [ 971 | "cr_KNN = CR(yp_KNN,yt)\n", 972 | "cr_KNN" 973 | ] 974 | }, 975 | { 976 | "cell_type": "markdown", 977 | "metadata": {}, 978 | "source": [ 979 | "### Store Model" 980 | ] 981 | }, 982 | { 983 | "cell_type": "code", 984 | "execution_count": 26, 985 | "metadata": {}, 986 | "outputs": [], 987 | "source": [ 988 | "Models = {}" 989 | ] 990 | }, 991 | { 992 | "cell_type": "code", 993 | "execution_count": 27, 994 | "metadata": {}, 995 | "outputs": [], 996 | "source": [ 997 | "Models['60-40'] = [clf_SVM, clf_RF, clf_DT, clf_KNN]" 998 | ] 999 | }, 1000 | { 1001 | "cell_type": "markdown", 1002 | "metadata": {}, 1003 | "source": [ 1004 | "## Train : Test = 70:30" 1005 | ] 1006 | }, 1007 | { 1008 | "cell_type": "code", 1009 | "execution_count": 28, 1010 | "metadata": {}, 1011 | "outputs": [], 1012 | "source": [ 1013 | "Xtr, Xt, ytr, yt = train_test_split(X,y, test_size = 0.3, train_size = 0.7)" 1014 | ] 1015 | }, 1016 | { 1017 | "cell_type": "markdown", 1018 | "metadata": {}, 1019 | "source": [ 1020 | "### SVM Classifier" 1021 | ] 1022 | }, 1023 | { 1024 | "cell_type": "code", 1025 | "execution_count": 29, 1026 | "metadata": {}, 1027 | "outputs": [ 1028 | { 1029 | "data": { 1030 | "text/html": [ 1031 | "
\n", 1032 | "\n", 1045 | "\n", 1046 | " \n", 1047 | " \n", 1048 | " \n", 1049 | " \n", 1050 | " \n", 1051 | " \n", 1052 | " \n", 1053 | " \n", 1054 | " \n", 1055 | " \n", 1056 | " \n", 1057 | " \n", 1058 | " \n", 1059 | " \n", 1060 | " \n", 1061 | " \n", 1062 | " \n", 1063 | " \n", 1064 | " \n", 1065 | " \n", 1066 | " \n", 1067 | " \n", 1068 | "
PrecisionRecallf1_score
00.700.810.75
10.830.740.78
\n", 1069 | "
" 1070 | ], 1071 | "text/plain": [ 1072 | " Precision Recall f1_score\n", 1073 | "0 0.70 0.81 0.75\n", 1074 | "1 0.83 0.74 0.78" 1075 | ] 1076 | }, 1077 | "execution_count": 29, 1078 | "metadata": {}, 1079 | "output_type": "execute_result" 1080 | } 1081 | ], 1082 | "source": [ 1083 | "clf_SVM = SVC(gamma = 'auto')\n", 1084 | "clf_SVM.fit(Xtr,ytr)\n", 1085 | "yp_SVM = clf_SVM.predict(Xt)\n", 1086 | "cr_SVM = CR(yp_SVM,yt)\n", 1087 | "cr_SVM" 1088 | ] 1089 | }, 1090 | { 1091 | "cell_type": "markdown", 1092 | "metadata": {}, 1093 | "source": [ 1094 | "### Random Forest" 1095 | ] 1096 | }, 1097 | { 1098 | "cell_type": "code", 1099 | "execution_count": 30, 1100 | "metadata": {}, 1101 | "outputs": [ 1102 | { 1103 | "name": "stderr", 1104 | "output_type": "stream", 1105 | "text": [ 1106 | "C:\\Users\\Sumit\\Anaconda3\\lib\\site-packages\\sklearn\\ensemble\\forest.py:248: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.\n", 1107 | " \"10 in version 0.20 to 100 in 0.22.\", FutureWarning)\n" 1108 | ] 1109 | }, 1110 | { 1111 | "data": { 1112 | "text/html": [ 1113 | "
\n", 1114 | "\n", 1127 | "\n", 1128 | " \n", 1129 | " \n", 1130 | " \n", 1131 | " \n", 1132 | " \n", 1133 | " \n", 1134 | " \n", 1135 | " \n", 1136 | " \n", 1137 | " \n", 1138 | " \n", 1139 | " \n", 1140 | " \n", 1141 | " \n", 1142 | " \n", 1143 | " \n", 1144 | " \n", 1145 | " \n", 1146 | " \n", 1147 | " \n", 1148 | " \n", 1149 | " \n", 1150 | "
PrecisionRecallf1_score
00.710.920.8
10.920.710.8
\n", 1151 | "
" 1152 | ], 1153 | "text/plain": [ 1154 | " Precision Recall f1_score\n", 1155 | "0 0.71 0.92 0.8\n", 1156 | "1 0.92 0.71 0.8" 1157 | ] 1158 | }, 1159 | "execution_count": 30, 1160 | "metadata": {}, 1161 | "output_type": "execute_result" 1162 | } 1163 | ], 1164 | "source": [ 1165 | "clf_RF = RandomForestClassifier()\n", 1166 | "clf_RF.fit(Xtr,ytr)\n", 1167 | "yp_RF = clf_RF.predict(Xt)\n", 1168 | "cr_RF = CR(yp_RF,yt)\n", 1169 | "cr_RF" 1170 | ] 1171 | }, 1172 | { 1173 | "cell_type": "markdown", 1174 | "metadata": {}, 1175 | "source": [ 1176 | "### Decision Tree" 1177 | ] 1178 | }, 1179 | { 1180 | "cell_type": "code", 1181 | "execution_count": 31, 1182 | "metadata": {}, 1183 | "outputs": [ 1184 | { 1185 | "data": { 1186 | "text/html": [ 1187 | "
\n", 1188 | "\n", 1201 | "\n", 1202 | " \n", 1203 | " \n", 1204 | " \n", 1205 | " \n", 1206 | " \n", 1207 | " \n", 1208 | " \n", 1209 | " \n", 1210 | " \n", 1211 | " \n", 1212 | " \n", 1213 | " \n", 1214 | " \n", 1215 | " \n", 1216 | " \n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | "
PrecisionRecallf1_score
00.530.620.57
10.670.590.62
\n", 1225 | "
" 1226 | ], 1227 | "text/plain": [ 1228 | " Precision Recall f1_score\n", 1229 | "0 0.53 0.62 0.57\n", 1230 | "1 0.67 0.59 0.62" 1231 | ] 1232 | }, 1233 | "execution_count": 31, 1234 | "metadata": {}, 1235 | "output_type": "execute_result" 1236 | } 1237 | ], 1238 | "source": [ 1239 | "clf_DT = DecisionTreeClassifier()\n", 1240 | "clf_DT.fit(Xtr,ytr)\n", 1241 | "yp_DT = clf_DT.predict(Xt)\n", 1242 | "cr_DT = CR(yp_DT,yt)\n", 1243 | "cr_DT" 1244 | ] 1245 | }, 1246 | { 1247 | "cell_type": "markdown", 1248 | "metadata": {}, 1249 | "source": [ 1250 | "### K Nearest Neighbors" 1251 | ] 1252 | }, 1253 | { 1254 | "cell_type": "code", 1255 | "execution_count": 32, 1256 | "metadata": {}, 1257 | "outputs": [ 1258 | { 1259 | "data": { 1260 | "text/html": [ 1261 | "
\n", 1262 | "\n", 1275 | "\n", 1276 | " \n", 1277 | " \n", 1278 | " \n", 1279 | " \n", 1280 | " \n", 1281 | " \n", 1282 | " \n", 1283 | " \n", 1284 | " \n", 1285 | " \n", 1286 | " \n", 1287 | " \n", 1288 | " \n", 1289 | " \n", 1290 | " \n", 1291 | " \n", 1292 | " \n", 1293 | " \n", 1294 | " \n", 1295 | " \n", 1296 | " \n", 1297 | " \n", 1298 | "
PrecisionRecallf1_score
00.680.880.77
10.880.680.77
\n", 1299 | "
" 1300 | ], 1301 | "text/plain": [ 1302 | " Precision Recall f1_score\n", 1303 | "0 0.68 0.88 0.77\n", 1304 | "1 0.88 0.68 0.77" 1305 | ] 1306 | }, 1307 | "execution_count": 32, 1308 | "metadata": {}, 1309 | "output_type": "execute_result" 1310 | } 1311 | ], 1312 | "source": [ 1313 | "clf_KNN = KNeighborsClassifier(n_neighbors=3)\n", 1314 | "clf_KNN.fit(Xtr,ytr)\n", 1315 | "yp_KNN = clf_KNN.predict(Xt)\n", 1316 | "cr_KNN = CR(yp_KNN,yt)\n", 1317 | "cr_KNN" 1318 | ] 1319 | }, 1320 | { 1321 | "cell_type": "markdown", 1322 | "metadata": {}, 1323 | "source": [ 1324 | "### Store Model" 1325 | ] 1326 | }, 1327 | { 1328 | "cell_type": "code", 1329 | "execution_count": 33, 1330 | "metadata": {}, 1331 | "outputs": [], 1332 | "source": [ 1333 | "Models['70-30'] = [clf_SVM, clf_RF, clf_DT, clf_KNN]" 1334 | ] 1335 | }, 1336 | { 1337 | "cell_type": "markdown", 1338 | "metadata": {}, 1339 | "source": [ 1340 | "## Train : Test = 80:20" 1341 | ] 1342 | }, 1343 | { 1344 | "cell_type": "code", 1345 | "execution_count": 34, 1346 | "metadata": {}, 1347 | "outputs": [], 1348 | "source": [ 1349 | "Xtr, Xt, ytr, yt = train_test_split(X,y, test_size = 0.2, train_size = 0.8)" 1350 | ] 1351 | }, 1352 | { 1353 | "cell_type": "markdown", 1354 | "metadata": {}, 1355 | "source": [ 1356 | "### SVM Classifier" 1357 | ] 1358 | }, 1359 | { 1360 | "cell_type": "code", 1361 | "execution_count": 35, 1362 | "metadata": {}, 1363 | "outputs": [ 1364 | { 1365 | "data": { 1366 | "text/html": [ 1367 | "
\n", 1368 | "\n", 1381 | "\n", 1382 | " \n", 1383 | " \n", 1384 | " \n", 1385 | " \n", 1386 | " \n", 1387 | " \n", 1388 | " \n", 1389 | " \n", 1390 | " \n", 1391 | " \n", 1392 | " \n", 1393 | " \n", 1394 | " \n", 1395 | " \n", 1396 | " \n", 1397 | " \n", 1398 | " \n", 1399 | " \n", 1400 | " \n", 1401 | " \n", 1402 | " \n", 1403 | " \n", 1404 | "
PrecisionRecallf1_score
00.810.850.83
10.840.800.82
\n", 1405 | "
" 1406 | ], 1407 | "text/plain": [ 1408 | " Precision Recall f1_score\n", 1409 | "0 0.81 0.85 0.83\n", 1410 | "1 0.84 0.80 0.82" 1411 | ] 1412 | }, 1413 | "execution_count": 35, 1414 | "metadata": {}, 1415 | "output_type": "execute_result" 1416 | } 1417 | ], 1418 | "source": [ 1419 | "clf_SVM = SVC(gamma = 'auto')\n", 1420 | "clf_SVM.fit(Xtr,ytr)\n", 1421 | "yp_SVM = clf_SVM.predict(Xt)\n", 1422 | "cr_SVM = CR(yp_SVM,yt)\n", 1423 | "cr_SVM" 1424 | ] 1425 | }, 1426 | { 1427 | "cell_type": "markdown", 1428 | "metadata": {}, 1429 | "source": [ 1430 | "### Random Forest" 1431 | ] 1432 | }, 1433 | { 1434 | "cell_type": "code", 1435 | "execution_count": 36, 1436 | "metadata": {}, 1437 | "outputs": [ 1438 | { 1439 | "data": { 1440 | "text/html": [ 1441 | "
\n", 1442 | "\n", 1455 | "\n", 1456 | " \n", 1457 | " \n", 1458 | " \n", 1459 | " \n", 1460 | " \n", 1461 | " \n", 1462 | " \n", 1463 | " \n", 1464 | " \n", 1465 | " \n", 1466 | " \n", 1467 | " \n", 1468 | " \n", 1469 | " \n", 1470 | " \n", 1471 | " \n", 1472 | " \n", 1473 | " \n", 1474 | " \n", 1475 | " \n", 1476 | " \n", 1477 | " \n", 1478 | "
PrecisionRecallf1_score
00.840.800.82
10.810.850.83
\n", 1479 | "
" 1480 | ], 1481 | "text/plain": [ 1482 | " Precision Recall f1_score\n", 1483 | "0 0.84 0.80 0.82\n", 1484 | "1 0.81 0.85 0.83" 1485 | ] 1486 | }, 1487 | "execution_count": 36, 1488 | "metadata": {}, 1489 | "output_type": "execute_result" 1490 | } 1491 | ], 1492 | "source": [ 1493 | "clf_RF = RandomForestClassifier(n_estimators=100, max_depth=40,random_state=0)\n", 1494 | "clf_RF.fit(Xtr,ytr)\n", 1495 | "yp_RF = clf_RF.predict(Xt)\n", 1496 | "cr_RF = CR(yp_RF,yt)\n", 1497 | "cr_RF" 1498 | ] 1499 | }, 1500 | { 1501 | "cell_type": "markdown", 1502 | "metadata": {}, 1503 | "source": [ 1504 | "### Decision Tree" 1505 | ] 1506 | }, 1507 | { 1508 | "cell_type": "code", 1509 | "execution_count": 37, 1510 | "metadata": {}, 1511 | "outputs": [ 1512 | { 1513 | "data": { 1514 | "text/html": [ 1515 | "
\n", 1516 | "\n", 1529 | "\n", 1530 | " \n", 1531 | " \n", 1532 | " \n", 1533 | " \n", 1534 | " \n", 1535 | " \n", 1536 | " \n", 1537 | " \n", 1538 | " \n", 1539 | " \n", 1540 | " \n", 1541 | " \n", 1542 | " \n", 1543 | " \n", 1544 | " \n", 1545 | " \n", 1546 | " \n", 1547 | " \n", 1548 | " \n", 1549 | " \n", 1550 | " \n", 1551 | " \n", 1552 | "
PrecisionRecallf1_score
00.680.750.71
10.720.650.68
\n", 1553 | "
" 1554 | ], 1555 | "text/plain": [ 1556 | " Precision Recall f1_score\n", 1557 | "0 0.68 0.75 0.71\n", 1558 | "1 0.72 0.65 0.68" 1559 | ] 1560 | }, 1561 | "execution_count": 37, 1562 | "metadata": {}, 1563 | "output_type": "execute_result" 1564 | } 1565 | ], 1566 | "source": [ 1567 | "clf_DT = DecisionTreeClassifier()\n", 1568 | "clf_DT.fit(Xtr,ytr)\n", 1569 | "yp_DT = clf_DT.predict(Xt)\n", 1570 | "cr_DT = CR(yp_DT,yt)\n", 1571 | "cr_DT" 1572 | ] 1573 | }, 1574 | { 1575 | "cell_type": "markdown", 1576 | "metadata": {}, 1577 | "source": [ 1578 | "### K Nearest Neighbors" 1579 | ] 1580 | }, 1581 | { 1582 | "cell_type": "code", 1583 | "execution_count": 38, 1584 | "metadata": {}, 1585 | "outputs": [ 1586 | { 1587 | "data": { 1588 | "text/html": [ 1589 | "
\n", 1590 | "\n", 1603 | "\n", 1604 | " \n", 1605 | " \n", 1606 | " \n", 1607 | " \n", 1608 | " \n", 1609 | " \n", 1610 | " \n", 1611 | " \n", 1612 | " \n", 1613 | " \n", 1614 | " \n", 1615 | " \n", 1616 | " \n", 1617 | " \n", 1618 | " \n", 1619 | " \n", 1620 | " \n", 1621 | " \n", 1622 | " \n", 1623 | " \n", 1624 | " \n", 1625 | " \n", 1626 | "
PrecisionRecallf1_score
00.700.950.81
10.920.600.73
\n", 1627 | "
" 1628 | ], 1629 | "text/plain": [ 1630 | " Precision Recall f1_score\n", 1631 | "0 0.70 0.95 0.81\n", 1632 | "1 0.92 0.60 0.73" 1633 | ] 1634 | }, 1635 | "execution_count": 38, 1636 | "metadata": {}, 1637 | "output_type": "execute_result" 1638 | } 1639 | ], 1640 | "source": [ 1641 | "clf_KNN = KNeighborsClassifier(n_neighbors=3)\n", 1642 | "clf_KNN.fit(Xtr,ytr)\n", 1643 | "yp_KNN = clf_KNN.predict(Xt)\n", 1644 | "cr_KNN = CR(yp_KNN,yt)\n", 1645 | "cr_KNN" 1646 | ] 1647 | }, 1648 | { 1649 | "cell_type": "markdown", 1650 | "metadata": {}, 1651 | "source": [ 1652 | "### Store Model" 1653 | ] 1654 | }, 1655 | { 1656 | "cell_type": "code", 1657 | "execution_count": 39, 1658 | "metadata": {}, 1659 | "outputs": [], 1660 | "source": [ 1661 | "Models['80-20'] = [clf_SVM, clf_RF, clf_DT, clf_KNN]" 1662 | ] 1663 | }, 1664 | { 1665 | "cell_type": "markdown", 1666 | "metadata": {}, 1667 | "source": [ 1668 | "## Function to predict for a single Image" 1669 | ] 1670 | }, 1671 | { 1672 | "cell_type": "code", 1673 | "execution_count": 40, 1674 | "metadata": {}, 1675 | "outputs": [], 1676 | "source": [ 1677 | "def read_preprocess_path(path):\n", 1678 | " \n", 1679 | " frame = cv2.imread(path)\n", 1680 | " imG = cv2.equalizeHist(frame[:,:,1])\n", 1681 | " blG = gaussian_filter(np.max(imG) - imG, sigma=50) \n", 1682 | " fG = ( blG < np.mean(blG) )* (np.max(imG) - imG)\n", 1683 | " pifG = (fG/np.mean(fG))**2\n", 1684 | " pifG = (pifG * (255/np.max(pifG))).astype(int)\n", 1685 | " frame[:,:,1] = pifG\n", 1686 | " fr = cv2.resize(frame,(256,256), interpolation = cv2.INTER_AREA)\n", 1687 | " fg = fr[:,:,1]\n", 1688 | " fg1 = np.max(fg**2) - fg**2\n", 1689 | " fg2 = (fg1>245) * fg1\n", 1690 | " fg3 = (fg2>=248) * 255\n", 1691 | " \n", 1692 | " return (fg3.reshape(256*256))/255 " 1693 | ] 1694 | }, 1695 | { 1696 | "cell_type": "code", 1697 | "execution_count": 41, 1698 | "metadata": {}, 1699 | "outputs": [], 1700 | "source": [ 1701 | "def Predict(path,ratio,model_index):\n", 1702 | " X1 = read_preprocess_path(path)\n", 1703 | " X1 = X1.reshape((1,256*256))\n", 1704 | " pred = Models[str(ratio)][model_index].predict(X1)\n", 1705 | " return pred" 1706 | ] 1707 | }, 1708 | { 1709 | "cell_type": "code", 1710 | "execution_count": 42, 1711 | "metadata": {}, 1712 | "outputs": [ 1713 | { 1714 | "data": { 1715 | "text/plain": [ 1716 | "array([1], dtype=int64)" 1717 | ] 1718 | }, 1719 | "execution_count": 42, 1720 | "metadata": {}, 1721 | "output_type": "execute_result" 1722 | } 1723 | ], 1724 | "source": [ 1725 | "Predict('dataset/trainimages/0ceb222f6629.png','70-30',3)" 1726 | ] 1727 | }, 1728 | { 1729 | "cell_type": "markdown", 1730 | "metadata": {}, 1731 | "source": [ 1732 | "## Confusion Matrix" 1733 | ] 1734 | }, 1735 | { 1736 | "cell_type": "code", 1737 | "execution_count": 43, 1738 | "metadata": {}, 1739 | "outputs": [ 1740 | { 1741 | "data": { 1742 | "text/plain": [ 1743 | "" 1744 | ] 1745 | }, 1746 | "execution_count": 43, 1747 | "metadata": {}, 1748 | "output_type": "execute_result" 1749 | }, 1750 | { 1751 | "data": { 1752 | "image/png": "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\n", 1753 | "text/plain": [ 1754 | "
" 1755 | ] 1756 | }, 1757 | "metadata": { 1758 | "needs_background": "light" 1759 | }, 1760 | "output_type": "display_data" 1761 | } 1762 | ], 1763 | "source": [ 1764 | "cm = ConfusionMatrix(Models['70-30'][1].predict(Xt),yt)\n", 1765 | "cm.plot() " 1766 | ] 1767 | }, 1768 | { 1769 | "cell_type": "code", 1770 | "execution_count": 44, 1771 | "metadata": {}, 1772 | "outputs": [ 1773 | { 1774 | "data": { 1775 | "text/plain": [ 1776 | "Predicted False True __all__\n", 1777 | "Actual \n", 1778 | "False 20 2 22\n", 1779 | "True 0 18 18\n", 1780 | "__all__ 20 20 40" 1781 | ] 1782 | }, 1783 | "execution_count": 44, 1784 | "metadata": {}, 1785 | "output_type": "execute_result" 1786 | } 1787 | ], 1788 | "source": [ 1789 | "cm" 1790 | ] 1791 | }, 1792 | { 1793 | "cell_type": "code", 1794 | "execution_count": null, 1795 | "metadata": {}, 1796 | "outputs": [], 1797 | "source": [] 1798 | } 1799 | ], 1800 | "metadata": { 1801 | "kernelspec": { 1802 | "display_name": "Python 3", 1803 | "language": "python", 1804 | "name": "python3" 1805 | }, 1806 | "language_info": { 1807 | "codemirror_mode": { 1808 | "name": "ipython", 1809 | "version": 3 1810 | }, 1811 | "file_extension": ".py", 1812 | "mimetype": "text/x-python", 1813 | "name": "python", 1814 | "nbconvert_exporter": "python", 1815 | "pygments_lexer": "ipython3", 1816 | "version": "3.7.0" 1817 | } 1818 | }, 1819 | "nbformat": 4, 1820 | "nbformat_minor": 2 1821 | } 1822 | --------------------------------------------------------------------------------