{ "cells": [ { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "# Feature Engineering\n", "# Klassifikation\n", "## Instanzbasierte Modelle" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "**Vorbereitung der Umgebung**" ] }, { "cell_type": "raw", "metadata": { "tags": [] }, "source": [ "## for scikit-learn 1.4.2, to silence warnings regarding physical cores\n", "import os\n", "os.environ['LOKY_MAX_CPU_COUNT'] = '4' ## depending on the hardware used" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [] }, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns; sns.set()\n", "%matplotlib inline\n", "\n", "datapath = '../3_data'\n", "from os import chdir; chdir(datapath)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Vorbereitung der Daten**" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "## load data\n", "data = pd.read_csv('bank_data_prep.csv')\n", "data.shape ## check\n", "\n", "## features - target - split\n", "## organize features and target as independent objects\n", "X = data.drop('y', axis=1)\n", "y = data['y']\n", "\n", "## test - train - split\n", "from sklearn.model_selection import train_test_split\n", "X_train, X_test, y_train, y_test = train_test_split(\n", " X,\n", " y,\n", " train_size=2 / 3,\n", " random_state=1234)\n", "\n", "## demo dataset\n", "demo_data = pd.read_csv('demo_data_class.csv')\n", "X_demo = demo_data.drop('y', axis=1)\n", "y_demo = demo_data['y']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### KNeighborsClassifier\n", "#### Theorie\n", "#### Praxis" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:53.227097Z", "start_time": "2020-03-17T11:35:53.124006Z" } }, "outputs": [], "source": [ "## import trainer class\n", "from sklearn.neighbors import KNeighborsClassifier" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:53.242354Z", "start_time": "2020-03-17T11:35:53.231829Z" } }, "outputs": [], "source": [ "## instantiate (and parameterize) the model\n", "model = KNeighborsClassifier()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:53.389975Z", "start_time": "2020-03-17T11:35:53.247879Z" }, "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
KNeighborsClassifier()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "KNeighborsClassifier()" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## train model\n", "model.fit(X_train, y_train)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'algorithm': 'auto', 'leaf_size': 30, 'metric': 'minkowski', 'metric_params': None, 'n_jobs': None, 'n_neighbors': 5, 'p': 2, 'weights': 'uniform'}\n" ] } ], "source": [ "## show effective parameters\n", "print(model.get_params())" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:53.829687Z", "start_time": "2020-03-17T11:35:53.393579Z" } }, "outputs": [], "source": [ "## apply model to test data\n", "y_pred = model.predict(X_test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "if `model.predict()` causes error like \"'NoneType' object has no attribute 'split'\", upgrade\n", "threadpoolctl to version 3.1.0 like this\n", "\n", " !pip install threadpoolctl==3.1.0" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:53.845894Z", "start_time": "2020-03-17T11:35:53.833743Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "y no yes\n", "row_0 \n", "no 1384 473\n", "yes 351 1079\n" ] } ], "source": [ "## show confusion matrix, actual vs. predicted target values\n", "print(pd.crosstab(y_pred, y_test))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.7493154852449042\n" ] } ], "source": [ "## calculate accuracy manually:\n", "## rate of correct predicted classes divided by all observations\n", "print(np.diag(pd.crosstab(y_pred, y_test)).sum() / y_test.size)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:53.924481Z", "start_time": "2020-03-17T11:35:53.898903Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.7493154852449042\n" ] } ], "source": [ "## accuracy as imported function from sklearn.metrics\n", "from sklearn.metrics import accuracy_score\n", "print(accuracy_score(y_pred, y_test))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:35:54.370382Z", "start_time": "2020-03-17T11:35:53.930041Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.7493154852449042\n" ] } ], "source": [ "## accuracy as internal model scorer\n", "print(model.score(X_test, y_test))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Parameter Tuning" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:38:46.751155Z", "start_time": "2020-03-17T11:38:39.891108Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 0.7003346516580469\n", "2 0.7027684818983876\n", "3 0.7377547916032857\n", "4 0.7423182233039245\n", "5 0.7493154852449042\n", "6 0.7505324003650745\n", "7 0.7520535442652875\n", "8 0.7517493154852449\n", "9 0.7554000608457561\n", "10 0.7532704593854579\n", "11 0.7608761788865227\n", "12 0.7532704593854579\n", "13 0.7602677213264375\n", "14 0.7554000608457561\n", "15 0.7578338910860968\n", "16 0.7550958320657134\n", "17 0.7541831457255856\n", "18 0.7529662306054152\n", "19 0.7511408579251597\n", "20 0.7517493154852449\n", "CPU times: user 16.8 s, sys: 8.73 s, total: 25.5 s\n", "Wall time: 2.36 s\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAG1CAYAAAD6GvACAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAV0hJREFUeJzt3Qd4lFXWB/B/eg9JSKUTWmihCChSBCm6ilJVUFgRsHzuiroiiouo4IoKiguKigKKirqoICIqIgiitABSpFeBVJKQ3me+59wwMZNMIIQh78z7/n/PM2Tmzcxwb6aduffcc13MZrMZRERERAblqnUDiIiIiLTEYIiIiIgMjcEQERERGRqDISIiIjI0BkNERERkaAyGiIiIyNAYDBEREZGhMRgiIiIiQ2MwRERERIbmrnUDnIUU6jaZ9F+s29XVxRD9NFpfjdZf9lW/jNRf9tU+9+vi4nLJ6zEYqiZ5kNLScqBn7u6uCA72Q2ZmLoqLTdAzI/XVaP1lX/XLSP1lX+0jJMQPbm6XDoY4TUZERESGxmCIiIiIDI3BEBERERkagyEiIiIyNAZDREREZGgMhoiIiMjQGAwRERGRoTEYIiIiIkNjMERERESGxgrURETVVFJSgi1bfkNSUiIiIiJx3XXXw83NTetmEdEVYjBERFQNq1atxNSpkxEfH192rF69enjxxVcxaNDtmraNiK4Mp8mIiKoRCI0fP8YqEBIJCQnquPyeiJwXgyEioktMjcmIkNlceUdty7GpU59S1yMi58RgiIjoIiRHyDIi5O7pi5bdR8IvuJ5VQBQff1Zdj4ick+bBkMlkwty5c9GrVy907NgR999/P06fPm3zuvPmzUOrVq1snqZMmVJ2vRMnTuCBBx5Ap06d0KNHD0yfPh15eXm12Csi0gtJlrZoc8N9Khi65ran4OLiWuX1iMi5aB4MzZ8/H0uXLsWMGTPw2WefqeBowoQJKCwsrHTdcePGYdOmTVan8ePHw9fXF2PHjlXXSU9Px+jRo+Hu7o5ly5Zh1qxZ+PHHH/HKK69o0DsicnayakwEhDZBw3b91PnA0MZo2K6/zesRkfPRNBiSgGfRokWYOHEi+vTpg5iYGMyZMweJiYlYs2ZNpev7+fkhLCys7JSSkoIlS5Zg2rRpanRIfPzxxyoQkvtp3rw5rr/+enX/e/bssTnnT0R0MbJ8XlaNte0zTo0G5WenqeOtrr8b7p4+cHFxQb169dX1HF1ufjEycyp/0SQyOk2DoYMHDyInJwfdu3cvOxYYGIg2bdpg+/btl7y9TH916dIFQ4cOLTsmo0UDBgyAl5dX2bE77rgDX331lXrTIiK6HFJH6B+TX0Noo1iUFBdi8//+jey0s/DyC0LzbsPVdV588RWHrzeUV1CM5xdvw+R3fsOxsxlaN4fIoWhaZ0hGgERUVJTV8fDw8LLfVWX9+vXYtWsXVqxYYXVc8oX69euHmTNn4ocffoCHh4cKjh599FGrAKkm3N01n1W8qtzcXK1+6pmR+mq0/tq7r8UlJpzMqSvjKkg5/DNyzidg/8YP0G3IvxF9zWBMvPcWDBlyu8P3deX6kziXka/Oz/1yD6aN7YqIEF84Ez6P9cnNAfqqaTBkSWr29PS0Oi5BS0bGxb+5LF68GH379kXr1q2tjmdnZ+O9997DrbfeijfffFOtApF8JJlSk/yhmnJ1dUFwsB+MIDDQB0ZhpL4arb/26uuqTceRkJqLOv6e+GTZa9gZdwfi4xPw6yk3/HkOyPZuovl7w6X6eiI+Az9uL12YEh7ii+S0XLz++W7MmtgLdfyv7EuiFvg81qdADfuqaTDk7e1dljtkOS8KCgrg41P1H0UCnK1bt2LBggWVfif5Qk2bNsXzzz+vLrdr107V/3jsscfw9NNPo25d+YZ3+UwmMzIzc6FnEpXLkzEzMw8lJSbomZH6arT+2rOvOXlF+OT7g+r8kF7RKCkqQYcOXdGhA9AmMQvT3t+KjbvOok+HemjeoA4csa8msxlzP9+l3sO6tg7HmJtaYfri7UhIzcFzC37D06OvgZeHY0/xWfB5rE9uV7Gvcr/VGXHSNBiyTI8lJyejUaNGZcflsiUh2pa1a9ciJCRELZuvKDIyEi1atLA6Zrl89uzZGgdDorhY309IC3kysq/6ZKT+2qOvK345juy8IkTV9UXP9pFW91c/1A892kdh094EfPLjITwz+hrN8hIv1teNu+Nx9EwGvDzdMPLGFvD39sDjd3bASx/twLGzmZj/1V78Y2h7NfrtLPg81qcSDfuq6WSkrB7z9/dXozwWmZmZ2L9/P7p27Vrl7eLi4tCtWzc1ClSR3K7iyrHDhw+r5MYGDRpchV4QkR4lp+fipx1n1Pm7bmwBN9fKb5dDe0fD08NVBRXbDybD0WTlFmLZ+qPq/JCeTREcUDolFlXXD48Mj4W7myt2HTmHT386wtW2ZGiaBkOSKyQ1gWbPno2ffvpJrS57/PHH1ejOwIED1fSW5Prk55cm/VlIsCSBlC1Sd0iKNj733HMqmfqXX35RNYYGDx6sRpOIiKrji5+PobjEjLZNQ9A+2vZ7hwQXt1zbuOz6RcWOtSWHtCknvxgNwvzRv4v1l8GWDYMwYVBpzqUEfT9ss13slsgINE9TlxpAI0aMwNSpUzFq1Cg1grNw4UK1Ckw2QezZsydWr15tdRsJkIKCgmzeX3R0tKo9dPz4cRUASZ7QLbfcghdeeKGWekREzu7w6fOIO5QCmfW6q2/zi05/3dStkQqKZKXW2gsjSY5ApsZ+2ZOgzo+5qaXNka1urSNwZ9/m6vz/1h/FtgNJtd5OIkegac6QkODnySefVKeKZFrr0KFDlY7v3r37ovcZGxurii8SEV0uSTj+fN0Rdb53h3poEO5/0etLLs6w3tFY+O0BrPrtpMojCvS1XiFb20pMJiz5ofS9s1dsFFo0sP3lUdzUrSFSM/PV6ND7q/YjyN9LjRoRGYnmI0NERI5k6/4knEjIUkGOrCCrju7tItE4IgB5BSX4etMJaO2nuDM4k5INP293jOjT7KLXlVGvUf1aoHPLMDUtOO/LPYg/l1NrbSVyBAyGiIguKCgqUXk2YlD3xqjjV70RHlcXF4zsVzrdtGFXPM5qGEykZeZj+YWA7I6+zRFQjVEqWUn2wG1t0KxeoMoxmvO/3cjILqiF1hI5BgZDREQXrNl+GulZBagb6IUBXRpe1m1bNQpWoysyzWZZwaWFz9YdRUFhCZrVD0TPWOvq/hfj6eGGR0bEIjzYR02bvbFsD/ILi69qW4kcBYMhIiJAjYSs3nxKnR/ep5kKDi7XHX2awc3VBXuOpWLfiVTUtn3HUxF3MFmNVI0Z2Er9vByS6yQ1iPx9PHAqKQvvfP2Hyj8i0jsGQ0REAJb/clxNk0XXC8S1rSNqdB+y11e/a0qXsH++7qiq+lxbZFn/x2sOq/OyjL5RRECN7ici2BePjoiFp7urCuo++uGwQ9QgkuDynRX7sH3/xfetJKoJBkNEZHh/JmXhl92ly9ClSvOVVJK+rUcTlbh8NiUHv+yJR235dvMpJJ/PQ5C/Jwb3bHpF99Wsfh08cHtbuFyoYL3qwoiZFmTbkDeW7VZ7qf22LxHTF25VVbMzcwo1axPpD4MhIjI0GfWQURwZ++gaE37Fe4z5eXvg9gvByPKNx5FXcPXzbhLTcrF6y5/q/Kj+LeHjdeVVUyT/6e4BLcv6sXlf7Y7IyDYoS388jGkLt6kRKpl+7NA8FLJryJb9Sfj3e1vw694Ehxi1IueneZ0hIiItyQftgVPpcHdzueQy9Orq26k+1u04g6T0PKzecgrDb7DP/doiwcBH3x9CcYlJVcvu0irMbvctU36pGfn4ftufWLT6gBp1at3k6lbyl378vOusKlEgK9tEx+ahuPPG5qrmU2p2EeZ8ugN/JmWr2k6b/0jE32+OQXiQcXZ3J/vjyBARGZZ88ErlZdG/S0OE2ekDVfb8slR2lm0uzmXk4Wr5dU889h5PVf/n6IEt7b5Z7Ii+zdCtdThKTGa8uXwvziRn42oFdXuOncNzi7Zh6dojKhCqH+aHJ0Z2xMQRsYgM8VXXa94wCM+P66YCVw93V+w/mY5p72/F91v/ZLI31RiDISIyrA2/xyMhNVetnpK6QvbUsUUoYhoFqYDrqw3HcTXIFNx7K/ap87dc10glP9ubrEgbf2trVZVaikrOWbZb1TKyp7Mp2aq2kSznl8cjwNcDf7+pFZ6/ryva2hiJksDvlusaY/r4bupvXFhcGtS+uERGjLLs2jYyBgZDRGRIuflFZdWih/RqCl9vD7vev4zQyG73Mk4jOS7H4jNgb19tPK4CE6kNdKudg7nyPNzd8M9h7RFV11fVYZKgxR65UFm5hfhozSE8t2g79p1IU3lBN1/bCDMf6I4+nerb3E+tPAn+nhzVCff9LQa+Xu44lZiF6R/EYdnPR1FY5Fib5pJjYzBERIa06rdTKklXPuBv6FjvqvwfjSMDcH37SHX+85+O2jXZV0ZAfryw0/zfb26lAparSUbPHr+jg6rKLVt9vLV8rxr1qgm53Q/b/sTT727B+p1nVaHKa1qG4T/3X6umF3293S8r6OzVoZ66bZeYcHVf3235E9MWbVO5YETVwWCIiAxHlqCv3VEaSNx1Y/NLjkBciWG9pYCjK46ezUDcoRS73Kd84MuIivzsEVsPsc1CURtCg3zw2B0d4OXhpnJ1Pvju4GUFeHLdXUdSMPX9rWoFn4wuNQr3x+RRnfCPYe0RfgXTfHX8vfDwkHZ4ZFh7leidnJ6HWZ/uwgffHUBOflGN75eMgcEQERmO7D8mm5K2bRKM9tF1r+r/FRzghb9dWzqFJdt0SHHEK7VpTwKOnc2Et6cb7h/SDrVJRrv+b0g7lUskdX9W/FK9jWlPJ2dj9me/Y96Xe1WgEujnibF/i8G0sV0R0zjYbu3r1DIML064Tq3oExt3J+Df721Vlbm5DJ+qwmCIiAzlyJnz6oNRFl2pnB47r76y5eZujdRoxbmMfKzdceaK82wse58N7R2NunVqf0l5bLO6GHNTaQ2ib347qQozVkWKI374/UE8v7h02kqSnyW/aeYD16F3h3pqk1h7k2m2MTe1wtP3dFbToNKG+Sv24c2v9qqcJ6KKGAwRkWHItNJnP5UGEr1i66m6NbXBy9OtrNbQqt9OIjO38IpGtWTZeYMwfwzsdnmbydrTDR3rY9D1pSNeS74/pOo1lVdUbMJ3W07h6Xc3q1V7MigjRS1fuv9a9bewR2HIS5EVcLIi7bbrm6jk7F1HzmHq+1uwfldpnhKRBYMhIjKMbfuTcCIhUwUnQ3td2ZYVl6t7u0g0jghQy9Mtq9gu19EzGfhlT+m2ITIyczVznapjaK9odG8bqQKLt1fsU6u5ZCpKRt4k6Fj28zHkF5aoqTUZpZHpNck7qk2SWC4jaM/d11XtOyd//49+OIRXPtmptvogEgyGiKhWyWao57Nrf6pCllp/seGYOn/rdY1Vwm1tkhwbSdYWG3bFI/7c5X0QS0HBJT8cUud7xUahRYMgaE2mGO+7JQatGwerx1X2EHt16S41JZVyPh91/D1VjaJn7+2iRmm0JCNpz4y+Bnf3b6ESwI+cyVAFHr/59USNV8WRfjAYIqJaI9WLp763BU+8+Sve+Xofzl5mQHAl1mw/jbTMAoQEemFgV22mlyRRuFOLUDWSYql8XV0/xZ1RS9plE1h7bRtiD5ID9I+h7dEgzA8ZOYU4dPq8qgwtU1OSF9SjfZQKBB2B5CdJpfEXJ1yrEucliX75Lyfwwgfbr0odKHIe3JuMiGqFbBkhUykybSK2HUjG9gPJ6No6XH1w1g+7evk7GdkF+HZL6c7rI26Qpe5XtybPxUgdHcmvkdMfJ9LUfmKXIoUVl1+YWrujb3ME+HrCkUjCsiy5f3/VfoQEeqvps7p1vOGopG2P3RGLrQeSsPTHIzibkoOXluzADZ3qo3OLUDStF6g23CXjYDBERFfdup1n8MmPh1USrWyfMLhnU6yNO4Mdh1PKgiIpmHdbjyZqOsPe5Nt/QWEJmkYFolubCGgpIsQXN3ZugB/jTuPzdUfw/H3dLrmi6rN1R1X7m9UPRM/YKDgiCYIm390ZzkKm+K5rE6m2+5CaR1ImQDaIlZOICPZROUbR9eqo503DcH814kX6xGCIiK4ak8msPmjkg1/0aB+Je2+OUVMrrRoFqyrK3/x6UgVF2w8mq5MERbfbMSiS+ja/7Cld+j2yX3OHmLKRoO+3fQk4k5KDTXsT1BLzquw7nqoSkqXdYwa2coj264mMsk0Y1EYluP+6JwHH4zNVUc6k9NLT5j+S1PXc3VzQKCJABUalQVIgwoN8aqU0A119DIaI6KrILyzGgpX78fvRc+ry8Bui1eaa5T885MNFKg9LwLLy1xPYcShFffDLqUurMNzeo+kVLX+XlU0y+iIjUnJ/jpB0bNna4rYeTfHZT0fU/mKy5NzWUnMp0PjxmsPqfP8uDdTfi64OGSGybAor27RIUCQrDy0/Lcfk9NOO0ttI/pZMqUVfCJAkUHK0KUyqHgZDRGR3kuMy94s9+DM5W40CTRjUGt1aVz09JVMQkoR75kJQJNtWWE7XXAiK5Do1yVOSbSPkW70jJR2LGzvXV9OHUo35u62n1LYdFX27+ZQapZCCjTK1SLUXrEphSTlZguqU83mlwVBCJk7EZ+JUUraq97TveJo6WchoUfkAqVGETK9pl6NG1cNgiIjsSmrN/PeL3TifXYgAXw9MHB6LZvXrVOu2Mgr0sCUo+u0kdhxMVqNFcpKNPGV6qbqjI7JcWqboRP9rGl7RvldXgwSJkkwtVZF/2HYaN3Sob5V0nJSWi9Vb/lTnR/VvWStFCsk2Gc2U54+crmsbWfb8khHN8iNIiWm5KniV09b9pdNrUuxRAnkJjJo3qIN2TeuqYIscC19dRGQ3vx85h3dX/qFqztQL9cOjI2IRVoMieyooGtJOLSWXnCKZNpO8Ijl1bikjRZcOiiQRNiE1V33wWColOxpZZt+qYZBajv7lxmN44La2ZSMRknAuH7iy2kym+AgOF8zKtJicLGRD2JMJWTgen4ETF35m5hbhZGKWOq3beRYySSwjR7K0X05NogKYB+YAGAwR0RWTD+8f487g85+OQDY5kA1Qpdqw7xUuT5YkarmfsxIU/XZSrTrbeThFnSSQkOkzqW5ckeR3LN94XJ2X6aUrbcfVHHEY2a8Fpn+wHVv+SFIjWDKCINOD+06kqQ/c0QNbMknXSchyfAleLeUS5HWRmpGvptZk5EimbCXAt+QeSSVyCdbbRYegfdO6aBsdgkDmHGmCwRARXRGpjLx07RGs31m6JPmGjvVwz4CW6oPcXqQG0UOD2+G2HjmqYrAERbLPlJw6Ng9VAU/5oGjZ2sPIyi1Sm3RKexyZtPt6Wcm0LxGfrTuCx+/ogE/XliZN33JdI0Q42PQeVZ8EsbL9iJwsOXOyUazkspXms6WpwF0CYTlJyCsjRTJi1LFFGDrX4WNfW1zMErrSJZWUmJCWpu99bNzdXREc7If09BwUF+u7PL2R+no1+5tXUIy3v96nEkhdLhQEvKlbw6s+kiFbWchIkew1ZnkDk6Do9p5NUMfPC0+9s1lNMck0XYfmoXB08gE55d3NKCw2oWlUgJpikUTcGRO6XTT5ls9j5ybPURkhUsHRsVS14KA8WZnWtmmwWuXWLrou6vjpc9TI/So+riEhfnCrxhczBkPVxGBIX4zU16vV33MZefjvF3tU9V5PD1eV7yL5PLVJgiLZBV4qCVveyWQ/rIzsQjVV8a87OzjNFNOKX45j5a8nyy4/fmcHNUJwMXwe64vs2Vc6apSmRo1y84srjSLKcyI2ui6a1gvQfKNePQVDnCYjossmq2ckEMrMKVTfVh+9IxZNIv9KJK0tkqT9wO1t1SozGSmSFTwSCEn8M6p/C6cJhMTfrm2MDbvjVfslYfpSgRDpT5C/F3rF1lMnF1cgObMQv+46g91HU3EqKUut1JSTfAGQGkdtmoRcSMQOqfWNh/WGI0PVxJEhfTFSX+3dX1nZJXtQyZSOJDjLHk+yFYMjSEjNwYbf4xHTtC66tAx1usf20J/p2PxHoqo5FFiNKRE+j43TV9lfT5LqZeRI9rSTGkflST2ja1tHoFeHek63dN/dAUaGGAxVE4MhfTFSX+3VX3mr+H7rn1j28zF1Wb6RPjS4rcPVvzHSY2ukvhqtvxfrqyxaOBGfVZaILcv2LWT/tOvaRKDfNc5TsdzdAYIhx3oXIyKHTfT86IdD+GVPgrrcr3MDjOzfXDc5C0TORF53UsBRTkN7R6vpatn2Riqa/5kke/ElqFPLhkHof00DdGoZytfqJTAYIqKLys0vwlvL9+HAqfTSXJx+LdC/S0Otm0VEF8iUqmz22ys2CkfOZOCnHWdU1fbDp8+rU3CAl9r+Ra7DvdNsYzBERFWSbQX+u2y3quTs5emGh25v6xRL1YmMSBYMyGiQnKRcw/pdZ7Hh97Pq/JcbjuPrTSdxbZtwVdzTVrFSI2MwROREJFdARmh2H0lVl/183FXVW0mYtJz38ym97OvlDlfXmq+mOnomA/O+2qOKF8o3S6nZ4yw5CERGJ6/ZYb2jcdv1jbHtQDLW7jijVqL9ujdRnWSKTabQpByGux0LpDorBkNEDk4SlyVBUlYZyZua5AdUlwREEiT5+3giONAbnu4upceqCKBkua6vtzviDqZg4bcHVK5Q44gATBwRq95cici5SNHOHu2jVJXzY/GZagpNVoTKlx05Bfl7ok+n+rihY33dFnWsDq4mqyauJtMXZ+hrUnoutv6RhM37k9QO5hYStEgdGn9fD+TkFavNIXPyipBtOZ9fhLyCEru0Qao6P3h7WzVF5iyc4bG1FyP11Wj9vZp9leKOspHxz7/Hl325cndzQdeYCPTv0sBq81l7ki9XqZn5SErLQ3J6LpLS5Weemo4P8PXApJGd4Olu31EqriYjckLyxrTtQBK27E9SZfot5A2iY4tQXNc2Eu2ahlxyWFvedHILilWQJAFTXlEx4OqKpHM56v+wBFBSq6Q0kCo9L9trCJlcG9C1Ie7s2/yKptqIyDGLOw7pFY1buzdB3KFkNVok7zcy+iynZvUC1dL8LjHhlz2FpgKejHz1ZU4FO2l5SDqfq4Kec+fzYapi/CUzxw2FRSV2D4aqi8EQkcbyC4ux6/A5bN6fiP0n0sveLGTlllSYlZohMq9/OfV85A1Mdr+27IBd3W+ZkpMkWwBIIqazFW4jossjNYm6t41UJwmGftpxWk3Fy3Tasfj9+HzdUbXRsUyjSQBVPuA5JwFPWmmQI4GPGuGRgCej6oBHSLATHuyD8GBf9TMi2AdRoX6IbRWB4oIizUb8GAwRaUDeTKSKrIwA7TqSgsKiv94AZKPO69pEolvr8FovsS+1SLj0lsh4ousFIrpeW9x5Ywu1Ak1WosnWMLJf3rebTyG2WV1VdV4CIJnquliCjSXgibAEPCG+auNh+Sl7B7pW2CZHvqzJ+056QRG0wmCIqJZIet6xs5lqBGj7gWQ1NWUhbxgyAiTTYJEhvpq2k4iMq46fJ27v0RS3XNdY1SqSKbSjZzOw68g5q+vJ5szhQb6ICPEpC3wiLoz4SFK2M+0LKBgMEdXCzupb9idiyx9JagjZItDXA91alwZAMhrkbG8eRKRf7m6uuLZNhDqdTMzEvuNpqrijMwc8Dh0MmUwmvPnmm1i2bBmysrLQtWtXTJs2DQ0bVq5wO2/ePHVdW4YNG4aZM2eq8/fddx9+++03q99369YNH3300VXqBZG1tMx8NfcuQZCUx7fw8nBD55ahao6+dZNglsgnIofXJDJQnfRM82Bo/vz5WLp0KV5++WVERkZi1qxZmDBhAr755ht4elrnLowbNw4jR460OrZ48WJ8+umnGDt2bNmxQ4cO4fnnn0f//v3Ljnl4MBmUrm4O0LGzGdgjGyceS8OZlL8CIDdXF7RtGoLr2kagU/Mwp1qmTkRkBJoGQ4WFhVi0aBEmTZqEPn36qGNz5sxBr169sGbNGgwaNMjq+n5+fupksX//fixZsgQzZsxAq1at1LHU1FR16tChA8LCwmq5R2S00Z/SXaPTsP9kGvIL/6rtI4PHzerXUQFQ15hwJiUTETkwTYOhgwcPIicnB927dy87FhgYiDZt2mD79u2VgqGKpk+fji5dumDo0KFWo0Iyj9m0adOr2nYy5uiPbIJYGgCl4myKdRFOWYreLjoE7aPrqpEgy7J2IiJybJoGQ4mJiepnVFSU1fHw8PCy31Vl/fr12LVrF1asWGF1/PDhwwgICFCB0q+//gpfX1/cfPPNePjhhytNu10uWf6nZ5YqndWp1mmUvkrC856j57DnWKrN0Z/o+nXQoVldxDaviyZRgZWWjDoKPrb6ZKS+Gq2/7KuBgqG8vDz1s2KQ4uXlhYyMjIveVnKF+vbti9atW1cKhgoKChAbG6sSqQ8cOIBXX30V8fHx6mdNSRVeKVpnBIGBPjCKin0tKi7B/uNpiDuYhB0Hk3E6Kcvq91J4rHNMODq3CkenVuFqdYUzMfJjq2dG6qvR+su+GiAY8vb2LssdspwXEsz4+FT9R5HAZuvWrViwYEGl38mI0FNPPYU6deqoyy1btlTJ048//jgmT56M0NDQGrXVZDIjM/Ov/aH0SKJyeTJmZuapvdiM0tfE1Bw18iMjQPtPpqOgqNzojwvQvH4dVXAstnkoGkcGlI3+lBQWIb1QuyJhl8Oojy37qi9G6i/7ah9yvw6/N5lleiw5ORmNGjUqOy6XLQnRtqxduxYhISHo0aNHpd+5u7uXBUIWLVq0UD9l6q2mwZDQ+8aAFvJk1HtfU9Lz8L/1x7DtjwQkpOZWKjpmyf2R7TDKb0thKjHDBOfd29gIj60F+6pfRuov+1o7NA2GYmJi4O/vr0Z5LMFQZmamWiU2evToKm8XFxen6gZJ4FPRmDFj0KBBg7KaQ2Lv3r1qdKhJkyZXqSfkbHuB/WdJHNKyCtRlGelpXj8Q7aLrqgCoYYS/w+b+EBGRzoIhyRWSoGf27NlqpKd+/fqqzpDUGxo4cCBKSkqQlpamEqLLT6NJsDR8+HCb93nTTTfhpZdeUjlDPXv2VIGQ5AqNHz9eBV5EKzedVIFQeIgv7uzbDDENg+DrzTpURERGpXnRxYkTJ6K4uBhTp05Ffn6+qkC9cOFCNZJz5swZ9OvXT43ySIVpi5SUFAQFBdm8PwmuZGm9VJuWoEhqDUlBxgceeKAWe0WOSoohrtl+Wp3/v2GxaBbpb5ghaCIiss3FLLtHUrXmMtPSrOvK6I2UDpAVc+npOboMEExmM175ZKeqFdQlJgzP3X+9bvtqtMe2PPZVv4zUX/bVPkJC/KqVQK3/AgZEF/y2N1EFQrI/2D0Dqk7QJyIiY2EwRIaQnVeE/60/qs4P7tkUdev8lYNGRETGxmCIDOHLDcdUQFQ/zA/9uzTQujlERORAGAyR7slu8ht+j1fnxwxsBXcDlLcnIqLq46cC6VqJyYSPfjikzvdoH4mWDW2vQiQiIuNiMES6tm7nWfyZnA0/b3fc0be51s0hIiIHxGCIdCs9qwDLNx5X54f3aYZAX+faVJWIiGoHgyHSrc/XHUF+YQmi6wWid4d6WjeHiIgcFIMh0qU/TqRh24Fkteu8JE1zrzEiIqoKgyHSnaJiEz5eU5o03e+aBmgcGaB1k4iIyIExGCLd+W7rKSSl56GOvyeG9orWujlEROTgGAyRriSn52LVb6fU+ZE3toCPl+Z7ERMRkYNjMES6IXsOL117BMUlJrRpEoxurcO1bhIRETkBBkOkGzsPp2DPsVS4u7lg9MBWcGHSNBERVQODIdKF/MJiNSok/nZtY0SG+GrdJCIichIMhkgXVm46qYoshgV549bujbVuDhEROREGQ+T0zqRkY8320+r8PQNawdPDTesmERGRE2EwRE7NZDarjVjl5zUtwxDbrK7WTSIiIifDYIic2m97E3HkTAa8PNwwqn8LrZtDREROiMEQOa3svCL8b/1RdX5wz6YICfTWuklEROSEGAyR0/pywzEVENUP80P/Lg20bg4RETkpBkPklI6dzcDG3+PVedmI1d2NT2UiIqoZfoKQ0ykxmVTStBlAj/aRaNkwSOsmERGRE2MwRE5n3c6z+DM5G37e7rijb3Otm0NERE6OwRA5FSmsuHzjcXV+eJ9mCPT11LpJRETk5BgMkVP5fN0R5BeWILpeIHp3qKd1c4iISAcYDJHT+ONkGrYdSIbsvypJ067ciJWIiOyAwRA5haJiEz5ec1id79e5ARpHBmjdJCIi0gkGQ+QUvt96Cklpuajj74mhvaO1bg4REekIgyFyeMnn87Bq8yl1fuSNLeDj5a51k4iISEcYDJFDM5vNWPrjYTVN1qZJMLq1Dte6SUREpDMMhsih7Tycgj3HUuHu5oLRA1vBhUnTRERkZwyGyGHlFxZj6doj6vzfrm2MyBBfrZtEREQ6xGCIHNbKX0+qIouhdbxxa/fGWjeHiIh0isEQOaQzydn4cftpdX70wJbw9HDTuklERKRTDIbI4aRl5uO/X+xGicmMzi3DENssVOsmERGRjjEYIoeSmVuI2Z/9jtTMApUj9PebW2ndJCIi0jkGQ+QwcvOL8frnvyMxLRd1A70waWRHbsRKRERXHYMhcggFRSVqauzPpGwE+nli0shOCAn01rpZRERkAAyGSHPFJSa8tXwvjpzJgK+XO/51ZwdEcBk9ERHVEgZDpCmTyYwF3+zHvuNp8PRwxWN3dECjCG7CSkREtYfBEGm61caH3x9E3MFkVWH6kWGxaN6gjtbNIiIig2EwRJoFQp+vO4pf9iRAdth48Pa2aNs0ROtmERGRAWkeDJlMJsydOxe9evVCx44dcf/99+P06dJiexXNmzcPrVq1snmaMmWKzQ/c8ePHY8yYMbXQE7ocq347iTUXiire97fWuKYVN2AlIiKDBkPz58/H0qVLMWPGDHz22WcqOJowYQIKCwsrXXfcuHHYtGmT1UmCHV9fX4wdO7bS9T/88EN1HXIsa+NOY/kvJ9T5Uf1aoGdslNZNIiIiA9M0GJKAZ9GiRZg4cSL69OmDmJgYzJkzB4mJiVizZk2l6/v5+SEsLKzslJKSgiVLlmDatGlqdKi8Q4cO4a233lKjTeQ4ft2bULb56pCeTTGga0Otm0RERAanaTB08OBB5OTkoHv37mXHAgMD0aZNG2zfvv2St58+fTq6dOmCoUOHWh0vKCjApEmTVJDVtGnTq9J2unw7DqVg0eoD6vyALg1xW48mWjeJiIgI7lr+5zICJKKirKdJwsPDy35XlfXr12PXrl1YsWJFpd/NmjVL3cfo0aNt5hLVlLu75rOKV5Wbm6vVT3vadzwV767cB7MZ6NUhCvfc1BKukjmtkavZV0dkpP6yr/plpP6yrwYKhvLy8tRPT0/rLRe8vLyQkZFx0dsuXrwYffv2RevWra2Ob9y4Ed988w1WrlwJFzt+2Lq6uiA42A9GEBjoY9f7O3gqDXO/2IPiEjOuj43CE/d0cZgXuL376uiM1F/2Vb+M1F/21QDBkLe3d1nukOW8ZZrLx6fqP0p8fDy2bt2KBQsWWB1PS0vDM888g+effx4RERF2Lw6YmZkLPZMARZ6MmZl5KCkx2eU+/0zKwksf7UB+YQnaRYdg/C2t1f3rsa+OzEj9ZV/1y0j9ZV/tQ+63Ol++NQ2GLNNjycnJaNSoUdlxuVwxIbq8tWvXIiQkBD169LA6vmHDBpVULQGRnCyBlqxQ69SpE7799lvUq1evxu0tLtb3E9JCnoz26GtSei5eXbpLbcDavH4d/GNIe7g42N/RXn11FkbqL/uqX0bqL/taOzQNhmT1mL+/vxrlsQRDmZmZ2L9/v8r3qUpcXBy6desGd3fr5g8YMACdO3e2OjZ79myVfyQ/JY+IakdaZj5mf/o7MnMK0SjcH4/dEQsvTzetm0VERORYwZDkCknQI4GKjPTUr19fJT9HRkZi4MCBKCkpUVNfAQEBVtNoEiwNHz680v1JYCWnisvx5baNGzeulT4RkJlbiNc+/x2pmfmICPbB43d1hK+3h9bNIiIisknzLFZZ/j5ixAhMnToVo0aNgpubGxYuXAgPDw8kJCSgZ8+eWL16tdVtZCosKChIszZT1WRKbM7nu5GQmouQQC9MGtkJdfysE+SJiIgciYtZ9qygas1lpqXlQM+kdICsmEtPz6nRvG1BUQnmfP47Dp/JQICvB56+pzOi6vrpsq/Oxkj9ZV/1y0j9ZV/tIyTEr1oJ1JqPDJE+FJeYMH/5PhUI+Xi54193dnTYQIiIiKg8BkNkl7ID732zH3uPp8LT3VUlSzeODNC6WURERNXCYIiuiMyyLvnhILYfTIabqwv+Oaw9WjRgPhcRETkPBkN0RYHQ/9YfxcbdCZBi3w/e3hbtoutq3SwiIqLLwmCIamzV5lP4YdtpdX7szTHoEsM6TkRE5HwYDFGNt9lYvvG4Oj/yxubo1aHmlb2JiIi0xGCIauRUYpb6GdMoCAO7/bWVChERkbNhMEQ1ItWlRUSIr9ZNISIiuiIMhqhGUjNKg6G6gX9tk0JEROSMGAzRFY0M1a3DYIiIiJwbgyGqkXMXRoZCGQwREZGTYzBENao4nZ5VoM5zmoyIiJwdgyG6bOezC1BiMquK00H+Xlo3h4iI6IowGKIaT5EFB3jB1dVF6+YQERHVfjCUlJR0Zf8r6WIlGfOFiIjIsMFQ3759MWHCBKxevRqFhYX2bxU5tHNcSUZEREYPhmbOnAmTyYRJkyahZ8+eeOGFF7B37177t44cUmpGnvrJ5GkiItID95rcaPDgweok02XLly/H119/jU8//RTNmzfHsGHDcPvttyM0NNT+rSUHmybz0bopRERE2iZQR0RE4KGHHsJ3332HL7/8EsHBwZg1axb69OmDRx55BLt3777yFpLDOZd5YVk9p8mIiEgHrng1WVxcHJ599lmMHz8eO3bsQI8ePfD0008jLy8Po0aNwgcffGCflpJDMJvNSGPOEBERGX2a7NSpU2pqbOXKlTh79izq16+PMWPGqCmyqKgodZ3Ro0ernKK3334bY8eOtXe7SSOZOYUoKjbBxQUICWCNISIiMmgwdNNNN8HLywv9+/fHjBkz0L17d5vXi46OxsmTJ6+0jeSAK8mk2KK7G8tUERGRQYMhmRaTJOmAgICLXu/hhx9WJ9LhbvWcIiMiIp2o0Vf7e+65B7/88gumTZtWdmznzp0YMWIE1q1bZ8/2kaOuJOOyeiIiMnIwtGLFCvzrX//C+fPny44FBQUhLCwM//znP7F27Vp7tpEcCAsuEhGR3tQoGFq4cCHuu+8+zJ071yo/SJKl7733XsyfP9+ebSQHwmkyIiLSmxoFQ3/++SduuOEGm7/r3bs3jh8/fqXtIgeVemFkiNNkRERk6GBIpsP27Nlj83cHDx5UxRdJnzWGLDvWc2SIiIgMvZps0KBBakrM19cXAwYMQEhICNLS0rB+/XrMmzdP1Rwi/cnJL0ZBYYk6z33JiIjI0MHQP/7xDzUV9uKLL+I///mP1cjBzTffrLbiIP3mCwX6esDTw03r5hAREWkXDHl4eKjk6cOHD6stODIyMlTNoWuuuQYxMTH2aRk5HE6RERGRHtUoGLJo2bKlOlWUnZ0Nf3//K7lrcuDk6brcrZ6IiIweDBUWFuLDDz/Etm3b1HmZHhPyMzc3F0ePHuWO9TrEgotERKRHNQqGXn31VXz88cdqVEgSp2WfMkmilmmzoqIiVXiR9DwyxGCIiIgMvrR+zZo1quii7Fovu9O3a9cOy5YtU8dlB3uTyWT/lpLmzmXkqZ8MhoiICEYPhmQ0SIorChkd2rt3rzofERGBBx54AKtXr7ZvK8khcJqMiIj0qEbBkKwck1wh0bhxYyQkJKikadGkSRN1mfQlr6BY1RkSHBkiIiIYPRjq0qULPvroI+Tl5algyMfHp2xz1l27dnElmY7zhXy93OHjdUWLEImIiJw/GJKii7///ruaEnN3d8fdd9+NZ599FsOGDcN///tf3HTTTfZvKTnGFBlHhYiISGdq9BVfCit+9913avWYeOKJJ9Ro0M6dO3HjjTeqIIn0hSvJiIhIr2oUDMko0IgRI9CjRw912cXFBQ899JC920YOODLEPcmIiEhvajRNJkvqc3Jy7N8acvitODhNRkREelOjYKhTp07YunWr/VtDDovTZEREpFc1miZr1aoVFi5ciO+//17lD/n6+lr9XqbNXnrpJXu1kRxpmozBEBER6UyNgqEff/wR4eHhausNS8HFisFQdUm16jfffFNVsM7KykLXrl0xbdo0NGzYsNJ1582bp65ri6xkmzlzpjovy/7lJPWOGjVqhHHjxmH48OGX1Uf6S1FxCTJySutKMWeIiIj0pkbB0Lp16+zWgPnz52Pp0qV4+eWXERkZiVmzZmHChAn45ptv4OnpaXVdCWpGjhxpdWzx4sX49NNPMXbsWHX5888/x+zZs/Hiiy+iY8eO2Lx5s0r4rlOnDvr372+3dhtJamaB+unl4QZ/Hw+tm0NERKR9zpC9SBXrRYsWYeLEiejTp4+acpszZw4SExPVPmcV+fn5ISwsrOyUkpKCJUuWqJEkmboTMrokS/1vu+02Nbp05513qi1Dfv31Vw16qL8psssZ9SMiItLtyNDf//73S15HgpRLOXjwoFqV1r1797JjgYGBaNOmDbZv345BgwZd9PbTp09X1bCHDh1adkxGlSxkGk+m9I4dO4Z//vOfl2wPXSJ5mlNkRESkQzUKhsxmc6Vjubm5KuiQZOqBAwdW635kBEhERUVZHZd8JMvvqrJ+/Xq19ceKFSts/j4uLg5jxoxROUmSL9SvXz9cKXd3TQfSrjo3N1ernxZpF4KhsGAf3fwNquqrXhmpv+yrfhmpv+yrEwRDkpxsS0ZGBu6//35ER0dX635kbzNRMTfIy8tL3dfFSK5Q37590bp1a5u/b9q0KZYvX64SvGVlW3BwMJ588knUlKurC4KD/WAEgYE+VpczL2zQ2jAyUHd/g4p91Tsj9Zd91S8j9Zd9rR123XFTkpRlKw4JPqozlebt7V2WO2Q5LwoKCtTmr1WJj49XdY4WLFhQ5XXq1q2rTpKHlJaWplahPfroo5UCr+oymczIzMyFnklULk/GzMw8lJSYyo4nJGern36erkhPz9F1X/XKSP1lX/XLSP1lX+1D7rc6I05XZfvx1NTUal3PMj2WnJyslsBbyGVLQrQta9euRUhISNl2IOVt3LgR9erVQ/PmzcuOyX1JwHX+/Hk1BVdTxcX6fkJayJOxfF9TMkpH8IL8vXT3N6jYV70zUn/ZV/0yUn/Z19pRo2BIkpsrKikpUXk+slS+bdu21bofGbWRDV5llMcSDGVmZmL//v0YPXp0lbeTfKBu3brB3b1y89944w00adIEr7/+etmx3bt3IygoCKGhodXsIVkUl5iQnlW6tJ5bcRARkR7VKBiSxGRZYi2J1Jal1pakahnteeaZZ6p1PzJlJUGP1AWSkZ769eurOkNSb0iSsCXAkimugIAAq2k0CZaqKqIoq8n+9a9/oXPnzujVq5cKtKRa9uTJk+Hqqv9ENHs7n1UAeWjd3VwQ6FezKUYiIiLdBUO2ls1LUCSjPDIldTlBh9QYKi4uxtSpU5Gfn68qUEvw4uHhgTNnzqhVYFJZWipMW0h9IRnpseWWW25RS+rfe+89vPLKK2rKTIou3nHHHTXpquFZltWHBHrDlTWGiIhIh2oUDMkUlUxn/f777+jdu7c6JoHLhg0b0KBBAzWSU11ubm5qlZetlV5yX4cOHap0XKa9Lmbw4MHqRFeOu9UTEZHe1WjeSOoJ3XrrrXj++efLjp0+fVqN4Mj0laz2Ip1Vn2bBRSIi0qkaBUOS1xMREaH2BLOQKtIyMiTTV6+++qo920gaOmepPs2RISIi0qkaBUM7d+7EI488ogKi8qSuz0MPPYQtW7bYq33kICNDnCYjIiK9qlEwJMnSlurRFUkytCQwkz5wmoyIiPSuRsGQrPh666231LL38qSo4TvvvKMSrMn5mcxmpGVxmoyIiPStRqvJnnjiCdx5551q2XvHjh1VjaD09HS1ukxqB7322mv2bynVuozsQhSXmNWS+uAAL62bQ0RE5DgjQ7IJ6qpVqzBy5Ei1W/2+ffvUUnsJkGQXefk96WeKTAIhNxasJCIinarx3mSSPC071MuokJBd5qUYolSPJn04l1maF8YpMiIi0rMafd3PyspS217cc889VoUQBw0apCpKSyVpcn5MniYiIiOoUTAke4kdOHBALa+3uO666zBv3jy17F5+kvPjsnoiIjKCGgVD69atw1NPPaX2AbOQxOkBAwaoTVJXr15tzzaSRlhwkYiIjKBGwVB2djbq1Klj83dhYWGVltyTk0+TMRgiIiIdq1EwFBMTgy+//NLm72Q1mexcT87NbDaX7VgfypwhIiLSsRqtJpMtN+Q0bNgwNTUm23DIaND69euxd+9evP322/ZvKdWqrLwiFBaZ1PkQBkNERKRjNQqGbrjhBsyfP18lSs+dO1eNIsgWHa1bt1bH5fekjymyOv6e8HBnjSEiItKvGtcZ6tu3L2JjY1FQUIDExEQEBgbC29tb7Vkmu9mPGjXKvi0lbVaScVSIiIh0rkbB0MGDBzFp0iQcO3bM5u9llIjBkHM7x+RpIiIyiBoFQ6+++qqqOC3L6yVPSJbVy0jRxo0b1WnJkiX2bynVKkvyNIMhIiLSuxolg0i16UcffRRjx45VtYZkauzuu+9WO9b3798fH330kf1bSrWK02RERGQUNQqGCgsL0aRJE3Vefsq0mYWsMJPd68m5cWSIiIiMokbBUL169XD69OmyYEiKMJ45c0ZdlikzmUIjveQM+WjdFCIiIscLhgYOHIjXXnsNP/zwg9q9Pjo6Gm+88QYOHTqERYsWoWHDhvZvKdWa3Pxi5BUUq/OcJiMiIr2rUTD0z3/+E507d8YXX3yhLk+ZMgU//vgjhgwZgi1btlht4ErO51xGnvrp7+MBL083rZtDRETkeKvJvLy8VLHFoqIidblXr15YtWoV9u3bh7Zt26JRo0b2bifVIi6rJyIiI6lx0UXh4eFRdl6mxjg9pq+RIU6RERGREXCfBaqEu9UTEZGRMBiiSs6dvxAMcWSIiIgMgMEQVZkzFMqRISIiMgAGQ1RlzhCnyYiIyAgYDJGV/MJiZOWWrhJkMEREREbAYIispKSXjgr5eLnB1+uKFhsSERE5BQZDZCU5PbcsedrFxUXr5hAREV11DIbISvKFkSGuJCMiIqNgMERWktMujAwxX4iIiAyCwRDZnCYL5W71RERkEAyGyGYCNUeGiIjIKBgMUZUJ1EREREbAYIjKFJeYkJbJ6tNERGQsDIbIaoNWsxnwdHdFgK+H1s0hIiKqFQyGyOZu9awxRERERsFgiMqkcE8yIiIyIAZDVGlkKIzL6omIyEAYDFGZc+WmyYiIiIxC82DIZDJh7ty56NWrFzp27Ij7778fp0+ftnndefPmoVWrVjZPU6ZMKbvel19+idtuu03d38CBA7FgwQKUlJTUYq+ce2SIK8mIiMhINA+G5s+fj6VLl2LGjBn47LPPVHA0YcIEFBYWVrruuHHjsGnTJqvT+PHj4evri7Fjx6rrrFy5Es899xxGjx6tzj/22GN499138fbbb2vQO+eScr40Zyg0iNNkRERkHJoGQxLwLFq0CBMnTkSfPn0QExODOXPmIDExEWvWrKl0fT8/P4SFhZWdUlJSsGTJEkybNk2NDolPP/0UQ4YMwV133YVGjRrhlltuUUHUF198oUEPnYfJZEZ6VoE6z5EhIiIyEnct//ODBw8iJycH3bt3LzsWGBiINm3aYPv27Rg0aNBFbz99+nR06dIFQ4cOLTs2adIkhISEWF3P1dUVGRkZV6EH+nE+uwAlJjPcXF0Q5O+lgiMiIiIj0DQYkhEgERUVZXU8PDy87HdVWb9+PXbt2oUVK1ZYHb/mmmusLmdlZanRIslJulLu7prPKl416dmlo0JhwT7w8HBDSYkJeubm5mr1U++M1F/2Vb+M1F/21UDBUF5eaY6Kp6en1XEvL69LjuQsXrwYffv2RevWrau8jow6PfzwwygoKMDkyZOvqK2uri4IDvaDXuUdT1M/w4N9ERhonJwhI/XVaP1lX/XLSP1lXw0QDHl7e5flDlnOCwlefHyq/qPEx8dj69atapVYVSSf6MEHH8SZM2ewcOFCNGjQ4IraKtNGmZmlm5jq0Z/xGWUjQ5mZeYYYGZIXnhH6arT+sq/6ZaT+sq/2IfdbnREnTYMhy/RYcnKySna2kMuWhGhb1q5dq/KCevToYfP3x44dUyvSZGXaJ598ghYtWtilvcXF+n1CJqfnlY0MyZNRz30tz0h9NVp/2Vf9MlJ/2dfaoelkpKwe8/f3V6M8FpmZmdi/fz+6du1a5e3i4uLQrVs3uLtXjuWkRtG9996rRpZkqb69AiG9S834KxgiIiIyEk1HhiRXSOoBzZ49W4301K9fH7NmzUJkZKQqliiFEtPS0hAQEGA1jSbB0vDhw23e5zPPPKOm3V5//XUVLMl0mYUsxyfbzmWWJlCHhxhnfpqIiEjzYEhIjaHi4mJMnToV+fn5akRIcnw8PDxUvk+/fv0wc+ZMDBs2rOw2EuAEBQVVuq+kpCRs27ZNnR88eHCl3x86dOgq98Y5mc1mpGWWVp/myBARERmN5sGQm5sbnnzySXWqSJKebQUwu3fvtnlfERERDHhqIDOnEEXFJri4yL5kPsjOKp0yIyIiMgL9FzCgSzp3YVQo2N8LHjqupURERGQLP/mobINW7lZPRERGxGCIkHphZCi0DpOniYjIeBgMEc5dGBkKDeLIEBERGQ+DISqbJuNu9UREZEQMhqhsmkxWkhERERkNgyGDkxpDlmmyME6TERGRATEYMric/GIUFJao83UDGQwREZHxMBgyOEu+UKCvBzw93LRuDhERUa1jMGRwf+ULcVSIiIiMicGQwVnyhZg8TURERsVgyODKltUzX4iIiAyKwZDBcZqMiIiMjsGQwZ3LKN2hnsEQEREZFYMhg+M0GRERGR2DIQPLLyxWdYYER4aIiMioGAwZmGVUyNfLHT5e7lo3h4iISBMMhgysbLd6jgoREZGBMRgyMK4kIyIiYjBkaJZpMu5JRkRERsZgyMA4TUZERMRgyNA4TUZERMRgyNDKpskYDBERkYExGDKoouISZOQUqvPMGSIiIiNjMGRQqZkF6qeXhxv8fTy0bg4REZFmGAwZVPkpMhcXF62bQ0REpBkGQ0ZPnuYUGRERGRyDIYPvVs9l9UREZHQMhgyKK8mIiIhKMRgyKFafJiIiKsVgyKDOXcgZ4jQZEREZHYMhAyouMSE9q3RpPafJiIjI6BgMGdD5rAKYzYC7mwsC/Ty1bg4REZGmGAwZeFl9SKA3XFljiIiIDI7BkAFxt3oiIqK/MBgyIK4kIyIi+guDIQOvJGPyNBEREYMhQ48McZqMiIiIwZAhcZqMiIjoLwyGDMZkNiMti9NkREREFgyGDCYjuxDFJWa1pD44wEvr5hAREWmOwZBBp8gkEHJz5cNPRETET0ODOZeZp35yioyIiKgUgyGDYfI0ERGRgwVDJpMJc+fORa9evdCxY0fcf//9OH36tM3rzps3D61atbJ5mjJlSqXrnzp1St3nmTNnaqEnzoHL6omIiBwsGJo/fz6WLl2KGTNm4LPPPlPB0YQJE1BYWFjpuuPGjcOmTZusTuPHj4evry/Gjh1rdd1jx46p6+fllU4LUSkWXCQiInKgYEgCnkWLFmHixIno06cPYmJiMGfOHCQmJmLNmjWVru/n54ewsLCyU0pKCpYsWYJp06ap0SGLd999FyNGjECdOnVquUdONE3GYIiIiEj7YOjgwYPIyclB9+7dy44FBgaiTZs22L59+yVvP336dHTp0gVDhw61Or527VrMnDkTTz311FVpt7Mym81lO9aHMmeIiIhIcYeGZARIREVFWR0PDw8v+11V1q9fj127dmHFihWVfrds2TL1c+vWrXZtr7u75rOKVyQzpxCFRSZ1PjzEt1J/3NxcrX7qmZH6arT+sq/6ZaT+sq8GCoYs+Tyenp5Wx728vJCRkXHR2y5evBh9+/ZF69atURtcXV0QHOwHZ3YuuzQPKyTQC+FhAVVeLzDQB0ZhpL4arb/sq34Zqb/sqwGCIW9v77LcIct5UVBQAB+fqv8o8fHxatRnwYIFqC0mkxmZmblwZidOp6ufwQHeSE/PqfR7icrlyZiZmYeSktIRJL0yUl+N1l/2Vb+M1F/21T7kfqsz4qRpMGSZHktOTkajRo3Kjsvl8gnRFUlOUEhICHr06IHaVFzs3E/IpLQLBRcDvS7aF3kyOntfq8tIfTVaf9lX/TJSf9nX2qHpZKSsHvP397fK7cnMzMT+/fvRtWvXKm8XFxeHbt26wd1d01jO6ViSp7mSjIiI6C+aRhOSKzR69GjMnj1bjfTUr18fs2bNQmRkJAYOHIiSkhKkpaUhICDAahpNgqXhw4dr2XTnLrjIlWRERERlNE9TlxpDUhNo6tSpGDVqFNzc3LBw4UJ4eHggISEBPXv2xOrVq61uI/WFgoKCNGuzs+LIEBERUWWazzNJ8PPkk0+qU0UNGjTAoUOHKh3fvXt3te772muvtXl7ozpXVnDROKsTiIiIHH5kiGpHbn4x8gqK1XlOkxEREf2FwZDBpsj8fTzg5emmdXOIiIgcBoMhgziXcWFZPfOFiIiIrDAYMgiuJCMiIrKNwZBBcCUZERGRbQyGDDYyVJcjQ0RERFYYDBlsWX0oR4aIiIisMBgyCE6TERER2cZgyAAKikqQlVukzjMYIiIissZgyAAs+UI+Xm7w9dK86DgREZFDYTBkpCmyQG+4uLho3RwiIiKHwmDIALiSjIiIqGoMhgw0MhTKDVqJiIgqYTBkqN3qOTJERERUEYMhI02TMRgiIiKqhMGQwRKoiYiIyBqDIZ0rLjHhfFaBOs/q00RERJUxGNK5tMx8mAF4ursiwNdD6+YQERE5HAZDBskXCmGNISIiIpsYDOncubJl9ZwiIyIisoXBkM5xJRkREdHFMRjSOVafJiIiujgGQ0ZZVs+RISIiIpsYDBmk+jRzhoiIiGxjMKRjJpMZ6RdqDHGajIiIyDYGQzp2PrsAJSYz3FxdEOTvpXVziIiIHBKDIQNMkYUEesHVlTWGiIiIbGEwpGNcSUZERHRpDIYMUHCRK8mIiIiqxmBIxzgyREREdGkMhnQsNSNP/Qyt46N1U4iIiBwWgyEdO5d5YVk9p8mIiIiq5F71r8iZ6wtt2puAc+dLR4YYDBEREVWNwZDOHDiVjs9+OoLTydnqcsuGQaw+TUREdBEMhnQiKT0X/1t3FLuOnFOXfb3ccXvPprixc324urDGEBERUVUYDDm53PxirPrtJH6MO62qTUvg06dTPQzu2RQBvp5aN4+IiMjhMRhyUiUmEzbuTsCKX44jK7dIHWvXNAR39WuB+qF+WjePiIjIaTAYckJ/nEjDZ+uO4GxKjrocVdcXd93YArHN6mrdNCIiIqfDYMiJJKTmqLyg3cdS1WU/b3cM6RWNGzrWg7sbqyQQERHVBIMhJ5CTX4SVm05i3c4zZbvQ9+1cH7f3aAp/Hw+tm0dEROTUGAw5sOISEzb8Hq/ygnLyi9WxDs3q4s4bmyOqLvOCiIiI7IHBkIPacywVn687goTUXHVZkqLv6tcc7ZoyL4iIiMieGAw5mLPnclQQtO94mros02BDe0ejd4couLkyL4iIiEh3wZDJZMKbb76JZcuWISsrC127dsW0adPQsGHDStedN2+euq4tw4YNw8yZM9X5zZs3Y9asWTh27BiioqLwyCOP4NZbb4Ujy84rwte/nMD6XWdhMpfmBfXv0gC3Xd8Evt7MCyIiItJtMDR//nwsXboUL7/8MiIjI1UQM2HCBHzzzTfw9LQuGjhu3DiMHDnS6tjixYvx6aefYuzYseqyBEAPPvgg7rvvPnVfP//8MyZPnoyQkBB0794djpgXtG7nWazcdAK5BaV5QZ1ahOLOvs0REeKrdfOIiIh0T9NgqLCwEIsWLcKkSZPQp08fdWzOnDno1asX1qxZg0GDBlld38/PT50s9u/fjyVLlmDGjBlo1aqVOvbhhx+q848//ri63KxZM3W9999/3+GCoVOJWXhn5R9ISivNC2oQ5o9R/ZqjdZMQrZtGRERkGJomoRw8eBA5OTlWQUpgYCDatGmD7du3X/L206dPR5cuXTB06NCyY3FxcZWCnuuuuw47duyA2WyGI/lu6ykVCAX6emDs32Lw/H1dGQgREREZaWQoMTFR/ZS8nvLCw8PLfleV9evXY9euXVixYkWl+5Tptor3l5eXh/T0dDVdVlPu7vaNHWXrjPbRddGtTQR8vDSfsYTbhcKNlp96ZqS+Gq2/7Kt+Gam/7Gvt0vQTWAIUUTE3yMvLCxkZGRe9reQK9e3bF61bt7Y6np+fX+n+LJdlWq6mXF1dEBxs39o+cn8tm4bC0QQG+sAojNRXo/WXfdUvI/WXfTVAMOTt7V0WpFjOi4KCAvj4VP1HiY+Px9atW7FgwYJKv5NAqmLQY7l8sfu8FJPJjMzM0twevZKoXJ6MmZl5KCkxQc+M1Fej9Zd91S8j9Zd9tQ+53+qMOGkaDFmmx5KTk9GoUaOy43LZkhBty9q1a9V0V48ePWzep9y+PLns6+uLgICAK2pvcbG+n5AW8mRkX/XJSP1lX/XLSP1lX2uHppORMTEx8Pf3V6M8FpmZmWr1l9QbqookSXfr1g3u7pVjOUmo3rZtm9WxLVu2oHPnznBl0UIiIiKqQNPoQHJ5Ro8ejdmzZ+Onn35Sq8tkSbwkQA8cOBAlJSVISUlReUDlSbAkgZQtY8aMwZ49e9R9Ss0hWbr//fffq9pFRERERBVpPlQyceJEjBgxAlOnTsWoUaPg5uaGhQsXwsPDAwkJCejZsydWr15tdRsJkIKCgmzeX4sWLVQhxw0bNmDIkCGqsrUUX3S0GkNERETkGFzMjlZ8x4HnMtPScqBnUjpAVrilp+fofo7aSH01Wn/ZV/0yUn/ZV/sICfGrVgK15iNDRERERFpiMERERESGxmCIiIiIDI3BEBERERkagyEiIiIyNAZDREREZGgMhoiIiMjQWGeomuTPJJu16p3UY9D7poBG7KvR+su+6peR+su+XjlXVxe4uLhc8noMhoiIiMjQOE1GREREhsZgiIiIiAyNwRAREREZGoMhIiIiMjQGQ0RERGRoDIaIiIjI0BgMERERkaExGCIiIiJDYzBEREREhsZgiIiIiAyNwRAREREZGoMhIiIiMjQGQ0RERGRoDIYM5Pz585g2bRp69+6Nzp07Y9SoUYiLi6vy+m+//TZatWpV6eQMkpKSbLb9q6++snn99PR0PPHEE+jatSu6deuGF154AXl5eXAGW7dutdlXOfXr18/mbXbs2GHz+nJfjuzdd9/FmDFjrI4dOHAAo0ePRseOHXHjjTdiyZIll7yf7777DrfccgtiY2MxZMgQbN68Gc7Q13Xr1mH48OHo1KmT6usrr7yC/Pz8Ku+jpKRE9bHi4zxv3jw4el+nTp1aqd3SZ2d/XG31V85X9RpesWJFlfdz3333Vbp+xb+jI37WbN68GcOGDUOHDh1w880349tvv73kfX7yySfq/Uwe27vvvhv79++3b6PNZBj33XefedCgQebt27ebjx8/bn7hhRfMsbGx5mPHjtm8/qOPPmp+8sknzcnJyVYnZ/Dzzz+b27dvb05KSrJqe15ens3rjx492jx8+HDzvn37zL/99pu5b9++5smTJ5udQUFBQaXHaM2aNeZWrVqZv/jiC5u3+eSTT8z9+/evdDu5L0f18ccfm2NiYtRjZZGWlma+9tprzVOmTDEfPXpU9Vce96r6LTZv3mxu27at+cMPP1S3efnll83t2rVT5x25r/K6bd26tfntt982nzhxQj3He/fubX766aervB/pU8uWLc0HDhywepyzs7PNjtxXMWLECPPrr79u1e7U1FSnflyr6m96erpVP+V96+677zbfeuutF32sunfvbl66dKnVbeW+HPmz5ujRo+o1Ko+tnH///ffNbdq0Ue+7Vfnqq6/U7b/++mvzkSNH1OdSt27dLvp8uFwMhgzi5MmT6k0xLi6u7JjJZFIfiG+88YbN2/ztb38zL1682OyMFixYYL7tttuqdd2dO3eqv035N81ffvlFBROJiYlmZ5OTk6OCuYt9SD733HPmhx56yOwM5DF48MEHzR07djTffPPNVh8i77zzjrlnz57moqKismOvvfaaeeDAgVXe37hx41SgX95dd91lfvbZZ82O3NcnnnjCPHbsWKvrL1++XAUAVQWx3377rblz585mR3Sxvsp7kxyXoL66HPlxvVR/K/roo49UIFfVF1Vx7tw59b71xx9/XKUWX53PGnk8JNAt71//+pd6/Koir+dXX3217LK83m+44Qb1+rcXTpMZRHBwMBYsWID27duXHXNxcVGnzMzMStcvLCzEyZMnER0dDWd06NAhNGvWrFrXleHbsLAwq+vLVJn8bWQ6ydm88847aorvqaeessvfR2t//PEHPDw8sHLlSjWsXvGxk8fK3d297Nh1112nnrvnzp2rdF8mkwk7d+5E9+7drY5fe+212L59Oxy5r+PGjav0mLq6uqKoqAjZ2dlO9zhfrK9//vkncnNzq/3+4+iP66X6W15aWhreeOMN/N///d9F+y+PrbxHNW3aFM70WRMXF1fpcZLXrLzXygBNRampqer1XP428nrv0qWLXR/bv95BSNcCAwNxww03WB374YcfcOrUKTzzzDOVrn/06FGVbyDX+c9//oOCggKVT/Pkk08iPDwcju7w4cPqRXnPPffgxIkTaNy4sXpzkTlsW/lFUVFRVsc8PT0RFBSEhIQEOBN5I/3ggw9U/pO0vypHjhxRfx+Zt5f+t2zZEo8//riaj3c0kidSVa5IYmKiant5luenPHahoaFWv5M3Y/mQjYyMrHQbuS9H7mubNm2sLksQJI91u3btEBISUuXroLi4GOPHj8fBgwcRERGBe++9F4MHD4Yj91XaLT766CNs3LhRBX3y2pXnaEBAQKXrO/rjeqn+lvfee+/B29tbPWYXI38j+VtMnz4dv/76K3x9fVX+zcMPP6zevxz1s2b58uU2Hyf5Aie5mxWfy5bHr+J7tNxGntP2wpEhg5JvUVOmTMHAgQPRp0+fKt+MfHx88N///lcFRMePH8ff//73iyZsOgJ585e2ZmRk4JFHHlHfUiS59oEHHrCZUCkvQltvHl5eXioIdCZLly5Vb5B33XVXldeRICErK0t9eEiS6vz581XQIEnIEgQ7E3kuVnzs5HETth47y3PX1m2c6bGW5/jkyZNVUPvcc89VeT35vSSzSlLtwoULcdNNN6nX/RdffAFHJu8/EgDJB56MdD799NPYtGmT+qCXUSC9Pq4ywve///1PBUKW5/HF/kbSN/kC8/7776sve8uWLVOvaUf+rMm38Zq1XJYZiYosC1mu9mPLkSEDWrt2LSZNmqSy/GfPnm3zOrISQ76JlY/SW7RooY7JihZZseGoZAhVVkW5ubmpb1hCvj3LB4N8IFQcopXr2HoRygtNvm05E1l5Io+dpd+2yDcsGV6WQFeG7YUMacvqDPkmLivpnIWtx87yBmnrsbN8wNi6jfw9nOUD87HHHsO2bdvw5ptvXnQ0b9WqVWqE18/PT12OiYlBfHy8eh2MGDECjko+2GXFkIxeChn9k6nsO++8E3v37q00zaSHx9Xy3ix9kBWDlyIjQjJtWqdOnbK/kbyeZfRMAuWKo6KO8lnj5eVV6XGyXLb1WFney672Y8uRIYP5+OOP1WhJ37591Teui337qDhcKd/SZOrFUYadL0be/CsGBBLMyZRQRTJkm5ycbHVMXnjyjdoZpgQtZMj49OnTuO2226o1lG0JhIR8C5fcElt/H0dm67GzXJYpoYrk+StBkq3b2Lq+o5F2ytTv77//rgKaitMRFclrwBIIWciHpqO/huX5aAmEyr9+ha22O/vjWj54kMdUXp/V+dJnCYSq8zdylM+aqKgom4+TPH62pkAt02NX+7FlMGQgMoUyY8YM9Wb6+uuvX3Reec6cOWpIvXxC25kzZ9ScbvPmzeHIZARIvolUrJmzb98+m22XXCh585A5bQv51i2uueYaOAtJTKxbt6769n8xkoMhdWokcCo/7SLBlKM/trYeO0m8lNEPiy1btqikUvlbVCRJnPLcsDy+FvJckYRMRybTvpLvI3lhUnNF+n4xkkcjyeUVa2vJyIrlQ9NRycjG2LFjK7Vb2HqOOvPjWp6t5OKqyNSnTD9V/BvJl5wmTZrAUT9runTpUulxktesPH4SBFckr2N5PZd/P5f3K/lbXeo1cDkYDBmEJBG/9NJLGDBgAB588EG10iYlJUWdJH9ERkLkvGUoUq539uxZPP/88+q2Mq0iUb48YXv16gVHJiMcsgpDhpHlBXPs2DHMnDlTfZuW4Xf54JS+WvIMZMhd+iXDy3v27FEvTCkYJtNNzvStUqa5qiqKKf3NyclR56Wv8q1bhtglQJRVKXJeRsIqfgA5OplOkGmjf//73yrfST74JalYnuMW8vyWAKJ8oTop8rZ48WL13Hj11VdV4UYJNByZPIclgJ01a5YatbW8fuVkCQblMZSTkNEFWaUjX2w2bNigVuRI/pysZpLXsiOTL2KS3yfTgLKyTNovybeDBg0qWx2nl8e1fC6ffNms6suMvH7lsS7/N/r666/x6aefqufF6tWrVZ8l38jf3x+O+lkzZswY9T4r02byOC1atAjff/89JkyYUHYf5Z/HlpWU8rhK8rW8zuW5IO/fdp3qtdsifXJoUqhNaj/YOj311FPmLVu2qPPy00KKYEmdDqmLIQWupLDd+fPnzc4gJSVF1dnp0aOHKvAl/ZACYOL06dOqr19++aVVzY5HHnlE9VWK+Ekdnvz8fLMzmTBhgvmxxx6z+Tvp79y5c8sunzp1SvVXHtcOHTqoGh+HDh0yOzp5rlasz7J7927znXfeqeqySH0lqdFS8TZyvGJ9ngEDBqjnxtChQy9a8M0R+lpcXKzaWtVrWJ7TQq5f/u+TlZVlfumll1RNFvn7DB482Pzjjz+aneFxXb16tXnIkCGq2J68jqWIYvnXpLM+rhd7Hlesd1aevH7l9xULOEo9OMtzX97nS0pKzI78WSM2bNigijJKu6XmktTDKq/i81hIcUYpMirPBylIuX//frM9ucg/9gutiIiIiJwLp8mIiIjI0BgMERERkaExGCIiIiJDYzBEREREhsZgiIiIiAyNwRAREREZGoMhIiIiMjQGQ0RkSDfeeKPaDZ2IiMEQERERGRqDISIiIjI0BkNERAC++OILtUnmW2+9pXVTiKiWMRgiIsOTHb+fffZZPPzww/jHP/6hdXOIqJYxGCIiQ1u/fj0mT56MBx54ABMnTtS6OUSkAe5aT0SGXU3m5+eHU6dOITQ0FGvXroWrK78fEhkRX/lEZFiHDx9G9+7dcfbsWXzyySdaN4eINMJgiIgMq1evXnj33Xdxyy234PXXX0dCQoLWTSIiDTAYIiLDkukxMWXKFLi5ueH555/XuklEpAEGQ0RkeOHh4Xj88cfx888/Y9WqVVo3h4hqGYMhIiIAo0aNQmxsLP7zn/8gPT1d6+YQUS3iajIiIiIyNI4MERERkaExGCIiIiJDYzBEREREhsZgiIiIiAyNwRAREREZGoMhIiIiMjQGQ0RERGRoDIaIiIjI0BgMERERkaExGCIiIiJDYzBEREREhsZgiIiIiGBk/w9x62ulQ3w3KAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%time\n", "\n", "## another outlook: parameter tuning\n", "from sklearn.neighbors import KNeighborsClassifier\n", "model = KNeighborsClassifier()\n", "\n", "params = range(1, 21) ## k values as range from 1 to 20 by 1\n", "scores = [] ## empty list for collecting score results by iteration\n", "\n", "## iterate over params\n", "for param in params:\n", " model.set_params(n_neighbors=param)\n", " model.fit(X_train, y_train)\n", " scores.append(model.score(X_test, y_test))\n", " print(param, model.score(X_test, y_test)) ## for trace progress only\n", " \n", "## visualization\n", "fig = sns.lineplot(x=params, y=scores)\n", "plt.scatter(x=params[scores.index(max(scores))], y=max(scores), color=\"black\")\n", "plt.xlabel('k')\n", "plt.ylabel('accuracy');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Standardisieren von gesplitteten Daten" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:36:12.816582Z", "start_time": "2020-03-17T11:36:12.761181Z" } }, "outputs": [], "source": [ "## get standardization parameters on the base of training data\n", "from sklearn.preprocessing import StandardScaler\n", "scaler = StandardScaler().set_output(transform='pandas')\n", "scaler.fit(X_train)\n", "\n", "## apply standardization to both data sets\n", "X_train_sc = scaler.transform(X_train)\n", "X_test_sc = scaler.transform(X_test)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2020-03-17T11:36:12.816582Z", "start_time": "2020-03-17T11:36:12.761181Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[40.2715655 4.4179218 0.55256352]\n", "age 40.271565\n", "education 4.417922\n", "housing 0.552564\n", "dtype: float64\n", "[11.83482251 1.65671617 0.4972294 ]\n", "age 11.835723\n", "education 1.656842\n", "housing 0.497267\n", "dtype: float64\n", "age 1.297203e-17\n", "education -1.086407e-16\n", "housing 1.135052e-16\n", "dtype: float64\n", "age 1.000076\n", "education 1.000076\n", "housing 1.000076\n", "dtype: float64\n", "age 0.027978\n", "education 0.023008\n", "housing 0.001667\n", "dtype: float64\n", "age 0.995850\n", "education 0.986509\n", "housing 0.999975\n", "dtype: float64\n" ] } ], "source": [ "## check\n", "## compare mean and std of data and scaler attribute\n", "print(scaler.mean_[0:3])\n", "print(X_train.iloc[:,[0,1,2]].mean())\n", "print(scaler.scale_[0:3])\n", "print(X_train.iloc[:,[0,1,2]].std())\n", "\n", "## compare mean and std before and after scalint\n", "print(X_train_sc.iloc[:,[0,1,2]].mean())\n", "print(X_train_sc.iloc[:,[0,1,2]].std())\n", "print(X_test_sc.iloc[:,[0,1,2]].mean())\n", "print(X_test_sc.iloc[:,[0,1,2]].std())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Weitere Instanzbasierte Methoden" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(kein Code)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Preparation für weitere Klassifikatoren (und Regressoren)" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "## read and prep real data\n", "from bfh_cas_pml import prep_data\n", "X_train, X_test, y_train, y_test = prep_data(\n", " 'bank_data_prep.csv', 'y', seed = 1234)" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "## read and prep demo data\n", "from bfh_cas_pml prep_demo_data\n", "X_demo, y_demo = prep_demo_data('demo_data_class.csv', 'y')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.0" }, "toc": { "base_numbering": "2.1", "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Inhalt", "title_sidebar": "Inhalt", "toc_cell": true, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "173.533px" }, "toc_section_display": true, "toc_window_display": true }, "toc-autonumbering": true, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "position": { "height": "144.183px", "left": "910px", "right": "20px", "top": "115px", "width": "350px" }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }