├── 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 | "
"
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 | "
"
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 | ""
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 | ""
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 | ""
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 | "
"
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 | ""
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 | ""
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 | "\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 | "\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 | }
--------------------------------------------------------------------------------