├── 3_4_social_network_theory.ipynb ├── Data_science_key_facts.ipynb ├── Lesson2_7_Trends_Supervized_Learning.ipynb ├── Lesson3_1_Cluster_Analysis.ipynb ├── Lesson3_2_GMM.ipynb ├── Lesson3_3_PCA.ipynb ├── Lesson3_5_recommendations.ipynb ├── Python_For_Data_Science_Introduction_to_Colab.ipynb ├── README.md ├── _config.yml ├── data_science_workflow.ipynb └── network_analysis.ipynb /Data_science_key_facts.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Data science key facts.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [ 9 | "8YwVmdSPnXmL", 10 | "4SJ4H2AdnX3v", 11 | "y6umVTQDncYc" 12 | ], 13 | "include_colab_link": true 14 | }, 15 | "kernelspec": { 16 | "name": "python3", 17 | "display_name": "Python 3" 18 | } 19 | }, 20 | "cells": [ 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "id": "view-in-github", 25 | "colab_type": "text" 26 | }, 27 | "source": [ 28 | "\"Open" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "jyL-pl5Nm6-m", 35 | "colab_type": "text" 36 | }, 37 | "source": [ 38 | "# Data science key facts" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "id": "omkKdqi3nS95", 45 | "colab_type": "text" 46 | }, 47 | "source": [ 48 | "## Data science workflow" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": { 54 | "id": "8YwVmdSPnXmL", 55 | "colab_type": "text" 56 | }, 57 | "source": [ 58 | "### Ingest" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": { 64 | "id": "6ygLG-5VnXuD", 65 | "colab_type": "text" 66 | }, 67 | "source": [ 68 | "" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": { 74 | "id": "4SJ4H2AdnX3v", 75 | "colab_type": "text" 76 | }, 77 | "source": [ 78 | "### EDA" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": { 84 | "id": "-JE_LIxfncVN", 85 | "colab_type": "text" 86 | }, 87 | "source": [ 88 | "" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": { 94 | "id": "y6umVTQDncYc", 95 | "colab_type": "text" 96 | }, 97 | "source": [ 98 | "### Modeling" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": { 104 | "id": "O_5nQRlJncbQ", 105 | "colab_type": "text" 106 | }, 107 | "source": [ 108 | "" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": { 114 | "id": "jMFvQlbmnesD", 115 | "colab_type": "text" 116 | }, 117 | "source": [ 118 | "### Conclusion" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": { 124 | "id": "UBqZMeP7ngyv", 125 | "colab_type": "text" 126 | }, 127 | "source": [ 128 | "" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": { 134 | "id": "d6-gq8e8oTOU", 135 | "colab_type": "text" 136 | }, 137 | "source": [ 138 | "## Becoming a Triple Threat" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": { 144 | "id": "Y9CnfhvYoVoU", 145 | "colab_type": "text" 146 | }, 147 | "source": [ 148 | "* Advanced Degree or Extensive Work Experience\n", 149 | "* Portfolio\n", 150 | "* Certifications" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": { 156 | "id": "e-gk6rwYol4E", 157 | "colab_type": "text" 158 | }, 159 | "source": [ 160 | "### Portfolio" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": { 166 | "id": "IkFIBLrAooXI", 167 | "colab_type": "text" 168 | }, 169 | "source": [ 170 | "* Original\n", 171 | "* Based on personal interest\n", 172 | "* Includes video \"demo\"\n", 173 | "* Written summary as well as notebooks\n", 174 | "* \"Reproducable\"" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": { 180 | "id": "-qAqQ06TozD3", 181 | "colab_type": "text" 182 | }, 183 | "source": [ 184 | "### Certifications" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": { 190 | "id": "ft1YJnZZo1wO", 191 | "colab_type": "text" 192 | }, 193 | "source": [ 194 | "* PALM Stack (Python, AWS, Linux, Machine Learning)\n", 195 | "* Cloud\n", 196 | "* Big Data & Data Analytics\n" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "metadata": { 202 | "id": "catcgqiqoybR", 203 | "colab_type": "code", 204 | "colab": {} 205 | }, 206 | "source": [ 207 | "" 208 | ], 209 | "execution_count": 0, 210 | "outputs": [] 211 | } 212 | ] 213 | } -------------------------------------------------------------------------------- /Lesson3_5_recommendations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Lesson3_5_recommendations.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [ 9 | "NhT7rabY0fp4", 10 | "6cAYslM7Ype9", 11 | "ulEBTojcapEH", 12 | "-wocOTgtcEX2", 13 | "dAyWCIaNfFBB", 14 | "5s7H0qT3iEj4", 15 | "LOrWDYMolR7b", 16 | "4huGqSbPtyo1", 17 | "EvTT7BrWxAPP", 18 | "kJ6xu_58xP-H", 19 | "UU_xwRmh9Acw", 20 | "LrTg1MvABj3T", 21 | "N_m0YG841Bfd" 22 | ], 23 | "include_colab_link": true 24 | }, 25 | "kernelspec": { 26 | "name": "python3", 27 | "display_name": "Python 3" 28 | }, 29 | "accelerator": "GPU" 30 | }, 31 | "cells": [ 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "id": "view-in-github", 36 | "colab_type": "text" 37 | }, 38 | "source": [ 39 | "\"Open" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "id": "NhT7rabY0fp4", 46 | "colab_type": "text" 47 | }, 48 | "source": [ 49 | "# Recommender Systems" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": { 55 | "id": "5s7H0qT3iEj4", 56 | "colab_type": "text" 57 | }, 58 | "source": [ 59 | "## Nearest Neighbor CF: Basics" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": { 65 | "id": "JcaN-oIXiIQO", 66 | "colab_type": "text" 67 | }, 68 | "source": [ 69 | "* One of most popular and common methods for CF (very intuitive)\n", 70 | "* User-based and Item Based\n", 71 | "* Naive Version (Very simple metric is Pearson correlation coefficient)\n", 72 | " * ***Measures covariance of two variables divided by product of standard deviations.***\n", 73 | " * Problem with basic version is it doesn't account for peoples' **baseline preferences.**\n" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": { 79 | "id": "LOrWDYMolR7b", 80 | "colab_type": "text" 81 | }, 82 | "source": [ 83 | "## What is in a Rating?" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": { 89 | "id": "yg4YFHoalVC9", 90 | "colab_type": "text" 91 | }, 92 | "source": [ 93 | "* Implicit vs. explicit ratings\n", 94 | " * Strongest signal is in explicit ratings made by people.\n", 95 | " * Implicit: Did you follow someone, buy the movie or watch the trailer" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": { 101 | "id": "4huGqSbPtyo1", 102 | "colab_type": "text" 103 | }, 104 | "source": [ 105 | "# Surprise SKLearn Recommendation Framework" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": { 111 | "id": "spaIVqXYt7vJ", 112 | "colab_type": "text" 113 | }, 114 | "source": [ 115 | "[Surprise](http://surpriselib.com/) is a Python scikit building and analyzing recommender systems." 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": { 121 | "id": "EvTT7BrWxAPP", 122 | "colab_type": "text" 123 | }, 124 | "source": [ 125 | "### Training a recommender with surprise" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "metadata": { 131 | "id": "t5PrwVKrt7Id", 132 | "colab_type": "code", 133 | "outputId": "b8ea1581-71b9-4303-c45c-bf29d419ad08", 134 | "colab": { 135 | "base_uri": "https://localhost:8080/", 136 | "height": 50 137 | } 138 | }, 139 | "source": [ 140 | "!pip install -q scikit-surprise" 141 | ], 142 | "execution_count": 0, 143 | "outputs": [ 144 | { 145 | "output_type": "stream", 146 | "text": [ 147 | "\u001b[K |████████████████████████████████| 3.3MB 1.4MB/s \n", 148 | "\u001b[?25h Building wheel for scikit-surprise (setup.py) ... \u001b[?25l\u001b[?25hdone\n" 149 | ], 150 | "name": "stdout" 151 | } 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "metadata": { 157 | "id": "vxTpiqXruynG", 158 | "colab_type": "code", 159 | "colab": {} 160 | }, 161 | "source": [ 162 | "from surprise import SVD\n", 163 | "from surprise import Dataset\n", 164 | "from surprise import accuracy\n", 165 | "from surprise.model_selection import train_test_split" 166 | ], 167 | "execution_count": 0, 168 | "outputs": [] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "metadata": { 173 | "id": "DIpKS6tqwUYh", 174 | "colab_type": "code", 175 | "outputId": "8fdb0cce-2def-4fea-fd68-10c6c970e809", 176 | "colab": { 177 | "base_uri": "https://localhost:8080/", 178 | "height": 67 179 | } 180 | }, 181 | "source": [ 182 | "# Load the movielens-100k dataset (download it if needed),\n", 183 | "data = Dataset.load_builtin('ml-100k')" 184 | ], 185 | "execution_count": 0, 186 | "outputs": [ 187 | { 188 | "output_type": "stream", 189 | "text": [ 190 | "Dataset ml-100k could not be found. Do you want to download it? [Y/n] Y\n", 191 | "Trying to download dataset from http://files.grouplens.org/datasets/movielens/ml-100k.zip...\n", 192 | "Done! Dataset ml-100k has been saved to /root/.surprise_data/ml-100k\n" 193 | ], 194 | "name": "stdout" 195 | } 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "metadata": { 201 | "id": "PcSBQ89QwRAc", 202 | "colab_type": "code", 203 | "colab": {} 204 | }, 205 | "source": [ 206 | "# sample random trainset and testset\n", 207 | "# test set is made of 25% of the ratings.\n", 208 | "trainset, testset = train_test_split(data, test_size=.25)" 209 | ], 210 | "execution_count": 0, 211 | "outputs": [] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "metadata": { 216 | "id": "XAbOLkNLu85F", 217 | "colab_type": "code", 218 | "colab": {} 219 | }, 220 | "source": [ 221 | "# We'll use the famous SVD algorithm.\n", 222 | "algo = SVD()" 223 | ], 224 | "execution_count": 0, 225 | "outputs": [] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "metadata": { 230 | "id": "hyHOszFew3Kd", 231 | "colab_type": "code", 232 | "colab": {} 233 | }, 234 | "source": [ 235 | "# Train the algorithm on the trainset, and predict ratings for the testset\n", 236 | "algo.fit(trainset)\n", 237 | "predictions = algo.test(testset)" 238 | ], 239 | "execution_count": 0, 240 | "outputs": [] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "metadata": { 245 | "id": "WtrrM7XKw5-H", 246 | "colab_type": "code", 247 | "outputId": "cf6ced8d-d5e1-46cc-fa53-635e8a0481e6", 248 | "colab": { 249 | "base_uri": "https://localhost:8080/", 250 | "height": 50 251 | } 252 | }, 253 | "source": [ 254 | "# Then compute RMSE\n", 255 | "accuracy.rmse(predictions)" 256 | ], 257 | "execution_count": 0, 258 | "outputs": [ 259 | { 260 | "output_type": "stream", 261 | "text": [ 262 | "RMSE: 0.9440\n" 263 | ], 264 | "name": "stdout" 265 | }, 266 | { 267 | "output_type": "execute_result", 268 | "data": { 269 | "text/plain": [ 270 | "0.9440155966414212" 271 | ] 272 | }, 273 | "metadata": { 274 | "tags": [] 275 | }, 276 | "execution_count": 8 277 | } 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": { 283 | "id": "kJ6xu_58xP-H", 284 | "colab_type": "text" 285 | }, 286 | "source": [ 287 | "### Get top-N recommendations for each user" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "metadata": { 293 | "id": "PiV9oegYx0Jq", 294 | "colab_type": "text" 295 | }, 296 | "source": [ 297 | "https://surprise.readthedocs.io/en/stable/FAQ.html#how-to-get-the-top-n-recommendations-for-each-user" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "metadata": { 303 | "id": "KjY-_tHaxTtA", 304 | "colab_type": "code", 305 | "colab": {} 306 | }, 307 | "source": [ 308 | "from collections import defaultdict" 309 | ], 310 | "execution_count": 0, 311 | "outputs": [] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "metadata": { 316 | "id": "z6aVHMD_xcGT", 317 | "colab_type": "code", 318 | "colab": {} 319 | }, 320 | "source": [ 321 | "def get_top_n(predictions, n=10):\n", 322 | " '''Return the top-N recommendation for each user from a set of predictions.\n", 323 | "\n", 324 | " Args:\n", 325 | " predictions(list of Prediction objects): The list of predictions, as\n", 326 | " returned by the test method of an algorithm.\n", 327 | " n(int): The number of recommendation to output for each user. Default\n", 328 | " is 10.\n", 329 | "\n", 330 | " Returns:\n", 331 | " A dict where keys are user (raw) ids and values are lists of tuples:\n", 332 | " [(raw item id, rating estimation), ...] of size n.\n", 333 | " '''\n", 334 | "\n", 335 | " # First map the predictions to each user.\n", 336 | " top_n = defaultdict(list)\n", 337 | " for uid, iid, true_r, est, _ in predictions:\n", 338 | " top_n[uid].append((iid, est))\n", 339 | "\n", 340 | " # Then sort the predictions for each user and retrieve the k highest ones.\n", 341 | " for uid, user_ratings in top_n.items():\n", 342 | " user_ratings.sort(key=lambda x: x[1], reverse=True)\n", 343 | " top_n[uid] = user_ratings[:n]\n", 344 | "\n", 345 | " return top_n" 346 | ], 347 | "execution_count": 0, 348 | "outputs": [] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "metadata": { 353 | "id": "N4EjAooUxh9Z", 354 | "colab_type": "code", 355 | "outputId": "63bfca6f-d3bc-48c9-f9db-909d156ba03e", 356 | "colab": { 357 | "base_uri": "https://localhost:8080/", 358 | "height": 1000 359 | } 360 | }, 361 | "source": [ 362 | "# First train an SVD algorithm on the movielens dataset.\n", 363 | "data = Dataset.load_builtin('ml-100k')\n", 364 | "trainset = data.build_full_trainset()\n", 365 | "algo = SVD()\n", 366 | "algo.fit(trainset)\n", 367 | "\n", 368 | "# Than predict ratings for all pairs (u, i) that are NOT in the training set.\n", 369 | "testset = trainset.build_anti_testset()\n", 370 | "predictions = algo.test(testset)\n", 371 | "\n", 372 | "top_n = get_top_n(predictions, n=10)\n", 373 | "\n", 374 | "# Print the recommended items for each user\n", 375 | "for uid, user_ratings in top_n.items():\n", 376 | " print(uid, [iid for (iid, _) in user_ratings])" 377 | ], 378 | "execution_count": 0, 379 | "outputs": [ 380 | { 381 | "output_type": "stream", 382 | "text": [ 383 | "196 ['114', '316', '318', '178', '483', '357', '429', '315', '12', '512']\n", 384 | "186 ['528', '169', '194', '133', '318', '136', '197', '603', '496', '498']\n", 385 | "22 ['100', '12', '64', '318', '357', '483', '530', '98', '11', '191']\n", 386 | "244 ['127', '408', '14', '474', '275', '285', '178', '483', '12', '641']\n", 387 | "166 ['50', '408', '64', '963', '174', '178', '199', '22', '251', '923']\n", 388 | "298 ['64', '408', '313', '251', '192', '169', '963', '923', '114', '480']\n", 389 | "115 ['114', '408', '223', '285', '180', '64', '474', '515', '427', '135']\n", 390 | "253 ['178', '169', '408', '174', '172', '480', '709', '136', '641', '515']\n", 391 | "305 ['647', '515', '114', '606', '496', '607', '316', '651', '513', '1194']\n", 392 | "6 ['603', '654', '114', '606', '923', '657', '611', '589', '83', '647']\n", 393 | "62 ['185', '661', '641', '187', '223', '615', '963', '175', '478', '272']\n", 394 | "286 ['86', '19', '963', '12', '479', '496', '318', '292', '488', '427']\n", 395 | "200 ['272', '64', '186', '641', '408', '114', '12', '316', '1039', '487']\n", 396 | "210 ['318', '515', '12', '64', '480', '603', '169', '427', '178', '199']\n", 397 | "224 ['174', '64', '173', '210', '172', '50', '265', '216', '95', '496']\n", 398 | "303 ['527', '135', '169', '114', '272', '515', '14', '89', '315', '192']\n", 399 | "122 ['603', '408', '100', '607', '483', '963', '657', '114', '169', '192']\n", 400 | "194 ['484', '272', '603', '251', '156', '611', '316', '408', '302', '480']\n", 401 | "291 ['127', '318', '357', '192', '408', '515', '209', '169', '178', '187']\n", 402 | "234 ['114', '189', '19', '83', '169', '302', '408', '958', '514', '529']\n", 403 | "119 ['114', '170', '178', '318', '357', '483', '183', '515', '136', '604']\n", 404 | "167 ['114', '272', '357', '56', '427', '178', '316', '12', '143', '98']\n", 405 | "299 ['357', '178', '1007', '316', '64', '272', '223', '189', '493', '657']\n", 406 | "308 ['474', '114', '173', '190', '272', '302', '478', '1449', '652', '1142']\n", 407 | "95 ['318', '12', '732', '923', '489', '603', '408', '124', '945', '427']\n", 408 | "38 ['496', '408', '178', '945', '170', '1137', '98', '483', '64', '143']\n", 409 | "102 ['408', '64', '483', '496', '603', '169', '318', '478', '661', '190']\n", 410 | "63 ['114', '169', '318', '64', '98', '357', '83', '694', '89', '178']\n", 411 | "160 ['12', '357', '180', '179', '134', '114', '272', '504', '523', '199']\n", 412 | "50 ['127', '64', '12', '408', '156', '50', '251', '357', '603', '963']\n", 413 | "301 ['315', '272', '251', '480', '242', '408', '178', '1137', '316', '603']\n", 414 | "225 ['483', '408', '178', '169', '607', '223', '515', '114', '313', '661']\n", 415 | "290 ['408', '313', '272', '316', '169', '275', '480', '12', '603', '1137']\n", 416 | "97 ['64', '12', '318', '285', '114', '178', '59', '641', '480', '45']\n", 417 | "157 ['318', '483', '657', '169', '498', '189', '408', '603', '178', '114']\n", 418 | "181 ['313', '22', '174', '12', '318', '181', '96', '50', '172', '143']\n", 419 | "278 ['12', '963', '169', '223', '318', '408', '127', '657', '251', '64']\n", 420 | "276 ['114', '134', '694', '190', '484', '1142', '654', '527', '651', '194']\n", 421 | "7 ['114', '302', '1142', '272', '408', '1039', '251', '313', '963', '316']\n", 422 | "10 ['318', '169', '313', '408', '528', '661', '83', '923', '173', '136']\n", 423 | "284 ['408', '134', '169', '170', '511', '513', '483', '114', '923', '211']\n", 424 | "201 ['474', '493', '168', '178', '1449', '611', '1007', '135', '114', '504']\n", 425 | "287 ['603', '408', '318', '357', '199', '657', '12', '169', '427', '429']\n", 426 | "246 ['268', '171', '127', '156', '179', '114', '302', '23', '514', '315']\n", 427 | "242 ['603', '480', '174', '479', '272', '172', '483', '408', '178', '127']\n", 428 | "249 ['127', '178', '515', '654', '923', '180', '285', '694', '528', '474']\n", 429 | "99 ['318', '357', '498', '515', '191', '272', '190', '180', '429', '205']\n", 430 | "178 ['408', '169', '186', '205', '114', '272', '251', '923', '963', '709']\n", 431 | "251 ['408', '483', '318', '511', '127', '285', '169', '187', '114', '474']\n", 432 | "81 ['483', '64', '178', '408', '603', '963', '357', '320', '515', '197']\n", 433 | "260 ['603', '174', '483', '178', '318', '64', '114', '1194', '169', '357']\n", 434 | "25 ['178', '318', '196', '251', '89', '64', '190', '210', '272', '216']\n", 435 | "59 ['641', '750', '694', '268', '493', '144', '114', '178', '475', '320']\n", 436 | "72 ['59', '496', '178', '251', '200', '316', '656', '269', '641', '132']\n", 437 | "87 ['69', '316', '251', '191', '603', '169', '265', '28', '480', '520']\n", 438 | "42 ['22', '313', '651', '191', '144', '435', '199', '482', '300', '604']\n", 439 | "292 ['134', '474', '302', '185', '513', '178', '89', '179', '318', '114']\n", 440 | "20 ['408', '169', '86', '963', '275', '923', '178', '19', '223', '603']\n", 441 | "13 ['192', '114', '528', '408', '923', '521', '611', '1019', '203', '963']\n", 442 | "138 ['173', '272', '50', '408', '64', '174', '316', '169', '127', '478']\n", 443 | "60 ['169', '318', '251', '408', '114', '190', '488', '1019', '170', '100']\n", 444 | "57 ['174', '169', '114', '172', '96', '1137', '429', '22', '178', '511']\n", 445 | "223 ['187', '265', '204', '64', '429', '12', '186', '661', '89', '174']\n", 446 | "189 ['190', '64', '515', '427', '242', '114', '302', '169', '189', '1039']\n", 447 | "243 ['408', '169', '513', '48', '483', '56', '178', '114', '357', '12']\n", 448 | "92 ['127', '285', '484', '513', '357', '483', '114', '530', '272', '603']\n", 449 | "241 ['657', '408', '483', '169', '98', '318', '178', '48', '127', '515']\n", 450 | "254 ['408', '651', '114', '483', '144', '316', '95', '963', '169', '96']\n", 451 | "293 ['276', '9', '191', '178', '408', '169', '114', '661', '525', '318']\n", 452 | "127 ['408', '189', '210', '478', '83', '169', '114', '657', '64', '705']\n", 453 | "222 ['199', '408', '187', '272', '523', '963', '251', '169', '126', '480']\n", 454 | "267 ['357', '173', '272', '318', '285', '178', '530', '513', '1449', '519']\n", 455 | "11 ['251', '64', '169', '408', '134', '1169', '272', '114', '483', '48']\n", 456 | "8 ['408', '313', '64', '197', '169', '483', '98', '963', '48', '603']\n", 457 | "162 ['408', '64', '313', '923', '22', '12', '318', '651', '272', '114']\n", 458 | "279 ['512', '8', '93', '223', '178', '171', '315', '478', '327', '604']\n", 459 | "145 ['357', '114', '208', '153', '187', '318', '191', '205', '519', '180']\n", 460 | "28 ['169', '408', '318', '172', '114', '513', '657', '285', '515', '963']\n", 461 | "135 ['408', '64', '169', '318', '483', '174', '480', '513', '285', '172']\n", 462 | "32 ['272', '483', '64', '641', '134', '178', '12', '127', '479', '603']\n", 463 | "90 ['169', '114', '48', '1142', '524', '320', '1449', '408', '1007', '902']\n", 464 | "216 ['515', '178', '89', '127', '185', '483', '474', '114', '657', '641']\n", 465 | "250 ['408', '483', '114', '134', '654', '511', '182', '923', '302', '427']\n", 466 | "271 ['483', '114', '408', '513', '23', '316', '144', '632', '251', '736']\n", 467 | "265 ['272', '313', '480', '64', '657', '98', '603', '12', '316', '251']\n", 468 | "198 ['408', '114', '169', '12', '483', '513', '479', '170', '178', '272']\n", 469 | "168 ['82', '79', '357', '923', '318', '98', '22', '527', '194', '64']\n", 470 | "110 ['318', '136', '170', '515', '316', '174', '408', '1019', '641', '265']\n", 471 | "58 ['114', '428', '179', '479', '1449', '52', '530', '489', '657', '251']\n", 472 | "237 ['114', '647', '223', '272', '50', '48', '56', '12', '657', '285']\n", 473 | "94 ['114', '340', '137', '285', '276', '171', '513', '530', '515', '480']\n", 474 | "128 ['408', '318', '479', '169', '498', '474', '316', '178', '480', '488']\n", 475 | "44 ['408', '12', '169', '186', '187', '127', '661', '488', '519', '272']\n", 476 | "264 ['272', '178', '134', '169', '114', '408', '483', '474', '223', '357']\n", 477 | "41 ['408', '169', '114', '483', '12', '654', '134', '187', '603', '272']\n", 478 | "82 ['98', '651', '210', '607', '251', '659', '189', '12', '192', '427']\n", 479 | "262 ['178', '12', '127', '657', '302', '357', '272', '114', '199', '136']\n", 480 | "174 ['528', '316', '170', '603', '588', '89', '367', '318', '657', '136']\n", 481 | "43 ['515', '657', '427', '251', '483', '378', '513', '132', '136', '183']\n", 482 | "84 ['357', '316', '603', '272', '483', '480', '174', '178', '169', '515']\n", 483 | "269 ['652', '114', '589', '223', '1449', '242', '178', '203', '190', '408']\n", 484 | "259 ['64', '483', '169', '515', '318', '251', '272', '127', '174', '191']\n", 485 | "85 ['178', '114', '285', '165', '484', '185', '408', '694', '48', '651']\n", 486 | "213 ['313', '168', '114', '615', '302', '272', '178', '408', '427', '285']\n", 487 | "121 ['408', '178', '132', '480', '483', '603', '657', '496', '513', '432']\n", 488 | "49 ['276', '134', '127', '23', '474', '9', '654', '180', '269', '156']\n", 489 | "155 ['134', '178', '169', '318', '357', '603', '657', '64', '483', '515']\n", 490 | "68 ['318', '408', '474', '114', '14', '515', '483', '238', '657', '169']\n", 491 | "172 ['100', '408', '12', '192', '150', '480', '474', '169', '127', '511']\n", 492 | "19 ['357', '483', '318', '474', '408', '64', '178', '480', '169', '50']\n", 493 | "268 ['603', '64', '530', '23', '318', '657', '272', '511', '199', '513']\n", 494 | "5 ['175', '285', '483', '474', '479', '316', '603', '522', '124', '896']\n", 495 | "80 ['408', '169', '114', '12', '192', '480', '285', '963', '320', '606']\n", 496 | "66 ['174', '12', '22', '963', '64', '195', '114', '496', '272', '603']\n", 497 | "18 ['316', '1194', '511', '272', '657', '656', '124', '632', '315', '606']\n", 498 | "26 ['318', '178', '173', '134', '483', '114', '64', '187', '923', '474']\n", 499 | "130 ['194', '603', '480', '483', '408', '318', '133', '657', '83', '169']\n", 500 | "256 ['318', '429', '178', '300', '923', '316', '114', '520', '313', '515']\n", 501 | "1 ['318', '483', '408', '647', '528', '515', '478', '1142', '657', '530']\n", 502 | "56 ['313', '272', '480', '511', '318', '357', '190', '12', '192', '1137']\n", 503 | "15 ['172', '694', '408', '513', '318', '511', '169', '478', '124', '136']\n", 504 | "207 ['178', '480', '923', '136', '427', '705', '251', '603', '513', '498']\n", 505 | "232 ['114', '169', '89', '190', '285', '134', '511', '513', '408', '529']\n", 506 | "52 ['474', '172', '483', '408', '357', '114', '12', '515', '50', '127']\n", 507 | "161 ['408', '512', '169', '12', '516', '59', '64', '475', '641', '251']\n", 508 | "148 ['22', '511', '313', '513', '512', '170', '483', '479', '12', '272']\n", 509 | "125 ['313', '96', '121', '169', '408', '196', '1137', '132', '694', '265']\n", 510 | "83 ['519', '136', '170', '496', '318', '735', '282', '936', '392', '194']\n", 511 | "272 ['603', '114', '64', '318', '408', '315', '169', '285', '316', '180']\n", 512 | "151 ['272', '515', '316', '479', '285', '242', '8', '1007', '251', '165']\n", 513 | "54 ['172', '12', '408', '285', '114', '316', '64', '320', '1449', '169']\n", 514 | "16 ['408', '169', '50', '187', '251', '313', '483', '488', '750', '132']\n", 515 | "91 ['114', '408', '694', '169', '1137', '302', '315', '513', '199', '96']\n", 516 | "294 ['318', '64', '98', '174', '172', '408', '173', '487', '169', '272']\n", 517 | "229 ['318', '480', '483', '659', '178', '481', '657', '493', '320', '197']\n", 518 | "36 ['483', '408', '318', '641', '285', '1194', '190', '64', '615', '114']\n", 519 | "70 ['114', '318', '64', '480', '12', '127', '515', '603', '272', '192']\n", 520 | "14 ['169', '114', '488', '178', '659', '483', '318', '180', '64', '480']\n", 521 | "295 ['302', '515', '512', '169', '611', '269', '923', '963', '657', '607']\n", 522 | "233 ['169', '251', '513', '408', '427', '114', '493', '496', '659', '641']\n", 523 | "214 ['513', '9', '178', '657', '488', '165', '654', '320', '205', '528']\n", 524 | "192 ['318', '12', '14', '474', '173', '64', '657', '483', '357', '480']\n", 525 | "100 ['318', '50', '64', '12', '515', '173', '251', '174', '483', '496']\n", 526 | "307 ['519', '268', '285', '489', '127', '479', '606', '709', '12', '530']\n", 527 | "297 ['657', '318', '483', '127', '427', '496', '478', '134', '169', '178']\n", 528 | "193 ['511', '483', '656', '482', '496', '169', '515', '178', '484', '480']\n", 529 | "113 ['64', '483', '408', '181', '174', '172', '480', '513', '519', '430']\n", 530 | "275 ['64', '603', '318', '513', '12', '251', '480', '357', '114', '136']\n", 531 | "219 ['185', '100', '175', '12', '408', '156', '285', '318', '169', '474']\n", 532 | "218 ['127', '408', '483', '515', '480', '114', '530', '963', '178', '474']\n", 533 | "123 ['408', '190', '357', '603', '484', '661', '1449', '191', '178', '923']\n", 534 | "158 ['427', '963', '192', '191', '318', '134', '603', '1137', '114', '180']\n", 535 | "302 ['64', '318', '603', '515', '483', '408', '114', '963', '12', '657']\n", 536 | "23 ['169', '272', '45', '474', '654', '478', '285', '963', '709', '923']\n", 537 | "296 ['132', '178', '511', '513', '318', '197', '657', '603', '64', '709']\n", 538 | "33 ['172', '50', '408', '318', '174', '496', '178', '483', '511', '169']\n", 539 | "154 ['178', '12', '127', '318', '64', '408', '483', '114', '511', '192']\n", 540 | "77 ['12', '11', '318', '64', '169', '180', '178', '408', '272', '603']\n", 541 | "270 ['1137', '515', '427', '512', '209', '479', '272', '14', '483', '408']\n", 542 | "187 ['318', '408', '313', '169', '12', '923', '480', '963', '185', '50']\n", 543 | "170 ['603', '127', '64', '87', '313', '12', '408', '483', '923', '22']\n", 544 | "101 ['313', '657', '98', '483', '199', '169', '515', '408', '272', '496']\n", 545 | "184 ['178', '114', '242', '661', '427', '169', '302', '408', '633', '921']\n", 546 | "112 ['357', '127', '64', '318', '603', '661', '12', '408', '169', '56']\n", 547 | "133 ['169', '56', '114', '408', '178', '603', '127', '9', '513', '174']\n", 548 | "215 ['169', '190', '408', '511', '285', '603', '199', '114', '178', '515']\n", 549 | "69 ['178', '483', '515', '173', '114', '127', '89', '318', '357', '170']\n", 550 | "104 ['56', '98', '515', '357', '174', '178', '61', '318', '641', '83']\n", 551 | "240 ['318', '64', '408', '316', '114', '357', '45', '641', '427', '178']\n", 552 | "144 ['483', '427', '481', '199', '513', '923', '511', '169', '114', '210']\n", 553 | "191 ['318', '357', '12', '169', '64', '174', '114', '50', '98', '615']\n", 554 | "61 ['408', '483', '169', '64', '966', '479', '484', '661', '197', '199']\n", 555 | "142 ['50', '480', '114', '318', '483', '191', '427', '187', '313', '12']\n", 556 | "177 ['169', '408', '474', '513', '180', '134', '191', '427', '48', '480']\n", 557 | "203 ['408', '172', '114', '483', '174', '606', '12', '963', '169', '98']\n", 558 | "21 ['268', '168', '192', '493', '114', '173', '156', '302', '175', '318']\n", 559 | "197 ['28', '64', '732', '1', '480', '204', '144', '192', '178', '69']\n", 560 | "134 ['174', '22', '172', '318', '483', '657', '408', '705', '169', '484']\n", 561 | "180 ['408', '190', '169', '189', '64', '286', '114', '134', '482', '132']\n", 562 | "236 ['197', '923', '589', '480', '357', '515', '251', '178', '902', '513']\n", 563 | "263 ['313', '170', '408', '216', '427', '705', '603', '1142', '114', '173']\n", 564 | "109 ['300', '692', '313', '169', '963', '659', '519', '1193', '194', '408']\n", 565 | "64 ['178', '114', '272', '357', '169', '192', '611', '408', '661', '513']\n", 566 | "114 ['408', '169', '114', '657', '285', '603', '50', '515', '12', '178']\n", 567 | "239 ['657', '357', '408', '182', '480', '656', '199', '963', '515', '127']\n", 568 | "117 ['603', '408', '169', '114', '199', '89', '203', '83', '1449', '318']\n", 569 | "65 ['169', '408', '483', '479', '251', '114', '172', '603', '488', '923']\n", 570 | "137 ['95', '603', '1137', '427', '498', '132', '272', '258', '483', '408']\n", 571 | "257 ['483', '114', '12', '357', '318', '515', '923', '511', '178', '606']\n", 572 | "111 ['318', '173', '64', '114', '170', '408', '515', '169', '98', '483']\n", 573 | "285 ['192', '127', '22', '12', '513', '180', '603', '174', '98', '165']\n", 574 | "96 ['12', '169', '408', '357', '178', '493', '647', '475', '285', '272']\n", 575 | "116 ['96', '114', '172', '12', '174', '178', '194', '318', '496', '357']\n", 576 | "73 ['114', '408', '50', '191', '168', '302', '169', '223', '190', '511']\n", 577 | "221 ['474', '168', '169', '408', '480', '513', '182', '179', '89', '1449']\n", 578 | "235 ['114', '169', '56', '408', '513', '60', '357', '484', '59', '479']\n", 579 | "164 ['427', '480', '195', '483', '408', '318', '64', '357', '197', '169']\n", 580 | "281 ['12', '474', '480', '483', '169', '357', '178', '318', '479', '50']\n", 581 | "182 ['318', '64', '357', '174', '408', '12', '169', '513', '173', '251']\n", 582 | "129 ['318', '408', '169', '64', '427', '474', '251', '178', '923', '316']\n", 583 | "45 ['169', '483', '408', '511', '114', '316', '12', '285', '199', '64']\n", 584 | "131 ['64', '318', '50', '114', '174', '603', '169', '12', '45', '316']\n", 585 | "230 ['318', '316', '57', '251', '178', '651', '114', '483', '657', '208']\n", 586 | "126 ['127', '923', '498', '114', '408', '483', '132', '191', '603', '64']\n", 587 | "231 ['408', '169', '64', '251', '59', '513', '114', '183', '519', '479']\n", 588 | "280 ['515', '189', '185', '179', '657', '493', '611', '357', '513', '275']\n", 589 | "288 ['513', '923', '484', '493', '133', '483', '480', '172', '661', '251']\n", 590 | "152 ['95', '603', '427', '174', '408', '178', '318', '705', '64', '169']\n", 591 | "217 ['318', '357', '64', '480', '302', '272', '603', '663', '313', '487']\n", 592 | "79 ['64', '169', '174', '408', '318', '198', '603', '512', '178', '480']\n", 593 | "75 ['173', '357', '64', '12', '50', '169', '1007', '127', '483', '178']\n", 594 | "245 ['64', '173', '408', '178', '12', '519', '127', '98', '251', '272']\n", 595 | "282 ['408', '114', '318', '169', '64', '190', '515', '478', '134', '657']\n", 596 | "78 ['408', '98', '923', '316', '8', '174', '483', '318', '169', '272']\n", 597 | "118 ['242', '246', '1137', '515', '512', '480', '498', '96', '648', '195']\n", 598 | "283 ['474', '408', '169', '114', '178', '641', '318', '515', '480', '357']\n", 599 | "171 ['408', '169', '357', '513', '178', '483', '191', '285', '12', '963']\n", 600 | "107 ['127', '100', '318', '211', '169', '474', '9', '408', '923', '647']\n", 601 | "226 ['318', '64', '515', '173', '100', '50', '114', '483', '79', '190']\n", 602 | "306 ['480', '408', '318', '479', '515', '963', '483', '169', '603', '474']\n", 603 | "173 ['474', '144', '98', '193', '603', '100', '181', '515', '427', '512']\n", 604 | "185 ['408', '22', '169', '603', '483', '12', '64', '923', '657', '187']\n", 605 | "150 ['12', '64', '56', '318', '178', '357', '114', '190', '483', '603']\n", 606 | "274 ['474', '603', '480', '479', '483', '408', '178', '357', '199', '169']\n", 607 | "188 ['114', '588', '136', '515', '272', '286', '170', '275', '735', '408']\n", 608 | "48 ['318', '169', '313', '408', '178', '963', '651', '180', '513', '89']\n", 609 | "311 ['313', '169', '408', '641', '272', '114', '316', '189', '694', '190']\n", 610 | "165 ['408', '114', '50', '98', '100', '172', '57', '178', '515', '64']\n", 611 | "208 ['483', '318', '50', '64', '12', '603', '408', '172', '170', '174']\n", 612 | "2 ['114', '64', '408', '483', '474', '132', '59', '480', '427', '641']\n", 613 | "205 ['318', '64', '114', '483', '513', '169', '515', '603', '187', '484']\n", 614 | "248 ['318', '12', '408', '169', '272', '357', '313', '513', '316', '654']\n", 615 | "93 ['408', '318', '64', '173', '178', '50', '483', '515', '114', '659']\n", 616 | "159 ['515', '136', '150', '408', '190', '313', '12', '656', '493', '57']\n", 617 | "146 ['480', '357', '661', '318', '603', '197', '479', '114', '178', '511']\n", 618 | "29 ['318', '114', '169', '603', '483', '427', '64', '357', '408', '659']\n", 619 | "156 ['408', '285', '513', '483', '50', '169', '427', '114', '127', '963']\n", 620 | "37 ['408', '318', '169', '272', '64', '8', '316', '251', '178', '98']\n", 621 | "141 ['64', '318', '161', '82', '136', '265', '98', '385', '87', '357']\n", 622 | "195 ['318', '511', '50', '64', '174', '48', '493', '187', '408', '172']\n", 623 | "108 ['318', '408', '64', '98', '169', '483', '480', '56', '114', '272']\n", 624 | "47 ['408', '114', '127', '169', '483', '183', '174', '50', '513', '963']\n", 625 | "255 ['318', '172', '127', '83', '174', '357', '132', '135', '306', '269']\n", 626 | "89 ['169', '963', '657', '114', '175', '484', '480', '192', '134', '60']\n", 627 | "140 ['318', '169', '178', '483', '603', '197', '100', '170', '64', '513']\n", 628 | "190 ['50', '174', '172', '408', '181', '483', '178', '657', '89', '12']\n", 629 | "24 ['408', '169', '114', '187', '313', '302', '199', '168', '483', '134']\n", 630 | "17 ['408', '98', '169', '474', '641', '50', '515', '89', '170', '56']\n", 631 | "313 ['528', '513', '251', '963', '408', '169', '316', '12', '48', '302']\n", 632 | "53 ['603', '483', '12', '408', '134', '272', '318', '197', '923', '479']\n", 633 | "124 ['56', '318', '480', '114', '357', '64', '430', '302', '513', '316']\n", 634 | "149 ['515', '318', '169', '474', '408', '480', '483', '657', '114', '98']\n", 635 | "176 ['56', '12', '357', '661', '114', '64', '427', '479', '302', '89']\n", 636 | "106 ['408', '114', '178', '603', '136', '357', '170', '515', '169', '50']\n", 637 | "312 ['64', '1137', '251', '344', '709', '285', '963', '694', '1149', '318']\n", 638 | "175 ['963', '178', '318', '480', '427', '114', '603', '408', '657', '251']\n", 639 | "153 ['475', '318', '156', '654', '98', '513', '1449', '178', '474', '114']\n", 640 | "220 ['318', '12', '173', '313', '64', '480', '174', '50', '272', '483']\n", 641 | "143 ['192', '127', '12', '603', '479', '408', '114', '174', '316', '156']\n", 642 | "199 ['56', '357', '64', '318', '474', '114', '127', '98', '169', '185']\n", 643 | "202 ['114', '408', '134', '963', '169', '272', '302', '511', '12', '478']\n", 644 | "277 ['318', '483', '64', '272', '251', '178', '480', '515', '199', '513']\n", 645 | "206 ['56', '12', '135', '156', '641', '474', '192', '276', '114', '176']\n", 646 | "76 ['127', '408', '483', '187', '357', '694', '606', '180', '511', '285']\n", 647 | "314 ['82', '79', '603', '133', '498', '480', '604', '483', '1194', '315']\n", 648 | "136 ['483', '474', '114', '357', '169', '134', '408', '657', '603', '272']\n", 649 | "179 ['408', '50', '143', '64', '12', '95', '174', '172', '318', '427']\n", 650 | "4 ['98', '603', '515', '427', '512', '480', '275', '272', '483', '408']\n", 651 | "304 ['12', '178', '603', '174', '64', '357', '285', '199', '172', '318']\n", 652 | "3 ['185', '408', '12', '50', '357', '191', '963', '483', '98', '480']\n", 653 | "227 ['178', '357', '515', '318', '483', '474', '302', '114', '169', '657']\n", 654 | "252 ['515', '272', '408', '178', '12', '657', '483', '318', '169', '98']\n", 655 | "212 ['408', '483', '170', '316', '923', '64', '114', '524', '189', '178']\n", 656 | "310 ['192', '127', '12', '408', '513', '169', '357', '272', '923', '603']\n", 657 | "35 ['22', '172', '12', '603', '483', '313', '519', '318', '28', '661']\n", 658 | "147 ['483', '178', '169', '251', '408', '64', '318', '513', '174', '98']\n", 659 | "105 ['64', '408', '12', '318', '169', '657', '173', '483', '190', '114']\n", 660 | "34 ['474', '100', '480', '408', '127', '318', '64', '357', '169', '185']\n", 661 | "71 ['318', '654', '12', '493', '408', '661', '427', '603', '320', '251']\n", 662 | "51 ['318', '12', '169', '313', '114', '408', '357', '174', '98', '89']\n", 663 | "204 ['357', '408', '272', '98', '603', '474', '127', '143', '483', '192']\n", 664 | "315 ['169', '114', '427', '134', '357', '191', '408', '474', '272', '170']\n", 665 | "31 ['169', '483', '657', '318', '479', '661', '474', '223', '528', '114']\n", 666 | "316 ['56', '475', '269', '408', '251', '242', '603', '902', '663', '512']\n", 667 | "103 ['357', '114', '318', '64', '169', '12', '251', '474', '408', '484']\n", 668 | "318 ['496', '22', '98', '199', '603', '515', '97', '427', '526', '483']\n", 669 | "30 ['318', '178', '64', '408', '56', '8', '513', '251', '114', '357']\n", 670 | "120 ['318', '178', '114', '98', '169', '190', '427', '657', '408', '132']\n", 671 | "46 ['483', '190', '408', '169', '64', '511', '59', '199', '357', '285']\n", 672 | "289 ['114', '474', '408', '513', '357', '315', '60', '169', '483', '427']\n", 673 | "209 ['64', '174', '178', '172', '187', '651', '114', '483', '318', '705']\n", 674 | "261 ['242', '474', '603', '1137', '100', '480', '498', '174', '195', '479']\n", 675 | "88 ['174', '408', '318', '427', '169', '50', '64', '170', '316', '513']\n", 676 | "9 ['12', '22', '408', '251', '318', '174', '199', '313', '64', '272']\n", 677 | "247 ['408', '98', '178', '83', '483', '114', '318', '657', '169', '427']\n", 678 | "321 ['408', '169', '318', '178', '98', '313', '606', '136', '189', '285']\n", 679 | "266 ['318', '98', '515', '483', '178', '654', '603', '64', '408', '480']\n", 680 | "74 ['169', '64', '318', '114', '408', '223', '483', '187', '178', '474']\n", 681 | "238 ['408', '169', '318', '603', '483', '496', '272', '191', '64', '515']\n", 682 | "319 ['318', '12', '64', '357', '483', '127', '272', '480', '174', '178']\n", 683 | "323 ['408', '174', '12', '187', '474', '169', '114', '285', '480', '603']\n", 684 | "67 ['480', '318', '357', '12', '483', '272', '169', '192', '22', '127']\n", 685 | "211 ['427', '923', '963', '134', '603', '408', '8', '313', '496', '511']\n", 686 | "98 ['174', '318', '408', '69', '50', '22', '170', '483', '172', '313']\n", 687 | "12 ['515', '178', '657', '8', '408', '483', '173', '496', '603', '83']\n", 688 | "40 ['178', '483', '64', '318', '136', '187', '408', '170', '114', '169']\n", 689 | "258 ['169', '408', '483', '64', '923', '480', '199', '114', '178', '430']\n", 690 | "228 ['169', '318', '174', '64', '408', '50', '189', '170', '483', '515']\n", 691 | "325 ['169', '963', '178', '515', '923', '606', '64', '488', '603', '171']\n", 692 | "320 ['408', '169', '114', '205', '357', '318', '963', '98', '189', '178']\n", 693 | "326 ['169', '1449', '408', '12', '489', '57', '604', '59', '114', '647']\n", 694 | "327 ['114', '483', '185', '513', '124', '661', '654', '134', '488', '511']\n", 695 | "183 ['603', '178', '657', '169', '515', '64', '480', '318', '408', '512']\n", 696 | "328 ['170', '603', '479', '95', '251', '197', '408', '124', '963', '169']\n", 697 | "322 ['408', '114', '474', '169', '661', '427', '56', '190', '135', '134']\n", 698 | "330 ['265', '515', '480', '498', '96', '272', '483', '408', '178', '89']\n", 699 | "27 ['408', '64', '169', '178', '318', '199', '114', '603', '22', '496']\n", 700 | "331 ['408', '114', '169', '12', '272', '127', '963', '474', '187', '98']\n", 701 | "332 ['427', '408', '318', '169', '488', '114', '641', '519', '190', '272']\n", 702 | "329 ['64', '408', '357', '511', '318', '192', '513', '480', '170', '1142']\n", 703 | "86 ['169', '603', '483', '114', '187', '64', '408', '318', '178', '180']\n", 704 | "139 ['174', '172', '50', '64', '318', '12', '48', '408', '169', '272']\n", 705 | "300 ['480', '483', '178', '357', '513', '657', '174', '12', '318', '515']\n", 706 | "163 ['408', '169', '194', '603', '114', '483', '515', '496', '694', '315']\n", 707 | "333 ['64', '408', '272', '12', '318', '251', '479', '603', '50', '515']\n", 708 | "334 ['178', '114', '923', '357', '1449', '64', '480', '647', '589', '493']\n", 709 | "39 ['187', '318', '178', '480', '357', '64', '513', '427', '496', '432']\n", 710 | "324 ['474', '98', '603', '515', '526', '427', '480', '496', '174', '479']\n", 711 | "132 ['1194', '511', '64', '408', '192', '169', '318', '1137', '603', '134']\n", 712 | "336 ['174', '22', '98', '64', '357', '272', '166', '12', '480', '169']\n", 713 | "335 ['12', '483', '480', '603', '923', '199', '302', '98', '197', '357']\n", 714 | "169 ['408', '272', '64', '169', '114', '170', '318', '513', '12', '657']\n", 715 | "338 ['98', '114', '124', '251', '64', '647', '315', '357', '1449', '127']\n", 716 | "339 ['114', '513', '14', '169', '318', '285', '408', '611', '137', '432']\n", 717 | "309 ['50', '173', '172', '483', '181', '272', '408', '64', '318', '174']\n", 718 | "342 ['127', '180', '474', '185', '205', '603', '178', '498', '187', '589']\n", 719 | "340 ['318', '22', '483', '657', '519', '479', '169', '170', '603', '408']\n", 720 | "317 ['64', '127', '56', '251', '318', '191', '187', '12', '483', '178']\n", 721 | "341 ['474', '603', '174', '272', '483', '408', '318', '89', '64', '191']\n", 722 | "343 ['151', '114', '285', '185', '514', '513', '647', '641', '172', '479']\n", 723 | "344 ['114', '474', '134', '135', '654', '318', '56', '659', '427', '480']\n", 724 | "345 ['187', '408', '178', '127', '515', '114', '134', '427', '169', '493']\n", 725 | "346 ['69', '316', '357', '28', '71', '194', '513', '923', '531', '963']\n", 726 | "347 ['408', '316', '64', '663', '194', '135', '114', '603', '213', '205']\n", 727 | "273 ['173', '169', '114', '657', '483', '168', '515', '134', '318', '12']\n", 728 | "55 ['12', '64', '408', '603', '272', '479', '318', '313', '178', '187']\n", 729 | "349 ['127', '12', '64', '357', '318', '408', '511', '483', '132', '661']\n", 730 | "348 ['603', '174', '172', '483', '408', '178', '64', '169', '963', '12']\n", 731 | "354 ['408', '114', '357', '56', '302', '633', '654', '474', '641', '427']\n", 732 | "351 ['98', '603', '181', '480', '174', '96', '79', '483', '408', '178']\n", 733 | "358 ['178', '285', '408', '657', '64', '641', '513', '528', '136', '189']\n", 734 | "352 ['513', '313', '189', '408', '483', '64', '272', '480', '963', '285']\n", 735 | "360 ['169', '114', '493', '408', '488', '1449', '487', '316', '603', '512']\n", 736 | "363 ['190', '478', '318', '661', '272', '83', '528', '445', '811', '305']\n", 737 | "355 ['474', '98', '603', '515', '480', '174', '483', '408', '127', '318']\n", 738 | "362 ['318', '169', '22', '64', '603', '483', '408', '124', '79', '14']\n", 739 | "357 ['302', '95', '603', '427', '480', '174', '514', '272', '172', '483']\n", 740 | "356 ['127', '56', '408', '169', '657', '963', '318', '64', '12', '100']\n", 741 | "361 ['134', '483', '127', '251', '318', '199', '169', '174', '480', '357']\n", 742 | "365 ['483', '192', '189', '513', '12', '428', '174', '173', '179', '50']\n", 743 | "350 ['318', '191', '178', '169', '488', '134', '513', '197', '963', '902']\n", 744 | "367 ['474', '603', '480', '174', '483', '408', '318', '89', '189', '64']\n", 745 | "368 ['64', '318', '168', '12', '963', '408', '603', '22', '169', '114']\n", 746 | "371 ['318', '169', '313', '408', '272', '178', '96', '205', '302', '427']\n", 747 | "373 ['408', '483', '272', '316', '478', '479', '429', '513', '646', '498']\n", 748 | "370 ['496', '169', '483', '251', '408', '963', '178', '479', '515', '313']\n", 749 | "374 ['313', '511', '136', '661', '528', '604', '523', '189', '215', '496']\n", 750 | "372 ['603', '515', '427', '480', '275', '498', '132', '479', '172', '483']\n", 751 | "337 ['272', '408', '512', '313', '316', '483', '523', '657', '170', '285']\n", 752 | "378 ['483', '515', '170', '114', '603', '427', '478', '657', '189', '408']\n", 753 | "366 ['302', '474', '603', '515', '480', '275', '174', '272', '298', '172']\n", 754 | "377 ['318', '64', '22', '12', '483', '174', '169', '657', '515', '603']\n", 755 | "375 ['408', '114', '318', '169', '64', '483', '98', '200', '178', '50']\n", 756 | "359 ['318', '169', '64', '173', '174', '178', '12', '114', '603', '210']\n", 757 | "379 ['318', '515', '114', '132', '493', '963', '657', '484', '483', '165']\n", 758 | "380 ['169', '408', '657', '484', '603', '641', '525', '275', '316', '178']\n", 759 | "381 ['114', '23', '169', '64', '603', '427', '242', '513', '185', '474']\n", 760 | "385 ['647', '60', '302', '856', '607', '519', '469', '223', '513', '248']\n", 761 | "382 ['178', '657', '60', '513', '189', '705', '603', '654', '83', '480']\n", 762 | "387 ['302', '276', '137', '497', '150', '493', '134', '275', '269', '272']\n", 763 | "364 ['318', '357', '483', '408', '480', '64', '657', '169', '251', '515']\n", 764 | "369 ['408', '12', '169', '483', '178', '474', '64', '89', '174', '480']\n", 765 | "388 ['603', '480', '483', '408', '318', '64', '169', '513', '963', '657']\n", 766 | "386 ['408', '654', '603', '318', '169', '64', '513', '12', '114', '89']\n", 767 | "389 ['114', '180', '12', '177', '528', '515', '272', '511', '137', '169']\n", 768 | "383 ['408', '318', '64', '169', '50', '98', '12', '251', '659', '172']\n", 769 | "390 ['408', '173', '513', '174', '64', '12', '483', '114', '178', '169']\n", 770 | "393 ['408', '300', '326', '251', '963', '1149', '603', '1019', '481', '429']\n", 771 | "392 ['603', '357', '483', '427', '124', '318', '100', '408', '153', '315']\n", 772 | "376 ['64', '483', '408', '169', '174', '318', '480', '12', '127', '22']\n", 773 | "394 ['64', '357', '318', '272', '408', '127', '114', '474', '316', '205']\n", 774 | "391 ['178', '654', '607', '408', '513', '192', '493', '251', '488', '114']\n", 775 | "398 ['318', '143', '22', '408', '657', '515', '963', '187', '313', '251']\n", 776 | "397 ['173', '187', '64', '89', '98', '48', '169', '114', '515', '234']\n", 777 | "399 ['408', '657', '515', '83', '478', '169', '512', '659', '479', '251']\n", 778 | "396 ['483', '64', '657', '480', '603', '285', '318', '12', '607', '512']\n", 779 | "401 ['30', '496', '178', '498', '607', '169', '170', '513', '694', '114']\n", 780 | "402 ['187', '318', '134', '170', '98', '114', '178', '484', '963', '656']\n", 781 | "384 ['174', '483', '408', '64', '199', '657', '480', '12', '114', '357']\n", 782 | "395 ['114', '408', '169', '963', '496', '357', '132', '427', '178', '511']\n", 783 | "353 ['169', '408', '603', '64', '483', '174', '657', '114', '56', '89']\n", 784 | "403 ['963', '603', '483', '657', '178', '89', '169', '479', '408', '661']\n", 785 | "405 ['144', '485', '487', '490', '1142', '936', '1189', '611', '459', '1137']\n", 786 | "400 ['114', '408', '169', '483', '50', '173', '172', '657', '174', '178']\n", 787 | "406 ['169', '408', '45', '653', '659', '530', '484', '189', '60', '114']\n", 788 | "407 ['318', '114', '513', '48', '124', '963', '654', '320', '511', '515']\n", 789 | "409 ['169', '408', '963', '488', '694', '1039', '114', '251', '124', '302']\n", 790 | "404 ['496', '178', '12', '64', '169', '318', '408', '8', '136', '251']\n", 791 | "413 ['318', '483', '64', '169', '408', '172', '178', '174', '316', '603']\n", 792 | "416 ['186', '170', '408', '487', '483', '193', '169', '478', '512', '59']\n", 793 | "408 ['178', '318', '641', '169', '480', '59', '136', '197', '483', '64']\n", 794 | "410 ['408', '98', '318', '357', '64', '496', '603', '169', '480', '483']\n", 795 | "411 ['511', '169', '357', '64', '480', '12', '114', '313', '483', '127']\n", 796 | "417 ['318', '22', '313', '205', '194', '87', '192', '641', '657', '520']\n", 797 | "412 ['12', '313', '272', '127', '176', '192', '657', '190', '98', '48']\n", 798 | "420 ['178', '318', '64', '483', '114', '511', '489', '480', '357', '169']\n", 799 | "422 ['408', '56', '169', '474', '493', '114', '318', '45', '64', '12']\n", 800 | "425 ['285', '408', '14', '512', '135', '513', '199', '137', '175', '663']\n", 801 | "419 ['169', '318', '272', '408', '114', '657', '64', '513', '512', '170']\n", 802 | "415 ['12', '64', '318', '50', '357', '96', '169', '285', '603', '408']\n", 803 | "423 ['169', '56', '318', '64', '89', '12', '178', '483', '603', '408']\n", 804 | "429 ['515', '187', '474', '657', '313', '302', '923', '963', '408', '641']\n", 805 | "428 ['127', '318', '64', '357', '12', '496', '98', '483', '178', '603']\n", 806 | "427 ['242', '474', '265', '95', '246', '98', '193', '194', '603', '1137']\n", 807 | "418 ['408', '64', '318', '515', '657', '9', '603', '483', '22', '173']\n", 808 | "424 ['64', '174', '98', '408', '603', '169', '481', '607', '199', '318']\n", 809 | "432 ['172', '318', '174', '427', '513', '657', '133', '199', '143', '64']\n", 810 | "421 ['408', '480', '169', '513', '272', '483', '313', '48', '515', '963']\n", 811 | "435 ['408', '272', '475', '114', '530', '251', '198', '150', '1449', '641']\n", 812 | "433 ['98', '199', '408', '483', '513', '169', '427', '480', '511', '64']\n", 813 | "426 ['169', '408', '963', '64', '89', '923', '12', '114', '48', '615']\n", 814 | "436 ['408', '641', '474', '523', '1019', '169', '69', '64', '12', '272']\n", 815 | "430 ['513', '169', '408', '251', '316', '272', '197', '178', '187', '483']\n", 816 | "434 ['174', '313', '114', '187', '64', '285', '357', '82', '172', '178']\n", 817 | "437 ['127', '427', '187', '178', '57', '510', '498', '136', '661', '114']\n", 818 | "438 ['174', '96', '272', '313', '136', '12', '408', '657', '114', '178']\n", 819 | "431 ['64', '318', '174', '169', '251', '272', '408', '114', '483', '50']\n", 820 | "442 ['408', '114', '178', '127', '285', '183', '357', '200', '475', '50']\n", 821 | "440 ['474', '98', '427', '480', '23', '483', '408', '127', '318', '56']\n", 822 | "445 ['318', '185', '178', '641', '187', '134', '427', '180', '483', '496']\n", 823 | "447 ['114', '169', '64', '408', '172', '173', '127', '187', '194', '196']\n", 824 | "449 ['474', '408', '134', '169', '50', '185', '180', '511', '178', '654']\n", 825 | "450 ['513', '198', '189', '1007', '156', '963', '320', '408', '515', '8']\n", 826 | "446 ['408', '64', '357', '318', '313', '114', '127', '603', '12', '511']\n", 827 | "439 ['480', '12', '318', '178', '169', '174', '483', '496', '64', '657']\n", 828 | "451 ['12', '174', '22', '82', '313', '210', '173', '64', '117', '480']\n", 829 | "452 ['169', '657', '1131', '408', '28', '524', '699', '604', '511', '313']\n", 830 | "454 ['251', '1137', '187', '170', '408', '963', '863', '186', '744', '19']\n", 831 | "453 ['474', '64', '169', '484', '480', '483', '176', '127', '89', '434']\n", 832 | "414 ['127', '56', '89', '12', '156', '318', '357', '169', '134', '513']\n", 833 | "455 ['408', '169', '603', '194', '302', '480', '427', '190', '272', '114']\n", 834 | "444 ['127', '12', '318', '191', '195', '474', '173', '408', '64', '185']\n", 835 | "448 ['127', '408', '169', '100', '50', '187', '192', '480', '114', '474']\n", 836 | "457 ['408', '187', '313', '603', '963', '657', '480', '513', '496', '750']\n", 837 | "456 ['285', '408', '661', '169', '178', '513', '276', '428', '512', '275']\n", 838 | "458 ['480', '511', '479', '185', '528', '657', '89', '963', '923', '856']\n", 839 | "462 ['408', '318', '64', '96', '172', '174', '132', '316', '191', '169']\n", 840 | "459 ['96', '408', '313', '272', '12', '513', '176', '315', '483', '316']\n", 841 | "460 ['357', '474', '483', '318', '408', '197', '427', '178', '64', '98']\n", 842 | "461 ['134', '318', '483', '56', '178', '603', '169', '513', '64', '1194']\n", 843 | "467 ['318', '357', '56', '178', '513', '408', '479', '603', '515', '64']\n", 844 | "468 ['513', '527', '302', '923', '313', '114', '1142', '134', '483', '408']\n", 845 | "466 ['318', '603', '64', '191', '511', '524', '408', '251', '114', '12']\n", 846 | "472 ['302', '474', '512', '480', '317', '750', '479', '272', '61', '48']\n", 847 | "465 ['251', '9', '302', '657', '519', '479', '1449', '515', '165', '124']\n", 848 | "463 ['318', '357', '191', '174', '603', '178', '515', '513', '496', '427']\n", 849 | "471 ['313', '318', '28', '64', '520', '515', '251', '174', '408', '127']\n", 850 | "474 ['156', '114', '408', '1142', '169', '272', '694', '144', '129', '251']\n", 851 | "469 ['318', '169', '89', '316', '963', '408', '488', '251', '22', '187']\n", 852 | "464 ['272', '318', '64', '199', '178', '56', '169', '611', '513', '480']\n", 853 | "476 ['64', '114', '98', '318', '50', '313', '169', '408', '136', '199']\n", 854 | "478 ['127', '174', '316', '251', '603', '272', '313', '408', '483', '515']\n", 855 | "473 ['408', '100', '89', '169', '272', '12', '114', '318', '178', '98']\n", 856 | "470 ['127', '408', '963', '427', '474', '64', '302', '480', '269', '320']\n", 857 | "480 ['513', '408', '357', '318', '1142', '427', '694', '173', '134', '657']\n", 858 | "441 ['169', '480', '318', '408', '513', '511', '50', '357', '479', '483']\n", 859 | "479 ['114', '519', '178', '64', '12', '484', '223', '654', '132', '494']\n", 860 | "484 ['511', '169', '64', '513', '12', '483', '520', '604', '178', '114']\n", 861 | "486 ['318', '511', '134', '357', '116', '480', '64', '483', '427', '513']\n", 862 | "487 ['408', '177', '251', '923', '198', '316', '523', '1039', '603', '228']\n", 863 | "482 ['199', '483', '408', '12', '923', '603', '169', '272', '251', '64']\n", 864 | "481 ['511', '408', '169', '483', '496', '174', '603', '480', '694', '515']\n", 865 | "492 ['357', '180', '8', '12', '79', '484', '427', '114', '50', '313']\n", 866 | "493 ['408', '169', '313', '709', '520', '8', '83', '478', '604', '661']\n", 867 | "490 ['408', '114', '357', '169', '185', '223', '190', '178', '496', '474']\n", 868 | "489 ['603', '480', '408', '12', '22', '127', '50', '483', '223', '484']\n", 869 | "483 ['408', '169', '114', '483', '478', '64', '519', '172', '178', '196']\n", 870 | "496 ['408', '12', '529', '474', '272', '169', '963', '511', '357', '488']\n", 871 | "494 ['313', '318', '302', '187', '22', '173', '114', '12', '493', '272']\n", 872 | "495 ['408', '169', '223', '124', '923', '180', '177', '316', '604', '285']\n", 873 | "477 ['302', '474', '265', '144', '1', '95', '98', '193', '603', '1137']\n", 874 | "497 ['357', '318', '64', '313', '480', '199', '513', '478', '272', '166']\n", 875 | "488 ['313', '408', '615', '169', '194', '603', '165', '251', '121', '166']\n", 876 | "498 ['357', '114', '408', '178', '513', '428', '318', '654', '199', '511']\n", 877 | "499 ['923', '316', '178', '1194', '515', '496', '203', '134', '498', '242']\n", 878 | "491 ['64', '174', '272', '318', '427', '50', '313', '963', '251', '178']\n", 879 | "500 ['647', '512', '114', '474', '1449', '357', '654', '530', '603', '187']\n", 880 | "502 ['318', '12', '64', '50', '11', '114', '173', '408', '1019', '603']\n", 881 | "503 ['178', '169', '483', '258', '114', '251', '242', '208', '480', '408']\n", 882 | "504 ['302', '923', '408', '22', '657', '659', '524', '589', '963', '190']\n", 883 | "505 ['318', '143', '923', '603', '1194', '408', '483', '15', '963', '216']\n", 884 | "506 ['313', '144', '22', '318', '64', '127', '480', '526', '192', '483']\n", 885 | "443 ['318', '408', '169', '64', '50', '316', '190', '272', '427', '498']\n", 886 | "507 ['242', '346', '474', '265', '86', '392', '486', '144', '1', '246']\n", 887 | "514 ['1007', '657', '251', '513', '963', '478', '498', '223', '1142', '316']\n", 888 | "508 ['483', '606', '657', '178', '127', '313', '607', '499', '12', '302']\n", 889 | "511 ['302', '480', '318', '483', '427', '963', '357', '134', '127', '178']\n", 890 | "515 ['12', '178', '64', '408', '318', '114', '320', '272', '923', '963']\n", 891 | "512 ['474', '408', '657', '480', '98', '64', '357', '513', '169', '12']\n", 892 | "513 ['302', '474', '98', '603', '515', '427', '165', '480', '132', '174']\n", 893 | "475 ['603', '169', '483', '474', '178', '12', '408', '923', '479', '515']\n", 894 | "523 ['98', '603', '1137', '480', '498', '174', '172', '483', '178', '318']\n", 895 | "518 ['313', '172', '64', '483', '12', '194', '515', '318', '98', '178']\n", 896 | "509 ['408', '12', '173', '183', '114', '64', '474', '316', '483', '89']\n", 897 | "516 ['483', '114', '134', '408', '603', '498', '513', '64', '480', '487']\n", 898 | "510 ['12', '50', '181', '64', '172', '408', '318', '272', '174', '173']\n", 899 | "524 ['923', '169', '11', '853', '694', '114', '963', '512', '659', '524']\n", 900 | "501 ['408', '114', '169', '357', '64', '190', '318', '511', '12', '515']\n", 901 | "525 ['178', '318', '963', '64', '657', '98', '483', '12', '316', '480']\n", 902 | "521 ['318', '408', '64', '169', '513', '603', '478', '190', '357', '923']\n", 903 | "520 ['50', '318', '174', '496', '64', '191', '408', '22', '12', '194']\n", 904 | "519 ['242', '302', '474', '98', '194', '603', '1137', '515', '427', '512']\n", 905 | "528 ['169', '318', '408', '511', '114', '98', '515', '257', '603', '205']\n", 906 | "532 ['144', '174', '408', '69', '705', '64', '611', '192', '170', '89']\n", 907 | "530 ['12', '408', '169', '318', '603', '30', '480', '114', '515', '200']\n", 908 | "531 ['187', '174', '169', '173', '511', '127', '483', '50', '318', '22']\n", 909 | "529 ['187', '178', '408', '127', '205', '64', '313', '511', '50', '114']\n", 910 | "517 ['408', '173', '169', '132', '511', '318', '190', '488', '191', '114']\n", 911 | "527 ['656', '484', '654', '480', '178', '408', '199', '488', '510', '98']\n", 912 | "485 ['480', '511', '134', '603', '483', '169', '114', '127', '408', '427']\n", 913 | "533 ['173', '79', '251', '923', '170', '166', '604', '178', '963', '316']\n", 914 | "535 ['408', '659', '169', '251', '12', '124', '114', '191', '320', '490']\n", 915 | "536 ['187', '313', '64', '114', '316', '272', '315', '127', '429', '1137']\n", 916 | "526 ['318', '483', '515', '921', '114', '169', '427', '657', '603', '654']\n", 917 | "537 ['169', '114', '611', '154', '165', '1449', '223', '9', '8', '408']\n", 918 | "534 ['603', '143', '515', '480', '479', '272', '483', '408', '178', '318']\n", 919 | "541 ['169', '178', '114', '408', '64', '318', '480', '357', '191', '98']\n", 920 | "538 ['408', '169', '603', '64', '178', '480', '657', '251', '513', '357']\n", 921 | "542 ['114', '169', '134', '178', '483', '98', '480', '285', '529', '408']\n", 922 | "545 ['408', '12', '316', '529', '483', '272', '313', '169', '320', '963']\n", 923 | "539 ['114', '479', '178', '657', '318', '134', '427', '302', '169', '513']\n", 924 | "547 ['64', '318', '127', '50', '178', '427', '483', '114', '182', '170']\n", 925 | "543 ['178', '483', '285', '657', '484', '488', '511', '641', '127', '512']\n", 926 | "548 ['963', '524', '511', '174', '223', '22', '661', '1019', '169', '408']\n", 927 | "546 ['432', '165', '480', '174', '96', '479', '483', '408', '318', '169']\n", 928 | "522 ['127', '285', '603', '64', '408', '963', '169', '483', '174', '657']\n", 929 | "551 ['175', '60', '654', '750', '481', '736', '641', '694', '589', '513']\n", 930 | "544 ['127', '174', '50', '408', '64', '12', '22', '318', '173', '511']\n", 931 | "553 ['408', '529', '114', '285', '12', '357', '512', '1449', '302', '64']\n", 932 | "552 ['169', '408', '318', '64', '480', '483', '22', '174', '272', '251']\n", 933 | "540 ['127', '318', '408', '64', '357', '169', '251', '12', '480', '285']\n", 934 | "554 ['64', '603', '483', '408', '513', '480', '694', '520', '251', '357']\n", 935 | "550 ['64', '187', '318', '408', '12', '480', '963', '127', '657', '427']\n", 936 | "556 ['185', '483', '320', '28', '480', '316', '963', '651', '197', '169']\n", 937 | "559 ['357', '114', '496', '483', '189', '657', '83', '169', '59', '251']\n", 938 | "560 ['64', '172', '408', '285', '174', '272', '313', '513', '56', '114']\n", 939 | "561 ['169', '127', '114', '134', '408', '192', '275', '1007', '647', '528']\n", 940 | "563 ['12', '318', '408', '64', '127', '187', '357', '114', '603', '272']\n", 941 | "566 ['190', '187', '663', '357', '200', '180', '9', '185', '654', '641']\n", 942 | "557 ['178', '318', '483', '64', '87', '251', '19', '169', '408', '488']\n", 943 | "558 ['318', '64', '114', '127', '483', '169', '408', '603', '302', '480']\n", 944 | "564 ['64', '318', '191', '408', '483', '603', '963', '1137', '178', '498']\n", 945 | "565 ['603', '480', '479', '483', '408', '178', '318', '357', '169', '12']\n", 946 | "573 ['169', '318', '64', '408', '603', '56', '12', '483', '272', '316']\n", 947 | "549 ['408', '64', '169', '318', '603', '134', '190', '657', '114', '963']\n", 948 | "567 ['169', '408', '512', '275', '656', '114', '200', '320', '707', '180']\n", 949 | "569 ['318', '98', '515', '513', '657', '174', '408', '191', '132', '178']\n", 950 | "562 ['515', '22', '64', '496', '423', '657', '269', '12', '481', '963']\n", 951 | "576 ['174', '22', '64', '480', '483', '408', '183', '194', '87', '178']\n", 952 | "577 ['169', '408', '1019', '189', '923', '170', '483', '223', '647', '178']\n", 953 | "579 ['318', '483', '191', '64', '174', '515', '22', '657', '114', '132']\n", 954 | "574 ['408', '169', '657', '515', '86', '513', '12', '603', '190', '519']\n", 955 | "555 ['496', '174', '64', '170', '12', '603', '408', '127', '272', '515']\n", 956 | "572 ['515', '408', '98', '169', '483', '64', '83', '318', '657', '357']\n", 957 | "575 ['515', '169', '178', '136', '190', '408', '272', '170', '114', '22']\n", 958 | "584 ['64', '483', '408', '178', '318', '169', '98', '127', '498', '963']\n", 959 | "588 ['479', '197', '963', '661', '1103', '603', '487', '190', '300', '486']\n", 960 | "587 ['169', '98', '483', '114', '12', '408', '192', '474', '199', '482']\n", 961 | "568 ['318', '316', '64', '408', '169', '190', '251', '272', '12', '969']\n", 962 | "586 ['316', '64', '272', '12', '408', '480', '251', '315', '313', '300']\n", 963 | "585 ['64', '318', '603', '408', '12', '9', '272', '487', '251', '657']\n", 964 | "582 ['408', '127', '169', '511', '114', '180', '654', '318', '474', '135']\n", 965 | "591 ['318', '114', '408', '98', '515', '178', '169', '657', '512', '315']\n", 966 | "581 ['318', '169', '178', '408', '251', '89', '488', '190', '923', '12']\n", 967 | "592 ['156', '474', '515', '493', '506', '530', '1449', '152', '316', '114']\n", 968 | "580 ['408', '114', '169', '474', '480', '178', '318', '64', '98', '196']\n", 969 | "590 ['408', '318', '169', '483', '357', '64', '513', '694', '98', '197']\n", 970 | "593 ['205', '169', '114', '64', '22', '512', '12', '408', '484', '208']\n", 971 | "583 ['603', '98', '302', '56', '474', '64', '408', '318', '484', '197']\n", 972 | "596 ['318', '408', '172', '174', '22', '64', '513', '169', '357', '178']\n", 973 | "570 ['169', '483', '318', '511', '603', '178', '528', '114', '496', '408']\n", 974 | "599 ['196', '174', '172', '408', '178', '318', '64', '173', '50', '189']\n", 975 | "589 ['408', '169', '64', '86', '480', '83', '114', '22', '657', '318']\n", 976 | "594 ['318', '169', '59', '657', '64', '408', '190', '114', '923', '12']\n", 977 | "597 ['318', '178', '1194', '12', '132', '483', '89', '357', '480', '657']\n", 978 | "578 ['480', '22', '357', '199', '408', '64', '12', '178', '483', '603']\n", 979 | "601 ['169', '114', '89', '408', '474', '647', '190', '175', '641', '134']\n", 980 | "602 ['178', '318', '357', '64', '427', '483', '408', '513', '114', '480']\n", 981 | "600 ['114', '408', '474', '134', '603', '100', '64', '169', '480', '12']\n", 982 | "605 ['474', '515', '169', '134', '199', '56', '178', '114', '179', '480']\n", 983 | "603 ['169', '178', '114', '483', '316', '318', '408', '709', '603', '64']\n", 984 | "595 ['56', '357', '318', '64', '12', '408', '98', '515', '178', '135']\n", 985 | "606 ['318', '515', '169', '408', '603', '606', '199', '487', '657', '251']\n", 986 | "608 ['242', '200', '169', '515', '482', '189', '251', '170', '178', '408']\n", 987 | "607 ['515', '169', '318', '127', '12', '98', '187', '223', '168', '603']\n", 988 | "610 ['302', '657', '513', '134', '208', '285', '357', '178', '23', '654']\n", 989 | "611 ['318', '170', '178', '513', '483', '12', '251', '603', '64', '357']\n", 990 | "617 ['511', '479', '483', '180', '32', '169', '23', '484', '966', '285']\n", 991 | "618 ['357', '603', '134', '194', '251', '520', '480', '527', '482', '963']\n", 992 | "614 ['408', '169', '1019', '12', '654', '114', '474', '603', '189', '513']\n", 993 | "609 ['318', '178', '50', '64', '169', '427', '89', '174', '483', '114']\n", 994 | "615 ['483', '511', '318', '172', '169', '285', '98', '134', '484', '50']\n", 995 | "616 ['357', '483', '12', '480', '318', '56', '64', '169', '127', '474']\n", 996 | "620 ['483', '408', '64', '169', '114', '657', '178', '318', '515', '641']\n", 997 | "571 ['318', '515', '408', '178', '189', '483', '170', '169', '22', '132']\n", 998 | "619 ['1137', '64', '480', '169', '511', '87', '408', '483', '204', '963']\n", 999 | "613 ['408', '178', '169', '474', '357', '251', '183', '496', '98', '1449']\n", 1000 | "622 ['357', '318', '1449', '114', '186', '313', '513', '272', '205', '192']\n", 1001 | "621 ['169', '408', '98', '114', '56', '199', '357', '474', '511', '923']\n", 1002 | "604 ['50', '318', '172', '511', '181', '483', '285', '132', '489', '187']\n", 1003 | "624 ['12', '515', '64', '174', '98', '173', '172', '114', '408', '657']\n", 1004 | "612 ['483', '318', '169', '98', '114', '513', '136', '189', '408', '515']\n", 1005 | "627 ['173', '169', '209', '408', '483', '963', '272', '512', '114', '127']\n", 1006 | "623 ['408', '169', '318', '64', '174', '172', '199', '480', '12', '479']\n", 1007 | "628 ['474', '95', '98', '194', '603', '1137', '143', '515', '526', '427']\n", 1008 | "625 ['64', '272', '318', '205', '316', '474', '124', '223', '98', '313']\n", 1009 | "629 ['313', '169', '408', '134', '48', '318', '483', '1142', '192', '272']\n", 1010 | "633 ['178', '64', '480', '174', '12', '659', '251', '481', '210', '735']\n", 1011 | "632 ['178', '169', '496', '251', '187', '427', '190', '408', '659', '114']\n", 1012 | "631 ['408', '515', '170', '285', '427', '64', '114', '12', '513', '169']\n", 1013 | "634 ['187', '114', '318', '64', '205', '357', '168', '166', '56', '12']\n", 1014 | "639 ['318', '64', '479', '480', '133', '169', '408', '485', '603', '606']\n", 1015 | "630 ['408', '316', '1194', '313', '136', '189', '318', '169', '921', '114']\n", 1016 | "642 ['194', '408', '270', '169', '481', '275', '199', '57', '1149', '851']\n", 1017 | "637 ['22', '313', '318', '69', '174', '483', '265', '8', '64', '173']\n", 1018 | "640 ['603', '427', '480', '483', '408', '178', '127', '89', '654', '511']\n", 1019 | "626 ['318', '169', '64', '603', '483', '493', '657', '320', '427', '408']\n", 1020 | "643 ['513', '135', '285', '178', '134', '191', '272', '124', '318', '480']\n", 1021 | "598 ['318', '251', '174', '50', '513', '172', '357', '96', '64', '178']\n", 1022 | "638 ['318', '64', '178', '69', '12', '408', '15', '316', '427', '251']\n", 1023 | "635 ['169', '318', '114', '134', '98', '694', '513', '519', '182', '483']\n", 1024 | "644 ['169', '12', '923', '313', '64', '272', '223', '408', '22', '318']\n", 1025 | "636 ['603', '515', '480', '172', '483', '408', '318', '64', '357', '199']\n", 1026 | "645 ['114', '178', '603', '169', '657', '480', '285', '127', '515', '190']\n", 1027 | "648 ['313', '963', '258', '114', '480', '659', '257', '607', '494', '282']\n", 1028 | "647 ['114', '483', '318', '169', '64', '313', '12', '487', '178', '480']\n", 1029 | "650 ['114', '12', '408', '169', '318', '165', '45', '302', '83', '513']\n", 1030 | "651 ['98', '114', '408', '657', '50', '64', '135', '357', '318', '483']\n", 1031 | "654 ['96', '64', '427', '604', '378', '705', '429', '190', '316', '99']\n", 1032 | "653 ['408', '963', '12', '169', '285', '1137', '430', '529', '190', '483']\n", 1033 | "655 ['169', '114', '199', '641', '408', '482', '136', '648', '510', '189']\n", 1034 | "649 ['318', '114', '357', '515', '512', '98', '657', '474', '519', '484']\n", 1035 | "658 ['316', '513', '641', '272', '483', '64', '170', '357', '12', '174']\n", 1036 | "656 ['318', '178', '357', '498', '114', '185', '132', '169', '480', '511']\n", 1037 | "660 ['12', '127', '511', '199', '187', '963', '169', '223', '185', '171']\n", 1038 | "659 ['318', '480', '427', '12', '223', '515', '190', '615', '165', '169']\n", 1039 | "646 ['483', '114', '169', '408', '479', '603', '136', '172', '178', '657']\n", 1040 | "663 ['408', '114', '641', '168', '513', '166', '504', '527', '633', '285']\n", 1041 | "664 ['185', '474', '178', '511', '114', '48', '320', '641', '205', '515']\n", 1042 | "657 ['169', '408', '318', '174', '178', '603', '179', '165', '515', '479']\n", 1043 | "665 ['272', '318', '408', '178', '64', '169', '606', '316', '479', '478']\n", 1044 | "666 ['408', '9', '242', '1449', '316', '589', '178', '488', '524', '285']\n", 1045 | "661 ['483', '513', '12', '127', '251', '1449', '511', '651', '98', '114']\n", 1046 | "662 ['603', '180', '199', '483', '484', '169', '114', '251', '654', '318']\n", 1047 | "667 ['408', '169', '603', '64', '12', '251', '170', '89', '114', '178']\n", 1048 | "641 ['170', '318', '114', '12', '357', '529', '661', '127', '480', '316']\n", 1049 | "668 ['114', '89', '12', '487', '474', '199', '357', '178', '169', '135']\n", 1050 | "673 ['408', '483', '603', '511', '64', '169', '357', '174', '480', '8']\n", 1051 | "671 ['95', '143', '64', '272', '434', '651', '408', '483', '169', '170']\n", 1052 | "669 ['170', '318', '487', '178', '242', '651', '419', '116', '661', '489']\n", 1053 | "676 ['199', '210', '357', '511', '484', '408', '513', '180', '203', '498']\n", 1054 | "674 ['64', '169', '98', '487', '408', '136', '318', '603', '357', '483']\n", 1055 | "652 ['56', '313', '318', '603', '178', '169', '408', '187', '127', '136']\n", 1056 | "677 ['12', '89', '199', '313', '114', '524', '223', '168', '64', '11']\n", 1057 | "682 ['483', '199', '408', '169', '316', '921', '313', '198', '189', '923']\n", 1058 | "679 ['127', '515', '474', '657', '178', '114', '187', '191', '408', '511']\n", 1059 | "684 ['318', '603', '313', '169', '174', '511', '498', '22', '478', '272']\n", 1060 | "685 ['100', '178', '483', '64', '963', '408', '187', '12', '603', '169']\n", 1061 | "683 ['519', '178', '357', '479', '603', '484', '483', '114', '488', '408']\n", 1062 | "691 ['515', '487', '357', '190', '408', '114', '191', '173', '488', '169']\n", 1063 | "672 ['178', '483', '408', '169', '98', '513', '89', '114', '189', '357']\n", 1064 | "692 ['50', '169', '483', '172', '114', '408', '178', '181', '357', '511']\n", 1065 | "690 ['97', '318', '50', '480', '408', '483', '603', '114', '251', '176']\n", 1066 | "689 ['228', '169', '511', '483', '12', '89', '64', '408', '318', '603']\n", 1067 | "686 ['100', '515', '483', '408', '169', '190', '511', '114', '223', '489']\n", 1068 | "693 ['515', '165', '493', '408', '513', '657', '923', '1143', '251', '474']\n", 1069 | "688 ['242', '51', '474', '265', '86', '257', '486', '144', '1', '246']\n", 1070 | "697 ['603', '483', '178', '89', '169', '168', '511', '114', '694', '172']\n", 1071 | "698 ['408', '313', '64', '318', '114', '12', '519', '1007', '136', '251']\n", 1072 | "670 ['513', '963', '408', '172', '178', '169', '64', '313', '318', '22']\n", 1073 | "694 ['64', '408', '114', '251', '513', '169', '272', '79', '651', '96']\n", 1074 | "680 ['12', '483', '603', '89', '963', '56', '223', '178', '272', '127']\n", 1075 | "705 ['524', '408', '607', '487', '603', '480', '136', '430', '835', '315']\n", 1076 | "701 ['480', '408', '657', '169', '513', '483', '114', '479', '474', '178']\n", 1077 | "699 ['408', '169', '178', '661', '513', '483', '251', '1194', '313', '114']\n", 1078 | "704 ['64', '169', '251', '483', '515', '79', '114', '357', '531', '694']\n", 1079 | "707 ['512', '408', '657', '513', '652', '223', '1137', '114', '357', '178']\n", 1080 | "700 ['178', '483', '170', '172', '408', '114', '498', '313', '1137', '272']\n", 1081 | "687 ['408', '169', '483', '603', '172', '50', '114', '511', '178', '498']\n", 1082 | "695 ['169', '474', '183', '408', '179', '178', '114', '483', '654', '98']\n", 1083 | "675 ['408', '178', '603', '22', '180', '197', '132', '511', '430', '83']\n", 1084 | "708 ['174', '64', '169', '172', '318', '12', '357', '603', '144', '79']\n", 1085 | "709 ['408', '480', '963', '251', '736', '496', '169', '521', '357', '923']\n", 1086 | "711 ['9', '474', '515', '657', '178', '14', '479', '357', '57', '709']\n", 1087 | "710 ['480', '178', '98', '474', '408', '511', '169', '170', '513', '114']\n", 1088 | "712 ['22', '318', '300', '272', '429', '12', '133', '408', '64', '169']\n", 1089 | "715 ['357', '169', '178', '515', '316', '483', '705', '527', '166', '408']\n", 1090 | "713 ['408', '127', '169', '474', '50', '114', '178', '480', '187', '357']\n", 1091 | "716 ['302', '12', '313', '165', '170', '114', '57', '657', '923', '607']\n", 1092 | "681 ['408', '169', '50', '180', '603', '114', '483', '923', '474', '480']\n", 1093 | "678 ['114', '64', '357', '318', '302', '480', '408', '169', '223', '483']\n", 1094 | "719 ['173', '169', '408', '963', '515', '12', '197', '657', '178', '496']\n", 1095 | "702 ['169', '408', '511', '50', '114', '59', '127', '963', '187', '223']\n", 1096 | "721 ['210', '496', '169', '79', '963', '251', '96', '190', '408', '313']\n", 1097 | "714 ['408', '483', '963', '169', '496', '190', '172', '83', '12', '96']\n", 1098 | "717 ['923', '178', '318', '603', '199', '136', '966', '657', '483', '519']\n", 1099 | "718 ['50', '511', '408', '191', '170', '603', '318', '169', '661', '483']\n", 1100 | "696 ['318', '64', '98', '127', '408', '56', '12', '272', '100', '659']\n", 1101 | "722 ['408', '647', '50', '357', '511', '483', '661', '192', '199', '963']\n", 1102 | "724 ['173', '127', '12', '187', '174', '50', '64', '176', '89', '408']\n", 1103 | "727 ['318', '190', '272', '64', '313', '479', '519', '1007', '193', '493']\n", 1104 | "725 ['318', '169', '480', '190', '64', '603', '79', '408', '641', '513']\n", 1105 | "706 ['172', '174', '318', '496', '169', '64', '170', '963', '513', '408']\n", 1106 | "720 ['318', '64', '169', '408', '114', '190', '483', '50', '98', '181']\n", 1107 | "729 ['408', '64', '59', '114', '963', '169', '194', '98', '923', '50']\n", 1108 | "726 ['318', '515', '50', '98', '64', '408', '174', '178', '169', '480']\n", 1109 | "728 ['408', '114', '12', '64', '318', '169', '172', '190', '173', '272']\n", 1110 | "703 ['174', '64', '172', '483', '408', '22', '313', '1137', '12', '511']\n", 1111 | "738 ['272', '513', '114', '694', '1137', '483', '187', '657', '641', '165']\n", 1112 | "736 ['56', '64', '169', '357', '408', '114', '98', '318', '285', '427']\n", 1113 | "734 ['923', '657', '408', '963', '127', '302', '114', '189', '512', '196']\n", 1114 | "730 ['169', '318', '657', '64', '603', '12', '127', '170', '136', '251']\n", 1115 | "743 ['127', '178', '513', '357', '187', '285', '493', '318', '169', '174']\n", 1116 | "742 ['169', '603', '513', '408', '192', '511', '134', '483', '318', '9']\n", 1117 | "737 ['408', '114', '515', '98', '134', '135', '168', '480', '647', '269']\n", 1118 | "733 ['318', '483', '357', '178', '187', '479', '197', '427', '511', '923']\n", 1119 | "745 ['318', '357', '56', '408', '83', '528', '661', '136', '173', '251']\n", 1120 | "740 ['318', '169', '408', '483', '474', '427', '316', '513', '498', '64']\n", 1121 | "735 ['318', '114', '408', '169', '357', '172', '64', '12', '483', '480']\n", 1122 | "747 ['114', '191', '42', '647', '484', '589', '528', '515', '513', '641']\n", 1123 | "723 ['408', '64', '479', '480', '963', '12', '483', '318', '427', '511']\n", 1124 | "739 ['174', '408', '64', '89', '512', '513', '169', '199', '285', '228']\n", 1125 | "749 ['12', '923', '408', '318', '963', '588', '269', '97', '515', '611']\n", 1126 | "748 ['272', '12', '285', '127', '513', '313', '178', '963', '190', '251']\n", 1127 | "746 ['318', '12', '169', '69', '496', '195', '313', '173', '251', '480']\n", 1128 | "731 ['174', '98', '318', '178', '408', '657', '651', '530', '515', '193']\n", 1129 | "750 ['178', '98', '172', '318', '515', '357', '50', '483', '136', '657']\n", 1130 | "741 ['12', '474', '127', '483', '318', '302', '114', '408', '89', '484']\n", 1131 | "751 ['132', '318', '496', '357', '963', '285', '513', '427', '408', '22']\n", 1132 | "756 ['313', '189', '114', '483', '357', '12', '169', '318', '511', '498']\n", 1133 | "757 ['318', '408', '12', '963', '114', '178', '603', '127', '285', '483']\n", 1134 | "752 ['496', '83', '657', '98', '180', '654', '318', '603', '478', '498']\n", 1135 | "758 ['515', '178', '318', '357', '114', '9', '408', '493', '187', '1020']\n", 1136 | "732 ['127', '318', '64', '169', '302', '408', '654', '59', '114', '480']\n", 1137 | "762 ['50', '318', '269', '185', '603', '100', '172', '127', '408', '641']\n", 1138 | "744 ['12', '170', '169', '272', '408', '187', '318', '496', '511', '134']\n", 1139 | "754 ['408', '169', '114', '59', '483', '64', '515', '178', '50', '496']\n", 1140 | "753 ['318', '178', '603', '100', '197', '479', '480', '169', '136', '659']\n", 1141 | "763 ['474', '169', '272', '114', '134', '657', '709', '269', '408', '512']\n", 1142 | "764 ['316', '513', '520', '408', '519', '192', '427', '603', '315', '170']\n", 1143 | "767 ['64', '50', '114', '169', '134', '178', '318', '480', '408', '511']\n", 1144 | "769 ['114', '169', '100', '357', '318', '134', '603', '408', '12', '89']\n", 1145 | "755 ['318', '178', '357', '190', '56', '313', '187', '127', '169', '408']\n", 1146 | "771 ['12', '479', '178', '483', '183', '64', '272', '921', '89', '316']\n", 1147 | "768 ['172', '190', '408', '12', '64', '511', '174', '191', '169', '318']\n", 1148 | "773 ['114', '483', '474', '511', '48', '285', '135', '134', '484', '480']\n", 1149 | "765 ['318', '178', '169', '483', '132', '511', '64', '114', '197', '357']\n", 1150 | "772 ['603', '174', '408', '127', '64', '22', '357', '170', '12', '511']\n", 1151 | "766 ['56', '114', '190', '475', '488', '12', '251', '1449', '223', '1137']\n", 1152 | "774 ['114', '474', '694', '169', '462', '408', '483', '268', '484', '285']\n", 1153 | "760 ['64', '512', '174', '114', '357', '178', '603', '134', '408', '143']\n", 1154 | "761 ['318', '498', '604', '265', '22', '357', '169', '963', '114', '178']\n", 1155 | "777 ['316', '64', '178', '114', '318', '408', '498', '513', '136', '96']\n", 1156 | "759 ['318', '64', '12', '96', '483', '79', '169', '22', '69', '480']\n", 1157 | "776 ['408', '114', '302', '170', '169', '172', '100', '528', '197', '313']\n", 1158 | "780 ['64', '251', '483', '480', '1', '651', '169', '205', '181', '272']\n", 1159 | "779 ['318', '408', '496', '169', '64', '127', '12', '603', '83', '479']\n", 1160 | "778 ['169', '408', '603', '302', '64', '182', '318', '12', '199', '427']\n", 1161 | "782 ['408', '22', '64', '174', '12', '96', '195', '210', '187', '498']\n", 1162 | "786 ['64', '603', '251', '12', '22', '513', '408', '170', '272', '316']\n", 1163 | "784 ['408', '603', '318', '127', '963', '12', '178', '483', '114', '64']\n", 1164 | "770 ['194', '603', '515', '512', '479', '272', '483', '408', '178', '127']\n", 1165 | "788 ['313', '170', '603', '515', '127', '408', '169', '1137', '48', '242']\n", 1166 | "789 ['64', '12', '408', '285', '641', '178', '114', '251', '357', '603']\n", 1167 | "790 ['318', '272', '315', '480', '114', '169', '408', '357', '498', '474']\n", 1168 | "787 ['408', '496', '169', '50', '318', '190', '483', '174', '114', '194']\n", 1169 | "783 ['474', '483', '408', '178', '64', '484', '199', '169', '251', '511']\n", 1170 | "785 ['357', '408', '114', '169', '302', '641', '316', '98', '45', '480']\n", 1171 | "794 ['474', '483', '408', '178', '318', '114', '603', '657', '12', '357']\n", 1172 | "781 ['511', '408', '199', '168', '169', '963', '12', '484', '114', '479']\n", 1173 | "796 ['170', '408', '136', '148', '963', '1193', '11', '519', '523', '1137']\n", 1174 | "795 ['127', '56', '603', '223', '408', '114', '302', '64', '474', '9']\n", 1175 | "793 ['169', '408', '251', '318', '313', '172', '496', '98', '173', '603']\n", 1176 | "798 ['313', '300', '641', '12', '385', '169', '604', '316', '483', '22']\n", 1177 | "791 ['408', '114', '318', '64', '172', '178', '285', '169', '515', '483']\n", 1178 | "802 ['64', '313', '12', '174', '318', '172', '480', '178', '496', '251']\n", 1179 | "800 ['408', '169', '318', '64', '603', '199', '483', '513', '114', '657']\n", 1180 | "804 ['169', '408', '190', '178', '223', '114', '484', '251', '607', '12']\n", 1181 | "803 ['169', '100', '515', '357', '483', '603', '474', '513', '408', '318']\n", 1182 | "775 ['56', '64', '114', '357', '169', '318', '251', '408', '513', '474']\n", 1183 | "792 ['318', '64', '114', '169', '427', '480', '657', '251', '178', '483']\n", 1184 | "799 ['64', '408', '318', '114', '272', '169', '134', '178', '357', '483']\n", 1185 | "805 ['114', '919', '171', '896', '275', '302', '201', '408', '474', '652']\n", 1186 | "806 ['64', '134', '114', '191', '603', '1039', '194', '513', '208', '427']\n", 1187 | "807 ['64', '513', '482', '1019', '480', '479', '169', '519', '481', '190']\n", 1188 | "797 ['114', '64', '603', '408', '12', '192', '483', '169', '178', '480']\n", 1189 | "801 ['178', '318', '198', '64', '357', '12', '114', '316', '272', '1019']\n", 1190 | "809 ['98', '357', '318', '22', '515', '169', '408', '12', '79', '603']\n", 1191 | "815 ['178', '657', '519', '498', '64', '478', '194', '408', '923', '648']\n", 1192 | "817 ['313', '169', '357', '114', '408', '318', '89', '178', '56', '483']\n", 1193 | "821 ['480', '172', '408', '178', '169', '251', '114', '513', '285', '127']\n", 1194 | "818 ['654', '114', '483', '178', '603', '134', '408', '64', '511', '318']\n", 1195 | "814 ['408', '318', '64', '169', '483', '12', '50', '114', '172', '603']\n", 1196 | "812 ['64', '169', '483', '603', '199', '114', '187', '318', '408', '488']\n", 1197 | "823 ['178', '285', '251', '114', '513', '357', '515', '272', '132', '1007']\n", 1198 | "825 ['22', '313', '300', '210', '190', '169', '684', '318', '173', '484']\n", 1199 | "827 ['408', '318', '169', '480', '474', '515', '178', '185', '199', '114']\n", 1200 | "829 ['483', '64', '169', '98', '480', '114', '320', '134', '50', '127']\n", 1201 | "811 ['302', '474', '98', '603', '100', '480', '132', '135', '272', '172']\n", 1202 | "830 ['302', '12', '408', '215', '192', '64', '114', '170', '515', '357']\n", 1203 | "826 ['408', '98', '64', '12', '318', '169', '963', '173', '114', '272']\n", 1204 | "831 ['169', '408', '172', '480', '661', '114', '487', '98', '651', '496']\n", 1205 | "819 ['318', '357', '12', '480', '479', '64', '603', '483', '169', '114']\n", 1206 | "828 ['318', '408', '169', '114', '272', '516', '64', '474', '251', '641']\n", 1207 | "808 ['603', '174', '172', '48', '483', '408', '127', '318', '64', '169']\n", 1208 | "835 ['408', '64', '480', '169', '251', '12', '483', '22', '694', '178']\n", 1209 | "833 ['169', '190', '507', '114', '480', '9', '603', '91', '528', '86']\n", 1210 | "836 ['480', '127', '178', '694', '408', '963', '87', '191', '135', '656']\n", 1211 | "816 ['603', '427', '480', '174', '172', '408', '178', '127', '318', '64']\n", 1212 | "838 ['357', '515', '64', '98', '483', '178', '513', '427', '269', '657']\n", 1213 | "839 ['408', '318', '114', '427', '316', '513', '89', '169', '923', '64']\n", 1214 | "840 ['318', '178', '9', '923', '589', '408', '302', '114', '242', '488']\n", 1215 | "832 ['12', '64', '318', '178', '654', '603', '169', '127', '408', '483']\n", 1216 | "810 ['265', '222', '98', '194', '603', '1137', '181', '196', '515', '427']\n", 1217 | "844 ['357', '408', '64', '483', '272', '641', '474', '178', '191', '320']\n", 1218 | "843 ['169', '408', '694', '1019', '963', '272', '114', '12', '1137', '512']\n", 1219 | "834 ['318', '408', '12', '64', '98', '114', '603', '963', '357', '169']\n", 1220 | "846 ['169', '408', '100', '9', '653', '114', '286', '129', '285', '750']\n", 1221 | "837 ['318', '64', '357', '98', '169', '657', '603', '12', '408', '483']\n", 1222 | "813 ['50', '22', '408', '170', '98', '515', '483', '923', '153', '127']\n", 1223 | "842 ['483', '318', '178', '489', '511', '603', '87', '923', '519', '515']\n", 1224 | "847 ['64', '318', '408', '170', '963', '513', '178', '126', '483', '515']\n", 1225 | "848 ['258', '408', '178', '735', '230', '169', '114', '64', '651', '228']\n", 1226 | "822 ['114', '50', '96', '89', '511', '83', '694', '60', '174', '963']\n", 1227 | "852 ['169', '483', '64', '474', '114', '603', '963', '178', '134', '285']\n", 1228 | "851 ['408', '114', '169', '493', '96', '173', '482', '265', '654', '663']\n", 1229 | "849 ['242', '302', '474', '86', '144', '1', '98', '194', '603', '1137']\n", 1230 | "854 ['209', '276', '179', '474', '178', '408', '114', '654', '169', '641']\n", 1231 | "850 ['12', '313', '64', '408', '143', '963', '195', '603', '483', '251']\n", 1232 | "858 ['180', '318', '513', '187', '657', '654', '169', '114', '357', '199']\n", 1233 | "853 ['657', '313', '483', '169', '318', '963', '64', '408', '22', '178']\n", 1234 | "855 ['127', '318', '169', '408', '50', '64', '480', '12', '178', '511']\n", 1235 | "824 ['603', '169', '114', '191', '408', '12', '483', '318', '496', '136']\n", 1236 | "845 ['64', '515', '496', '408', '318', '483', '169', '98', '657', '114']\n", 1237 | "841 ['408', '64', '12', '657', '318', '603', '427', '480', '169', '479']\n", 1238 | "859 ['408', '272', '178', '8', '318', '64', '169', '479', '483', '22']\n", 1239 | "862 ['242', '275', '272', '408', '318', '169', '923', '511', '963', '114']\n", 1240 | "856 ['169', '408', '98', '603', '12', '318', '64', '223', '1449', '427']\n", 1241 | "820 ['64', '318', '173', '127', '169', '12', '190', '191', '114', '603']\n", 1242 | "863 ['56', '408', '64', '50', '12', '156', '318', '169', '170', '172']\n", 1243 | "860 ['64', '318', '483', '12', '173', '50', '172', '114', '132', '515']\n", 1244 | "857 ['318', '64', '127', '483', '12', '178', '190', '357', '408', '515']\n", 1245 | "864 ['515', '529', '272', '316', '963', '480', '89', '657', '520', '45']\n", 1246 | "865 ['179', '474', '114', '127', '190', '191', '223', '12', '428', '276']\n", 1247 | "868 ['483', '275', '171', '285', '175', '515', '654', '530', '124', '276']\n", 1248 | "867 ['408', '169', '488', '513', '170', '357', '427', '114', '315', '199']\n", 1249 | "861 ['408', '318', '64', '316', '174', '315', '114', '272', '427', '12']\n", 1250 | "870 ['408', '275', '515', '493', '1142', '251', '14', '705', '190', '611']\n", 1251 | "871 ['69', '12', '64', '493', '408', '318', '963', '144', '98', '480']\n", 1252 | "875 ['127', '114', '515', '483', '275', '100', '589', '408', '320', '59']\n", 1253 | "876 ['408', '169', '963', '513', '512', '483', '320', '285', '272', '45']\n", 1254 | "872 ['408', '64', '114', '136', '223', '12', '98', '302', '185', '50']\n", 1255 | "866 ['408', '64', '318', '100', '197', '169', '483', '603', '178', '98']\n", 1256 | "877 ['174', '12', '272', '318', '187', '64', '276', '127', '523', '480']\n", 1257 | "873 ['64', '174', '50', '408', '651', '251', '318', '172', '178', '173']\n", 1258 | "880 ['134', '654', '482', '480', '511', '199', '211', '192', '513', '408']\n", 1259 | "878 ['483', '480', '169', '178', '408', '603', '484', '114', '963', '513']\n", 1260 | "869 ['12', '180', '169', '64', '187', '185', '603', '172', '313', '408']\n", 1261 | "881 ['313', '12', '963', '169', '1194', '223', '496', '603', '604', '1149']\n", 1262 | "879 ['318', '357', '313', '114', '169', '272', '64', '178', '408', '480']\n", 1263 | "883 ['474', '169', '114', '483', '480', '178', '32', '963', '488', '179']\n", 1264 | "882 ['480', '483', '318', '178', '12', '520', '923', '513', '963', '657']\n", 1265 | "884 ['45', '276', '483', '493', '134', '512', '187', '408', '272', '320']\n", 1266 | "886 ['169', '603', '515', '114', '480', '210', '272', '408', '498', '193']\n", 1267 | "885 ['64', '357', '408', '251', '313', '657', '98', '480', '496', '515']\n", 1268 | "889 ['114', '313', '272', '136', '478', '963', '166', '641', '316', '611']\n", 1269 | "874 ['64', '98', '483', '515', '318', '316', '408', '114', '427', '272']\n", 1270 | "892 ['408', '169', '963', '285', '199', '272', '513', '223', '48', '251']\n", 1271 | "890 ['178', '318', '124', '191', '511', '242', '169', '83', '197', '923']\n", 1272 | "893 ['313', '318', '408', '64', '316', '174', '272', '169', '483', '520']\n", 1273 | "887 ['272', '483', '133', '286', '52', '316', '205', '529', '48', '498']\n", 1274 | "891 ['603', '272', '483', '408', '178', '318', '89', '709', '169', '173']\n", 1275 | "894 ['357', '127', '197', '483', '8', '474', '56', '169', '178', '513']\n", 1276 | "896 ['114', '169', '194', '192', '408', '205', '1137', '612', '513', '111']\n", 1277 | "897 ['64', '408', '656', '481', '487', '178', '657', '318', '480', '190']\n", 1278 | "901 ['408', '496', '64', '265', '143', '170', '316', '79', '270', '603']\n", 1279 | "899 ['408', '170', '705', '657', '513', '169', '134', '199', '511', '272']\n", 1280 | "903 ['408', '178', '285', '134', '963', '603', '169', '511', '132', '1449']\n", 1281 | "904 ['98', '318', '515', '480', '513', '272', '654', '170', '483', '661']\n", 1282 | "907 ['302', '265', '95', '193', '603', '1137', '515', '512', '480', '174']\n", 1283 | "905 ['318', '483', '173', '408', '114', '515', '199', '169', '50', '479']\n", 1284 | "902 ['408', '64', '357', '114', '98', '474', '178', '169', '242', '174']\n", 1285 | "898 ['98', '318', '603', '114', '408', '169', '178', '199', '515', '1449']\n", 1286 | "895 ['408', '483', '169', '64', '127', '474', '178', '98', '641', '251']\n", 1287 | "906 ['318', '178', '483', '169', '64', '199', '657', '480', '114', '709']\n", 1288 | "900 ['50', '172', '169', '174', '313', '408', '603', '181', '285', '114']\n", 1289 | "908 ['169', '408', '178', '923', '114', '316', '604', '132', '136', '498']\n", 1290 | "916 ['127', '357', '114', '285', '169', '513', '408', '603', '178', '1142']\n", 1291 | "911 ['50', '408', '114', '963', '12', '169', '318', '127', '511', '64']\n", 1292 | "912 ['923', '515', '603', '114', '408', '98', '22', '651', '480', '57']\n", 1293 | "914 ['483', '64', '178', '100', '515', '98', '199', '318', '169', '496']\n", 1294 | "918 ['515', '313', '408', '114', '57', '657', '242', '12', '169', '285']\n", 1295 | "919 ['408', '515', '659', '511', '192', '603', '611', '150', '657', '427']\n", 1296 | "921 ['300', '12', '408', '22', '318', '64', '496', '265', '251', '963']\n", 1297 | "910 ['318', '187', '64', '515', '272', '169', '251', '496', '661', '408']\n", 1298 | "913 ['479', '272', '192', '513', '165', '611', '170', '135', '114', '615']\n", 1299 | "915 ['169', '483', '98', '114', '515', '408', '318', '603', '512', '484']\n", 1300 | "922 ['318', '64', '178', '483', '408', '316', '515', '735', '963', '480']\n", 1301 | "923 ['302', '474', '603', '515', '480', '498', '479', '483', '408', '178']\n", 1302 | "928 ['302', '474', '603', '515', '427', '512', '480', '23', '479', '483']\n", 1303 | "927 ['408', '483', '169', '657', '479', '524', '272', '709', '478', '22']\n", 1304 | "924 ['169', '22', '513', '735', '199', '483', '189', '98', '170', '484']\n", 1305 | "929 ['64', '114', '408', '169', '178', '603', '357', '313', '190', '657']\n", 1306 | "931 ['98', '408', '318', '64', '169', '187', '114', '170', '357', '513']\n", 1307 | "917 ['12', '272', '114', '357', '169', '56', '515', '408', '603', '657']\n", 1308 | "932 ['48', '408', '127', '223', '190', '50', '318', '272', '23', '12']\n", 1309 | "909 ['474', '98', '515', '483', '408', '178', '127', '318', '89', '357']\n", 1310 | "934 ['64', '493', '408', '166', '430', '178', '79', '169', '251', '22']\n", 1311 | "933 ['408', '484', '316', '169', '694', '528', '199', '513', '963', '641']\n", 1312 | "935 ['316', '483', '22', '318', '114', '272', '189', '603', '136', '498']\n", 1313 | "938 ['98', '408', '12', '191', '173', '64', '603', '83', '185', '194']\n", 1314 | "940 ['408', '519', '318', '136', '603', '132', '190', '661', '64', '496']\n", 1315 | "888 ['515', '178', '318', '408', '427', '114', '483', '1131', '603', '357']\n", 1316 | "925 ['12', '318', '172', '64', '50', '178', '174', '483', '603', '480']\n", 1317 | "942 ['408', '64', '169', '483', '603', '223', '178', '98', '515', '194']\n", 1318 | "937 ['169', '483', '64', '357', '98', '603', '127', '963', '513', '480']\n", 1319 | "926 ['169', '64', '318', '408', '478', '603', '56', '251', '114', '657']\n", 1320 | "943 ['272', '357', '474', '190', '199', '135', '134', '203', '156', '855']\n", 1321 | "939 ['144', '1', '234', '98', '193', '194', '603', '100', '181', '423']\n", 1322 | "936 ['483', '513', '357', '318', '189', '23', '169', '474', '192', '316']\n", 1323 | "930 ['169', '357', '251', '408', '320', '513', '613', '963', '59', '318']\n", 1324 | "920 ['174', '169', '318', '172', '50', '408', '12', '483', '480', '199']\n", 1325 | "941 ['174', '318', '64', '483', '251', '50', '127', '169', '651', '480']\n" 1326 | ], 1327 | "name": "stdout" 1328 | } 1329 | ] 1330 | }, 1331 | { 1332 | "cell_type": "markdown", 1333 | "metadata": { 1334 | "id": "a6SYyKSkx69r", 1335 | "colab_type": "text" 1336 | }, 1337 | "source": [ 1338 | "### How to get the k nearest neighbors of a user (or item)\n" 1339 | ] 1340 | }, 1341 | { 1342 | "cell_type": "code", 1343 | "metadata": { 1344 | "id": "nkNyq_LXx_Am", 1345 | "colab_type": "code", 1346 | "colab": {} 1347 | }, 1348 | "source": [ 1349 | "import io \n", 1350 | "from surprise import KNNBaseline\n", 1351 | "from surprise import Dataset\n", 1352 | "from surprise import get_dataset_dir" 1353 | ], 1354 | "execution_count": 0, 1355 | "outputs": [] 1356 | }, 1357 | { 1358 | "cell_type": "code", 1359 | "metadata": { 1360 | "id": "jIEwucMTyFJC", 1361 | "colab_type": "code", 1362 | "colab": {} 1363 | }, 1364 | "source": [ 1365 | "def read_item_names():\n", 1366 | " \"\"\"Read the u.item file from MovieLens 100-k dataset and return two\n", 1367 | " mappings to convert raw ids into movie names and movie names into raw ids.\n", 1368 | " \"\"\"\n", 1369 | "\n", 1370 | " file_name = get_dataset_dir() + '/ml-100k/ml-100k/u.item'\n", 1371 | " rid_to_name = {}\n", 1372 | " name_to_rid = {}\n", 1373 | " with io.open(file_name, 'r', encoding='ISO-8859-1') as f:\n", 1374 | " for line in f:\n", 1375 | " line = line.split('|')\n", 1376 | " rid_to_name[line[0]] = line[1]\n", 1377 | " name_to_rid[line[1]] = line[0]\n", 1378 | "\n", 1379 | " return rid_to_name, name_to_rid\n" 1380 | ], 1381 | "execution_count": 0, 1382 | "outputs": [] 1383 | }, 1384 | { 1385 | "cell_type": "markdown", 1386 | "metadata": { 1387 | "id": "QC2RGYQkyLKL", 1388 | "colab_type": "text" 1389 | }, 1390 | "source": [ 1391 | "Run KNN" 1392 | ] 1393 | }, 1394 | { 1395 | "cell_type": "code", 1396 | "metadata": { 1397 | "id": "70qzDCj_yIiw", 1398 | "colab_type": "code", 1399 | "outputId": "483d4d4c-4eb0-4352-dcf9-37a8e7a23aa8", 1400 | "colab": { 1401 | "base_uri": "https://localhost:8080/", 1402 | "height": 84 1403 | } 1404 | }, 1405 | "source": [ 1406 | "# First, train the algorithm to compute the similarities between items\n", 1407 | "data = Dataset.load_builtin('ml-100k')\n", 1408 | "trainset = data.build_full_trainset()\n", 1409 | "sim_options = {'name': 'pearson_baseline', 'user_based': False}\n", 1410 | "algo = KNNBaseline(sim_options=sim_options)\n", 1411 | "algo.fit(trainset)" 1412 | ], 1413 | "execution_count": 0, 1414 | "outputs": [ 1415 | { 1416 | "output_type": "stream", 1417 | "text": [ 1418 | "Estimating biases using als...\n", 1419 | "Computing the pearson_baseline similarity matrix...\n", 1420 | "Done computing similarity matrix.\n" 1421 | ], 1422 | "name": "stdout" 1423 | }, 1424 | { 1425 | "output_type": "execute_result", 1426 | "data": { 1427 | "text/plain": [ 1428 | "" 1429 | ] 1430 | }, 1431 | "metadata": { 1432 | "tags": [] 1433 | }, 1434 | "execution_count": 14 1435 | } 1436 | ] 1437 | }, 1438 | { 1439 | "cell_type": "markdown", 1440 | "metadata": { 1441 | "id": "nW568P_MyXVV", 1442 | "colab_type": "text" 1443 | }, 1444 | "source": [ 1445 | "Print out KNN Mappings" 1446 | ] 1447 | }, 1448 | { 1449 | "cell_type": "code", 1450 | "metadata": { 1451 | "id": "BwT_WsJPyWzf", 1452 | "colab_type": "code", 1453 | "outputId": "82ef126b-94d2-4ece-fcb4-894667e33460", 1454 | "colab": { 1455 | "base_uri": "https://localhost:8080/", 1456 | "height": 218 1457 | } 1458 | }, 1459 | "source": [ 1460 | "# Read the mappings raw id <-> movie name\n", 1461 | "rid_to_name, name_to_rid = read_item_names()\n", 1462 | "\n", 1463 | "# Retrieve inner id of the movie Toy Story\n", 1464 | "toy_story_raw_id = name_to_rid['Toy Story (1995)']\n", 1465 | "toy_story_inner_id = algo.trainset.to_inner_iid(toy_story_raw_id)\n", 1466 | "\n", 1467 | "# Retrieve inner ids of the nearest neighbors of Toy Story.\n", 1468 | "toy_story_neighbors = algo.get_neighbors(toy_story_inner_id, k=10)\n", 1469 | "\n", 1470 | "# Convert inner ids of the neighbors into names.\n", 1471 | "toy_story_neighbors = (algo.trainset.to_raw_iid(inner_id)\n", 1472 | " for inner_id in toy_story_neighbors)\n", 1473 | "toy_story_neighbors = (rid_to_name[rid]\n", 1474 | " for rid in toy_story_neighbors)\n", 1475 | "\n", 1476 | "print()\n", 1477 | "print('The 10 nearest neighbors of Toy Story are:')\n", 1478 | "for movie in toy_story_neighbors:\n", 1479 | " print(movie)\n" 1480 | ], 1481 | "execution_count": 0, 1482 | "outputs": [ 1483 | { 1484 | "output_type": "stream", 1485 | "text": [ 1486 | "\n", 1487 | "The 10 nearest neighbors of Toy Story are:\n", 1488 | "Beauty and the Beast (1991)\n", 1489 | "Raiders of the Lost Ark (1981)\n", 1490 | "That Thing You Do! (1996)\n", 1491 | "Lion King, The (1994)\n", 1492 | "Craft, The (1996)\n", 1493 | "Liar Liar (1997)\n", 1494 | "Aladdin (1992)\n", 1495 | "Cool Hand Luke (1967)\n", 1496 | "Winnie the Pooh and the Blustery Day (1968)\n", 1497 | "Indiana Jones and the Last Crusade (1989)\n" 1498 | ], 1499 | "name": "stdout" 1500 | } 1501 | ] 1502 | }, 1503 | { 1504 | "cell_type": "markdown", 1505 | "metadata": { 1506 | "id": "UU_xwRmh9Acw", 1507 | "colab_type": "text" 1508 | }, 1509 | "source": [ 1510 | "# Real-World Social Network Problems" 1511 | ] 1512 | }, 1513 | { 1514 | "cell_type": "markdown", 1515 | "metadata": { 1516 | "id": "lnDJdOoq-gd9", 1517 | "colab_type": "text" 1518 | }, 1519 | "source": [ 1520 | "\n", 1521 | "**Real World Problems**\n", 1522 | "\n", 1523 | "* UX\n", 1524 | "* Ethics\n", 1525 | "* Operational Complexity\n", 1526 | "\n" 1527 | ] 1528 | }, 1529 | { 1530 | "cell_type": "markdown", 1531 | "metadata": { 1532 | "id": "vkMSq18g9EN6", 1533 | "colab_type": "text" 1534 | }, 1535 | "source": [ 1536 | "![socialNetwork](https://user-images.githubusercontent.com/58792/62396018-f20cc100-b53f-11e9-9b34-ac791c0b732a.png)" 1537 | ] 1538 | }, 1539 | { 1540 | "cell_type": "markdown", 1541 | "metadata": { 1542 | "id": "LrTg1MvABj3T", 1543 | "colab_type": "text" 1544 | }, 1545 | "source": [ 1546 | "## Next Improvements?" 1547 | ] 1548 | }, 1549 | { 1550 | "cell_type": "markdown", 1551 | "metadata": { 1552 | "id": "_9P6Aw3iBoJA", 1553 | "colab_type": "text" 1554 | }, 1555 | "source": [ 1556 | "* Recommend Popular People for \"Cold Start\"\n", 1557 | "* Convert to Supervized ML problem" 1558 | ] 1559 | }, 1560 | { 1561 | "cell_type": "markdown", 1562 | "metadata": { 1563 | "id": "4tKhD56---wP", 1564 | "colab_type": "text" 1565 | }, 1566 | "source": [ 1567 | "# Cloud APIs?" 1568 | ] 1569 | }, 1570 | { 1571 | "cell_type": "markdown", 1572 | "metadata": { 1573 | "id": "-CrXDpbf_MKe", 1574 | "colab_type": "text" 1575 | }, 1576 | "source": [ 1577 | "https://azure.microsoft.com/en-us/blog/building-recommender-systems-with-azure-machine-learning-service/\n", 1578 | "\n", 1579 | "![Cloud APIs](https://azurecomcdn.azureedge.net/mediahandler/acomblog/media/Default/blog/7e796df5-ce15-488c-9c1b-ec110059b5d2.png)" 1580 | ] 1581 | }, 1582 | { 1583 | "cell_type": "markdown", 1584 | "metadata": { 1585 | "id": "2ycOcKaV_s-t", 1586 | "colab_type": "text" 1587 | }, 1588 | "source": [ 1589 | "## Related Areas?" 1590 | ] 1591 | }, 1592 | { 1593 | "cell_type": "markdown", 1594 | "metadata": { 1595 | "id": "ahH6OP_N_xP6", 1596 | "colab_type": "text" 1597 | }, 1598 | "source": [ 1599 | "[Topic Modeling with Gensim](https://radimrehurek.com/gensim/)" 1600 | ] 1601 | }, 1602 | { 1603 | "cell_type": "markdown", 1604 | "metadata": { 1605 | "id": "JVofRb1tGFvw", 1606 | "colab_type": "text" 1607 | }, 1608 | "source": [ 1609 | "## ML Maturity Model?" 1610 | ] 1611 | }, 1612 | { 1613 | "cell_type": "markdown", 1614 | "metadata": { 1615 | "id": "ZftIaHO7GIz8", 1616 | "colab_type": "text" 1617 | }, 1618 | "source": [ 1619 | "![ml maturity model](https://user-images.githubusercontent.com/58792/62405528-88ef7280-b56c-11e9-90a6-8ede635419a4.png)" 1620 | ] 1621 | }, 1622 | { 1623 | "cell_type": "markdown", 1624 | "metadata": { 1625 | "id": "N_m0YG841Bfd", 1626 | "colab_type": "text" 1627 | }, 1628 | "source": [ 1629 | "# References" 1630 | ] 1631 | }, 1632 | { 1633 | "cell_type": "markdown", 1634 | "metadata": { 1635 | "id": "GDoeA3Y61FlU", 1636 | "colab_type": "text" 1637 | }, 1638 | "source": [ 1639 | "\n", 1640 | "\n", 1641 | "* [Netflix Recommender Systems](https://dl.acm.org/citation.cfm?id=2843948)\n", 1642 | "* [Surprise](http://surpriselib.com/) is a Python scikit building and analyzing recommender systems.\n", 1643 | "* [azure recommender](https://azure.microsoft.com/en-us/blog/building-recommender-systems-with-azure-machine-learning-service/)\n", 1644 | "\n" 1645 | ] 1646 | }, 1647 | { 1648 | "cell_type": "code", 1649 | "metadata": { 1650 | "id": "iPLI3Rse_ldX", 1651 | "colab_type": "code", 1652 | "colab": {} 1653 | }, 1654 | "source": [ 1655 | "" 1656 | ], 1657 | "execution_count": 0, 1658 | "outputs": [] 1659 | } 1660 | ] 1661 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Core Statistics for datascience 2 | Core Statistics for Datascience 3 | 4 | ## Outline for Talk 5 | 6 | #### Part 1: 7 | 8 | * [Introduction to Colab & Introduction to Data Science](https://paiml.github.io/python_for_datascience/intro.html) 9 | * [Data science key facts](https://github.com/noahgift/core-stats-datascience/blob/master/Data_science_key_facts.ipynb) 10 | * [Data science libraries](https://paiml.github.io/python_for_datascience/lessons/Lesson9_Python_For_Data_Science_Data_Science_Libraries.html) 11 | 12 | #### Part 2: 13 | 14 | Notebooks in this repo [EDA, Feature Engineering and Predictive Modeling Theory]: 15 | 16 | * [Data Science Workflow](https://github.com/noahgift/core-stats-datascience/blob/master/data_science_workflow.ipynb) 17 | * [Trends Supervised Learning](https://github.com/noahgift/core-stats-datascience/blob/master/Lesson2_7_Trends_Supervized_Learning.ipynb) 18 | * [Clustering](https://github.com/noahgift/core-stats-datascience/blob/master/Lesson3_1_Cluster_Analysis.ipynb) 19 | * [GMM](https://github.com/noahgift/core-stats-datascience/blob/master/Lesson3_2_GMM.ipynb) 20 | * [PCA](https://github.com/noahgift/core-stats-datascience/blob/master/Lesson3_3_PCA.ipynb) 21 | * [Recommendations](https://github.com/noahgift/core-stats-datascience/blob/master/Lesson3_5_recommendations.ipynb) 22 | * [Network Analysis](https://github.com/noahgift/core-stats-datascience/blob/master/network_analysis.ipynb) 23 | 24 | #### Part 3 (Bonus): 25 | 26 | * Doing ML in the cloud: walk through census project AWS Sagemaker 27 | 28 | ### Additional Related Topics from Noah Gift 29 | 30 | His most recent books are: 31 | 32 | * [Pragmatic A.I.:   An introduction to Cloud-Based Machine Learning (Pearson, 2018)](https://www.amazon.com/Pragmatic-AI-Introduction-Cloud-Based-Analytics/dp/0134863860) 33 | * [Python for DevOps (O'Reilly, 2020)](https://www.amazon.com/Python-DevOps-Ruthlessly-Effective-Automation/dp/149205769X).  34 | 35 | His most recent video courses are: 36 | 37 | * [Essential Machine Learning and A.I. with Python and Jupyter Notebook LiveLessons (Pearson, 2018)](https://learning.oreilly.com/videos/essential-machine-learning/9780135261118) 38 | * [AWS Certified Machine Learning-Specialty (ML-S) (Pearson, 2019)](https://learning.oreilly.com/videos/aws-certified-machine/9780135556597) 39 | * [Python for Data Science Complete Video Course Video Training (Pearson, 2019)](https://learning.oreilly.com/videos/python-for-data/9780135687253) 40 | * [AWS Certified Big Data - Specialty Complete Video Course and Practice Test Video Training (Pearson, 2019)](https://learning.oreilly.com/videos/aws-certified-big/9780135772324) 41 | * [Building A.I. Applications on Google Cloud Platform (Pearson, 2019)](https://learning.oreilly.com/videos/building-ai-applications/9780135973462) 42 | * [Pragmatic AI and Machine Learning Core Principles (Pearson, 2019)](https://learning.oreilly.com/videos/pragmatic-ai-and/9780136554714) 43 | * [Data Engineering with Python and AWS Lambda (Pearson, 2019)](https://learning.oreilly.com/videos/data-engineering-with/9780135964330) 44 | 45 | His most recent online courses are: 46 | 47 | * [Microservices with this Udacity DevOps Nanodegree (Udacity, 2019)](https://www.udacity.com/course/cloud-dev-ops-nanodegree--nd9991) 48 | * [Command Line Automation in Python (DataCamp, 2019)](https://www.datacamp.com/instructors/ndgift) 49 | * [AWS Certified Cloud Practitioner 2020-Real World & Pragmatic](https://www.udemy.com/course/aws-certified-cloud-practitioner-2020-real-world-pragmatic/?referralCode=CAC679A7D08212773428). 50 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /data_science_workflow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "data-science-workflow.ipynb", 7 | "provenance": [], 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | } 14 | }, 15 | "cells": [ 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "id": "view-in-github", 20 | "colab_type": "text" 21 | }, 22 | "source": [ 23 | "\"Open" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": { 29 | "id": "ftdqokt1hSx9", 30 | "colab_type": "text" 31 | }, 32 | "source": [ 33 | "## Walking through Social Power NBA Data Science Project\n", 34 | "\n", 35 | "* *[Read related material covered in Chapter 6 of Pragmatic AI](https://www.safaribooksonline.com/library/view/pragmatic-ai-an/9780134863924/ch06.xhtml#ch06)*\n", 36 | "\n", 37 | "* *[Watch Video Lesson 9: Walking through Social Power NBA EDA and ML Project](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_00)*\n", 38 | "\n", 39 | "**Topics Covered**\n", 40 | "\n", 41 | "\n", 42 | "* Data Collection Sources\n", 43 | "* Importing and merging DataFrames in Pandas \n", 44 | "* Creating correlation heatmaps \n", 45 | "* Using seaborn lmplot \n", 46 | "* Using linear regression in Python\n", 47 | "* Using ggplot in Python \n", 48 | "* Doing KMeans clustering \n", 49 | "* Doing PCA with scikit-learn \n", 50 | "* Doing ML classification prediction with scikit-learn \n", 51 | "* Doing ML Regression prediction with scikit-learn \n", 52 | "* Using Plotly for interactive Data Visualization\n", 53 | "\n" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": { 59 | "id": "8rcRAtllCnlN", 60 | "colab_type": "text" 61 | }, 62 | "source": [ 63 | "#### Data Collection Sources \n", 64 | "\n", 65 | "* *[Watch Video Lesson 9.1: Data Collection of Social Media Data](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_01)*\n", 66 | "\n", 67 | "![Collection of Data](https://user-images.githubusercontent.com/58792/40758183-e64ba7c4-6440-11e8-97c5-c408e0bc321e.png)" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": { 73 | "id": "EM5z2cs7D-qO", 74 | "colab_type": "text" 75 | }, 76 | "source": [ 77 | "**Twitter Code:**\n", 78 | "\n", 79 | "https://github.com/noahgift/socialpowernba/blob/master/socialpower/sptwitter.py\n", 80 | "\n", 81 | "**Wikipedia Code:**\n", 82 | "\n", 83 | "https://github.com/noahgift/socialpowernba/blob/master/socialpower/spwikipedia.py" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": { 89 | "id": "8w97i7pcbmLT", 90 | "colab_type": "text" 91 | }, 92 | "source": [ 93 | "#### Import and merge DataFrames in Pandas\n", 94 | "\n", 95 | "* *[Watch Video Lesson 9.2: Import and merge DataFrames in Pandas](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_02)*" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "metadata": { 101 | "id": "L_hKsBgrg19R", 102 | "colab_type": "code", 103 | "colab": {} 104 | }, 105 | "source": [ 106 | "import pandas as pd\n", 107 | "import statsmodels.api as sm\n", 108 | "import statsmodels.formula.api as smf\n", 109 | "import matplotlib.pyplot as plt\n", 110 | "import seaborn as sns\n", 111 | "color = sns.color_palette()\n", 112 | "import warnings\n", 113 | "warnings.filterwarnings(\"ignore\")\n", 114 | "%matplotlib inline" 115 | ], 116 | "execution_count": 0, 117 | "outputs": [] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "metadata": { 122 | "id": "xMqHppZfg19Y", 123 | "colab_type": "code", 124 | "colab": {} 125 | }, 126 | "source": [ 127 | "attendance_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_attendance.csv\");attendance_df.head()" 128 | ], 129 | "execution_count": 0, 130 | "outputs": [] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "metadata": { 135 | "id": "h_8Y4ar1g19b", 136 | "colab_type": "code", 137 | "colab": {} 138 | }, 139 | "source": [ 140 | "endorsement_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_endorsements.csv\");endorsement_df.head()" 141 | ], 142 | "execution_count": 0, 143 | "outputs": [] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "metadata": { 148 | "id": "4B9AFL5ug19d", 149 | "colab_type": "code", 150 | "colab": {} 151 | }, 152 | "source": [ 153 | "valuations_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_team_valuations.csv\");valuations_df.head()" 154 | ], 155 | "execution_count": 0, 156 | "outputs": [] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "metadata": { 161 | "id": "Z8x8E0eXg19g", 162 | "colab_type": "code", 163 | "colab": {} 164 | }, 165 | "source": [ 166 | "salary_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_salary.csv\");salary_df.head()" 167 | ], 168 | "execution_count": 0, 169 | "outputs": [] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "metadata": { 174 | "id": "hh996u3Yg19k", 175 | "colab_type": "code", 176 | "colab": {} 177 | }, 178 | "source": [ 179 | "pie_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_pie.csv\");pie_df.head()" 180 | ], 181 | "execution_count": 0, 182 | "outputs": [] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "metadata": { 187 | "id": "uRx54_mwg19m", 188 | "colab_type": "code", 189 | "colab": {} 190 | }, 191 | "source": [ 192 | "plus_minus_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_real_plus_minus.csv\");plus_minus_df.head()" 193 | ], 194 | "execution_count": 0, 195 | "outputs": [] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "metadata": { 200 | "id": "ZHSJCrdhg19o", 201 | "colab_type": "code", 202 | "colab": {} 203 | }, 204 | "source": [ 205 | "br_stats_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_br.csv\");br_stats_df.head()" 206 | ], 207 | "execution_count": 0, 208 | "outputs": [] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "metadata": { 213 | "id": "6QGMORfag19s", 214 | "colab_type": "code", 215 | "colab": {} 216 | }, 217 | "source": [ 218 | "elo_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_elo.csv\");elo_df.head()" 219 | ], 220 | "execution_count": 0, 221 | "outputs": [] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": { 226 | "id": "xYEskOQjoYiD", 227 | "colab_type": "text" 228 | }, 229 | "source": [ 230 | "### Exploratory Data Analysis (EDA)" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "metadata": { 236 | "id": "VTqRnp99g19v", 237 | "colab_type": "code", 238 | "colab": {} 239 | }, 240 | "source": [ 241 | "attendance_valuation_df = attendance_df.merge(valuations_df, how=\"inner\", on=\"TEAM\")" 242 | ], 243 | "execution_count": 0, 244 | "outputs": [] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "metadata": { 249 | "id": "63s9iyOKg19y", 250 | "colab_type": "code", 251 | "colab": {} 252 | }, 253 | "source": [ 254 | "attendance_valuation_df.head()" 255 | ], 256 | "execution_count": 0, 257 | "outputs": [] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": { 262 | "id": "BsZ-pT-ib92R", 263 | "colab_type": "text" 264 | }, 265 | "source": [ 266 | "#### Understand correlation heatmaps and pairplots\n", 267 | "\n", 268 | "Exploratory Data Analysis and Feature Engineering\n", 269 | "\n", 270 | "* [Watch Video Lesson 9.3: Understand correlation heatmaps and pairplots](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_03)\n" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "metadata": { 276 | "id": "VkERuQxGg191", 277 | "colab_type": "code", 278 | "colab": {} 279 | }, 280 | "source": [ 281 | "attendance_valuation_df.corr()" 282 | ], 283 | "execution_count": 0, 284 | "outputs": [] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": { 289 | "id": "44oNrHAW6oiD", 290 | "colab_type": "text" 291 | }, 292 | "source": [ 293 | "**Correlation Heatmap**" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "metadata": { 299 | "id": "9JtPqF7ig194", 300 | "colab_type": "code", 301 | "colab": {} 302 | }, 303 | "source": [ 304 | "corr = attendance_valuation_df.corr()\n", 305 | "sns.heatmap(corr, \n", 306 | " xticklabels=corr.columns.values,\n", 307 | " yticklabels=corr.columns.values)" 308 | ], 309 | "execution_count": 0, 310 | "outputs": [] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": { 315 | "id": "ArTqiGHK6gV-", 316 | "colab_type": "text" 317 | }, 318 | "source": [ 319 | "**Correlation DataFrame Output**" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "metadata": { 325 | "id": "naE63bpxg195", 326 | "colab_type": "code", 327 | "colab": {} 328 | }, 329 | "source": [ 330 | "corr" 331 | ], 332 | "execution_count": 0, 333 | "outputs": [] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": { 338 | "id": "hrEJkd127AdB", 339 | "colab_type": "text" 340 | }, 341 | "source": [ 342 | "**Creating a Pivot Table Based Heatmap in Seaborn**\n", 343 | "\n", 344 | "A few patterns are detected: Look at the *three highest valued signals*" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "metadata": { 350 | "id": "Sj8yepIJg198", 351 | "colab_type": "code", 352 | "colab": {} 353 | }, 354 | "source": [ 355 | "valuations = attendance_valuation_df.pivot(\"TEAM\", \"TOTAL_MILLIONS\", \"VALUE_MILLIONS\")" 356 | ], 357 | "execution_count": 0, 358 | "outputs": [] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "metadata": { 363 | "id": "MsWTja6xg19-", 364 | "colab_type": "code", 365 | "colab": {} 366 | }, 367 | "source": [ 368 | "plt.subplots(figsize=(20,15))\n", 369 | "ax = plt.axes()\n", 370 | "ax.set_title(\"NBA Team AVG Attendance vs Valuation in Millions: 2016-2017 Season\")\n", 371 | "sns.heatmap(valuations,linewidths=.5, annot=True, fmt='g')" 372 | ], 373 | "execution_count": 0, 374 | "outputs": [] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": { 379 | "id": "dSa6dqtFcJ__", 380 | "colab_type": "text" 381 | }, 382 | "source": [ 383 | "#### Using linear regression in Python\n", 384 | "\n", 385 | "There is a signal here, attendence and valuation do seem to be related, but residual values look non-uniform.\n", 386 | "\n", 387 | "* *[Watch Video Lesson 9.4: Use linear regression in Python](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_04)*" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "metadata": { 393 | "id": "RXHe3_DWg19_", 394 | "colab_type": "code", 395 | "colab": {} 396 | }, 397 | "source": [ 398 | "results = smf.ols('VALUE_MILLIONS ~TOTAL_MILLIONS', data=attendance_valuation_df).fit()" 399 | ], 400 | "execution_count": 0, 401 | "outputs": [] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "metadata": { 406 | "id": "9vhFW84Og1-A", 407 | "colab_type": "code", 408 | "colab": {} 409 | }, 410 | "source": [ 411 | "print(results.summary())" 412 | ], 413 | "execution_count": 0, 414 | "outputs": [] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "metadata": { 419 | "id": "3f93IePIg1-G", 420 | "colab_type": "code", 421 | "colab": {} 422 | }, 423 | "source": [ 424 | "sns.residplot(y=\"VALUE_MILLIONS\", x=\"TOTAL_MILLIONS\", data=attendance_valuation_df)" 425 | ], 426 | "execution_count": 0, 427 | "outputs": [] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "metadata": { 432 | "id": "R477xvAGg1-H", 433 | "colab_type": "code", 434 | "colab": {} 435 | }, 436 | "source": [ 437 | "attendance_valuation_predictions_df = attendance_valuation_df.copy()" 438 | ], 439 | "execution_count": 0, 440 | "outputs": [] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "metadata": { 445 | "id": "eOotfovcg1-J", 446 | "colab_type": "code", 447 | "colab": {} 448 | }, 449 | "source": [ 450 | "attendance_valuation_predictions_df[\"predicted\"] = results.predict()\n", 451 | "attendance_valuation_predictions_df" 452 | ], 453 | "execution_count": 0, 454 | "outputs": [] 455 | }, 456 | { 457 | "cell_type": "markdown", 458 | "metadata": { 459 | "id": "ZgCjsBrncYuV", 460 | "colab_type": "text" 461 | }, 462 | "source": [ 463 | "#### Use seaborn lmplot to plot predicted vs actual values\n", 464 | "\n" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "metadata": { 470 | "id": "tkXlniu4g1-O", 471 | "colab_type": "code", 472 | "colab": {} 473 | }, 474 | "source": [ 475 | "sns.lmplot(x=\"predicted\", y=\"VALUE_MILLIONS\", data=attendance_valuation_predictions_df)" 476 | ], 477 | "execution_count": 0, 478 | "outputs": [] 479 | }, 480 | { 481 | "cell_type": "markdown", 482 | "metadata": { 483 | "id": "odFCgj-j70d-", 484 | "colab_type": "text" 485 | }, 486 | "source": [ 487 | "##### Generating a RMSE (Root Mean Squared Error Prediction)" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "metadata": { 493 | "id": "-Px0VERig1-L", 494 | "colab_type": "code", 495 | "colab": {} 496 | }, 497 | "source": [ 498 | "import statsmodels\n", 499 | "rmse = statsmodels.tools.eval_measures.rmse(attendance_valuation_predictions_df[\"predicted\"], attendance_valuation_predictions_df[\"VALUE_MILLIONS\"])\n", 500 | "rmse" 501 | ], 502 | "execution_count": 0, 503 | "outputs": [] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": { 508 | "id": "Ns5Dg8v4-p4H", 509 | "colab_type": "text" 510 | }, 511 | "source": [ 512 | "#### Adding ELO (Strength of Schedule Ranking to DataFrame)" 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "metadata": { 518 | "id": "NrBH_Dheg1-R", 519 | "colab_type": "code", 520 | "colab": {} 521 | }, 522 | "source": [ 523 | "attendance_valuation_elo_df = attendance_valuation_df.merge(elo_df, how=\"inner\", on=\"TEAM\")" 524 | ], 525 | "execution_count": 0, 526 | "outputs": [] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "metadata": { 531 | "id": "fiSpPmhkg1-U", 532 | "colab_type": "code", 533 | "colab": {} 534 | }, 535 | "source": [ 536 | "attendance_valuation_elo_df.head()" 537 | ], 538 | "execution_count": 0, 539 | "outputs": [] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "metadata": { 544 | "id": "QBljJ83pg1-Y", 545 | "colab_type": "code", 546 | "colab": {} 547 | }, 548 | "source": [ 549 | "corr_elo = attendance_valuation_elo_df.corr()\n", 550 | "plt.subplots(figsize=(10,5))\n", 551 | "ax = plt.axes()\n", 552 | "ax.set_title(\"NBA Team Correlation Heatmap: 2016-2017 Season (ELO, AVG Attendance, VALUATION IN MILLIONS)\")\n", 553 | "sns.heatmap(corr_elo, \n", 554 | " xticklabels=corr_elo.columns.values,\n", 555 | " yticklabels=corr_elo.columns.values)" 556 | ], 557 | "execution_count": 0, 558 | "outputs": [] 559 | }, 560 | { 561 | "cell_type": "code", 562 | "metadata": { 563 | "id": "DyDMz-eyg1-e", 564 | "colab_type": "code", 565 | "colab": {} 566 | }, 567 | "source": [ 568 | "corr_elo" 569 | ], 570 | "execution_count": 0, 571 | "outputs": [] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "metadata": { 576 | "id": "zWfgkHuKg1-g", 577 | "colab_type": "code", 578 | "colab": {} 579 | }, 580 | "source": [ 581 | "ax = sns.lmplot(x=\"ELO\", y=\"TOTAL_MILLIONS\", data=attendance_valuation_elo_df, hue=\"CONF\", size=6)\n", 582 | "ax.set(xlabel='ELO Score', ylabel='TOTAL ATTENDANCE IN MILLIONS', title=\"NBA Team AVG Attendance vs ELO Ranking: 2016-2017 Season\")" 583 | ], 584 | "execution_count": 0, 585 | "outputs": [] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "metadata": { 590 | "id": "QKN3dZI9g1-h", 591 | "colab_type": "code", 592 | "colab": {} 593 | }, 594 | "source": [ 595 | "attendance_valuation_elo_df.groupby(\"CONF\")[\"ELO\"].median()\n" 596 | ], 597 | "execution_count": 0, 598 | "outputs": [] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "metadata": { 603 | "id": "9B5USMG-g1-j", 604 | "colab_type": "code", 605 | "colab": {} 606 | }, 607 | "source": [ 608 | "attendance_valuation_elo_df.groupby(\"CONF\")[\"TOTAL_MILLIONS\"].median()" 609 | ], 610 | "execution_count": 0, 611 | "outputs": [] 612 | }, 613 | { 614 | "cell_type": "code", 615 | "metadata": { 616 | "id": "pREeYRNKg1-l", 617 | "colab_type": "code", 618 | "colab": {} 619 | }, 620 | "source": [ 621 | "results = smf.ols('TOTAL_MILLIONS ~ELO', data=attendance_valuation_elo_df).fit()\n" 622 | ], 623 | "execution_count": 0, 624 | "outputs": [] 625 | }, 626 | { 627 | "cell_type": "code", 628 | "metadata": { 629 | "id": "MAs4wdmFg1-n", 630 | "colab_type": "code", 631 | "colab": {} 632 | }, 633 | "source": [ 634 | "print(results.summary())\n", 635 | " \n" 636 | ], 637 | "execution_count": 0, 638 | "outputs": [] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "metadata": { 643 | "id": "QMKXg1Svg1-p", 644 | "colab_type": "code", 645 | "colab": {} 646 | }, 647 | "source": [ 648 | "val_housing_win_df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/socialpowernba/master/data/nba_2017_att_val_elo_win_housing.csv\");val_housing_win_df.head()" 649 | ], 650 | "execution_count": 0, 651 | "outputs": [] 652 | }, 653 | { 654 | "cell_type": "code", 655 | "metadata": { 656 | "id": "Us9f3KEFg1-q", 657 | "colab_type": "code", 658 | "colab": {} 659 | }, 660 | "source": [ 661 | "val_housing_win_df.columns" 662 | ], 663 | "execution_count": 0, 664 | "outputs": [] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "metadata": { 669 | "id": "g553dDsRg1-s", 670 | "colab_type": "code", 671 | "colab": {} 672 | }, 673 | "source": [ 674 | "results = smf.ols('VALUE_MILLIONS ~COUNTY_POPULATION_MILLIONS+TOTAL_ATTENDANCE_MILLIONS+MEDIAN_HOME_PRICE_COUNTY_MILLIONS', data=val_housing_win_df).fit()\n", 675 | "print(results.summary())" 676 | ], 677 | "execution_count": 0, 678 | "outputs": [] 679 | }, 680 | { 681 | "cell_type": "markdown", 682 | "metadata": { 683 | "id": "qZybJR7H80yV", 684 | "colab_type": "text" 685 | }, 686 | "source": [ 687 | "#### Using ggplot in Python\n", 688 | "\n", 689 | "* *[Watch Vidoe Lesson 9.5: Use ggplot in Python](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_05)*" 690 | ] 691 | }, 692 | { 693 | "cell_type": "code", 694 | "metadata": { 695 | "id": "99B2VfRp9RrY", 696 | "colab_type": "code", 697 | "colab": {} 698 | }, 699 | "source": [ 700 | "!pip -q install ggplot" 701 | ], 702 | "execution_count": 0, 703 | "outputs": [] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "metadata": { 708 | "id": "cY85GiLgg1-t", 709 | "colab_type": "code", 710 | "colab": {} 711 | }, 712 | "source": [ 713 | "from ggplot import *\n", 714 | "ggplot(val_housing_win_df, aes(x=\"TOTAL_ATTENDANCE_MILLIONS\", y=\"VALUE_MILLIONS\",\n", 715 | " color=\"WINNING_SEASON\")) + geom_point(size=400)" 716 | ], 717 | "execution_count": 0, 718 | "outputs": [] 719 | }, 720 | { 721 | "cell_type": "markdown", 722 | "metadata": { 723 | "id": "u4G64jDug1-7", 724 | "colab_type": "text" 725 | }, 726 | "source": [ 727 | "#### Use k-means clustering\n", 728 | "\n", 729 | "**Unsupervised Machine Learning**\n", 730 | "\n", 731 | "* Unlabeled Data\n", 732 | "* \"Discovers\" Labels\n", 733 | "* Finds Hidden Patterns\n", 734 | "\n", 735 | "\n", 736 | "**References:**\n", 737 | "\n", 738 | "\n", 739 | "\n", 740 | "* *[Watch Video Lesson 9.6: Use k-means clustering](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_06)*\n", 741 | "* [Read Chapter 6: Pragmatic AI: Social Power and Influence](https://www.safaribooksonline.com/library/view/pragmatic-ai-an/9780134863924/ch06.html#ch06) \n", 742 | "* [Python Machine Learning](https://www.safaribooksonline.com/library/view/Python+Machine+Learning+-+Second+Edition/9781787125933/ch11.html#ch11lvl2sec114) Cluster and Silhoutte plot examples.\n", 743 | "\n", 744 | "\n", 745 | "\n", 746 | "*NBA Season Faceted Cluster Plot *\n", 747 | "\n", 748 | "![Discovering Clusters in the NBA](https://user-images.githubusercontent.com/58792/40759110-6a93a2f8-6445-11e8-980b-ecbb1a2cc029.png)" 749 | ] 750 | }, 751 | { 752 | "cell_type": "markdown", 753 | "metadata": { 754 | "id": "3XtFzuUHBkSe", 755 | "colab_type": "text" 756 | }, 757 | "source": [ 758 | "#### Data Preparation for Clustering\n", 759 | "\n", 760 | "* Clustering on four columns: Attendence, ELO, Valuation and Median Home Prices\n", 761 | "* Scaling the data\n" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "metadata": { 767 | "id": "dBesNFDrg1-y", 768 | "colab_type": "code", 769 | "colab": {} 770 | }, 771 | "source": [ 772 | "numerical_df = val_housing_win_df.loc[:,[\"TOTAL_ATTENDANCE_MILLIONS\", \"ELO\", \"VALUE_MILLIONS\", \"MEDIAN_HOME_PRICE_COUNTY_MILLIONS\"]]" 773 | ], 774 | "execution_count": 0, 775 | "outputs": [] 776 | }, 777 | { 778 | "cell_type": "code", 779 | "metadata": { 780 | "id": "M4cq7-ucg1-0", 781 | "colab_type": "code", 782 | "colab": {} 783 | }, 784 | "source": [ 785 | "from sklearn.preprocessing import MinMaxScaler\n", 786 | "scaler = MinMaxScaler()\n", 787 | "print(scaler.fit(numerical_df))\n", 788 | "print(scaler.transform(numerical_df))" 789 | ], 790 | "execution_count": 0, 791 | "outputs": [] 792 | }, 793 | { 794 | "cell_type": "code", 795 | "metadata": { 796 | "id": "a04Zrzx5g1-2", 797 | "colab_type": "code", 798 | "colab": {} 799 | }, 800 | "source": [ 801 | "from sklearn.cluster import KMeans\n", 802 | "k_means = KMeans(n_clusters=3)\n", 803 | "kmeans = k_means.fit(scaler.transform(numerical_df))\n", 804 | "val_housing_win_df['cluster'] = kmeans.labels_\n", 805 | "val_housing_win_df.head()" 806 | ], 807 | "execution_count": 0, 808 | "outputs": [] 809 | }, 810 | { 811 | "cell_type": "code", 812 | "metadata": { 813 | "id": "Yp-Cj0uQlq9P", 814 | "colab_type": "code", 815 | "colab": {} 816 | }, 817 | "source": [ 818 | "# Yellowbrick method\n", 819 | "from yellowbrick.cluster import KElbowVisualizer\n", 820 | "\n", 821 | "k_means = KMeans()\n", 822 | "visualizer = KElbowVisualizer(kmeans, k=(3,12))\n", 823 | "\n", 824 | "visualizer.fit(scaler.transform(numerical_df)) # Fit the data to the visualizer\n", 825 | "visualizer.poof() # Draw/show/poof the data" 826 | ], 827 | "execution_count": 0, 828 | "outputs": [] 829 | }, 830 | { 831 | "cell_type": "markdown", 832 | "metadata": { 833 | "id": "yWSaKke2g1--", 834 | "colab_type": "text" 835 | }, 836 | "source": [ 837 | " Elbow method shows that 3 clusters is decent choice" 838 | ] 839 | }, 840 | { 841 | "cell_type": "code", 842 | "metadata": { 843 | "id": "7J-sjTsMg1--", 844 | "colab_type": "code", 845 | "colab": {} 846 | }, 847 | "source": [ 848 | "distortions = []\n", 849 | "for i in range(1, 11):\n", 850 | " km = KMeans(n_clusters=i,\n", 851 | " init='k-means++',\n", 852 | " n_init=10,\n", 853 | " max_iter=300,\n", 854 | " random_state=0)\n", 855 | " km.fit(scaler.transform(numerical_df))\n", 856 | " distortions.append(km.inertia_)\n", 857 | " \n", 858 | "plt.plot(range(1,11), distortions, marker='o')\n", 859 | "plt.xlabel('Number of clusters')\n", 860 | "plt.ylabel('Distortion')\n", 861 | "plt.title(\"Team Valuation Elbow Method Cluster Analysis\")\n", 862 | "plt.show()" 863 | ], 864 | "execution_count": 0, 865 | "outputs": [] 866 | }, 867 | { 868 | "cell_type": "markdown", 869 | "metadata": { 870 | "id": "hHwE5jfEg1_D", 871 | "colab_type": "text" 872 | }, 873 | "source": [ 874 | "##### Silhouette Plot\n", 875 | "\n" 876 | ] 877 | }, 878 | { 879 | "cell_type": "code", 880 | "metadata": { 881 | "id": "aLeDtiH8g1_E", 882 | "colab_type": "code", 883 | "colab": {} 884 | }, 885 | "source": [ 886 | "km = KMeans(n_clusters=3,\n", 887 | " init='k-means++',\n", 888 | " n_init=10,\n", 889 | " max_iter=300,\n", 890 | " random_state=0)\n", 891 | "y_km = km.fit_predict(scaler.transform(numerical_df))" 892 | ], 893 | "execution_count": 0, 894 | "outputs": [] 895 | }, 896 | { 897 | "cell_type": "code", 898 | "metadata": { 899 | "id": "uB1RFnk1g1_F", 900 | "colab_type": "code", 901 | "colab": {} 902 | }, 903 | "source": [ 904 | "import numpy as np\n", 905 | "from matplotlib import cm\n", 906 | "from sklearn.metrics import silhouette_samples\n", 907 | "cluster_labels = np.unique(y_km)\n", 908 | "n_clusters = cluster_labels.shape[0]\n", 909 | "silhouette_vals = silhouette_samples(scaler.transform(numerical_df),\n", 910 | " y_km,\n", 911 | " metric='euclidean')\n", 912 | "y_ax_lower, y_ax_upper = 0, 0\n", 913 | "yticks = []\n", 914 | "for i, c in enumerate(cluster_labels):\n", 915 | " c_silhouette_vals = silhouette_vals[y_km == c]\n", 916 | " c_silhouette_vals.sort()\n", 917 | " y_ax_upper += len(c_silhouette_vals)\n", 918 | " color = cm.jet(float(i)/n_clusters)\n", 919 | " plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0, edgecolor='none',color=color)\n", 920 | " yticks.append((y_ax_lower + y_ax_upper)/2)\n", 921 | " y_ax_lower += len(c_silhouette_vals)\n", 922 | "silhouette_avg = np.mean(silhouette_vals)\n", 923 | "plt.axvline(silhouette_avg,\n", 924 | " color=\"red\",\n", 925 | " linestyle=\"--\")\n", 926 | "plt.yticks(yticks, cluster_labels + 1)\n", 927 | "plt.ylabel('Cluster')\n", 928 | "plt.xlabel('Silhouette coefficient')\n", 929 | "plt.title('Silhouette Plot Team Valuation')\n", 930 | "plt.figure(figsize=(20,10))\n", 931 | "plt.show()" 932 | ], 933 | "execution_count": 0, 934 | "outputs": [] 935 | }, 936 | { 937 | "cell_type": "markdown", 938 | "metadata": { 939 | "id": "mY45V9pwg1_H", 940 | "colab_type": "text" 941 | }, 942 | "source": [ 943 | "##### Agglomerative clustering (Hierachial) vs KMeans clustering\n" 944 | ] 945 | }, 946 | { 947 | "cell_type": "code", 948 | "metadata": { 949 | "id": "_DKbgOtFg1_H", 950 | "colab_type": "code", 951 | "colab": {} 952 | }, 953 | "source": [ 954 | "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3))\n", 955 | "km = KMeans(n_clusters=2,\n", 956 | " random_state=0)\n", 957 | "X = scaler.transform(numerical_df)\n", 958 | "y_km = km.fit_predict(X)\n", 959 | "ax1.scatter(X[y_km==0,0],\n", 960 | " X[y_km==0,1],\n", 961 | " c='lightblue',\n", 962 | " edgecolor='black',\n", 963 | " marker='o',\n", 964 | " s=40,\n", 965 | " label='cluster 1')\n", 966 | "ax1.scatter(X[y_km==1,0],\n", 967 | " X[y_km==1,1],\n", 968 | " c='red',\n", 969 | " edgecolor='black',\n", 970 | " marker='s',\n", 971 | " s=40,\n", 972 | " label='cluster 2')\n", 973 | "ax1.set_title('NBA Team K-means clustering')\n", 974 | "from sklearn.cluster import AgglomerativeClustering\n", 975 | "\n", 976 | "X = scaler.transform(numerical_df)\n", 977 | "ac = AgglomerativeClustering(n_clusters=2,\n", 978 | " affinity='euclidean',\n", 979 | " linkage='complete')\n", 980 | "y_ac = ac.fit_predict(X)\n", 981 | "ax2.scatter(X[y_ac==0,0],\n", 982 | " X[y_ac==0,1],\n", 983 | " c='lightblue',\n", 984 | " edgecolor='black',\n", 985 | " marker='o',\n", 986 | " s=40,\n", 987 | " label='cluster 1')\n", 988 | "ax2.scatter(X[y_ac==1,0],\n", 989 | " X[y_ac==1,1],\n", 990 | " c='red',\n", 991 | " edgecolor='black',\n", 992 | " marker='s',\n", 993 | " s=40,\n", 994 | " label='cluster 2')\n", 995 | "ax2.set_title('NBA Team Agglomerative clustering')\n", 996 | "plt.legend()\n", 997 | "plt.show()" 998 | ], 999 | "execution_count": 0, 1000 | "outputs": [] 1001 | }, 1002 | { 1003 | "cell_type": "markdown", 1004 | "metadata": { 1005 | "id": "gjJnZM4Pg1_J", 1006 | "colab_type": "text" 1007 | }, 1008 | "source": [ 1009 | "##### 3D Plot in R\n", 1010 | "\n", 1011 | "![Valuation 3D Plot](https://user-images.githubusercontent.com/58792/36056809-7f87a266-0dbc-11e8-8877-9bb87905adbd.png)\n", 1012 | "\n", 1013 | "Source Code: https://github.com/noahgift/socialpowernba/blob/master/plot_team_cluster.R" 1014 | ] 1015 | }, 1016 | { 1017 | "cell_type": "markdown", 1018 | "metadata": { 1019 | "id": "0j1oxFY9d6hZ", 1020 | "colab_type": "text" 1021 | }, 1022 | "source": [ 1023 | "#### Use PCA with sklearn\n", 1024 | "\n", 1025 | "References:\n", 1026 | "\n", 1027 | "\n", 1028 | "\n", 1029 | "1. [ PCA sklearn](http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html)\n", 1030 | "\n", 1031 | "\n", 1032 | "\n" 1033 | ] 1034 | }, 1035 | { 1036 | "cell_type": "code", 1037 | "metadata": { 1038 | "id": "io-MtBQRd_qK", 1039 | "colab_type": "code", 1040 | "colab": {} 1041 | }, 1042 | "source": [ 1043 | "import pandas as pd\n", 1044 | "from sklearn.decomposition import PCA\n", 1045 | "pca = PCA(n_components=2)\n", 1046 | "pca.fit(numerical_df)\n", 1047 | "X = pca.transform(numerical_df)\n", 1048 | "print(f\"Before PCA Reduction{numerical_df.shape}\")\n", 1049 | "print(f\"After PCA Reduction {X.shape}\")" 1050 | ], 1051 | "execution_count": 0, 1052 | "outputs": [] 1053 | }, 1054 | { 1055 | "cell_type": "markdown", 1056 | "metadata": { 1057 | "id": "w5sxCSV3dGvO", 1058 | "colab_type": "text" 1059 | }, 1060 | "source": [ 1061 | "##### Simple Scatter Plot of Reduced Dimensions" 1062 | ] 1063 | }, 1064 | { 1065 | "cell_type": "code", 1066 | "metadata": { 1067 | "id": "YygzH0jzb1GX", 1068 | "colab_type": "code", 1069 | "colab": {} 1070 | }, 1071 | "source": [ 1072 | "plt.scatter(X[:, 0], X[:, 1])\n", 1073 | "plt.show()\n" 1074 | ], 1075 | "execution_count": 0, 1076 | "outputs": [] 1077 | }, 1078 | { 1079 | "cell_type": "code", 1080 | "metadata": { 1081 | "id": "LZxHsQY8vYvR", 1082 | "colab_type": "code", 1083 | "colab": {} 1084 | }, 1085 | "source": [ 1086 | "" 1087 | ], 1088 | "execution_count": 0, 1089 | "outputs": [] 1090 | }, 1091 | { 1092 | "cell_type": "markdown", 1093 | "metadata": { 1094 | "id": "WkV-e3Rk8pZt", 1095 | "colab_type": "text" 1096 | }, 1097 | "source": [ 1098 | "#### Using yellowbrick road for Feature Ranking" 1099 | ] 1100 | }, 1101 | { 1102 | "cell_type": "markdown", 1103 | "metadata": { 1104 | "id": "wAKFbR7F8tq_", 1105 | "colab_type": "text" 1106 | }, 1107 | "source": [ 1108 | "![yb viz](https://user-images.githubusercontent.com/58792/48080128-d7b8d900-e1a1-11e8-8f8c-aba2473bfc81.png)\n", 1109 | "\n", 1110 | "Another \"road\" to travel\n", 1111 | "\n", 1112 | "```python\n", 1113 | "!pip install yellowbrick\n", 1114 | "from yellowbrick.features import Rank2D\n", 1115 | "\n", 1116 | "visualizer = Rank2D(algorithm=\"pearson\")\n", 1117 | "visualizer.fit_transform(val_housing_win_df.as)\n", 1118 | "visualizer.poof()```" 1119 | ] 1120 | }, 1121 | { 1122 | "cell_type": "code", 1123 | "metadata": { 1124 | "id": "IUTHH1b6mpW5", 1125 | "colab_type": "code", 1126 | "colab": {} 1127 | }, 1128 | "source": [ 1129 | "!pip -q install -U yellowbrick" 1130 | ], 1131 | "execution_count": 0, 1132 | "outputs": [] 1133 | }, 1134 | { 1135 | "cell_type": "code", 1136 | "metadata": { 1137 | "id": "nN7O8inJmm0q", 1138 | "colab_type": "code", 1139 | "colab": {} 1140 | }, 1141 | "source": [ 1142 | "from yellowbrick.features import Rank2D\n", 1143 | "\n", 1144 | "visualizer = Rank2D(algorithm=\"pearson\")\n", 1145 | "visualizer.fit_transform(numerical_df)\n", 1146 | "visualizer.poof()" 1147 | ], 1148 | "execution_count": 0, 1149 | "outputs": [] 1150 | }, 1151 | { 1152 | "cell_type": "markdown", 1153 | "metadata": { 1154 | "id": "JxbzSrhdeBvu", 1155 | "colab_type": "text" 1156 | }, 1157 | "source": [ 1158 | "#### Use ML classification prediction with scikit-learn\n", 1159 | "\n", 1160 | "Create supervized classification prediction" 1161 | ] 1162 | }, 1163 | { 1164 | "cell_type": "code", 1165 | "metadata": { 1166 | "id": "FvcbNEIWeCO4", 1167 | "colab_type": "code", 1168 | "colab": {} 1169 | }, 1170 | "source": [ 1171 | "from sklearn.neighbors import KNeighborsClassifier\n", 1172 | "neigh = KNeighborsClassifier(n_neighbors=3)\n", 1173 | "neigh.fit?" 1174 | ], 1175 | "execution_count": 0, 1176 | "outputs": [] 1177 | }, 1178 | { 1179 | "cell_type": "markdown", 1180 | "metadata": { 1181 | "id": "GaVMoq_nk91E", 1182 | "colab_type": "text" 1183 | }, 1184 | "source": [ 1185 | "#### ML Regression prediction with scikit-learn\n", 1186 | "\n", 1187 | "Create supervized regression prediction" 1188 | ] 1189 | }, 1190 | { 1191 | "cell_type": "code", 1192 | "metadata": { 1193 | "id": "WmB4TJ3ElDLI", 1194 | "colab_type": "code", 1195 | "colab": {} 1196 | }, 1197 | "source": [ 1198 | "from sklearn.neighbors import KNeighborsRegressor\n", 1199 | "neigh = KNeighborsRegressor(n_neighbors=2)\n", 1200 | "neigh.fit?\n" 1201 | ], 1202 | "execution_count": 0, 1203 | "outputs": [] 1204 | }, 1205 | { 1206 | "cell_type": "markdown", 1207 | "metadata": { 1208 | "id": "VCsBWe8gva-k", 1209 | "colab_type": "text" 1210 | }, 1211 | "source": [ 1212 | "#### ML auto-sklearn\n", 1213 | "\n", 1214 | "automated machine learning toolkit: [automl drop-in replacement for scikit-learn estimator](http://automl.github.io/auto-sklearn/stable/)" 1215 | ] 1216 | }, 1217 | { 1218 | "cell_type": "markdown", 1219 | "metadata": { 1220 | "id": "2_3ltF-BxqVD", 1221 | "colab_type": "text" 1222 | }, 1223 | "source": [ 1224 | "Emerging trend is to automatically pick the right model using \"Automl\"\n", 1225 | "\n", 1226 | "\n", 1227 | "```\n", 1228 | "\n", 1229 | "!pip install auto-sklearn\n", 1230 | "\n", 1231 | "```\n", 1232 | "\n", 1233 | "\n", 1234 | "\n", 1235 | "```python\n", 1236 | "import autosklearn.classification\n", 1237 | "```\n", 1238 | "\n", 1239 | "\n", 1240 | "\n" 1241 | ] 1242 | }, 1243 | { 1244 | "cell_type": "markdown", 1245 | "metadata": { 1246 | "id": "f0HXl7nllFn_", 1247 | "colab_type": "text" 1248 | }, 1249 | "source": [ 1250 | "#### Using Plotly for interactive Data Visualization\n", 1251 | "\n", 1252 | "* *[Read related material covered in Chapter 10 of Pragmatic AI](https://www.safaribooksonline.com/library/view/pragmatic-ai-an/9780134863924/ch10.xhtml#ch10)*\n", 1253 | "\n", 1254 | "* *[Watch Video Lesson 9:10: Use Plotly for interactive data visualization](https://www.safaribooksonline.com/videos/essential-machine-learning/9780135261118/9780135261118-EMLA_01_09_10)*\n" 1255 | ] 1256 | }, 1257 | { 1258 | "cell_type": "markdown", 1259 | "metadata": { 1260 | "id": "V3lJoE5YGt9f", 1261 | "colab_type": "text" 1262 | }, 1263 | "source": [ 1264 | "Cell configuration to setup Plotly\n", 1265 | "Further documentation available from [Google on Plotly Colab Integration](https://colab.research.google.com/notebooks/charts.ipynb#scrollTo=YVhMPxwa-wmS)\n", 1266 | "\n" 1267 | ] 1268 | }, 1269 | { 1270 | "cell_type": "code", 1271 | "metadata": { 1272 | "id": "bExwVgaAlGOi", 1273 | "colab_type": "code", 1274 | "colab": {} 1275 | }, 1276 | "source": [ 1277 | "def configure_plotly_browser_state():\n", 1278 | " import IPython\n", 1279 | " display(IPython.core.display.HTML('''\n", 1280 | " \n", 1281 | " \n", 1289 | " '''))\n" 1290 | ], 1291 | "execution_count": 0, 1292 | "outputs": [] 1293 | }, 1294 | { 1295 | "cell_type": "markdown", 1296 | "metadata": { 1297 | "id": "Y7d2n3UsPLLJ", 1298 | "colab_type": "text" 1299 | }, 1300 | "source": [ 1301 | "##### Going Further with Real Estate Exploration" 1302 | ] 1303 | }, 1304 | { 1305 | "cell_type": "code", 1306 | "metadata": { 1307 | "id": "BKhccX1uPOec", 1308 | "colab_type": "code", 1309 | "colab": {} 1310 | }, 1311 | "source": [ 1312 | "import pandas as pd\n", 1313 | "pd.set_option('display.float_format', lambda x: '%.3f' % x)\n", 1314 | "import numpy as np\n", 1315 | "import matplotlib.pyplot as plt\n", 1316 | "import seaborn as sns\n", 1317 | "import seaborn as sns; sns.set(color_codes=True)\n", 1318 | "from sklearn.cluster import KMeans\n", 1319 | "color = sns.color_palette()\n", 1320 | "from IPython.core.display import display, HTML\n", 1321 | "display(HTML(\"\"))\n", 1322 | "%matplotlib inline" 1323 | ], 1324 | "execution_count": 0, 1325 | "outputs": [] 1326 | }, 1327 | { 1328 | "cell_type": "code", 1329 | "metadata": { 1330 | "id": "Alk6KD_WPhyb", 1331 | "colab_type": "code", 1332 | "colab": {} 1333 | }, 1334 | "source": [ 1335 | "df = pd.read_csv(\"https://raw.githubusercontent.com/noahgift/real_estate_ml/master/data/Zip_Zhvi_SingleFamilyResidence.csv\")" 1336 | ], 1337 | "execution_count": 0, 1338 | "outputs": [] 1339 | }, 1340 | { 1341 | "cell_type": "code", 1342 | "metadata": { 1343 | "id": "5JAeis7sPvzr", 1344 | "colab_type": "code", 1345 | "colab": {} 1346 | }, 1347 | "source": [ 1348 | "df.describe()" 1349 | ], 1350 | "execution_count": 0, 1351 | "outputs": [] 1352 | }, 1353 | { 1354 | "cell_type": "markdown", 1355 | "metadata": { 1356 | "id": "PQan_MCrP7eF", 1357 | "colab_type": "text" 1358 | }, 1359 | "source": [ 1360 | "**Clean Up DataFrame**\n", 1361 | "Rename RegionName to ZipCode and Change Zip Code to String\n", 1362 | "\n" 1363 | ] 1364 | }, 1365 | { 1366 | "cell_type": "code", 1367 | "metadata": { 1368 | "id": "93nEMwVWP5ic", 1369 | "colab_type": "code", 1370 | "colab": {} 1371 | }, 1372 | "source": [ 1373 | "df.rename(columns={\"RegionName\":\"ZipCode\"}, inplace=True)\n", 1374 | "df[\"ZipCode\"]=df[\"ZipCode\"].map(lambda x: \"{:.0f}\".format(x))\n", 1375 | "df[\"RegionID\"]=df[\"RegionID\"].map(lambda x: \"{:.0f}\".format(x))\n", 1376 | "df.head()" 1377 | ], 1378 | "execution_count": 0, 1379 | "outputs": [] 1380 | }, 1381 | { 1382 | "cell_type": "code", 1383 | "metadata": { 1384 | "id": "lFau8qKWP_Y9", 1385 | "colab_type": "code", 1386 | "colab": {} 1387 | }, 1388 | "source": [ 1389 | "median_prices = df.median()" 1390 | ], 1391 | "execution_count": 0, 1392 | "outputs": [] 1393 | }, 1394 | { 1395 | "cell_type": "code", 1396 | "metadata": { 1397 | "id": "sD2pYER-QEd9", 1398 | "colab_type": "code", 1399 | "colab": {} 1400 | }, 1401 | "source": [ 1402 | "median_prices.tail()" 1403 | ], 1404 | "execution_count": 0, 1405 | "outputs": [] 1406 | }, 1407 | { 1408 | "cell_type": "code", 1409 | "metadata": { 1410 | "id": "1HLi8XudQGW9", 1411 | "colab_type": "code", 1412 | "colab": {} 1413 | }, 1414 | "source": [ 1415 | "marin_df = df[df[\"CountyName\"] == \"Marin\"].median()\n", 1416 | "sf_df = df[df[\"City\"] == \"San Francisco\"].median()\n", 1417 | "palo_alto = df[df[\"City\"] == \"Palo Alto\"].median()\n", 1418 | "df_comparison = pd.concat([marin_df, sf_df, palo_alto, median_prices], axis=1)\n", 1419 | "df_comparison.columns = [\"Marin County\", \"San Francisco\", \"Palo Alto\", \"Median USA\"]" 1420 | ], 1421 | "execution_count": 0, 1422 | "outputs": [] 1423 | }, 1424 | { 1425 | "cell_type": "markdown", 1426 | "metadata": { 1427 | "id": "er6GHFbuSmh3", 1428 | "colab_type": "text" 1429 | }, 1430 | "source": [ 1431 | "**Plotly visualization**\n", 1432 | "\n", 1433 | "[Shortcut view of plot if slow to load](http://nbviewer.jupyter.org/github/noahgift/real_estate_ml/blob/648361ce7392a0af29ce79780e6e5159c1a378e9/notebooks/explore_zillow_data_sets.ipynb)" 1434 | ] 1435 | }, 1436 | { 1437 | "cell_type": "code", 1438 | "metadata": { 1439 | "id": "irsjeE3NQI0l", 1440 | "colab_type": "code", 1441 | "colab": {} 1442 | }, 1443 | "source": [ 1444 | "import cufflinks as cf\n", 1445 | "cf.go_offline()\n", 1446 | "\n", 1447 | "from plotly.offline import init_notebook_mode\n", 1448 | "configure_plotly_browser_state()\n", 1449 | "init_notebook_mode(connected=False)\n", 1450 | "\n", 1451 | "\n", 1452 | "df_comparison.iplot(title=\"Bay Area Median Single Family Home Prices 1996-2017\",\n", 1453 | " xTitle=\"Year\",\n", 1454 | " yTitle=\"Sales Price\",\n", 1455 | " #bestfit=True, bestfit_colors=[\"pink\"],\n", 1456 | " #subplots=True,\n", 1457 | " shape=(4,1),\n", 1458 | " #subplot_titles=True,\n", 1459 | " fill=True,)" 1460 | ], 1461 | "execution_count": 0, 1462 | "outputs": [] 1463 | }, 1464 | { 1465 | "cell_type": "markdown", 1466 | "metadata": { 1467 | "id": "WXyhJ40mQv85", 1468 | "colab_type": "text" 1469 | }, 1470 | "source": [ 1471 | "**Cluster on Size Rank and Price**" 1472 | ] 1473 | }, 1474 | { 1475 | "cell_type": "code", 1476 | "metadata": { 1477 | "id": "yyE-ZIreQMCF", 1478 | "colab_type": "code", 1479 | "colab": {} 1480 | }, 1481 | "source": [ 1482 | "from sklearn.preprocessing import MinMaxScaler" 1483 | ], 1484 | "execution_count": 0, 1485 | "outputs": [] 1486 | }, 1487 | { 1488 | "cell_type": "code", 1489 | "metadata": { 1490 | "id": "JWAAujsdRU04", 1491 | "colab_type": "code", 1492 | "colab": {} 1493 | }, 1494 | "source": [ 1495 | "columns_to_drop = ['RegionID', 'ZipCode', 'City', 'State', 'Metro', 'CountyName']\n", 1496 | "df_numerical = df.dropna()\n", 1497 | "df_numerical = df_numerical.drop(columns_to_drop, axis=1)" 1498 | ], 1499 | "execution_count": 0, 1500 | "outputs": [] 1501 | }, 1502 | { 1503 | "cell_type": "code", 1504 | "metadata": { 1505 | "id": "YxTm9GFjRWp5", 1506 | "colab_type": "code", 1507 | "colab": {} 1508 | }, 1509 | "source": [ 1510 | "df_numerical.describe()" 1511 | ], 1512 | "execution_count": 0, 1513 | "outputs": [] 1514 | }, 1515 | { 1516 | "cell_type": "code", 1517 | "metadata": { 1518 | "id": "p_RMHy0yRYFB", 1519 | "colab_type": "code", 1520 | "colab": {} 1521 | }, 1522 | "source": [ 1523 | "scaler = MinMaxScaler()\n", 1524 | "scaled_df = scaler.fit_transform(df_numerical)\n", 1525 | "kmeans = KMeans(n_clusters=3, random_state=0).fit(scaled_df)\n", 1526 | "print(len(kmeans.labels_))" 1527 | ], 1528 | "execution_count": 0, 1529 | "outputs": [] 1530 | }, 1531 | { 1532 | "cell_type": "code", 1533 | "metadata": { 1534 | "id": "MVkemECRRZ2a", 1535 | "colab_type": "code", 1536 | "colab": {} 1537 | }, 1538 | "source": [ 1539 | "cluster_df = df.copy(deep=True)\n", 1540 | "cluster_df.dropna(inplace=True)\n", 1541 | "cluster_df.describe()\n", 1542 | "cluster_df['cluster'] = kmeans.labels_\n", 1543 | "cluster_df['appreciation_ratio'] = round(cluster_df[\"2017-09\"]/cluster_df[\"1996-04\"],2)\n", 1544 | "cluster_df['CityZipCodeAppRatio'] = cluster_df['City'].map(str) + \"-\" + cluster_df['ZipCode'] + \"-\" + cluster_df[\"appreciation_ratio\"].map(str)\n", 1545 | "cluster_df.head()" 1546 | ], 1547 | "execution_count": 0, 1548 | "outputs": [] 1549 | }, 1550 | { 1551 | "cell_type": "markdown", 1552 | "metadata": { 1553 | "id": "oTy9CdrARrQZ", 1554 | "colab_type": "text" 1555 | }, 1556 | "source": [ 1557 | "**Create a 3D Plot**\n", 1558 | "\n", 1559 | "[Shortcut view of plot if slow to load](http://nbviewer.jupyter.org/github/noahgift/real_estate_ml/blob/648361ce7392a0af29ce79780e6e5159c1a378e9/notebooks/explore_zillow_data_sets.ipynb)\n" 1560 | ] 1561 | }, 1562 | { 1563 | "cell_type": "code", 1564 | "metadata": { 1565 | "id": "w7bd3lXpRbqh", 1566 | "colab_type": "code", 1567 | "colab": {} 1568 | }, 1569 | "source": [ 1570 | "import plotly.offline as py\n", 1571 | "import plotly.graph_objs as go\n", 1572 | "\n", 1573 | "from plotly.offline import init_notebook_mode\n", 1574 | "configure_plotly_browser_state()\n", 1575 | "init_notebook_mode(connected=False)\n", 1576 | "\n", 1577 | "trace1 = go.Scatter3d(\n", 1578 | " x=cluster_df[\"appreciation_ratio\"],\n", 1579 | " y=cluster_df[\"1996-04\"],\n", 1580 | " z=cluster_df[\"2017-09\"],\n", 1581 | " mode='markers',\n", 1582 | " text=cluster_df[\"CityZipCodeAppRatio\"],\n", 1583 | " marker=dict(\n", 1584 | " size=12,\n", 1585 | " color=cluster_df[\"cluster\"], # set color to an array/list of desired values\n", 1586 | " colorscale='Viridis', # choose a colorscale\n", 1587 | " opacity=0.8\n", 1588 | " )\n", 1589 | ")\n", 1590 | "#print(trace1)\n", 1591 | "data = [trace1]\n", 1592 | "layout = go.Layout(\n", 1593 | " showlegend=False,\n", 1594 | " title=\"30 Year History USA Real Estate Prices (Clusters Colored)\",\n", 1595 | " scene = dict(\n", 1596 | " xaxis = dict(title='X: Appreciation Ratio'),\n", 1597 | " yaxis = dict(title=\"Y: 1996 Prices\"),\n", 1598 | " zaxis = dict(title=\"Z: 2017 Prices\"),\n", 1599 | " ),\n", 1600 | " width=1000,\n", 1601 | " height=900,\n", 1602 | ")\n", 1603 | "fig = go.Figure(data=data, layout=layout)\n", 1604 | "py.iplot(fig, filename='3d-scatter-colorscale')" 1605 | ], 1606 | "execution_count": 0, 1607 | "outputs": [] 1608 | }, 1609 | { 1610 | "cell_type": "markdown", 1611 | "metadata": { 1612 | "id": "KASHuUj8WC_Z", 1613 | "colab_type": "text" 1614 | }, 1615 | "source": [ 1616 | "**NBA Player Endorsements Interactive Plotly Graph**\n", 1617 | "\n", 1618 | "Reference:\n", 1619 | "\n", 1620 | "* https://plot.ly/~ngift/17/\n", 1621 | "\n", 1622 | "\n", 1623 | "\n", 1624 | "\n" 1625 | ] 1626 | }, 1627 | { 1628 | "cell_type": "code", 1629 | "metadata": { 1630 | "id": "wGYRxCXqWnVH", 1631 | "colab_type": "code", 1632 | "colab": {} 1633 | }, 1634 | "source": [ 1635 | "from plotly.offline import init_notebook_mode\n", 1636 | "configure_plotly_browser_state()\n", 1637 | "init_notebook_mode(connected=False)\n", 1638 | "\n", 1639 | "\n", 1640 | "import plotly.offline as py\n", 1641 | "from plotly.graph_objs import *\n", 1642 | "trace1 = {\n", 1643 | " \"x\": [\"LeBron James\", \"Kevin Durant\", \"James Harden\", \"Russell Westbrook\", \"Carmelo Anthony\", \"Dwyane Wade\", \"Chris Paul\", \"Derrick Rose\", \"Kyrie Irving\", \"Stephen Curry\"], \n", 1644 | " \"y\": [55, 36, 20, 15, 8, 13, 8, 14, 13, 35], \n", 1645 | " \"name\": \"Endorsements in Millions\", \n", 1646 | " \"type\": \"bar\", \n", 1647 | " \"uid\": \"df2707\", \n", 1648 | " \"xsrc\": \"ngift:16:53adec\", \n", 1649 | " \"ysrc\": \"ngift:16:0e0504\"\n", 1650 | "}\n", 1651 | "trace2 = {\n", 1652 | " \"x\": [\"LeBron James\", \"Kevin Durant\", \"James Harden\", \"Russell Westbrook\", \"Carmelo Anthony\", \"Dwyane Wade\", \"Chris Paul\", \"Derrick Rose\", \"Kyrie Irving\", \"Stephen Curry\"], \n", 1653 | " \"y\": [14.7, 6.29, 3.28, 4.28, 3.77, 4.67, 2.69, 3.27, 4.8, 17.57], \n", 1654 | " \"name\": \"Wikipedia Pageviews\", \n", 1655 | " \"type\": \"bar\", \n", 1656 | " \"uid\": \"c9d073\", \n", 1657 | " \"xsrc\": \"ngift:16:53adec\", \n", 1658 | " \"ysrc\": \"ngift:16:fea27a\"\n", 1659 | "}\n", 1660 | "trace3 = {\n", 1661 | " \"x\": [\"LeBron James\", \"Kevin Durant\", \"James Harden\", \"Russell Westbrook\", \"Carmelo Anthony\", \"Dwyane Wade\", \"Chris Paul\", \"Derrick Rose\", \"Kyrie Irving\", \"Stephen Curry\"], \n", 1662 | " \"y\": [20.43, 12.24, 15.54, 17.34, 5.26, 2.52, 13.48, 1.17, 8.28, 18.8], \n", 1663 | " \"name\": \"Wins Attributed to Player\", \n", 1664 | " \"type\": \"bar\", \n", 1665 | " \"uid\": \"cfe1ac\", \n", 1666 | " \"xsrc\": \"ngift:16:53adec\", \n", 1667 | " \"ysrc\": \"ngift:16:f3c87e\"\n", 1668 | "}\n", 1669 | "trace4 = {\n", 1670 | " \"x\": [\"LeBron James\", \"Kevin Durant\", \"James Harden\", \"Russell Westbrook\", \"Carmelo Anthony\", \"Dwyane Wade\", \"Chris Paul\", \"Derrick Rose\", \"Kyrie Irving\", \"Stephen Curry\"], \n", 1671 | " \"y\": [30.96, 26.5, 26.5, 26.5, 24.56, 23.2, 22.87, 21.32, 17.64, 12.11], \n", 1672 | " \"name\": \"Salary in Millions\", \n", 1673 | " \"type\": \"bar\", \n", 1674 | " \"uid\": \"f83635\", \n", 1675 | " \"xsrc\": \"ngift:16:53adec\", \n", 1676 | " \"ysrc\": \"ngift:16:2cdf3e\"\n", 1677 | "}\n", 1678 | "trace5 = {\n", 1679 | " \"x\": [\"LeBron James\", \"Kevin Durant\", \"James Harden\", \"Russell Westbrook\", \"Carmelo Anthony\", \"Dwyane Wade\", \"Chris Paul\", \"Derrick Rose\", \"Kyrie Irving\", \"Stephen Curry\"], \n", 1680 | " \"y\": [5.53, 1.43, 0.97, 2.13, 0.72, 0.35, 0.83, 1.86, 1.54, 12.28], \n", 1681 | " \"name\": \"Twitter Favorite Count/1000\", \n", 1682 | " \"type\": \"bar\", \n", 1683 | " \"uid\": \"9d1aad\", \n", 1684 | " \"xsrc\": \"ngift:16:53adec\", \n", 1685 | " \"ysrc\": \"ngift:16:191da9\"\n", 1686 | "}\n", 1687 | "data = Data([trace1, trace2, trace3, trace4, trace5])\n", 1688 | "layout = {\n", 1689 | " \"barmode\": \"group\", \n", 1690 | " \"title\": \"2016-2017 NBA Season Endorsement and Social Power\", \n", 1691 | " \"xaxis\": {\n", 1692 | " \"autorange\": True, \n", 1693 | " \"range\": [-0.5, 9.5], \n", 1694 | " \"type\": \"category\"\n", 1695 | " }, \n", 1696 | " \"yaxis\": {\n", 1697 | " \"autorange\": True, \n", 1698 | " \"range\": [0, 57.8947368421], \n", 1699 | " \"type\": \"linear\"\n", 1700 | " }\n", 1701 | "}\n", 1702 | "fig = Figure(data=data, layout=layout)\n", 1703 | "py.iplot(fig, filename='3d-scatter-colorscale')" 1704 | ], 1705 | "execution_count": 0, 1706 | "outputs": [] 1707 | }, 1708 | { 1709 | "cell_type": "code", 1710 | "metadata": { 1711 | "id": "vUD6tZk0CeMI", 1712 | "colab_type": "code", 1713 | "colab": {} 1714 | }, 1715 | "source": [ 1716 | "" 1717 | ], 1718 | "execution_count": 0, 1719 | "outputs": [] 1720 | } 1721 | ] 1722 | } --------------------------------------------------------------------------------