├── .gitignore
├── README.md
├── docker_setup.sh
├── imgs
├── JupyterLabInterface.png
├── JupyterLabURL.png
├── chapter5notebook.png
└── docker_shell_run.png
└── notebooks
├── appendixA
├── Appendix_A.ipynb
└── Appendix_A_intro.ipynb
├── ch05
└── Chapter5.ipynb
├── ch06
└── Chapter6.ipynb
├── ch07
├── Chapter7_1.ipynb
└── Chapter7_2.ipynb
├── ch08
├── Chapter8_1.dbc
├── Chapter8_1.html
└── Chapter8_1.ipynb
├── ch09
├── CleanCode.py
├── UnitTestExample.py
├── WoT.py
└── __init__.py
├── ch10
└── Chapter10_1.ipynb
├── ch11
└── Chapter11.ipynb
├── ch12
└── Chapter12.ipynb
├── ch13
├── Chapter_13.dbc
├── Chapter_13.html
└── Chapter_13.scala
├── ch14
└── Chapter14.ipynb
├── ch15
├── Chapter15_1.ipynb
└── Chapter15_2.ipynb
└── ch16
├── Chapter16_1.dbc
├── Chapter16_1.html
├── Chapter16_1.ipynb
├── Chapter16_2.dbc
├── Chapter16_2.html
└── Chapter16_2.ipynb
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ML-Engineering
2 | Reference code base for ML Engineering in Action, Manning Publications
3 | Author: Ben Wilson
4 |
5 |
6 | ### About this repo
7 | This is a companion to the Manning book Machine Learning Engineering in Action.
8 | Within this repo are two separate types of notebooks, linked to the examples shown in chapters within the book.
9 | The formats of these notebooks come in several different flavors, depending on the type of examples that they are covering:
10 | - Jupyter notebooks for 'standalone Python'
11 | - PySpark Databricks archive notebooks (these can be imported into Databricks or Databricks Community Edition (free of charge))
12 | - PySpark html notebook representations (these can be loaded into any web browser for visualization)
13 | - Scala Spark Databricks notebooks (in .dbc, .html, and pure .scala formats)
14 |
15 | For the Jupyter notebooks, a pre-configured bash script is provided at the root level of this directory that will generate a docker image and automatically start the created container for you to rapidly get started with these notebooks.
16 |
17 |
18 | ### Getting Started with Docker
19 | To utilize the pre-built environment and follow along with the examples in the book with additional notes and code that wasn't included in the book, we first need Docker.
20 |
21 | There are a number of different ways to acquire Docker. Please visit their [website](https://docs.docker.com/get-docker/) for instructions on installing the desktop GUI and the engine.
22 |
23 | #### Creating the image
24 | The file [here](/docker_setup.sh) will, when executed through a bash command in your linux terminal, create the container to execute the Jupyter notebooks in this repo.
25 | The script will link this repo to the docker environment through piped synchronization to your local machine, download the required data to execute the code in the notebooks, and
26 | install the necessary dependencies to get Jupyter working (as well as some required libraries that are not part of the Anacondas runtime).
27 | ```text
28 | NOTE: Within the bash script is a variable named 'port' that will allow you to customize
29 | the access port that Jupyter and Docker will use to allow you to utilize a Jupyter notebook
30 | from your local web browser. If you currently have Jupyter running on your machine with the
31 | general 'default port' of 8888, this configuration utilizes 8887. Feel free to change it
32 | if there is a conflict.
33 | ```
34 | Once the shell script is executed, as shown below, the container will be constructed for your use.
35 |
36 | 
37 |
38 | #### Getting Jupyter to start up
39 | At the end of the container creation process, your terminal will have a url that you can paste
40 | into your web browser of choice, as shown below.
41 |
42 | 
43 |
44 | After copying one of these URL's (I typically stick to the local host 127.0.0.1/ one), paste it
45 | into a browser. You'll have all of the notebooks available that are part of the chapters of
46 | ML Engineering in Action.
47 |
48 | 
49 |
50 | Navigating within each of the chapters (the ones that have supported standalone Python Jupterlab
51 | examples; the Spark ones will not load here!) will give you the notebook links that you can click
52 | on and open the notebook in a new tab for reading, running, modification, and anything else
53 | you'd like to do.
54 |
55 | 
--------------------------------------------------------------------------------
/docker_setup.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # A shell script to initialize a new docker container that will host jupyter notebooks with the conda environment.
3 | # Many thanks to Jas Bali for making this so much better than what I originally had here. -Ben
4 | set -x
5 | port=8887
6 | dataset_repo_folder="$(mktemp -d)/tmp-datasets-folder"
7 | dataset_folder="$dataset_repo_folder/datasets"
8 | final_dataset_folder="$PWD/notebooks/TCPD/datasets"
9 | mkdir -p $dataset_repo_folder
10 |
11 | echo "Cloning datasets into folder: $dataset_repo_folder"
12 | git clone https://github.com/alan-turing-institute/TCPD $dataset_repo_folder
13 |
14 | rm -r $final_dataset_folder
15 | echo "Copying datasets from $dataset_folder into $final_dataset_folder"
16 | mkdir -p $final_dataset_folder
17 | cp -r "$dataset_folder/" "$final_dataset_folder/"
18 |
19 | echo "Starting Jupyter notebooks"s
20 |
21 | docker run -i --name=MLEngineeringInAction \
22 | -v $(PWD)/notebooks:/opt/notebooks -t \
23 | -p $port:$port continuumio/anaconda3 bin/bash \
24 | -c "/opt/conda/bin/conda install jupyter -y --quiet && \
25 | /opt/conda/bin/conda install -c conda-forge hyperopt=0.2.5 -y --quiet && \
26 | mkdir -p /opt/notebooks && \
27 | /opt/conda/bin/jupyter notebook --notebook-dir=/opt/notebooks \
28 | --ip='*' --port=$port --no-browser --allow-root"
29 |
--------------------------------------------------------------------------------
/imgs/JupyterLabInterface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenWilson2/ML-Engineering/0fc05f4b876b26bbacc85bcb11c7c2aef517cd20/imgs/JupyterLabInterface.png
--------------------------------------------------------------------------------
/imgs/JupyterLabURL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenWilson2/ML-Engineering/0fc05f4b876b26bbacc85bcb11c7c2aef517cd20/imgs/JupyterLabURL.png
--------------------------------------------------------------------------------
/imgs/chapter5notebook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenWilson2/ML-Engineering/0fc05f4b876b26bbacc85bcb11c7c2aef517cd20/imgs/chapter5notebook.png
--------------------------------------------------------------------------------
/imgs/docker_shell_run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenWilson2/ML-Engineering/0fc05f4b876b26bbacc85bcb11c7c2aef517cd20/imgs/docker_shell_run.png
--------------------------------------------------------------------------------
/notebooks/ch07/Chapter7_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Chapter 7, ML Engineering\n",
8 | "##### Author: Ben Wilson\n",
9 | "\n",
10 | "In this notebook, we'll be following along with the code listings shown in Chapter 7 for the stand-alone (local VM) portion. This covers section 7.1, listings 7.1 through 7.3. \n",
11 | "For the remainder of the listing references in section 7.1, you can refer to the project notebook for the local VM implementation for hyperopt tuning of the forecasting problem in the companion notebook to this entitled, \"Chapter7_Local_Hyperopt_Forecasting_Notebook\". That notebook will serve as a full-implementation guide to the remainder of the code listings in section 7.1."
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 1,
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "from matplotlib import pyplot as plt\n",
21 | "import random\n",
22 | "from hyperopt import hp, tpe, Trials, fmin"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "### Listing 7.1 Hyperopt fundamentals: the objective function\n",
30 | "In these first 3 listings, we're going to take a look at what hyperopt is actually doing and how it's a bit different from other implementations of hyperparameter tuning. We'll be comparing how the other algorithms (Random Search and Grid Search) fare against hyperopt from an accuracy standpoint and see what comes of our results. \n",
31 | "To start off, we need a function to optimize. Listing 7.1 below is building a very simple 4th order polynomial that will, based on a value of x that is passed in, provide a loss metric in the form of a reduction factor to the 'y' value based on the submitted x. "
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": 2,
37 | "metadata": {},
38 | "outputs": [],
39 | "source": [
40 | "import numpy as np\n",
41 | "def objective_function(x):\n",
42 | " func = np.poly1d([1, -3, -88, 112, -5])\n",
43 | " return func(x) * 0.01\n"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "For fun, let's see what this equation yields if we plot it in the space of [-100:100]"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 3,
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "# Get a sorted list between -100 and 100 at every 0.1 increment\n",
60 | "x_values_big = np.arange(-100, 100, 0.1)\n",
61 | "\n",
62 | "# Get the y value for the x values defined above using list comprehension shorthand\n",
63 | "y_values_big = [objective_function(x) for x in x_values_big]\n",
64 | "\n",
65 | "# For those of you who prefer lambda calculus... (and more efficient execution)\n",
66 | "y_values_lambda_big = (lambda x: objective_function(x))(x_values_big)\n",
67 | "\n",
68 | "# Just to placate anyone who wonders if they do the same thing.\n",
69 | "np.testing.assert_array_equal(np.array(y_values_big), y_values_lambda_big)"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "Ok, hold on... what's with the lambda stuff? Who wants functional programming concepts and partial functions in their code base for ML?
\n",
77 | "Professional ML Engineers do. \n",
78 | "That is, when it's called for. \n",
79 | "... and here's why."
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 4,
85 | "metadata": {},
86 | "outputs": [],
87 | "source": [
88 | "# let's make a few more x values here...\n",
89 | "big_x_test = np.arange(-100, 100, 0.0001)"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 5,
95 | "metadata": {},
96 | "outputs": [
97 | {
98 | "name": "stdout",
99 | "output_type": "stream",
100 | "text": [
101 | "Let's make this many: 2000000\n"
102 | ]
103 | }
104 | ],
105 | "source": [
106 | "print(\"Let's make this many: {}\".format(len(big_x_test)))"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": 6,
112 | "metadata": {},
113 | "outputs": [
114 | {
115 | "name": "stdout",
116 | "output_type": "stream",
117 | "text": [
118 | "CPU times: user 1min 18s, sys: 298 ms, total: 1min 18s\n",
119 | "Wall time: 1min 18s\n"
120 | ]
121 | }
122 | ],
123 | "source": [
124 | "%time list_comp_test = [objective_function(x) for x in big_x_test]"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": 7,
130 | "metadata": {},
131 | "outputs": [
132 | {
133 | "name": "stdout",
134 | "output_type": "stream",
135 | "text": [
136 | "CPU times: user 38.9 ms, sys: 33.8 ms, total: 72.7 ms\n",
137 | "Wall time: 72.6 ms\n"
138 | ]
139 | }
140 | ],
141 | "source": [
142 | "%time lambda_test = (lambda x: objective_function(x))(big_x_test)"
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {},
148 | "source": [
149 | "That's... quite the difference. \n",
150 | "Feel free to play around with the value specified in the definition for big_x_test and see if you can melt your CPU and see the non-linear relationship in performance between a list comprehension and a lambda. \n",
151 | "Note: There are many times that a list comprehension will actually out-perform lambda tasks. But in this particular case, where we're effectively mapping over a collection and calling a function, the optimizations of how lambda handles the traversal with the numpy array (and the subsequent compiled C++ code at the heart of numpy) means that operating on the numpy array with a lambda is going to be MUCH faster than traversing a Python list with a comprehension. These differences only really come into play when you're doing large-scale operations such as this."
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": 8,
157 | "metadata": {},
158 | "outputs": [
159 | {
160 | "name": "stdout",
161 | "output_type": "stream",
162 | "text": [
163 | "CPU times: user 434 ms, sys: 70.7 ms, total: 505 ms\n",
164 | "Wall time: 502 ms\n"
165 | ]
166 | },
167 | {
168 | "data": {
169 | "text/plain": [
170 | "[]"
171 | ]
172 | },
173 | "execution_count": 8,
174 | "metadata": {},
175 | "output_type": "execute_result"
176 | },
177 | {
178 | "data": {
179 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAEDCAYAAAAlRP8qAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deXxcdb3/8ddnJkuztEmzdEvSJV3pXhpK2fddqSgoVa8biqhc9aFewYd38+H9uV69XhREXC7ivcKFCwpCoWyytoWG7nvTNjRJ0zZtmqRNmnW+vz9mUqchaaftzJyZyfv5eIRkzpxk3pyk75x8z/ecY845REQk+fm8DiAiItGhQhcRSREqdBGRFKFCFxFJESp0EZEUoUIXEUkRnha6mf3OzPab2YYI1/+wmW0ys41m9sdY5xMRSSbm5Tx0M7sYOAI85JybeZJ1JwOPApc75w6Z2Qjn3P545BQRSQae7qE7514DGsOXmdlEM3vOzN4xs9fNbFroqc8B9zrnDoU+V2UuIhImEcfQHwD+3jk3H/gGcF9o+RRgipm9aWYrzOxazxKKiCSgNK8DhDOzXOB84DEz612cGXqfBkwGLgVKgdfNbKZzrineOUVEElFCFTrBvxianHNz+3muFljhnOsCdpnZVoIFvzKeAUVEElVCDbk451oIlvUtABY0J/T0n4HLQsuLCA7B7PQkqIhIAvJ62uLDwHJgqpnVmtltwMeA28xsLbARWBRafSlw0Mw2AX8F/sE5d9CL3CIiicjTaYsiIhI9CTXkIiIip8+zg6JFRUVu/PjxXr28iEhSeueddw4454r7e86zQh8/fjyVlZVevbyISFIys3cHek5DLiIiKUKFLiKSIlToIiIpQoUuIpIiVOgiIilChS4ikiJU6CIiKSLpCn3r3sN8f8lmWju6vY4iIpJQkq7Qaxrb+NVrO9lU3+J1FBGRhHLSQj/ZjZxDl7i9x8yqzGydmZ0d/Zh/M6s0D4D1tc2xfBkRkaQTyR76g8CJbvd2HcEbTUwGbgd+eeaxBjZy2BCKh2ayoU6FLiIS7qSF3t+NnPtYBDzkglYA+WY2OloB+zO7JI/1KnQRkeNEYwy9BKgJe1wbWvYeZna7mVWaWWVDQ8Npv+DMkjyqGo7owKiISJhoFLr1s6zfu2Y45x5wzlU45yqKi/u9+mNEZpXk4Rw6MCoiEiYahV4LlIU9LgX2ROHrDkgHRkVE3isahf4U8InQbJeFQLNzrj4KX3dAOjAqIvJeJ73BRehGzpcCRWZWC/wLkA7gnLsfWAJcD1QBbcCnYxU23CwdGBUROc5JC905t/gkzzvgS1FLFKGZJXm8snU/bZ3dZGd4duMlEZGEkXRnivaaXZJHwMGmPTowKiLJoyfQ75yRqEjaQj92YFTDLiKSJJxznPf9l/iPF7bF5OsnbaH3HhhVoYtIsqg9dJT9hzsoHpoZk6+ftIUOwQOjmukiIsliTU0TAHPL8mPy9ZO60GeW5FG1/whtnTpjVEQS37raJjLSfEwdNTQmXz+pC32WDoyKSBJZW9vMjDHDSPfHpnqTvtBBB0ZFJPH1BBwb6pqZUxqb4RZI8kIfOSwzeGBUlwAQkQQXHB7uYU5ZXsxeI6kL3cyYU5rPmtomr6OIiJzQ2tAB0dnaQx/YvLH57Gxopbmty+soIiIDWlvbxNDMNCYU5sTsNZK+0Hun/6zVXrqIJLC1tU3MLsvD5+vviuPRkfSFPqs0D7O/ze8UEUk07V09bKk/HNPhFkiBQh82JJ2JxbnHxqdERBLNpvoWugMupjNcIAUKHYLDLmtqmghe+FFEJLGsC+1wxnKGC6RQoR9s7aT20FGvo4iIvMfa2mZGDM1k1LAhMX2dlCl0gNUadhGRBLS2tonZpfmYxe6AKKRIoU8dNZTMNJ/G0UUk4TQf7WJnQytzSmM73AIpUujpfh+zSvI000VEEk7vFWFnx+gKi+FSotAB5pTls6Guma6egNdRRESOWfXuIQDmxniGC6RQoc8ty6ejO8CW+sNeRxEROead3YeYPCKXvOz0mL9WShU6oOu6iEjCCAQcq3c3cfbY4XF5vZQp9NLhWRTlZrBmtwpdRBLDzgOtNB/t4uxxsR9ugRQq9GNXXqw55HUUEREAVu0O9pH20E/DvLH57NCVF0UkQazefYhhQ9KYWJwbl9dLqUI/e1zwt2Dvb0URES+tereJuWOHx/QKi+FSqtDnluXj9xmV7zZ6HUVEBrmW9i627T/M/DgNt0CKFXp2RhrTRw/jnXe1hy4i3lqzuwnniNsBUUixQgeYP244a2qadIKRiHhq1e5DmP1tSnU8pFyhV4wfTntXgE17WryOIiKD2KrdTUwZMZShQ2J/QlGvlCv0+aEDoxp2ERGvBE8oOhTX4RaIsNDN7Foz22pmVWZ2dz/P55nZX8xsrZltNLNPRz9qZEbnZVGSn6VCFxHP7Gg4wuH2bubF8YAoRFDoZuYH7gWuA6YDi81sep/VvgRscs7NAS4FfmJmGVHOGrH544ZT+W6j7mAkIp6I9wlFvSLZQ18AVDnndjrnOoFHgEV91nHAUAtevT0XaAS6o5r0FMwfN5x9LR3UNekORiISf5XVh8jPTqe8KCeurxtJoZcANWGPa0PLwv0COAvYA6wHvuKce880EzO73cwqzayyoaHhNCOfnMbRRcRLK6sbqRgXvxOKekVS6P0l6juWcQ2wBhgDzAV+YWbD3vNJzj3gnKtwzlUUFxefcthITRs1lOwMvwpdROJu/+F2qg+2sWBCQdxfO5JCrwXKwh6XEtwTD/dp4AkXVAXsAqZFJ+KpS/P7mDc2n8pqFbqIxNfKXcHeOWd8Yhb6SmCymU0IHei8FXiqzzq7gSsAzGwkMBXYGc2gp2r+uAK27G3hSIdnQ/kiMgitrG4kK93PzJLY30O0r5MWunOuG7gTWApsBh51zm00szvM7I7Qat8Fzjez9cBLwF3OuQOxCh2J+eOGE3DBq52JiMTL27samTc2n3R//E/zSYtkJefcEmBJn2X3h328B7g6utHOzNlj8/FZcONeNDl24/UiIr2aj3axeW8LX758sievn3JnivYaOiSdmSV5vLVLV14UkfhY9e4hnINzPTggCilc6BDcqGtqmmjv6vE6iogMAm9XN5Lms7ifIdorxQu9kM7uAGtqdJ9REYm9lbsamVmSR1aG35PXT+lCP2d8AWbw1k4Nu4hIbLV39bCuttmT+ee9UrrQ87LTmTZqGG/tOuh1FBFJcWtrmujsCXgy/7xXShc6BMfRV+0+RGe3bnghIrGzsjo4ElAxzpvxcxgEhb6wvID2rgDrajWOLiKx89auRqaOHMrwHM8uNJv6hb5gQiGApi+KSMx09QR4591Dno6fwyAo9IKcDKaMzFWhi0jMrKttoq2zh/MnFnqaI+ULHYLTF9+pbqRbN44WkRhYVhWceLGwXIUec+eWF9Da2cMG3ThaRGJg+c6DnDV6mKfj5zBICr13XOutnZq+KCLR1d7VQ+W7hzwfboFBUugjhg6hvDiH5Sp0EYmy1bub6OwOcJ7Hwy0wSAod4IKJRby9q1Hz0UUkqpbvOIDPYEG5tzNcYDAV+qQi2jp7WKv56CISRct2HGRWaT7DhqR7HWXwFPp55YX4DN7Y7ul9N0QkhbR1drOmpikhhltgEBV6XnY6s0ryWLZDhS4i0bGy+hDdAZcQB0RhEBU6wPmTili9u4lW3WdURKJg+Y6DpPuNivHeXb8l3KAq9AsnFdEdcLyts0ZFJAqW7zjA3LJ8sjMiuptnzA2qQp8/bjgZaT7eqNKwi4icmeajXayva06Y8XMYZIU+JN3POeOH86YKXUTO0PIdBwg4uGhK4tyEflAVOgSnL27Ze5gDRzq8jiIiSey17QfIzUxjblm+11GOGXyFPrEICM4dFRE5Hc45XtvWwHkTC0n3J06NJk6SOJlZksewIWm8qfnoInKaqg+2UXvoKBcn0HALDMJC9/uM8yYW8kbVAZxzXscRkST0+vYGAC6eXORxkuMNukIHuGhyMXVNR9l5oNXrKCKShF7b1sDYgmzGFeZ4HeU4g7LQLwn9mfTK1gaPk4hIsunsDrB8x0EuSrC9cxikhV5WkM3E4hxe2brf6ygikmRW7z5Ea2dPwo2fwyAtdIBLp47grV2NHO3s8TqKiCSR17Y3HDsWl2gGcaEX09kdYIVueiEip+D17QeYV5YYl8vtK6JCN7NrzWyrmVWZ2d0DrHOpma0xs41m9mp0Y0bfOeMLyEr38+o2jaOLSGQaWztZX9fMRZMTb7gF4KRXlDEzP3AvcBVQC6w0s6ecc5vC1skH7gOudc7tNrMRsQocLUPS/Zw3sTA0jj7D6zgikgRe396Ac3DxlMQ7IAqR7aEvAKqcczudc53AI8CiPut8FHjCObcbwDmXFEcbL5lSTPXBNqo1fVFEIvDS5v0U5mQwpzRxTvcPF0mhlwA1YY9rQ8vCTQGGm9krZvaOmX2ivy9kZrebWaWZVTY0eD/UcenU4J9NGnYRkZPp7gnw6rYGLp06Ap/PvI7Tr0gKvb/kfU+xTAPmAzcA1wD/ZGZT3vNJzj3gnKtwzlUUF3s/BjWuMIcJRZq+KCInt2p3E81Hu7jirMQdUY6k0GuBsrDHpcCeftZ5zjnX6pw7ALwGzIlOxNi6ZEoxy3cepL1L0xdFZGAvb9lPms+4MAFPKOoVSaGvBCab2QQzywBuBZ7qs86TwEVmlmZm2cC5wOboRo2NS6YW094VYLmmL4rICby8ZR8LJhQk5HTFXictdOdcN3AnsJRgST/qnNtoZneY2R2hdTYDzwHrgLeB3zjnNsQudvScV15Idoaflzbv8zqKiCSomsY2tu07wuXTEne4BSKYtgjgnFsCLOmz7P4+j38M/Dh60eJjSLqfiycX8+Km/Xx3kcMsMQ92iIh3/ho6zpbohT5ozxQNd+X0kextaWfjnhavo4hIAnp5y37GF2ZTXpzrdZQTUqEDl00txmfwwiYNu4jI8do6u1m24yCXTxvpdZSTUqEDhbmZzB83nBc1ji4ifSyrOkhndyDhh1tAhX7MlWeNZOOeFvY0HfU6iogkkOc37WVoZhoLJhR4HeWkVOghV04P/jmlvXQR6dXdE+DFzfu5/KwRZKQlfl0mfsI4mVicS3lRjsbRReSYyncP0djayTUzRnkdJSIq9DBXTh/Jip0HOdze5XUUEUkAz23YS0aa79htKxOdCj3MlWeNpKvH6WJdIoJzjhc27ePiyUXkZEZ0yo7nVOhh5o8bTlFuBs9t2Ot1FBHx2Ia6FuqajnJ1kgy3gAr9OH6fcfWMUby8Zb8u1iUyyC3duBefBf9yTxYq9D6unzmats4eXtmqYReRwWzpxr0smFBAQU6G11EipkLvY2F5AcOz03l2Q73XUUTEIzsbjrB9/5Gkmd3SS4XeR5rfxzUzRvHSZg27iAxWz20MHkdLpvFzUKH367pZoznS0c0b2w94HUVEPPDMunrmlOVTkp/ldZRTokLvx/kTC8nLSmeJhl1EBp1dB1rZuKeF988e7XWUU6ZC70e638fV00fywqZ9dHRr2EVkMHl6bfAOmzeo0FPH9bNGc7i9m2VVujWdyGDyl3V7OGf8cEbnJddwC6jQB3TBpCKGDknj6XUadhEZLLbtO8y2fUd43+wxXkc5LSr0AWSk+bh2xiiWbtyr2S4ig8TTa/fgM7huVnLNbumlQj+BD8wr4UhHNy9t3u91FBGJMeccT6+rZ2F5ISOGDvE6zmlRoZ9A8BubyZNr6ryOIiIxtqm+hZ0HWpN2uAVU6Cfk9xnvnzOGV7Y20NymS+qKpLK/rK3H7zOunZmcwy2gQj+pD8wtobMnoDnpIiksEHA8uaaOiyYXJdW1W/pSoZ/EzJJhlBfn8OfVGnYRSVUrdh6kvrmdD51d6nWUM6JCPwkzY9GcEt6ubtQNpEVS1OOr6hiamcZV05PnUrn9UaFHYNHcMTgHfwmdQSYiqaOts5tnN9Rzw+zRDEn3ex3njKjQIzC+KIe5Zfn8aXUdzjmv44hIFC3duJe2zh4+mOTDLaBCj9jN80vZsvcwG+pavI4iIlH0xKo6ygqyqBg33OsoZ0yFHqH3zxlDZpqPRytrvI4iIlGyt7mdN6oOcNO8Unw+8zrOGYuo0M3sWjPbamZVZnb3CdY7x8x6zOzm6EVMDHlZ6Vw3cxRPrqnTpQBEUsSf19ThHHxwXonXUaLipIVuZn7gXuA6YDqw2MymD7DeD4Gl0Q6ZKD5cUUZLezdLQ3czEZHk5Zzjscoa5o8bzviiHK/jREUke+gLgCrn3E7nXCfwCLCon/X+HngcSNkLnywsL6R0eBaPVdZ6HUVEztDK6kPsaGjlI+eUeR0laiIp9BIgfOC4NrTsGDMrAW4C7j/RFzKz282s0swqGxoaTjWr53w+45b5Zby54wA1jW1exxGRM/Dw27sZmpnG+5LwRhYDiaTQ+ztS0Hfu3s+Au5xzJxxcds494JyrcM5VFBcXR5oxodxcEZza9Pgq7aWLJKumtk6eWV/PonljyM5I8zpO1ERS6LVA+N8kpUDfM2wqgEfMrBq4GbjPzD4QlYQJpiQ/iwsnFfFYZS09Ac1JF0lGf1pdR2d3gMULxnodJaoiKfSVwGQzm2BmGcCtwFPhKzjnJjjnxjvnxgP/B3zROffnqKdNEIsXjKWu6SivbkvZwwUiKcs5xyNv1zC7NI8ZY/K8jhNVJy1051w3cCfB2SubgUedcxvN7A4zuyPWARPRVdNHMmJoJn9Y/q7XUUTkFK2uaWLrvsMpt3cOENHgkXNuCbCkz7J+D4A65z515rESW7rfx+IFY7nn5e3sPtjG2MJsryOJSIQefms32Rl+3j8neW9kMRCdKXqaFi8Yi8+M/3lbe+kiyeJQaydPrd3Dorkl5GamzsHQXir00zQqbwhXTx/JoytrdOaoSJJ4ZGUNHd0BPnn+OK+jxIQK/Qx8fOE4DrV1sWS97mYkkui6ewL894p3Oa+8kGmjhnkdJyZU6Gfg/ImFlBfn8IcVGnYRSXQvbt5HXdNRPnn+eK+jxIwK/QyYGX+3cByrdzexpqbJ6zgicgIPLqumJD+LK88a4XWUmFGhn6FbKsoYmpnGb17f6XUUERnA5voWVuxs5BPnjSPNn7q1l7r/Z3GSm5nG4nPH8uyGvdQe0vVdRBLRQ8urGZLuS6kLcfVHhR4Fnzp/PAb815vVXkcRkT4aDnfw+Ko6bppXSn52htdxYkqFHgVj8rO4YfZo/ndlDS3tXV7HEZEwv19WTVdPgM9dNMHrKDGnQo+Sz11UzpGObh55e7fXUUQkpLWjm4eWV3PN9FGUF+d6HSfmVOhRMrMkj4XlBfzXm8G9ARHx3sNv76alvZvPX1LudZS4UKFH0e0Xl1Pf3M6Ta/peXVhE4q2rJ8Bv39jFuRMKmDd2uNdx4kKFHkWXTR3B9NHDuO+vVbpWuojHnlqzh/rmdu64ZKLXUeJGhR5FZsbfXz6JnQdaeUaXAxDxTCDguP/VHUwdOZRLpybn3dFOhwo9yq6ZMYrJI3L5xcvbCWgvXcQTSzbUs33/Eb50+STM+ruLZmpSoUeZz2fcefkktu07wvOb9nkdR2TQCQQc//nidiaPyOWGWalzA+hIqNBj4IZZoxlfmM3PX96Oc9pLF4mnZ9YH986/fMVk/L7Bs3cOKvSYSPP7+OJlk9i4p4UXN+u+oyLx0hNw3PPS4Nw7BxV6zHxwXgkTinL496VbNeNFJE6WhPbOv3LlZHyDbO8cVOgxk+b38bWrprB132GeWlvndRyRlNfdE+BnL25jyshcrp85+PbOQYUeUzfMGs2MMcP46Qvb6OzW2aMisfRoZS07Glr5+tVTB+XeOajQY8rnM/7hmqnUNB7lkZW6xotIrLR1dvMfL26jYtxwrp4+0us4nlGhx9glU4pZMKGAe16qoq2z2+s4Iinpt6/vouFwB9+6ftqgmnfelwo9xsyMu66dyoEjHfzqVd3VSCTaDhzp4P5Xd3DNjJHMH1fgdRxPqdDjYP64At43ezS/em0HdU1HvY4jklJ+/tJ22rsDfPPaaV5H8ZwKPU6+df1ZOAc/eHaL11FEUsbWvYf577d2s3hBGRMHwfXOT0aFHicl+Vl8/uJy/rJ2D5XVjV7HEUl6zjn+5akNDB2Sxtevmup1nISgQo+jOy6dyKhhQ/jOXzbpwl0iZ+jpdfWs2NnIN66eyvCc1L5XaKRU6HGUnZHG3ddNY31dM/9bWeN1HJGk1dbZzfeWbGbGmGEsXjDW6zgJQ4UeZ4vmjuHcCQV8f8lm9h9u9zqOSFL6xctV1De3850bZwy6C3CdSESFbmbXmtlWM6sys7v7ef5jZrYu9LbMzOZEP2pqMDO+98FZtHcF+O7Tm72OI5J0tuxt4YHXdvLBs0uoGD+4pyn2ddJCNzM/cC9wHTAdWGxm0/ustgu4xDk3G/gu8EC0g6aSicW5fPGyifxl7R5e2aqrMYpEqifguOvx9QzLSucfb+hbQxLJHvoCoMo5t9M51wk8AiwKX8E5t8w5dyj0cAVQGt2YqecLl05kYnEO//jnDTqDVCRC//XmLtbWNPGvN86gQAdC3yOSQi8Bwo/g1YaWDeQ24Nn+njCz282s0swqGxoaIk+ZgjLT/HzvplnUHjrKj57b6nUckYRX09jGT57fxhXTRvD+2YPzaoonE0mh93fEod85d2Z2GcFCv6u/551zDzjnKpxzFcXFg+fGrQM5t7yQT50/ngeXVbOs6oDXcUQSViDguOvxdfh9xr/dNHNQX6/lRCIp9FqgLOxxKbCn70pmNhv4DbDIOXcwOvFS313XTqO8KIdvPLaWlvYur+OIJKTfvbmLZTsO8o83nMXovCyv4ySsSAp9JTDZzCaYWQZwK/BU+ApmNhZ4Avg759y26MdMXVkZfn76kbnsO9zBd57a5HUckYSzub6FHz23launj+Qj55Sd/BMGsZMWunOuG7gTWApsBh51zm00szvM7I7Qav8MFAL3mdkaM6uMWeIUNLcsny9dOpHHV9Xy7Pp6r+OIJIz2rh6++sga8rLT+cGHZmuo5STSIlnJObcEWNJn2f1hH38W+Gx0ow0ud14+mVe3NfDNx9cxY0weYwuzvY4k4rkfPLuFrfsO8+Cnz9GslgjoTNEEkZHm4xcfPRsDvvTHVXR093gdScRTT6/bw4PLqvn0BeO5dOoIr+MkBRV6AikryObfb5nD+rpm/t8zOotUBq+q/Ue46//WcfbYfL513Vlex0kaKvQEc/WMUXz2wgk8tPxdnlxT53Uckbhr7ejmC//9DkPS/dz7sbPJSFNNRUpbKgHddd00Fowv4Jv/t451tU1exxGJm0DA8c3H17Gj4Qj3LJ6nKYqnSIWegNL9Pn758bMpys3kcw9VsrdZV2WUweFnL27jmXX13HXtNC6YVOR1nKSjQk9QhbmZ/PZTFRxp7+b2P1TS3qWDpJLanlhVyz0vV/HhilJuv7jc6zhJSYWewKaNGsbPbp3H+rpmvvzwarp7Al5HEomJt3c1cvfj6zmvvJB/+8AszTc/TSr0BHfV9JH8y/um8/ymfXz7TxtwTreuk9SyaU8Ln/39SkqHZ/HLj+sg6JmI6MQi8danLpjAwdZOfv5yFQW5Gdx17TSvI4lExa4DrXzid2+Rk5nGQ7ctID9bJw+dCRV6kvjaVVM42NrJL1/ZwbAh6Xzh0oleRxI5I/XNR/n4b94i4OAPt51L6XCdHX2mVOhJwsz47qKZHG7v5ofPbSHgHF+6bJLXsUROS13TUT766xU0H+3i4c8tZNKIXK8jpQQVehLx+4z/+PAcfAY/XrqVnoDjy1dM9jqWyCl592ArH/31W7S0d/H7zyxgVmme15FShgo9yaT5ffz0w3Pxm/HTF7bR3tXDP1wzVbMCJCnsaDjCR3+9go7uAA9/biEzS1Tm0aRCT0J+n/HjW+aQme7jvld2sLelnR98cLZmB0hCq6xu5HMPVeL3GY/cvpBpo4Z5HSnlqNCTlN9nfO+mWYzOy+KnL2yj4XAH933sbIYOSfc6msh7PL1uD197dC0l+Vk8+OlzGFeY43WklKRduiRmZnz5isn86ObZLNtxkA/9chm7DrR6HUvkGOcc9/61ijv/uJo5pXk88YXzVeYxpEJPAR+uKOOhzyyg4XAHN/7iDV7avM/rSCK0tHfx+T+8w4+XbuXGOWP4w23nMlw3qYgpFXqKuGBSEU/deSFjC7K57feV/PT5rbpUgHhmc30LN/78DV7esp9/et90/vPWuQxJ93sdK+Wp0FNIWUE2j3/hfG6eX8o9L1dx8/3LqdYQjMRRIOD4zes7WXTvm7R19vDw7Qu57cIJmoUVJyr0FDMk3c+/3zKHexbPY2fDEa6/53Uefnu3rgEjMVfT2MbiX6/g357ZzCVTilnylYs4Z3yB17EGFc1ySVE3zhlDxbjhfP3RtXzrifX8aXUd37tpJpNGDPU6mqSYrp4AD75Zzc9e3IaZ8eObZ3Pz/FLtlXvAvNpzq6iocJWVlZ689mASCDgerazh+89uoa2zm9svLueLl04iJ1O/y+XMvb2rkX/68wa27jvM5dNG8J0bZ1BWoGuyxJKZveOcq+j3ORX64HDgSAffe2YzT6yuoyg3k69eOZmPnFNGul+jbnLqqvYf5ifPb+PZDXspyc/iX94/naumj9ReeRyo0OWYd949xA+e3czK6kOUF+XwlSsnc8Os0aSp2CUCNY1t3PPSdh5fVUtWup/PXlTO5y8pJztDf/HFiwpdjuOc46XN+/nR0i1s23eEsoIsbr94IrfML9XUMunXhrpmfvXaTpasr8dvxt+dN44vXjqRwtxMr6MNOip06Vcg4Hhx8z7ue2UHa2qaKMjJ4Ob5pSxeMJYJRTqbb7Dr6O7h+Y37+ONbu1m+8yC5mWksXlDGZy6cwOi8LK/jDVoqdDkh5xxv7WrkwTereWHzPnoCjvPKC7l5filXTh9JXpauDzNYOOfYuKeFx1fV8ufVdRxq66IkP4tPnDeOxeeOZZiuFeS5ExW6Br4EM2NheSELywvZ39LOY+/U8sjK3Xz9sbVk+H1cPKWI62eN5rKpI3TqdgoKBBxraptYumEvz27Yy9nTrEYAAAlQSURBVO7GNtL9xtUzRvGRijIumFSE36eDnclAe+jSL+cca2qaeGZdPUvW17OnuR0zmFWSx8WTi7lochFzyvI15p6kahrbeLPqAG9UHWD5joMcbO0k3W+cP7GI62aO4uoZoyjQL++EpCEXOSOBgGNdXTOvbWvgtW0NrK5poifgSPcb08fkMa8sn3lj85kxJo/xhdmaMZNgWtq72FDbzJraJtbVNLOutok9ze0AjByWyQUTi7hoShGXT9PwWjI440I3s2uB/wT8wG+ccz/o87yFnr8eaAM+5ZxbdaKvqUJPXs1Hu3hr50FW7W5i9e5DrKtt5mhXDwAZfh/lxTlMHTWUySNyKR2eTenwLEqHZzNiaCY+/ekeE0c6uqlvOsqe5naqD7Syo+EIVfuPsKPhCPtaOo6tN74wm9ml+Zw9Np8LJxcxsThXc8eTzBmNoZuZH7gXuAqoBVaa2VPOuU1hq10HTA69nQv8MvReUlBeVjpXzwj+WQ7Q3RNg677DbKk/zLZ9wbfK6kM8uWbPcZ+X7jdG5Q2hKDeTwpwMCnMyKcjNoDAng7ysdHIz08jJTCMn0x98nxF8nJnmI81vpPt8KfsLoSfgaO/q4WhXD+3H3gK0d/XQ2tlDU1snTW1dHAq9bz7axcHWTvY1t7On+SiH27uP+3q5mWlMHJHLhZOKmTgih5lj8phdmkd+toZRUlkkB0UXAFXOuZ0AZvYIsAgIL/RFwEMuuLu/wszyzWy0c64+6okl4aT5fcwYk8eMMcffH/JoZw91TW3UHjp67K2++SgHj3RS19TOutpmGls76Q5EPuzn9xnpoXJPT/OR5jPSfHZsL7N3Z9MMDAu9711mwY971wEcwf84gscNgu/B4YLvQ9H6fY7e58MfB9ejd93exyd4jYBzdPVEvg2GDkljeHYG+dnpjCvMZmF5AaPzsxidN4TReVmMKwz+NaQ978EnkkIvAWrCHtfy3r3v/tYpAY4rdDO7HbgdYOzYsaeaVZJMVoafSSOGnvCCYM45Wo5209LexZGOblo7umnt7KG1o/vY466eAF09LvQ+QHePozP0vqsnQHfAHSvI4BcdoFxDy0KrBP8TKvzesrc+j+nzi+G4XxShFfp9LvS64b9o3vN1Qq/h8xlD0vxkZfgYku7/21uaj6wMP9kZfvKzM8jPSicvK13HKGRAkRR6f7/m++5ORLIOzrkHgAcgOIYewWtLijMz8rLTycvWwTiRMxXJr/paoCzscSmw5zTWERGRGIqk0FcCk81sgpllALcCT/VZ5yngExa0EGjW+LmISHyddMjFOddtZncCSwlOW/ydc26jmd0Rev5+YAnBKYtVBKctfjp2kUVEpD8RnfrvnFtCsLTDl90f9rEDvhTdaCIicip0uFxEJEWo0EVEUoQKXUQkRajQRURShGdXWzSzBuDd0/z0IuBAFONES6LmgsTNplynRrlOTSrmGuecK+7vCc8K/UyYWeVAVxvzUqLmgsTNplynRrlOzWDLpSEXEZEUoUIXEUkRyVroD3gdYACJmgsSN5tynRrlOjWDKldSjqGLiMh7JeseuoiI9KFCFxFJEQlf6GZ2i5ltNLOAmVX0ee5bZlZlZlvN7Jqw5fPNbH3ouXssxvfiMrP/NbM1obdqM1sTWj7ezI6GPXf/yb5WlHP9q5nVhb3+9WHP9bvt4pTrx2a2xczWmdmfzCw/tNzT7RXKcG1om1SZ2d3xfv2wHGVm9lcz2xz6+f9KaPmA39M4ZqsO/ftaY2aVoWUFZvaCmW0PvR8e50xTw7bJGjNrMbOverG9zOx3ZrbfzDaELRtw+0T136JzLqHfgLOAqcArQEXY8unAWiATmADsAPyh594GziN4J6VngevimPcnwD+HPh4PbPBw2/0r8I1+lg+47eKU62ogLfTxD4EfJsj28oe2RTmQEdpG0z3KMho4O/TxUGBb6PvW7/c0ztmqgaI+y34E3B36+O7e76mH38e9wDgvthdwMXB2+M/yQNsn2v8WE34P3Tm32Tm3tZ+nFgGPOOc6nHO7CF6LfYGZjQaGOeeWu+AWewj4QDyyhv4S+DDwcDxe7wz0u+3i9eLOueedc723qV9B8A5XieDYDdGdc51A7w3R4845V++cWxX6+DCwmeB9ehPVIuD3oY9/T5z+zQ3gCmCHc+50z0Q/I86514DGPosH2j5R/beY8IV+AgPdmLok9HHf5fFwEbDPObc9bNkEM1ttZq+a2UVxyhHuztDQxu/C/swbaNt54TME/4rq5eX2SqTtcoyZjQfmAW+FFvX3PY0nBzxvZu9Y8MbvACNd6C5lofcjPMjV61aO36nyenvBwNsnqj9zCVHoZvaimW3o5+1Ee0cD3Zg6ohtWxyjjYo7/QaoHxjrn5gFfA/5oZsPONMsp5PolMBGYG8ryk95P6+dLRXX+aiTby8y+DXQD/xNaFPPtdbLY/SzzdF6vmeUCjwNfdc61MPD3NJ4ucM6dDVwHfMnMLvYgQ78seJvMG4HHQosSYXudSFR/5iK6Y1GsOeeuPI1PG+jG1LUc/yd8VG5YfbKMZpYGfBCYH/Y5HUBH6ON3zGwHMAWoPNM8keYKy/dr4OnQw5jf1DuC7fVJ4H3AFaGhsbhsr5NIqJudm1k6wTL/H+fcEwDOuX1hz4d/T+PGObcn9H6/mf2J4BDBPjMb7ZyrDw177o93rpDrgFW92ykRtlfIQNsnqj9zCbGHfpqeAm41s0wzmwBMBt4O/Tlz2MwWhsa0PwE8GYc8VwJbnHPHhnvMrNjM/KGPy0MZd8YhS+/rjw57eBPQe9S9320Xx1zXAncBNzrn2sKWe7q9iOyG6HER+tn9LbDZOffTsOUDfU/jlSvHzIb2fkzwAPcGgtvpk6HVPkl8/s3157i/kr3eXmEG2j7R/bfo1ZHoUzhifBPB32IdwD5gadhz3yZ4VHgrYTNZgAqC37gdwC8InREb45wPAnf0WfYhYCPBo9irgPfHedv9AVgPrAv94Iw+2baLU64qguOGa0Jv9yfC9gpluJ7gjJIdwLfj/fphOS4k+Kf3urDtdP2JvqdxylUe+v6sDX2vvh1aXgi8BGwPvS/wYJtlAweBvLBlcd9eBH+h1ANdoe667UTbJ5r/FnXqv4hIikjmIRcREQmjQhcRSREqdBGRFKFCFxFJESp0EZEUoUIXEUkRKnQRkRTx/wGfMxbUw6FvIQAAAABJRU5ErkJggg==\n",
180 | "text/plain": [
181 | ""
182 | ]
183 | },
184 | "metadata": {
185 | "needs_background": "light"
186 | },
187 | "output_type": "display_data"
188 | }
189 | ],
190 | "source": [
191 | "# Evaluate the wall-clock speed of plotting the list comprehension\n",
192 | "%time plt.plot(big_x_test, list_comp_test)"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": 9,
198 | "metadata": {},
199 | "outputs": [
200 | {
201 | "name": "stdout",
202 | "output_type": "stream",
203 | "text": [
204 | "CPU times: user 71 ms, sys: 44 ms, total: 115 ms\n",
205 | "Wall time: 116 ms\n"
206 | ]
207 | },
208 | {
209 | "data": {
210 | "text/plain": [
211 | "[]"
212 | ]
213 | },
214 | "execution_count": 9,
215 | "metadata": {},
216 | "output_type": "execute_result"
217 | },
218 | {
219 | "data": {
220 | "image/png": "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\n",
221 | "text/plain": [
222 | ""
223 | ]
224 | },
225 | "metadata": {
226 | "needs_background": "light"
227 | },
228 | "output_type": "display_data"
229 | }
230 | ],
231 | "source": [
232 | "# And evaluate the wall-clock of plotting the lambda implementation\n",
233 | "%time plt.plot(big_x_test, lambda_test)"
234 | ]
235 | },
236 | {
237 | "cell_type": "markdown",
238 | "metadata": {},
239 | "source": [
240 | ".... and for those who will state, \"But lambda and list comprehensions are lazily evaluated in Py3.x....\", let's ensure that they're materialized through a forced execution by plotting their values in pyplot. This comes down the fact that one is a numpy array and one is a list (because the initial calculation to generate the collections above in the first block of timeit cells actually wasn't lazy)."
241 | ]
242 | },
243 | {
244 | "cell_type": "code",
245 | "execution_count": 10,
246 | "metadata": {},
247 | "outputs": [
248 | {
249 | "data": {
250 | "text/plain": [
251 | "[]"
252 | ]
253 | },
254 | "execution_count": 10,
255 | "metadata": {},
256 | "output_type": "execute_result"
257 | },
258 | {
259 | "data": {
260 | "image/png": "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\n",
261 | "text/plain": [
262 | ""
263 | ]
264 | },
265 | "metadata": {
266 | "needs_background": "light"
267 | },
268 | "output_type": "display_data"
269 | }
270 | ],
271 | "source": [
272 | "y_lambda = (lambda x: objective_function(x))(x_values_big)\n",
273 | "plt.plot(x_values_big, y_lambda)"
274 | ]
275 | },
276 | {
277 | "cell_type": "markdown",
278 | "metadata": {},
279 | "source": [
280 | "So... that's not super helpful for seeing the nuance to this equation. The resolution of the plot doesn't allow us to see where the actual minimum value is."
281 | ]
282 | },
283 | {
284 | "cell_type": "markdown",
285 | "metadata": {},
286 | "source": [
287 | "Let's see what the representation will be for this equation if we generate values against this function (in the x space before it becomes very large in the y space so that we can see the challenge that these different methods of searching for a global minima will have. This will help to inform our search range for the different approaches as well."
288 | ]
289 | },
290 | {
291 | "cell_type": "code",
292 | "execution_count": 11,
293 | "metadata": {},
294 | "outputs": [
295 | {
296 | "data": {
297 | "text/plain": [
298 | "[]"
299 | ]
300 | },
301 | "execution_count": 11,
302 | "metadata": {},
303 | "output_type": "execute_result"
304 | },
305 | {
306 | "data": {
307 | "image/png": "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\n",
308 | "text/plain": [
309 | ""
310 | ]
311 | },
312 | "metadata": {
313 | "needs_background": "light"
314 | },
315 | "output_type": "display_data"
316 | }
317 | ],
318 | "source": [
319 | "# Now, let's see it zoomed in to the range where we can see what's going on with minimum range of values for y...\n",
320 | "x_axis_values = np.arange(-12.0, 12.0, 0.01).tolist()\n",
321 | "y_values = (lambda x: objective_function(x))(x_axis_values)\n",
322 | "plt.plot(x_axis_values, y_values)"
323 | ]
324 | },
325 | {
326 | "cell_type": "markdown",
327 | "metadata": {},
328 | "source": [
329 | "Now, I know what you might be thinking... (it's what I'd be thinking if someone showed me this as well, likely...) \n",
330 | "\"But Ben, dude, you can just get the minimum value directly from the data.\" \n",
331 | "To which I would reply... \n",
332 | "\"Shhhh... I'm just trying to make a point here. Let's play pretend and think of this as a supervised learning problem where our vector has 17 dimensions and there's no way that our human minds can figure out how to minimize the function.\" \n",
333 | "But, to humor us both, here's the actual minimum x value."
334 | ]
335 | },
336 | {
337 | "cell_type": "code",
338 | "execution_count": 12,
339 | "metadata": {},
340 | "outputs": [
341 | {
342 | "data": {
343 | "text/plain": [
344 | "7.569999999999581"
345 | ]
346 | },
347 | "execution_count": 12,
348 | "metadata": {},
349 | "output_type": "execute_result"
350 | }
351 | ],
352 | "source": [
353 | "x_axis_values[np.argmin(y_values)]"
354 | ]
355 | },
356 | {
357 | "cell_type": "markdown",
358 | "metadata": {},
359 | "source": [
360 | "So, how would this look as a grid search problem?