├── .gitignore ├── 01-Constant-features.ipynb ├── 02-One-way-ANOVA.ipynb ├── 03-Lasso.ipynb ├── 04-Feature-shuffling.ipynb ├── 2022_DataTalksClub_FeatureSelection.pdf ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Jupyter Notebook 2 | .ipynb_checkpoints 3 | 4 | # datasets 5 | *.csv 6 | *.zip -------------------------------------------------------------------------------- /01-Constant-features.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Constant features" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import pandas as pd\n", 17 | "\n", 18 | "from sklearn.datasets import make_classification\n", 19 | "from sklearn.model_selection import train_test_split\n", 20 | "\n", 21 | "from sklearn.feature_selection import VarianceThreshold\n", 22 | "from feature_engine.selection import DropConstantFeatures" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "data": { 32 | "text/html": [ 33 | "
\n", 34 | "\n", 47 | "\n", 48 | " \n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \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 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | "
0123456789
01-0.376539-0.620180-0.157567-1.1208051-1.5745781.6780461.0801801
110.762409-0.784210-0.096479-0.40875810.210942-0.850449-0.4613011
212.2279340.547727-0.341481-0.8175771-2.6636782.4400421.6989191
310.061129-0.995868-0.214351-0.5589571-2.1491672.294192-1.3839651
410.0463490.834756-0.104845-0.4555281-0.9110180.8980981.0682591
\n", 131 | "
" 132 | ], 133 | "text/plain": [ 134 | " 0 1 2 3 4 5 6 7 8 \\\n", 135 | "0 1 -0.376539 -0.620180 -0.157567 -1.120805 1 -1.574578 1.678046 1.080180 \n", 136 | "1 1 0.762409 -0.784210 -0.096479 -0.408758 1 0.210942 -0.850449 -0.461301 \n", 137 | "2 1 2.227934 0.547727 -0.341481 -0.817577 1 -2.663678 2.440042 1.698919 \n", 138 | "3 1 0.061129 -0.995868 -0.214351 -0.558957 1 -2.149167 2.294192 -1.383965 \n", 139 | "4 1 0.046349 0.834756 -0.104845 -0.455528 1 -0.911018 0.898098 1.068259 \n", 140 | "\n", 141 | " 9 \n", 142 | "0 1 \n", 143 | "1 1 \n", 144 | "2 1 \n", 145 | "3 1 \n", 146 | "4 1 " 147 | ] 148 | }, 149 | "execution_count": 2, 150 | "metadata": {}, 151 | "output_type": "execute_result" 152 | } 153 | ], 154 | "source": [ 155 | "# Toy dataset with redundant and constant features\n", 156 | "\n", 157 | "X, y = make_classification(\n", 158 | " n_samples=1000,\n", 159 | " n_features=10,\n", 160 | " n_classes=2,\n", 161 | " random_state=10,\n", 162 | ")\n", 163 | "\n", 164 | "X = pd.DataFrame(X)\n", 165 | "y = pd.Series(y)\n", 166 | "\n", 167 | "# Add constant features\n", 168 | "X[[0, 5, 9]] = 1\n", 169 | "\n", 170 | "X.head()" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 3, 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "data": { 180 | "text/plain": [ 181 | "((700, 10), (300, 10))" 182 | ] 183 | }, 184 | "execution_count": 3, 185 | "metadata": {}, 186 | "output_type": "execute_result" 187 | } 188 | ], 189 | "source": [ 190 | "# separate dataset into train and test\n", 191 | "\n", 192 | "X_train, X_test, y_train, y_test = train_test_split(\n", 193 | " X, y, test_size=0.3, random_state=0,\n", 194 | ")\n", 195 | "\n", 196 | "X_train.shape, X_test.shape" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "## VarianceThreshold from Scikit-learn\n", 204 | "\n", 205 | "Only works with numerical variables. Categorical variables need to be encoded first." 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 4, 211 | "metadata": {}, 212 | "outputs": [ 213 | { 214 | "data": { 215 | "text/html": [ 216 | "
VarianceThreshold(threshold=0)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 217 | ], 218 | "text/plain": [ 219 | "VarianceThreshold(threshold=0)" 220 | ] 221 | }, 222 | "execution_count": 4, 223 | "metadata": {}, 224 | "output_type": "execute_result" 225 | } 226 | ], 227 | "source": [ 228 | "# To remove constant features\n", 229 | "sel = VarianceThreshold(threshold=0)\n", 230 | "\n", 231 | "# fit finds the features with zero variance\n", 232 | "sel.fit(X_train) " 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 5, 238 | "metadata": {}, 239 | "outputs": [ 240 | { 241 | "data": { 242 | "text/plain": [ 243 | "7" 244 | ] 245 | }, 246 | "execution_count": 5, 247 | "metadata": {}, 248 | "output_type": "execute_result" 249 | } 250 | ], 251 | "source": [ 252 | "# get_support is a boolean vector flags \n", 253 | "# the features to keep\n", 254 | "\n", 255 | "# Number of selected features (the non-constant)\n", 256 | "\n", 257 | "sum(sel.get_support())" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": 6, 263 | "metadata": {}, 264 | "outputs": [ 265 | { 266 | "data": { 267 | "text/plain": [ 268 | "Int64Index([0, 5, 9], dtype='int64')" 269 | ] 270 | }, 271 | "execution_count": 6, 272 | "metadata": {}, 273 | "output_type": "execute_result" 274 | } 275 | ], 276 | "source": [ 277 | "# the constant feautures\n", 278 | "\n", 279 | "constant = X_train.columns[~sel.get_support()]\n", 280 | "\n", 281 | "constant" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": 7, 287 | "metadata": {}, 288 | "outputs": [ 289 | { 290 | "data": { 291 | "text/plain": [ 292 | "array(['x1', 'x2', 'x3', 'x4', 'x6', 'x7', 'x8'], dtype=object)" 293 | ] 294 | }, 295 | "execution_count": 7, 296 | "metadata": {}, 297 | "output_type": "execute_result" 298 | } 299 | ], 300 | "source": [ 301 | "sel.get_feature_names_out()" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 8, 307 | "metadata": {}, 308 | "outputs": [ 309 | { 310 | "data": { 311 | "text/plain": [ 312 | "((700, 7), (300, 7))" 313 | ] 314 | }, 315 | "execution_count": 8, 316 | "metadata": {}, 317 | "output_type": "execute_result" 318 | } 319 | ], 320 | "source": [ 321 | "# drop constant features\n", 322 | "\n", 323 | "X_train_t = sel.transform(X_train)\n", 324 | "X_test_t = sel.transform(X_test)\n", 325 | "\n", 326 | "X_train_t.shape, X_test_t.shape" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 9, 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/html": [ 337 | "
\n", 338 | "\n", 351 | "\n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | "
x1x2x3x4x6x7x8
00.0398011.501392-0.1892401.546828-1.8311931.9196340.209412
1-0.078494-1.536507-0.4968060.965100-0.873804-1.2468720.629114
2-0.7317120.972453-0.309300-1.432922-0.419046-0.9759840.377169
3-0.1211870.516685-0.800862-0.736170-1.219396-2.312341-1.027631
4-2.0891870.899235-0.2411111.2875360.643273-2.3109120.085618
\n", 417 | "
" 418 | ], 419 | "text/plain": [ 420 | " x1 x2 x3 x4 x6 x7 x8\n", 421 | "0 0.039801 1.501392 -0.189240 1.546828 -1.831193 1.919634 0.209412\n", 422 | "1 -0.078494 -1.536507 -0.496806 0.965100 -0.873804 -1.246872 0.629114\n", 423 | "2 -0.731712 0.972453 -0.309300 -1.432922 -0.419046 -0.975984 0.377169\n", 424 | "3 -0.121187 0.516685 -0.800862 -0.736170 -1.219396 -2.312341 -1.027631\n", 425 | "4 -2.089187 0.899235 -0.241111 1.287536 0.643273 -2.310912 0.085618" 426 | ] 427 | }, 428 | "execution_count": 9, 429 | "metadata": {}, 430 | "output_type": "execute_result" 431 | } 432 | ], 433 | "source": [ 434 | "# sklearn returns numpy arrays. Convert to dataframe\n", 435 | "\n", 436 | "X_train_t = pd.DataFrame(X_train_t, columns=sel.get_feature_names_out())\n", 437 | "X_test_t = pd.DataFrame(X_test_t, columns=sel.get_feature_names_out())\n", 438 | "\n", 439 | "# show result\n", 440 | "X_train_t.head()" 441 | ] 442 | }, 443 | { 444 | "cell_type": "markdown", 445 | "metadata": {}, 446 | "source": [ 447 | "## DropConstantFeatures from Feature-engine\n", 448 | "\n", 449 | "Works with numerical and categorical variables." 450 | ] 451 | }, 452 | { 453 | "cell_type": "code", 454 | "execution_count": 10, 455 | "metadata": {}, 456 | "outputs": [ 457 | { 458 | "data": { 459 | "text/html": [ 460 | "
DropConstantFeatures()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 461 | ], 462 | "text/plain": [ 463 | "DropConstantFeatures()" 464 | ] 465 | }, 466 | "execution_count": 10, 467 | "metadata": {}, 468 | "output_type": "execute_result" 469 | } 470 | ], 471 | "source": [ 472 | "# To remove constant features\n", 473 | "sel = DropConstantFeatures(tol=1)\n", 474 | "\n", 475 | "# fit finds the features with only 1 value\n", 476 | "sel.fit(X_train) " 477 | ] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": 11, 482 | "metadata": {}, 483 | "outputs": [ 484 | { 485 | "data": { 486 | "text/plain": [ 487 | "[0, 5, 9]" 488 | ] 489 | }, 490 | "execution_count": 11, 491 | "metadata": {}, 492 | "output_type": "execute_result" 493 | } 494 | ], 495 | "source": [ 496 | "# the constant features\n", 497 | "\n", 498 | "sel.features_to_drop_" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 12, 504 | "metadata": {}, 505 | "outputs": [ 506 | { 507 | "data": { 508 | "text/plain": [ 509 | "((700, 7), (300, 7))" 510 | ] 511 | }, 512 | "execution_count": 12, 513 | "metadata": {}, 514 | "output_type": "execute_result" 515 | } 516 | ], 517 | "source": [ 518 | "# drop constant features\n", 519 | "\n", 520 | "X_train_t = sel.transform(X_train)\n", 521 | "X_test_t = sel.transform(X_test)\n", 522 | "\n", 523 | "X_train_t.shape, X_test_t.shape" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": 13, 529 | "metadata": {}, 530 | "outputs": [ 531 | { 532 | "data": { 533 | "text/html": [ 534 | "
\n", 535 | "\n", 548 | "\n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | " \n", 555 | " \n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | " \n", 560 | " \n", 561 | " \n", 562 | " \n", 563 | " \n", 564 | " \n", 565 | " \n", 566 | " \n", 567 | " \n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \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 | "
1234678
1050.0398011.501392-0.1892401.546828-1.8311931.9196340.209412
68-0.078494-1.536507-0.4968060.965100-0.873804-1.2468720.629114
479-0.7317120.972453-0.309300-1.432922-0.419046-0.9759840.377169
399-0.1211870.516685-0.800862-0.736170-1.219396-2.312341-1.027631
434-2.0891870.899235-0.2411111.2875360.643273-2.3109120.085618
\n", 614 | "
" 615 | ], 616 | "text/plain": [ 617 | " 1 2 3 4 6 7 8\n", 618 | "105 0.039801 1.501392 -0.189240 1.546828 -1.831193 1.919634 0.209412\n", 619 | "68 -0.078494 -1.536507 -0.496806 0.965100 -0.873804 -1.246872 0.629114\n", 620 | "479 -0.731712 0.972453 -0.309300 -1.432922 -0.419046 -0.975984 0.377169\n", 621 | "399 -0.121187 0.516685 -0.800862 -0.736170 -1.219396 -2.312341 -1.027631\n", 622 | "434 -2.089187 0.899235 -0.241111 1.287536 0.643273 -2.310912 0.085618" 623 | ] 624 | }, 625 | "execution_count": 13, 626 | "metadata": {}, 627 | "output_type": "execute_result" 628 | } 629 | ], 630 | "source": [ 631 | "# the result is already a dataframe\n", 632 | "\n", 633 | "X_train_t.head()" 634 | ] 635 | } 636 | ], 637 | "metadata": { 638 | "kernelspec": { 639 | "display_name": "fsml", 640 | "language": "python", 641 | "name": "fsml" 642 | }, 643 | "language_info": { 644 | "codemirror_mode": { 645 | "name": "ipython", 646 | "version": 3 647 | }, 648 | "file_extension": ".py", 649 | "mimetype": "text/x-python", 650 | "name": "python", 651 | "nbconvert_exporter": "python", 652 | "pygments_lexer": "ipython3", 653 | "version": "3.10.5" 654 | }, 655 | "toc": { 656 | "base_numbering": 1, 657 | "nav_menu": {}, 658 | "number_sections": true, 659 | "sideBar": true, 660 | "skip_h1_title": false, 661 | "title_cell": "Table of Contents", 662 | "title_sidebar": "Contents", 663 | "toc_cell": false, 664 | "toc_position": { 665 | "height": "583px", 666 | "left": "0px", 667 | "right": "20px", 668 | "top": "107px", 669 | "width": "319px" 670 | }, 671 | "toc_section_display": "block", 672 | "toc_window_display": true 673 | } 674 | }, 675 | "nbformat": 4, 676 | "nbformat_minor": 2 677 | } 678 | -------------------------------------------------------------------------------- /03-Lasso.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Lasso" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np\n", 17 | "import pandas as pd\n", 18 | "from sklearn.datasets import fetch_california_housing\n", 19 | "from sklearn.feature_selection import SelectFromModel\n", 20 | "from sklearn.linear_model import Lasso\n", 21 | "from sklearn.model_selection import train_test_split\n", 22 | "from sklearn.preprocessing import StandardScaler" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# load the California House price data\n", 32 | "\n", 33 | "X, y = fetch_california_housing(return_X_y=True, as_frame=True)\n", 34 | "\n", 35 | "# Separate data into train and test sets\n", 36 | "\n", 37 | "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "data": { 47 | "text/html": [ 48 | "
StandardScaler()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 49 | ], 50 | "text/plain": [ 51 | "StandardScaler()" 52 | ] 53 | }, 54 | "execution_count": 3, 55 | "metadata": {}, 56 | "output_type": "execute_result" 57 | } 58 | ], 59 | "source": [ 60 | "# scale the features\n", 61 | "\n", 62 | "scaler = StandardScaler()\n", 63 | "scaler.fit(X_train)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 4, 69 | "metadata": { 70 | "scrolled": true 71 | }, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/html": [ 76 | "
SelectFromModel(estimator=Lasso(alpha=0.001, random_state=10))
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 77 | ], 78 | "text/plain": [ 79 | "SelectFromModel(estimator=Lasso(alpha=0.001, random_state=10))" 80 | ] 81 | }, 82 | "execution_count": 4, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | } 86 | ], 87 | "source": [ 88 | "# here, again I will train a Lasso Linear regression and select\n", 89 | "# the non zero features in one line.\n", 90 | "\n", 91 | "# bear in mind that the linear regression object from sklearn does\n", 92 | "# not allow for regularisation. So If you want to make a regularised\n", 93 | "# linear regression you need to import specifically \"Lasso\"\n", 94 | "\n", 95 | "sel_ = SelectFromModel(Lasso(alpha=0.001, random_state=10))\n", 96 | "sel_.fit(scaler.transform(X_train), y_train)" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 5, 102 | "metadata": {}, 103 | "outputs": [ 104 | { 105 | "data": { 106 | "text/plain": [ 107 | "array([ True, True, True, True, True, True, True, True])" 108 | ] 109 | }, 110 | "execution_count": 5, 111 | "metadata": {}, 112 | "output_type": "execute_result" 113 | } 114 | ], 115 | "source": [ 116 | "sel_.get_support()" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 6, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "name": "stdout", 126 | "output_type": "stream", 127 | "text": [ 128 | "total features: 8\n", 129 | "selected features: 8\n", 130 | "features with coefficients shrank to zero: 0\n" 131 | ] 132 | } 133 | ], 134 | "source": [ 135 | "# make a list with the selected features and print the outputs\n", 136 | "selected_feat = X_train.columns[(sel_.get_support())]\n", 137 | "\n", 138 | "print('total features: {}'.format((X_train.shape[1])))\n", 139 | "print('selected features: {}'.format(len(selected_feat)))\n", 140 | "print('features with coefficients shrank to zero: {}'.format(\n", 141 | " np.sum(sel_.estimator_.coef_ == 0)))" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 7, 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "data": { 151 | "text/plain": [ 152 | "((15480, 8), (5160, 8))" 153 | ] 154 | }, 155 | "execution_count": 7, 156 | "metadata": {}, 157 | "output_type": "execute_result" 158 | } 159 | ], 160 | "source": [ 161 | "# we can then remove the features from the training and testing set\n", 162 | "# like this:\n", 163 | "\n", 164 | "X_train_selected = sel_.transform(scaler.transform(X_train))\n", 165 | "X_test_selected = sel_.transform(scaler.transform(X_test))\n", 166 | "\n", 167 | "X_train_selected.shape, X_test_selected.shape" 168 | ] 169 | } 170 | ], 171 | "metadata": { 172 | "kernelspec": { 173 | "display_name": "fsml", 174 | "language": "python", 175 | "name": "fsml" 176 | }, 177 | "language_info": { 178 | "codemirror_mode": { 179 | "name": "ipython", 180 | "version": 3 181 | }, 182 | "file_extension": ".py", 183 | "mimetype": "text/x-python", 184 | "name": "python", 185 | "nbconvert_exporter": "python", 186 | "pygments_lexer": "ipython3", 187 | "version": "3.10.5" 188 | }, 189 | "toc": { 190 | "base_numbering": 1, 191 | "nav_menu": {}, 192 | "number_sections": true, 193 | "sideBar": true, 194 | "skip_h1_title": false, 195 | "title_cell": "Table of Contents", 196 | "title_sidebar": "Contents", 197 | "toc_cell": false, 198 | "toc_position": {}, 199 | "toc_section_display": "block", 200 | "toc_window_display": true 201 | } 202 | }, 203 | "nbformat": 4, 204 | "nbformat_minor": 2 205 | } 206 | -------------------------------------------------------------------------------- /04-Feature-shuffling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Selection by Feature Shuffling" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import pandas as pd\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "\n", 19 | "from sklearn.base import clone\n", 20 | "from sklearn.datasets import load_breast_cancer\n", 21 | "from sklearn.ensemble import RandomForestClassifier\n", 22 | "from sklearn.metrics import roc_auc_score\n", 23 | "from sklearn.model_selection import train_test_split\n", 24 | "\n", 25 | "from feature_engine.selection import SelectByShuffling" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": {}, 32 | "outputs": [ 33 | { 34 | "data": { 35 | "text/html": [ 36 | "
\n", 37 | "\n", 50 | "\n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \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 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | "
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavitymean concave pointsmean symmetrymean fractal dimension...worst radiusworst textureworst perimeterworst areaworst smoothnessworst compactnessworst concavityworst concave pointsworst symmetryworst fractal dimension
29311.8517.4675.54432.70.083720.056420.0268800.0228000.18750.05715...13.0625.7584.35517.80.13690.175800.131600.091400.31010.07007
33211.2219.8671.94387.30.105400.067790.0050060.0075830.19400.06028...11.9825.7876.91436.10.14240.096690.013350.020220.32920.06522
56520.1328.25131.201261.00.097800.103400.1440000.0979100.17520.05533...23.6938.25155.001731.00.11660.192200.321500.162800.25720.06637
27813.5917.8486.24572.30.079480.040520.0199700.0123800.15730.05520...15.5026.1098.91739.10.10500.076220.106000.051850.23350.06263
48916.6920.20107.10857.60.074970.071120.0364900.0230700.18460.05325...19.1826.56127.301084.00.10090.292000.247700.087370.46770.07623
\n", 200 | "

5 rows × 30 columns

\n", 201 | "
" 202 | ], 203 | "text/plain": [ 204 | " mean radius mean texture mean perimeter mean area mean smoothness \\\n", 205 | "293 11.85 17.46 75.54 432.7 0.08372 \n", 206 | "332 11.22 19.86 71.94 387.3 0.10540 \n", 207 | "565 20.13 28.25 131.20 1261.0 0.09780 \n", 208 | "278 13.59 17.84 86.24 572.3 0.07948 \n", 209 | "489 16.69 20.20 107.10 857.6 0.07497 \n", 210 | "\n", 211 | " mean compactness mean concavity mean concave points mean symmetry \\\n", 212 | "293 0.05642 0.026880 0.022800 0.1875 \n", 213 | "332 0.06779 0.005006 0.007583 0.1940 \n", 214 | "565 0.10340 0.144000 0.097910 0.1752 \n", 215 | "278 0.04052 0.019970 0.012380 0.1573 \n", 216 | "489 0.07112 0.036490 0.023070 0.1846 \n", 217 | "\n", 218 | " mean fractal dimension ... worst radius worst texture \\\n", 219 | "293 0.05715 ... 13.06 25.75 \n", 220 | "332 0.06028 ... 11.98 25.78 \n", 221 | "565 0.05533 ... 23.69 38.25 \n", 222 | "278 0.05520 ... 15.50 26.10 \n", 223 | "489 0.05325 ... 19.18 26.56 \n", 224 | "\n", 225 | " worst perimeter worst area worst smoothness worst compactness \\\n", 226 | "293 84.35 517.8 0.1369 0.17580 \n", 227 | "332 76.91 436.1 0.1424 0.09669 \n", 228 | "565 155.00 1731.0 0.1166 0.19220 \n", 229 | "278 98.91 739.1 0.1050 0.07622 \n", 230 | "489 127.30 1084.0 0.1009 0.29200 \n", 231 | "\n", 232 | " worst concavity worst concave points worst symmetry \\\n", 233 | "293 0.13160 0.09140 0.3101 \n", 234 | "332 0.01335 0.02022 0.3292 \n", 235 | "565 0.32150 0.16280 0.2572 \n", 236 | "278 0.10600 0.05185 0.2335 \n", 237 | "489 0.24770 0.08737 0.4677 \n", 238 | "\n", 239 | " worst fractal dimension \n", 240 | "293 0.07007 \n", 241 | "332 0.06522 \n", 242 | "565 0.06637 \n", 243 | "278 0.06263 \n", 244 | "489 0.07623 \n", 245 | "\n", 246 | "[5 rows x 30 columns]" 247 | ] 248 | }, 249 | "execution_count": 2, 250 | "metadata": {}, 251 | "output_type": "execute_result" 252 | } 253 | ], 254 | "source": [ 255 | "# load dataset\n", 256 | "\n", 257 | "breast_cancer = load_breast_cancer()\n", 258 | "X = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)\n", 259 | "y = breast_cancer.target\n", 260 | "\n", 261 | "# Separate data into train and test sets\n", 262 | "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)\n", 263 | "\n", 264 | "X_train.head()" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 3, 270 | "metadata": {}, 271 | "outputs": [], 272 | "source": [ 273 | "# the ML model for which we want to select features\n", 274 | "\n", 275 | "rf = RandomForestClassifier(\n", 276 | " n_estimators=10,\n", 277 | " random_state=2909,\n", 278 | ")" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 4, 284 | "metadata": {}, 285 | "outputs": [ 286 | { 287 | "data": { 288 | "text/html": [ 289 | "
SelectByShuffling(estimator=RandomForestClassifier(n_estimators=10,\n",
290 |        "                                                   random_state=2909),\n",
291 |        "                  random_state=1, threshold=0)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 294 | ], 295 | "text/plain": [ 296 | "SelectByShuffling(estimator=RandomForestClassifier(n_estimators=10,\n", 297 | " random_state=2909),\n", 298 | " random_state=1, threshold=0)" 299 | ] 300 | }, 301 | "execution_count": 4, 302 | "metadata": {}, 303 | "output_type": "execute_result" 304 | } 305 | ], 306 | "source": [ 307 | "sel = SelectByShuffling(\n", 308 | " estimator=rf, # the ML model\n", 309 | " scoring='roc_auc', # the metric to evaluate\n", 310 | " threshold=0,# the maximum performance drop allowed to select the feature\n", 311 | " cv=3, # cross validation\n", 312 | " random_state=1 # seed\n", 313 | ")\n", 314 | "\n", 315 | "sel.fit(X_train, y_train)" 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": 5, 321 | "metadata": {}, 322 | "outputs": [ 323 | { 324 | "data": { 325 | "text/plain": [ 326 | "0.9822274044237158" 327 | ] 328 | }, 329 | "execution_count": 5, 330 | "metadata": {}, 331 | "output_type": "execute_result" 332 | } 333 | ], 334 | "source": [ 335 | "# performance of model trained with all features\n", 336 | "\n", 337 | "sel.initial_model_performance_" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 6, 343 | "metadata": {}, 344 | "outputs": [ 345 | { 346 | "data": { 347 | "image/png": "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xRW95pprtg4jIiIiIiIiIuJ/xpw5c/5ue6XR2+8XyaY111yTCy+8sHUYERERERERERH/MyTdMNb2LKOLiIiIiIiIiIgpk2RTRERERERERERMmSSbIiIiIiIiIiJiyiTZFBERERERERERUybJpoiIiIiIiIiImDJJNkVERERERERExJRJsikiIiIiIiIiIqZMkk0RERERERERETFlkmyKiIiIiIiIiIgpk2RTRERERERERERMmSSbIiIiIiIiIiJiyiTZFBERERERERERUybJpoiIiIiIiIiImDKLtg4gIiIiIiIi/jNr7vPTKXus6z++/ZQ9VkTcv6WyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREyZJJsiIiIiIiIiImLKJNkUERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREyZJJsiIiIiIiIiImLKJNkUERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREyZJJsiIiIiIiIiImLKJNkUERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREyZJJsiIiIiIiIiImLKJNkUERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREyZJJsiIiIiIiIiImLKJNkUERERERERERFTZtHxviDpcsDjfd32RkOJKCIiIiIiIiIiZqxxk03Ac+q/b6r/Hlb/3W144URERERERERExEw2brLJ9g0Akp5h+zF9X9pH0kXAPsMOLiIiIiIiIiIiZpZBejZJ0hP7bmw54P2Q9CxJV0u6RtJCySlJS0j6Xv36zyWtWbevIOl0Sf+SdNCo+5xRH/OS+vHgQWKJiIiIiIiIiIjhm2gZXc+rgK9LWq7evhl45WR3kjQL+CLwDOBG4AJJx9i+ctRj/9P2IyS9GPgE8CLgTuD9wIb1Y7TdbF84QOwRERERERERETGNJk022Z4DbNxLNtm+ZcDHfhxwje1rASR9F9gJ6E827QTsVz8/GjhIkmzfBpwj6REDPldERERERERERHTApMvhJK0s6RDgu7ZvkbS+pFcN8NgPA37fd/vGum3M77F9D3ALsMIAj31oXUL3fkka4PsjIiIiIiIiImIaDNJ76RvAicAq9favgbcOKZ5B7Gb70cCT6sfuY32TpNdKulDShX/729+mNcCIiIiIiIiIiPurQZJNK9o+ErgX5lcgzRvgfn8AVuu7vWrdNub3SFoUWA64aaIHtf2H+u9c4NuU5Xpjfd9XbG9me7OVVlppgHAjIiIiIiIiIuK/NUiy6TZJKwAGkLQFZbnbZC4A1pG0lqTFgRcDx4z6nmOAl9fPXwCcZtvjPaCkRSWtWD9fDHgO8MsBYomIiIiIiIiIiGkwyDS6t1OSQmtLOhdYiZIYmpDteyS9mbIEbxbwddtXSNofuND2McAhwGGSrgH+QUlIASDpemA2sLiknYFtgRuAE2uiaRZwCvDVAf+vERERERERERExZINMo7tI0lOA9QABV9u+e5AHt30ccNyobR/o+/xO4IXj3HfNcR72sYM8d0RERERERERETL9xk02SnjfOl9aVhO0fDCmmiIiIiIiIiIiYoSaqbNphgq8ZSLIpIiIiIiIiIiJGmCjZdIntAyRtZfucaYsoIiIiIiIiIiJmrImm0e1R//3CdAQSEREREREREREz30SVTb+S9BvgYZIu69suwLY3Gm5oEREREREREREx04ybbLK9q6SHACcCO05fSBERERERERERMVNNNI3uVNtPk3Si7RumM6iIiIiIiIiIiJiZJlpG91BJWwI7SPoOZfncfLYvGmpkEREREREREREx40yUbPoA8H5gVeCzo75mYJthBRURERERERERETPTRD2bjgaOlvR+2x+expgiIiIiIiIiImKGmqiyqedMSU8evdH2WUOIJyIiIiIiIiIiZrBBkk17932+JPA4YA5ZRhcREREREREREaNMmmyyvUP/bUmrAZ8fVkARERERERERETFzLfIf3OdG4FFTHUhERERERERERMx8k1Y2STqQMn0OSnJqE+CiIcYUEREREREREREz1CA9my7s+/we4Du2zx1SPBERERERERERMYMN0rPpm9MRSEREREREREREzHyDLKN7IrAfsEb9fgG2/fDhhhYRERERERERETPNIMvoDgHeBswB5g03nIiIiIiIiIiImMkGSTbdYvv4oUcSEREREREREREz3rjJJkmb1k9Pl/Qp4AfAXb2v285EuoiIiIiIiIiIGGGiyqbPjLq9Wd/nBraZ+nAiIiIiIiIiImImGzfZZHvr6QwkIiIiIiIiIiJmvkUm+wZJe0mareJrki6StO10BBcRERERERERETPLpMkm4JW2bwW2BVYAdgc+PtSoIiIiIiIiIiJiRhok2aT677OBb9m+om9bRERERERERETEfIMkm+ZIOomSbDpR0rLAvcMNKyIiIiIiIiIiZqKJptH1vArYBLjW9u2SVgD2GGpUERERERERERExI02abLJ9L3BR3+2bgJuGGVRERERERERERMxMgyyji4iIiIiIiIiIGEiSTRERERERERERMWUmTTZJWlvSEvXzp0raU9LyQ48sIiIiIiIiIiJmnEEqm74PzJP0COArwGrAt4caVUREREREREREzEiDJJvutX0P8FzgQNt7Aw8dblgRERERERERETETDZJsulvSrsDLgWPrtsWGF1JERERERERERMxUgySb9gCeAHzU9nWS1gIOG25YERERERERERExEy062TfYvhLYs+/2dcAnhhlURERERERERETMTJMmmyStA3wMWB9Ysrfd9sOHGFdERERERERERMxAgyyjOxQ4GLgH2Br4FnD4MIOKiIiIiIiIiIiZaZBk01K2TwVk+wbb+wHbDzesiIiIiIiIiIiYiSZdRgfcJWkR4DeS3gz8AVhmuGFFRERERERERMRMNEhl017A0pQm4Y8FXgq8fJhBRURERERERETEzDRIZdM/bP8L+Bewx5DjiYiIiIiIiIiIGWyQZNPXJa0KXACcDZxl+/LhhhURERERERERETPRpMkm20+RtDiwOfBU4KeSlrH9oGEHFxERERERERERM8ukySZJWwFPqh/LA8dSKpwiIiIiIiIiIiJGGGQZ3RnAHOBjwHG2/z3UiCIiIiIiIiIiYsYaJNm0IvBE4MnAnpLuBc63/f6hRhYRERERERERETPOID2bbpZ0LbAasCqwJbDYsAOLiIiIiIiIiIiZZ5CeTdcCV1H6NB0M7JGldBERERERERERMZZBltE9wva9Q48kIiIiIiIiIiJmvEUm+4YkmiIiIiIiIiIiYlCTJpsiIiIiIiIiIiIGlWRTRERERERERERMmUmTTZJWlnSIpOPr7fUlvWr4oUVERERERERExEwzSGXTN4ATgVXq7V8Dbx1SPBERERERERERMYMNkmxa0faRwL0Atu8B5g01qoiIiIiIiIiImJEGSTbdJmkFwACStgBuGWpUERERERERERExIy06wPe8HTgGWFvSucBKwAuGGlVERERERERERMxIEyabJM0CnlI/1gMEXG377mmILSIiIiIiIiIiZpgJl9HZngfsavse21fY/mUSTRERERERERERMZ5BltGdK+kg4HvAbb2Nti8aWlQRERERERERETEjDdIgfBNgA2B/4DP149ODPLikZ0m6WtI1kvYZ4+tLSPpe/frPJa1Zt68g6XRJ/6qJrv77PFbS5fU+X5CkQWKJiIiIiIiIiIjhm7SyyfbW/8kD135PXwSeAdwIXCDpGNtX9n3bq4B/2n6EpBcDnwBeBNwJvB/YsH70Oxh4DfBz4DjgWcDx/0mMERERERERERExtSZNNkn6wFjbbe8/yV0fB1xj+9r6ON8FdgL6k007AfvVz48GDpIk27cB50h6xKhYHgrMtv2zevtbwM4k2RQRERERERER0QmDLKO7re9jHrAdsOYA93sY8Pu+2zfWbWN+j+17gFuAFSZ5zBsnecyIiIiIiIiIiGhkkGV0n+m/LenTwIlDi2iKSHot8FqA1VdfvXE0ERERERERERH3D4NUNo22NLDqAN/3B2C1vtur1m1jfo+kRYHlgJsmecz+5x7rMQGw/RXbm9nebKWVVhog3IiIiIiIiIiI+G9Nmmyqk98uqx9XAFcDBwzw2BcA60haS9LiwIuBY0Z9zzHAy+vnLwBOs+3xHtD2n4BbJW1Rp9C9DPjxALFERERERERERMQ0mHQZHfCcvs/vAf5S+ytNyPY9kt5MWXI3C/i67Ssk7Q9caPsY4BDgMEnXAP+gJKQAkHQ9MBtYXNLOwLZ1kt0bgW8AS1Eag6c5eERERERERERERwySbPqI7d37N0g6bPS2sdg+Djhu1LYP9H1+J/DCce675jjbLwQ2nDzsiIiIiIiIiIiYboP0bNqg/0btrfTY4YQTEREREREREREz2bjJJknvkTQX2EjSrfVjLvAX0icpIiIiIiIiIiLGMG6yyfbHbC8LfMr27PqxrO0VbL9nGmOMiIiIiIiIiIgZYtKeTbbfI+mBwDrAkn3bzxpmYBERERERERERMfNMmmyS9GpgL2BV4BJgC+B8YJuhRhYRERERERERETPOIA3C9wI2B26wvTXwGODmYQYVEREREREREREz0yDJpjtt3wkgaQnbVwHrDTesiIiIiIiIiIiYiSZdRgfcKGl54EfAyZL+CdwwzKAiIiIiIiIiImJmGqRB+HPrp/tJOh1YDjhhqFFFRERERERERMSMNEhlE5K2AtaxfaiklYCHAdcNNbKIiIiIiIiIiJhxJu3ZJOmDwLuB99RNiwGHDzOoiIiIiIiIiIiYmQZpEP5cYEfgNgDbfwSWHWZQERERERERERExMw2SbPq3bQMGkPSA4YYUEREREREREREz1SDJpiMlfRlYXtJrgFOArw43rIiIiIiIiIiImInGbRAuaQnbd9n+tKRnALcC6wEfsH3ytEUYEREREREREREzxkTT6M4HNpV0mO3dgSSYIiIiIiIiIiJiQhMlmxaX9BJgS0nPG/1F2z8YXlgRERERERERETETTZRsej2wG7A8sMOorxlIsikiIiIiIiIiIkYYN9lk+xzgHEkX2j5kGmOKiIiIiIiIiIgZatJpdEk0RURERERERETEoCZNNkVERERERERERAwqyaaIiIiIiIiIiJgyEzUIn0/Sw4A1+r/f9lnDCioiIiIiIiIiImamSZNNkj4BvAi4EphXNxtIsikiIiIiIiIiIkYYpLJpZ2A923cNOZaIiIiIiIiIiJjhBunZdC2w2LADiYiIiIiIiIiImW+QyqbbgUsknQrMr26yvefQooqIiIiIiIiIiBlpkGTTMfUjIiIiIiIiIiJiQpMmm2x/U9JSwOq2r56GmCIiIiIiIiIiYoaatGeTpB2AS4AT6u1NJKXSKSIiIiIiIiIiFjJIg/D9gMcBNwPYvgR4+NAiioiIiIiIiIiIGWuQZNPdtm8Zte3eYQQTEREREREREREz2yANwq+Q9BJglqR1gD2B84YbVkREREREREREzESDVDa9BdgAuAv4DnAr8NYhxhQRERERERERETPUINPobgf2rR8RERERERERERHjmjTZJGld4J3Amv3fb3ub4YUVEREREREREREz0SA9m44C/h/wNWDecMOJiIiIiIiIiIiZbJBk0z22Dx56JBERERERERERMeONm2yS9KD66U8kvRH4IaVJOAC2/zHk2CIiIiIiIiIiYoaZqLJpDmBA9fbefV8z8PBhBRURERERERERETPTuMkm22tNZyARERERERERETHzDTKN7hzgTOBs4Fzbc4ceVUREREREREREzEiLDPA9uwNXA88HzpN0oaTPDTesiIiIiIiIiIiYiSatbLJ9naQ7gX/Xj62BRw07sIiIiIiIiIiImHkmrWyS9FvgR8DKwCHAhrafNeS4IiIiIiIiIiJiBhpkGd0XgN8BuwJ7Ai+XtPZQo4qIiIiIiIiIiBlp0mST7QNsvxB4OjAH2A/49ZDjioiIiIiIiIiIGWiQaXSfAbYClgHOAz5AmUwXERERERERERExwqTJJuB84JO2/zLsYCIiIiIiIiIiYmYbZBrd0dMRSEREREREREREzHyDNAiPiIiIiIiIiIgYSJJNERERERERERExZQZKNknaStIe9fOVJK013LAiIiIiIiIiImImmjTZJOmDwLuB99RNiwGHDzOoiIiIiIiIiIiYmQapbHousCNwG4DtPwLLDjOoiIiIiIiIiIiYmQZJNv3btgEDSHrAcEOKiIiIiIiIiIiZapBk05GSvgwsL+k1wCnAV4cbVkREREREREREzESLTvYNtj8t6RnArcB6wAdsnzz0yCIiIiIiIiIiYsaZNNkEUJNLSTBFRERERERERMSEJk02SZpL7dfU5xbgQuAdtq8dRmARERERERERETHzDFLZ9HngRuDbgIAXA2sDFwFfB546pNgiIiIiIiIiImKGGaRB+I62v2x7ru1bbX8FeKbt7wEPHHJ8ERERERERERExgwySbLpd0i6SFqkfuwB31q+NXl4XERERERERERH3Y4Mkm3YDdgf+Cvylfv5SSUsBb57ojpKeJelqSddI2meMry8h6Xv16z+XtGbf195Tt18t6Zl926+XdLmkSyRdONh/MyIiIiIiIiIipsOkPZtqA/AdxvnyOePdT9Is4IvAMyg9ny6QdIztK/u+7VXAP20/QtKLgU8AL5K0PqU31AbAKsApkta1Pa/eb2vbf58s9oiIiIiIiIiImF6DTKNbCXgNsGb/99t+5SR3fRxwTW9anaTvAjsB/cmmnYD96udHAwdJUt3+Xdt3AddJuqY+3vmT/5ciIiIiIiIiIqKVQabR/Rg4GzgFmDfJ9/Z7GPD7vts3Ao8f73ts3yPpFmCFuv1no+77sPq5gZMkGfhybVgeEREREREREREdMEiyaWnb7x56JIPbyvYfJD0YOFnSVbbPGv1Nkl4LvBZg9dVXn+4YIyIiIiIiIiLulwZpEH6spGf/B4/9B2C1vtur1m1jfo+kRYHlgJsmuq/t3r9/BX5IWV63ENtfsb2Z7c1WWmml/yD8iIiIiIiIiIi4rwZJNu1FSTjdIelWSXMl3TrA/S4A1pG0lqTFKQ2/jxn1PccAL6+fvwA4zbbr9hfXaXVrAesAv5D0AEnLAkh6ALAt8MsBYomIiIiIiIiIiGkwyDS6Zf+TB649mN4MnAjMAr5u+wpJ+wMX2j4GOAQ4rDYA/wclIUX9viMpzcTvAd5ke56klYEflh7iLAp82/YJ/0l8EREREREREREx9Qbp2YSkB1Kqi5bsbRurT9Joto8Djhu17QN9n98JvHCc+34U+OiobdcCGw8Sc0RERERERERETL9Jk02SXk1ZSrcqcAmwBXA+sM1QI4uIiIiIiIiIiBln0J5NmwM32N4aeAxw8zCDioiIiIiIiIiImWmQZXR32r5TEpKWsH2VpPWGHllERETc76y5z0+n5HGu//j2U/I4EREREXHfDZJsulHS8sCPgJMl/RO4YZhBRURERERERETEzDTINLrn1k/3k3Q6sByQCXAREREREREREbGQQafRzQJWBq6rmx4C/G5YQUVERERERERExMw0yDS6twAfBP4C3Fs3G9hoiHFFRERERERERMQMNEhl017AerZvGnYwERERERERERExsy0ywPf8Hrhl2IFERERERERERMTMN25lk6S310+vBc6Q9FPgrt7XbX92yLFFRERERERERMQMM9EyumXrv7+rH4vXj4iIiIiIiIiIiDGNm2yy/aHpDCQiIiIiIiIiYrQ19/nplD3W9R/ffsoeK8Y3yDS6k4EX2r653n4g8F3bzxxybBERERERcT+Vk8uIiJlrkGl0K/USTQC2/ynpwcMLKSKirRzcRkRERERE/OcGmUY3T9LqvRuS1gA8vJAiIiIiIiIiImKmGqSyaV/gHElnAgKeBLx2qFFFRERERERERMSMNGmyyfYJkjYFtqib3mr778MNKyIiIiIiIiIiZqJBKpuoyaVjhxxLRERERERERETMcIP0bIqIiIiIiIiIiBhIkk0RERERERERETFlxk02Sdpc0nZjbH+2pMcON6yIiIiIiIiIiJiJJqps+gRw5RjbrwA+NZxwIiIiIiIiIiJiJpso2bSs7RtGb6zbVhxeSBERERERERERMVNNlGx64ARfW3qqA4mIiIiIiIiIiJlvomTTKZI+Kkm9DSr2B04bfmgRERERERERETHTLDrB194BfA24RtIlddvGwIXAq4ccV0REREREREREzEDjJpts3wbsKunhwAZ18xW2r52WyCIiIiIiIiIiYsYZN9kkadO+m38ADNw99IgiIiIiIiIiImLGmmgZ3WfG2PYgSYsDu9q+ZDghRURERERERETETDXRMrqtx9ouaTPgC8CThxVUFGvu89Mpe6zrP779lDxOF2OKiIiIiIiIqZFzvpgKE1U2jcn2hZKWGUYwEf+pqXpDzJthRERERERExH9nkft6B0krU/o3RUREREREREREjDBRg/ADWTip9CBgS2CvYQYVEREREREREREz00TL6C4cddvATcDbbf91eCFFRERERERERMRMNVGD8G+OtV3SapL2tv2p4YUVEREREREREREz0UA9myStJOmNks4GzgBWHmpUERERERERERExI03Us2lZ4HnAS4B1gR8Aa9ledZpii4iIiIiIiIiIGWaink1/BX4BvA84x7YlPXd6woqIiIiIiOiWNff56ZQ91vUf337KHisiomsmWkb3HmAJ4EvAeyStPT0hRURERERERETETDVussn2521vAexUN/0IWEXSuyWtOx3BRURERERERETEzDJpg3Db19r+P9uPBjYDZgPHDT2yiIiIiIiIiIiYcQaaRtfnBbb3tf2IoUQTEREREREREREz2n1NNu04lCgiIiIiIiIiIuJ/wkTT6MaioUTRAZksERERERERERHx37uvlU2PHUoUERERERERERHxP2HcZJOkT0l6Xf822/dKep2kjw8/tIiIiIiIiIiImGkmWka3DfCuMbZ/FbgM2GcoEUVERERERERMsalqnZK2KRGTm2gZ3RK2PXqj7Xv5H+7dFBERERERERER/7mJkk13SFpn9Ma67Y7hhRQRERERERERETPVRMvoPgAcL+kjwJy6bTPgPcBbhxxXRERERERERETMQOMmm2wfL2lnYG/gLXXzFcDzbV8+DbFFRERERERERMQMM1FlE7Z/Cbxc0jL19r+mJaqIiIiIiIiIiJiRJurZhKQ3SvodcANwg6QbJL1xekKLiIiIiIiIiIiZZtzKJknvA7YEnmr72rrt4cABkh5k+yPTFGNERMTApmqsMWS0ccR9kd+9iIiI6JloGd3uwMa27+xtsH2tpF2AS4EkmyImMFUH3TngjoiIiIiIiJlkomV07k809W28A7h3eCFFRERERERERMRMNVGy6Q+SnjZ6o6RtgD8NL6SIiIiIiIiIiJipJlpGtyfwY0nnAHPqts2AJwI7DTuwiIiIiIiIiIiYecZNNtm+QtKGwEuADerms4DXjbW8LiIiIiIiIiIGl+EK8b9qosomalLp6/3bJC0iaTfbRww1soiIiIiIiIiIGFhXBlWN27NJ0mxJ75F0kKRnqHgzcC2wy3/1rBERERERERER8T9posqmw4B/AucDrwH2BQTsbPuS4YcWEREREREREREzzUTJpofbfjSApK9RJtCtnn5NERERERERERExnomSTXf3PrE9T9KN9zXRJOlZwAHALOBrtj8+6utLAN8CHgvcBLzI9vX1a+8BXgXMA/a0feIgjxkRERHxvy4NZSMiIqLLJko2bSzp1vq5gKXqbQG2PXuiB5Y0C/gi8AzgRuACScfYvrLv214F/NP2IyS9GPgE8CJJ6wMvpkzBWwU4RdK69T6TPWZERESnJDEQEV3XlYayERHxv2HcZJPtWf/lYz8OuMb2tQCSvgvsBPQnhnYC9qufHw0cJEl1+3dt3wVcJ+ma+ngM8JgREREREZ2VxE5ERPyvk+3hPLD0AuBZtl9db+8OPN72m/u+55f1e26st38LPJ6SgPqZ7cPr9kOA4+vdJnzMvsd+LfBagNVXX/2xN9xww1D+nxEzSRerK7oYU1fl5CSmUn73BpffvZkr+3lEO3nvjPuD7OcgaY7tzUZvX6RFMNPB9ldsb2Z7s5VWWql1OBERERERERER9wvDTDb9AVit7/aqdduY3yNpUWA5SqPw8e47yGNGREREREREREQjw0w2XQCsI2ktSYtTGn4fM+p7jgFeXj9/AXCay7q+Y4AXS1pC0lrAOsAvBnzMiIiIiIiIiIhoZKJpdP8V2/dIejNwIjAL+LrtKyTtD1xo+xjgEOCw2gD8H5TkEfX7jqQ0/r4HeJPteQBjPeaw/g8REREREREREXHfDC3ZBGD7OOC4Uds+0Pf5ncALx7nvR4GPDvKYERH3BzO5cWBERERERNx//M82CI+IiIiIiIiIiOmXZFNEREREREREREyZoS6ji4iYTJaGRURERERE/G9JsikiIiJiAkmKR0RERNw3WUYXERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmzaOsAIiIiIiIi4n/L9R/fvnUIEdFQKpsiIiIiIiIiImLKJNkUERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkym0UVERERERERE3EeZuji+VDZFRERERERERMSUSbIpIiIiIiIiIiKmTJJNERERERERERExZZJsioiIiIiIiIiIKZNkU0RERERERERETJkkmyIiIiIiIiIiYsok2RQREREREREREVNm0dYBREREREQMw/Uf3751CBEREfdLqWyKiIiIiIiIiIgpk2RTRERERERERERMmSSbIiIiIiIiIiJiyqRnU0RExP1QetlERERExLCksikiIiIiIiIiIqZMKpsi7kdSyRARERERERHDlsqmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREyZJJsiIiIiIiIiImLKJNkUERERERERERFTJsmmiIiIiIiIiIiYMkk2RURERERERETElEmyKSIiIiIiIiIipkySTRERERERERERMWWSbIqIiIiIiIiIiCmTZFNEREREREREREwZ2W4dw9BJ+htwwxQ81IrA36fgcaZaF+NKTINJTIPrYlyJaTCJaXBdjCsxDSYxDa6LcSWmwSSmwXUxrsQ0mMQ0uC7GlZgGM5UxrWF7pdEb7xfJpqki6ULbm7WOY7QuxpWYBpOYBtfFuBLTYBLT4LoYV2IaTGIaXBfjSkyDSUyD62JciWkwiWlwXYwrMQ1mOmLKMrqIiIiIiIiIiJgySTZFRERERERERMSUSbLpvvlK6wDG0cW4EtNgEtPguhhXYhpMYhpcF+NKTINJTIPrYlyJaTCJaXBdjCsxDSYxDa6LcSWmwQw9pvRsioiIiIiIiIiIKZPKpoiIiIiIiIiImDJJNkVERETMcCpWax1HREREBCTZFFNA0ixJn24dR/xvkTSrdQwTkbSIpNkdiGMHSXkvn0D9We3SOo7Ralxbto6jX30/f1vrOPp1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sCOl1fAy4DfA39YMFBERz43tVcDWXRtdRERMbl8CFkv6R0lzgEXA6YN8YNroIiIiIiJiDZK+C7wBuBJ4rHff9rnVQkVExPMiaQvK3CaAW23fP8jnpY0uIiImlKSZwKeB19L3cyYzmyIiJp3/6n5NATaunCUiIp4nSZcCNwA32r5rGM9MsSkiIibaXOATwB3AU5WzRETEcyTpEtvvB1bY/krtPBER8YJdCOwBfE3SdsBiYP4gX+PTRhcRERNK0k22d6+dIyIinh9JdwLvBK4G3gGo//dtPzTGfywiIhrWLX6YBewJHAustD19YM9LsSkiIiaSpL2BI4B5lCHhANi+olqoiIgYN0nHAx8BtgV+xchik21vWyVYREQ8L5LmAS8DFgI3AjfZfmCgz0yxKSIiJlLXEz4dWMbqNjrbPqZeqoiIeK4kfcP2R2rniIiIF0bSecAMyhfBNwPzgYW2Vw7smSk2RUTERJK03Pb2tXNERERERMRqkjYGjgJOAja3vf6gnpUB4RERMdEWSNrB9p21g0RERERErOskHUcZED4DuAe4iNJONzApNkVExESbDSyRdDflqK4obXQ7140VEREREbFO2gA4F1hk+8lhPDBtdBERMaEkbT3Wfdv3DjtLREREREQMX4pNERERERERERExYabUDhARERERERERES8eKTZFRERERERERMSESbEpIiIiIiIiIiImTIpNERERERERERExYVJsioiIiIiIiIiICfP/BjM7MsEloOQAAAAASUVORK5CYII=\n", 348 | "text/plain": [ 349 | "
" 350 | ] 351 | }, 352 | "metadata": { 353 | "needs_background": "light" 354 | }, 355 | "output_type": "display_data" 356 | } 357 | ], 358 | "source": [ 359 | "# Changes in performance after shuffling each feature\n", 360 | "\n", 361 | "pd.Series(sel.performance_drifts_).plot.bar(figsize=(20,6))\n", 362 | "plt.title('Performance change after shuffling features')\n", 363 | "plt.ylabel('ROC-AUC change when feature was shuffled')\n", 364 | "plt.show()" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 7, 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "data": { 374 | "text/plain": [ 375 | "['mean smoothness',\n", 376 | " 'mean compactness',\n", 377 | " 'mean concavity',\n", 378 | " 'mean symmetry',\n", 379 | " 'mean fractal dimension',\n", 380 | " 'radius error',\n", 381 | " 'texture error',\n", 382 | " 'perimeter error',\n", 383 | " 'smoothness error',\n", 384 | " 'compactness error',\n", 385 | " 'concavity error',\n", 386 | " 'concave points error',\n", 387 | " 'symmetry error',\n", 388 | " 'fractal dimension error',\n", 389 | " 'worst area',\n", 390 | " 'worst compactness',\n", 391 | " 'worst symmetry',\n", 392 | " 'worst fractal dimension']" 393 | ] 394 | }, 395 | "execution_count": 7, 396 | "metadata": {}, 397 | "output_type": "execute_result" 398 | } 399 | ], 400 | "source": [ 401 | "# the features to remove\n", 402 | "\n", 403 | "sel.features_to_drop_" 404 | ] 405 | }, 406 | { 407 | "cell_type": "code", 408 | "execution_count": 8, 409 | "metadata": {}, 410 | "outputs": [ 411 | { 412 | "data": { 413 | "text/plain": [ 414 | "Index(['mean radius', 'mean texture', 'mean perimeter', 'mean area',\n", 415 | " 'mean smoothness', 'mean compactness', 'mean concavity',\n", 416 | " 'mean concave points', 'mean symmetry', 'mean fractal dimension',\n", 417 | " 'radius error', 'texture error', 'perimeter error', 'area error',\n", 418 | " 'smoothness error', 'compactness error', 'concavity error',\n", 419 | " 'concave points error', 'symmetry error', 'fractal dimension error',\n", 420 | " 'worst radius', 'worst texture', 'worst perimeter', 'worst area',\n", 421 | " 'worst smoothness', 'worst compactness', 'worst concavity',\n", 422 | " 'worst concave points', 'worst symmetry', 'worst fractal dimension'],\n", 423 | " dtype='object')" 424 | ] 425 | }, 426 | "execution_count": 8, 427 | "metadata": {}, 428 | "output_type": "execute_result" 429 | } 430 | ], 431 | "source": [ 432 | "# the selected features\n", 433 | "\n", 434 | "(pd.Series(sel.performance_drifts_)>0).index" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": 9, 440 | "metadata": {}, 441 | "outputs": [ 442 | { 443 | "data": { 444 | "text/html": [ 445 | "
\n", 446 | "\n", 459 | "\n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | "
mean radiusmean texturemean perimetermean areamean concave pointsarea errorworst radiusworst textureworst perimeterworst smoothnessworst concavityworst concave points
51213.4020.5288.64556.70.0817233.6716.4129.66113.300.157400.510600.20510
45713.2125.2584.10537.90.0206817.5814.3534.2391.290.128900.139000.06005
43914.0215.6689.59606.50.0265219.2514.9119.3196.530.103400.062600.08216
29814.2618.1791.22633.10.0137420.5616.2225.26105.800.094450.156500.07530
3713.0318.4282.61523.80.0292314.1613.3022.8184.460.097010.048330.05013
\n", 555 | "
" 556 | ], 557 | "text/plain": [ 558 | " mean radius mean texture mean perimeter mean area \\\n", 559 | "512 13.40 20.52 88.64 556.7 \n", 560 | "457 13.21 25.25 84.10 537.9 \n", 561 | "439 14.02 15.66 89.59 606.5 \n", 562 | "298 14.26 18.17 91.22 633.1 \n", 563 | "37 13.03 18.42 82.61 523.8 \n", 564 | "\n", 565 | " mean concave points area error worst radius worst texture \\\n", 566 | "512 0.08172 33.67 16.41 29.66 \n", 567 | "457 0.02068 17.58 14.35 34.23 \n", 568 | "439 0.02652 19.25 14.91 19.31 \n", 569 | "298 0.01374 20.56 16.22 25.26 \n", 570 | "37 0.02923 14.16 13.30 22.81 \n", 571 | "\n", 572 | " worst perimeter worst smoothness worst concavity worst concave points \n", 573 | "512 113.30 0.15740 0.51060 0.20510 \n", 574 | "457 91.29 0.12890 0.13900 0.06005 \n", 575 | "439 96.53 0.10340 0.06260 0.08216 \n", 576 | "298 105.80 0.09445 0.15650 0.07530 \n", 577 | "37 84.46 0.09701 0.04833 0.05013 " 578 | ] 579 | }, 580 | "execution_count": 9, 581 | "metadata": {}, 582 | "output_type": "execute_result" 583 | } 584 | ], 585 | "source": [ 586 | "# reduce dataset\n", 587 | "\n", 588 | "X_train_t = sel.transform(X_train)\n", 589 | "X_test_t = sel.transform(X_test)\n", 590 | "\n", 591 | "X_test_t.head()" 592 | ] 593 | } 594 | ], 595 | "metadata": { 596 | "kernelspec": { 597 | "display_name": "fsml", 598 | "language": "python", 599 | "name": "fsml" 600 | }, 601 | "language_info": { 602 | "codemirror_mode": { 603 | "name": "ipython", 604 | "version": 3 605 | }, 606 | "file_extension": ".py", 607 | "mimetype": "text/x-python", 608 | "name": "python", 609 | "nbconvert_exporter": "python", 610 | "pygments_lexer": "ipython3", 611 | "version": "3.10.5" 612 | }, 613 | "toc": { 614 | "base_numbering": 1, 615 | "nav_menu": {}, 616 | "number_sections": true, 617 | "sideBar": true, 618 | "skip_h1_title": false, 619 | "title_cell": "Table of Contents", 620 | "title_sidebar": "Contents", 621 | "toc_cell": false, 622 | "toc_position": {}, 623 | "toc_section_display": "block", 624 | "toc_window_display": true 625 | } 626 | }, 627 | "nbformat": 4, 628 | "nbformat_minor": 2 629 | } 630 | -------------------------------------------------------------------------------- /2022_DataTalksClub_FeatureSelection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solegalli/DataTalks.Club2022/a0cea4cdfccaf17fb714d0012142ce4a20a7b8c2/2022_DataTalksClub_FeatureSelection.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) - Soledad Galli 4 | Feature Selection in Machine Learning - Book: 5 | https://leanpub.com/feature-selection-in-machine-learning 6 | 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | 2. Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | 3. Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![PythonVersion](https://img.shields.io/badge/python-3.6%20|3.7%20|%203.8%20|%203.9-success) 2 | [![License https://github.com/solegalli/DataTalks.Club2022/blob/main/LICENSE](https://img.shields.io/badge/license-BSD-success.svg)](https://github.com/solegalli/DataTalks.Club2022/blob/main/LICENSE) 3 | [![Sponsorship https://www.trainindata.com/](https://img.shields.io/badge/Powered%20By-TrainInData-orange.svg)](https://www.trainindata.com/) 4 | 5 | ## Feature Selection in Machine Learning 6 | 7 | ## Links 8 | 9 | - [Book](https://leanpub.com/feature-selection-in-machine-learning) 10 | - [Course](https://www.trainindata.com/p/feature-selection-for-machine-learning) 11 | 12 | ## Talk: Contents 13 | 14 | 1. Constant Features 15 | 2. ANOVA 16 | 3. Lasso 17 | 4. Feature Shuffling 18 | --------------------------------------------------------------------------------