|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "*Credits: this notebook origin (shared under MIT license) belongs to [ML course at ICL](https://github.com/yandexdataschool/MLatImperial2020) held by Yandex School of Data Analysis. Special thanks to the course team for making it available online.*" |
| 8 | + ] |
| 9 | + }, |
| 10 | + { |
| 11 | + "cell_type": "markdown", |
| 12 | + "metadata": { |
| 13 | + "colab_type": "text", |
| 14 | + "id": "Ij_zY4soDF2Z" |
| 15 | + }, |
| 16 | + "source": [ |
| 17 | + "## week0_05: Cross-validation riddle" |
| 18 | + ] |
| 19 | + }, |
| 20 | + { |
| 21 | + "cell_type": "markdown", |
| 22 | + "metadata": { |
| 23 | + "colab_type": "text", |
| 24 | + "id": "qUCsY5OlDJPl" |
| 25 | + }, |
| 26 | + "source": [ |
| 27 | + "Here's a small example of cross-validation done wrongly. Can you spot the problem?" |
| 28 | + ] |
| 29 | + }, |
| 30 | + { |
| 31 | + "cell_type": "code", |
| 32 | + "execution_count": 1, |
| 33 | + "metadata": { |
| 34 | + "colab": {}, |
| 35 | + "colab_type": "code", |
| 36 | + "id": "mSUzkXsC-R4H" |
| 37 | + }, |
| 38 | + "outputs": [], |
| 39 | + "source": [ |
| 40 | + "# Some imports...\n", |
| 41 | + "import numpy as np\n", |
| 42 | + "import matplotlib.pyplot as plt\n", |
| 43 | + "\n", |
| 44 | + "from sklearn.svm import LinearSVC\n", |
| 45 | + "from sklearn.model_selection import KFold, cross_val_score\n", |
| 46 | + "from sklearn.metrics import accuracy_score" |
| 47 | + ] |
| 48 | + }, |
| 49 | + { |
| 50 | + "cell_type": "markdown", |
| 51 | + "metadata": { |
| 52 | + "colab_type": "text", |
| 53 | + "id": "ZyDp3Xc_DaDM" |
| 54 | + }, |
| 55 | + "source": [ |
| 56 | + "**Plan:**\n", |
| 57 | + "\n", |
| 58 | + "- Let's create a binary classification dataset where targets are completely independent from the features\n", |
| 59 | + " - *(i.e. no model could ever predict them well)*\n", |
| 60 | + "- We'll do some simple feature selection\n", |
| 61 | + "- And cross-validate a model on this data\n", |
| 62 | + "\n", |
| 63 | + "**Q:** what accuracy do we expect (classes are even)?" |
| 64 | + ] |
| 65 | + }, |
| 66 | + { |
| 67 | + "cell_type": "markdown", |
| 68 | + "metadata": { |
| 69 | + "colab_type": "text", |
| 70 | + "id": "IHx51DKP8Rcf" |
| 71 | + }, |
| 72 | + "source": [ |
| 73 | + "We'll start from writing a class to select the best features:" |
| 74 | + ] |
| 75 | + }, |
| 76 | + { |
| 77 | + "cell_type": "code", |
| 78 | + "execution_count": 2, |
| 79 | + "metadata": { |
| 80 | + "colab": {}, |
| 81 | + "colab_type": "code", |
| 82 | + "id": "rRNmKZJJ8W7x" |
| 83 | + }, |
| 84 | + "outputs": [], |
| 85 | + "source": [ |
| 86 | + "class FeatureSelector:\n", |
| 87 | + " def __init__(self, num_features):\n", |
| 88 | + " self.n = num_features # number of best features to select\n", |
| 89 | + "\n", |
| 90 | + " def fit(self, X, y):\n", |
| 91 | + " # Select features that describe the targets best, i.e. have\n", |
| 92 | + " # highest correlation with them:\n", |
| 93 | + " covariance = ((X - X.mean(axis=0)) * (y[:,np.newaxis] - y.mean())).mean(axis=0)\n", |
| 94 | + " self.best_feature_ids = np.argsort(np.abs(covariance))[-self.n:]\n", |
| 95 | + "\n", |
| 96 | + " def transform(self, X):\n", |
| 97 | + " return X[:,self.best_feature_ids]\n", |
| 98 | + "\n", |
| 99 | + " def fit_transform(self, X, y):\n", |
| 100 | + " self.fit(X, y)\n", |
| 101 | + " return self.transform(X)" |
| 102 | + ] |
| 103 | + }, |
| 104 | + { |
| 105 | + "cell_type": "code", |
| 106 | + "execution_count": 3, |
| 107 | + "metadata": { |
| 108 | + "colab": { |
| 109 | + "base_uri": "https://localhost:8080/", |
| 110 | + "height": 34 |
| 111 | + }, |
| 112 | + "colab_type": "code", |
| 113 | + "id": "6mu9gHgNBk_V", |
| 114 | + "outputId": "020bdc20-04e3-45c3-a3a7-a4c2cf9139e5" |
| 115 | + }, |
| 116 | + "outputs": [ |
| 117 | + { |
| 118 | + "name": "stdout", |
| 119 | + "output_type": "stream", |
| 120 | + "text": [ |
| 121 | + "CV score is 0.8741414141414141\n" |
| 122 | + ] |
| 123 | + } |
| 124 | + ], |
| 125 | + "source": [ |
| 126 | + "num_features_total = 1000\n", |
| 127 | + "num_features_best = 100\n", |
| 128 | + "\n", |
| 129 | + "N = 100\n", |
| 130 | + "\n", |
| 131 | + "# Dataset generation\n", |
| 132 | + "X = np.random.normal(size=(N, num_features_total))\n", |
| 133 | + "y = np.random.randint(2, size=N)\n", |
| 134 | + "\n", |
| 135 | + "# Feature selection:\n", |
| 136 | + "X_best = FeatureSelector(num_features_best).fit_transform(X, y)\n", |
| 137 | + "\n", |
| 138 | + "# Simple classification model\n", |
| 139 | + "model = LinearSVC()\n", |
| 140 | + "\n", |
| 141 | + "# Estimatin accuracy using cross-validation:\n", |
| 142 | + "cv_score = cross_val_score(model, X_best, y, scoring='accuracy', cv=10, n_jobs=-1).mean()\n", |
| 143 | + "print(f\"CV score is {cv_score}\")" |
| 144 | + ] |
| 145 | + }, |
| 146 | + { |
| 147 | + "cell_type": "markdown", |
| 148 | + "metadata": { |
| 149 | + "colab_type": "text", |
| 150 | + "id": "afadN3ZVFKjF" |
| 151 | + }, |
| 152 | + "source": [ |
| 153 | + "What's going on?! Why accuracy is so high?\n", |
| 154 | + "\n", |
| 155 | + "Maybe it just happened by chance? Let's repeat this experiment many times and histogram the results:" |
| 156 | + ] |
| 157 | + }, |
| 158 | + { |
| 159 | + "cell_type": "code", |
| 160 | + "execution_count": 4, |
| 161 | + "metadata": { |
| 162 | + "colab": { |
| 163 | + "base_uri": "https://localhost:8080/", |
| 164 | + "height": 265 |
| 165 | + }, |
| 166 | + "colab_type": "code", |
| 167 | + "id": "QDbOMXnuC6uw", |
| 168 | + "outputId": "597d41e7-482b-4f6a-8565-316644c1b04e" |
| 169 | + }, |
| 170 | + "outputs": [ |
| 171 | + { |
| 172 | + "data": { |
| 173 | + "image/png": "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\n", |
| 174 | + "text/plain": [ |
| 175 | + "<Figure size 432x288 with 1 Axes>" |
| 176 | + ] |
| 177 | + }, |
| 178 | + "metadata": {}, |
| 179 | + "output_type": "display_data" |
| 180 | + } |
| 181 | + ], |
| 182 | + "source": [ |
| 183 | + "num_features_total = 1000\n", |
| 184 | + "num_features_best = 100\n", |
| 185 | + "\n", |
| 186 | + "N = 100\n", |
| 187 | + "def experiment():\n", |
| 188 | + " # Dataset generation\n", |
| 189 | + " X = np.random.normal(size=(N, num_features_total))\n", |
| 190 | + " y = np.random.randint(2, size=N)\n", |
| 191 | + "\n", |
| 192 | + " # Feature selection:\n", |
| 193 | + " X_best = FeatureSelector(num_features_best).fit_transform(X, y)\n", |
| 194 | + "\n", |
| 195 | + " # Simple classification model\n", |
| 196 | + " model = LinearSVC()\n", |
| 197 | + "\n", |
| 198 | + " # Estimatin accuracy using cross-validation:\n", |
| 199 | + " return cross_val_score(model, X_best, y, scoring='accuracy', cv=10, n_jobs=-1).mean()\n", |
| 200 | + "\n", |
| 201 | + "results = [experiment() for _ in range(100)]\n", |
| 202 | + "plt.hist(results, bins=10);" |
| 203 | + ] |
| 204 | + }, |
| 205 | + { |
| 206 | + "cell_type": "markdown", |
| 207 | + "metadata": { |
| 208 | + "colab_type": "text", |
| 209 | + "id": "8bLaEypoF5pb" |
| 210 | + }, |
| 211 | + "source": [ |
| 212 | + "Can you explain and fix this?" |
| 213 | + ] |
| 214 | + }, |
| 215 | + { |
| 216 | + "cell_type": "code", |
| 217 | + "execution_count": null, |
| 218 | + "metadata": {}, |
| 219 | + "outputs": [], |
| 220 | + "source": [ |
| 221 | + "# It's dangerous to go alone. Take this!\n", |
| 222 | + "from sklearn.pipeline import Pipeline" |
| 223 | + ] |
| 224 | + }, |
| 225 | + { |
| 226 | + "cell_type": "code", |
| 227 | + "execution_count": null, |
| 228 | + "metadata": {}, |
| 229 | + "outputs": [], |
| 230 | + "source": [ |
| 231 | + "# YOUR BEAUTIFUL FIX HERE" |
| 232 | + ] |
| 233 | + } |
| 234 | + ], |
| 235 | + "metadata": { |
| 236 | + "colab": { |
| 237 | + "include_colab_link": true, |
| 238 | + "name": "Cross-validation riddle.ipynb", |
| 239 | + "provenance": [] |
| 240 | + }, |
| 241 | + "kernelspec": { |
| 242 | + "display_name": "Py3 research env", |
| 243 | + "language": "python", |
| 244 | + "name": "py3_research" |
| 245 | + }, |
| 246 | + "language_info": { |
| 247 | + "codemirror_mode": { |
| 248 | + "name": "ipython", |
| 249 | + "version": 3 |
| 250 | + }, |
| 251 | + "file_extension": ".py", |
| 252 | + "mimetype": "text/x-python", |
| 253 | + "name": "python", |
| 254 | + "nbconvert_exporter": "python", |
| 255 | + "pygments_lexer": "ipython3", |
| 256 | + "version": "3.6.7" |
| 257 | + } |
| 258 | + }, |
| 259 | + "nbformat": 4, |
| 260 | + "nbformat_minor": 1 |
| 261 | +} |
0 commit comments