Newer
Older
{
"cell_type": "markdown",
"metadata": {
"toc": true
},
"source": [
"<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
"<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#COMPAS-data\" data-toc-modified-id=\"COMPAS-data-1\"><span class=\"toc-item-num\">1 </span>COMPAS data</a></span></li><li><span><a href=\"#Generate-synthetic-data-set\" data-toc-modified-id=\"Generate-synthetic-data-set-2\"><span class=\"toc-item-num\">2 </span>Generate synthetic data set</a></span><ul class=\"toc-item\"><li><span><a href=\"#Machine-evaluation\" data-toc-modified-id=\"Machine-evaluation-2.1\"><span class=\"toc-item-num\">2.1 </span>Machine evaluation</a></span></li></ul></li><li><span><a href=\"#Implementation-of-contraction-algorithm\" data-toc-modified-id=\"Implementation-of-contraction-algorithm-3\"><span class=\"toc-item-num\">3 </span>Implementation of contraction algorithm</a></span></li><li><span><a href=\"#Implementation-of-our-model\" data-toc-modified-id=\"Implementation-of-our-model-4\"><span class=\"toc-item-num\">4 </span>Implementation of our model</a></span></li><li><span><a href=\"#Validation-analysis\" data-toc-modified-id=\"Validation-analysis-5\"><span class=\"toc-item-num\">5 </span>Validation analysis</a></span></li></ul></div>"
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Bachelors thesis' analyses\n",
"\n",
"*This Jupyter notebook is for the analyses and model building for Riku Laine's bachelors thesis*\n",
"\n",
"Table of contents is provided above. First I will briefly present the COMPAS data set and then create the synthetic data set as done by Lakkaraju *et al.* ([link](https://helka.finna.fi/PrimoRecord/pci.acm3098066)). Then I will proceed to implement their algorithm as well as ours.\n",
"\n",
"## COMPAS data\n",
"\n",
"The following data filtering procedure follows the one described in the [ProPublica methodology](https://www.propublica.org/article/how-we-analyzed-the-compas-recidivism-algorithm)."
]
},
{
"cell_type": "code",
{
"name": "stdout",
"output_type": "stream",
"text": [
"(7214, 53)\n"
]
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from datetime import datetime\n",
"import matplotlib.pyplot as plt\n",
"import numpy.random as npr\n",
"\n",
"plt.rcParams.update({'font.size': 16})\n",
"\n",
"# Read file\n",
"compas_raw = pd.read_csv(\"../data/compas-scores-two-years.csv\")\n",
"\n",
"# Check dimensions, number of rows should be 7214\n",
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(6172, 13)"
]
},
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Select columns\n",
"compas = compas_raw[[\n",
" 'age', 'c_charge_degree', 'race', 'age_cat', 'score_text', 'sex',\n",
" 'priors_count', 'days_b_screening_arrest', 'decile_score', 'is_recid',\n",
" 'two_year_recid', 'c_jail_in', 'c_jail_out'\n",
"]]\n",
"\n",
"# Subset values\n",
"compas = compas.query('days_b_screening_arrest <= 30 and \\\n",
" days_b_screening_arrest >= -30 and \\\n",
" is_recid != -1 and \\\n",
" c_charge_degree != \"O\"')\n",
"\n",
"# Drop row if score_text is na\n",
"compas = compas[compas.score_text.notnull()]\n",
"\n",
"compas.shape"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" length_of_stay decile_score\n",
"length_of_stay 1.000000 0.207478\n",
"decile_score 0.207478 1.000000\n",
"[[1. 0.20747808]\n",
" [0.20747808 1. ]]\n"
]
},
{
"data": {
"text/plain": [
"(0.2074780847803181, 5.439585463018677e-61)"
]
},
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"out = pd.to_datetime(compas.c_jail_out, format=\"%Y-%m-%d %H:%M:%S\")\n",
"in_ = pd.to_datetime(compas.c_jail_in, format=\"%Y-%m-%d %H:%M:%S\")\n",
"\n",
"compas['length_of_stay'] = (out - in_).astype('timedelta64[D]')\n",
"\n",
"# as denominator in variance. Reference:\n",
"# https://stackoverflow.com/questions/53404367/why-pearson-correlation-is-different-between-tensorflow-and-scipy\n",
"print(compas[['length_of_stay', 'decile_score']].corr())\n",
"\n",
"print(np.corrcoef(compas.length_of_stay, compas.decile_score))\n",
"\n",
"from scipy.stats import pearsonr\n",
"\n",
"pearsonr(compas.length_of_stay, compas.decile_score)"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"25 - 45 3532\n",
"Less than 25 1347\n",
"Greater than 45 1293\n",
"Name: age_cat, dtype: int64\n"
]
}
],
"source": [
"print(compas.age_cat.value_counts())"
]
},
{
"cell_type": "code",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"African-American 3175\n",
"Caucasian 2103\n",
"Hispanic 509\n",
"Other 343\n",
"Asian 31\n",
"Native American 11\n",
"Name: race, dtype: int64\n"
]
}
],
"source": [
"print(compas.race.value_counts())"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Black defendants: 51.44%\n",
"White defendants: 34.07%\n",
"Hispanic defendants: 8.25%\n",
"Asian defendants: 0.50%\n",
"Native American defendants: 0.18%\n"
]
}
],
"source": [
"print(\"Black defendants: %.2f%%\" % (3175 / 6172 * 100))\n",
"print(\"White defendants: %.2f%%\" % (2103 / 6172 * 100))\n",
"print(\"Hispanic defendants: %.2f%%\" % (509 / 6172 * 100))\n",
"print(\"Asian defendants: %.2f%%\" % (31 / 6172 * 100))\n",
"print(\"Native American defendants: %.2f%%\" % (11 / 6172 * 100))"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Low 3421\n",
"Medium 1607\n",
"High 1144\n",
"Name: score_text, dtype: int64"
]
},
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"compas.score_text.value_counts()"
]
},
{
"cell_type": "code",
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>race</th>\n",
" <th>African-American</th>\n",
" <th>Asian</th>\n",
" <th>Caucasian</th>\n",
" <th>Hispanic</th>\n",
" <th>Native American</th>\n",
" <th>Other</th>\n",
" </tr>\n",
" <tr>\n",
" <th>sex</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Female</th>\n",
" <td>549</td>\n",
" <td>2</td>\n",
" <td>482</td>\n",
" <td>82</td>\n",
" <td>2</td>\n",
" <td>58</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Male</th>\n",
" <td>2626</td>\n",
" <td>29</td>\n",
" <td>1621</td>\n",
" <td>427</td>\n",
" <td>9</td>\n",
" <td>285</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"race African-American Asian Caucasian Hispanic Native American Other\n",
"sex \n",
"Female 549 2 482 82 2 58\n",
"Male 2626 29 1621 427 9 285"
]
},
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tab = compas.groupby(['sex', 'race']).size()\n",
"tab.unstack()"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"<Figure size 1008x504 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"\n",
"fig, ax = compas.query(\"race in ['Caucasian', 'African-American']\").hist(\n",
" \"decile_score\",\n",
" by=\"race\",\n",
" figsize=(14, 7),\n",
" sharey=True,\n",
" xrot='horizontal',\n",
" ec='black',\n",
" bins=np.arange(0.5, 11.5, 1.0),\n",
" rwidth=0.9)\n",
"\n",
"fig.text(-1.5, 350, \"Frequency\", rotation='vertical')\n",
"fig.text(11.5, -60, \"Decile score\", horizontalalignment='center')\n",
"plt.tight_layout(w_pad=-2)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>age</th>\n",
" <td>69</td>\n",
" <td>34</td>\n",
" <td>24</td>\n",
" </tr>\n",
" <tr>\n",
" <th>c_charge_degree</th>\n",
" <td>F</td>\n",
" <td>F</td>\n",
" <td>F</td>\n",
" </tr>\n",
" <tr>\n",
" <th>race</th>\n",
" <td>Other</td>\n",
" <td>African-American</td>\n",
" <td>African-American</td>\n",
" <td>Other</td>\n",
" <td>Caucasian</td>\n",
" </tr>\n",
" <tr>\n",
" <th>age_cat</th>\n",
" <td>Greater than 45</td>\n",
" <td>25 - 45</td>\n",
" <td>Less than 25</td>\n",
" <td>25 - 45</td>\n",
" <td>25 - 45</td>\n",
" </tr>\n",
" <tr>\n",
" <th>score_text</th>\n",
" <td>Low</td>\n",
" <td>Low</td>\n",
" <td>Low</td>\n",
" </tr>\n",
" <tr>\n",
" <th>sex</th>\n",
" <td>Male</td>\n",
" <td>Male</td>\n",
" <td>Male</td>\n",
" </tr>\n",
" <tr>\n",
" <th>priors_count</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>days_b_screening_arrest</th>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>decile_score</th>\n",
" <td>1</td>\n",
" <td>3</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>is_recid</th>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>two_year_recid</th>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>c_jail_in</th>\n",
" <td>2013-08-13 06:03:42</td>\n",
" <td>2013-01-26 03:45:27</td>\n",
" <td>2013-04-13 04:58:34</td>\n",
" <td>2013-11-30 04:50:18</td>\n",
" <td>2014-02-18 05:08:24</td>\n",
" </tr>\n",
" <tr>\n",
" <th>c_jail_out</th>\n",
" <td>2013-08-14 05:41:20</td>\n",
" <td>2013-02-05 05:36:53</td>\n",
" <td>2013-04-14 07:02:04</td>\n",
" <td>2013-12-01 12:28:56</td>\n",
" <td>2014-02-24 12:18:30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>length_of_stay</th>\n",
" <td>0</td>\n",
" <td>10</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 \\\n",
"age 69 34 \n",
"c_charge_degree F F \n",
"race Other African-American \n",
"age_cat Greater than 45 25 - 45 \n",
"score_text Low Low \n",
"sex Male Male \n",
"priors_count 0 0 \n",
"days_b_screening_arrest -1 -1 \n",
"decile_score 1 3 \n",
"is_recid 0 1 \n",
"two_year_recid 0 1 \n",
"c_jail_in 2013-08-13 06:03:42 2013-01-26 03:45:27 \n",
"c_jail_out 2013-08-14 05:41:20 2013-02-05 05:36:53 \n",
"length_of_stay 0 10 \n",
"\n",
" 2 5 \\\n",
"age 24 44 \n",
"c_charge_degree F M \n",
"race African-American Other \n",
"age_cat Less than 25 25 - 45 \n",
"score_text Low Low \n",
"sex Male Male \n",
"priors_count 4 0 \n",
"days_b_screening_arrest -1 0 \n",
"decile_score 4 1 \n",
"is_recid 1 0 \n",
"two_year_recid 1 0 \n",
"c_jail_in 2013-04-13 04:58:34 2013-11-30 04:50:18 \n",
"c_jail_out 2013-04-14 07:02:04 2013-12-01 12:28:56 \n",
"length_of_stay 1 1 \n",
"\n",
" 6 \n",
"age 41 \n",
"race Caucasian \n",
"age_cat 25 - 45 \n",
"score_text Medium \n",
"is_recid 1 \n",
"two_year_recid 1 \n",
"c_jail_in 2014-02-18 05:08:24 \n",
"c_jail_out 2014-02-24 12:18:30 \n",
"length_of_stay 6 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\stats\\stats.py:1713: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.\n",
" return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval\n"
]
},
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAzwAAAG5CAYAAABLFDGsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzs3Wd4XOW59fF1j3qzZBVbtmVJtuXeiDE2PRiHYppJKKGEng7pBRJOeAnpyUmHHCAQIHBoARIgmBZ6s3GhuWPLkiXZsiWr9/a8HzTyEcJlLI20RzP/33VxRZ7ZM7M0UmCWn73vx5xzAgAAAIBw5PM6AAAAAAAMFgoPAAAAgLBF4QEAAAAQtig8AAAAAMIWhQcAAABA2KLwAAAAAAhbFB4ACFFmdpyZbRqi17rRzO4botc6xsw+NLMGMzs7gOPvNrOfBvjcU83sHTOrN7OvDzztR577cjN7PZjPCQAYfBQeADgIMysys2b/h+gaM3vTzL5sZoP671Dn3GvOual9cnxqMF8zEEHIcZOkm51zyc65fwUrl9/3Jb3snEtxzv0pyM8dNIfyHprZy2Z2wiBHAoCwReEBgMCc6ZxLkZQn6ZeSrpV0p7eRhq08SeuG4XMDAIYhCg8AHALnXK1z7glJn5V0mZnNkiQzizOz/zaz7Wa2y8xuNbME/30nmFmpmX3HzHab2U4zu6LnOc3sNDNb719BKjOz7/Z+nP/reyXlSnrSfyrY983sKTP7Wu98Zvb+vk4TM7N8M3Nm9kUz2+HP8J39fZ9mdpaZrfOvaL1sZtP3l2M/j/+CmW0xsyoze8LMxvpv3yppYq/Hx+3jsZ8wszX+9+MhSfF97j/DzN7ttdo2x3/7i5IWSbrZ/9xTBvhzyfBnrzOztyVN6pPjj2ZW4r9/tZkd1+u+G83sYTP7u//7WGdm8/f3HppZvJndZ2Z7/N/XSjMbvb+fT6/XOd1/Cl+dP8uNfe6/1MyK/c/7o94rS2bmM7PrzGyr//6HzSzdf1+/8gBAKKLwAEA/OOfellQqqedD7q8kTZF0mKQCSeMk3dDrIdmSUv23XyXpFjMb6b/vTklf8q8gzZL04j5e7xJJ29W90pTsnPu1pHskfa7nGDOb63/+ZQeIvkjSZEknS7puX6dVmdkUSQ9I+qakLP/zPWlmsfvJ0ffxJ0r6haTzJY2RVCzpQf/3ManP41v7PDZW0r8k3SspXdI/JJ3T6/55kv4m6UuSMiTdJukJM4tzzp0o6TVJ1/ife7MG9nO5RVKL/3u40v9Pbyv9z5su6X5J/zCz3uXsLP/3nSbpCUk3+9+Dfb2Hl/lzjPd/X1+W1Ow//gTn3Mt932e/RkmX+l/jdElf6Sm8ZjZD0l8kXez/Hnq+zx5fl3S2pE9KGiup2v8960B5AGC4ofAAQP/tkJRuZibpC5K+5Zyrcs7VS/q5pAt6Hdsu6SbnXLtzbpmkBklTe903w8xGOOeqnXNrAnz9xyVNNrPJ/j9fIukh51zbAR7zY+dco3PuA0l3SbpwH8d8VtJTzrnnnXPtkv5bUoKkowPMdbGkvznn1vgLzQ8kHWVm+QE89khJMZL+4H+vHlF3sejxBUm3OedWOOc6nXP3SGr1P+4jBvJzMbModRetG/zv11p1F8y9nHP3Oef2OOc6nHO/lRSn//uZStLrzrllzrlOdRe4uQf4vtvVXSwK/N/Xaudc3cHeLOfcy865D5xzXc6599VdVD/pv/tcSU865173/07cIMn1eviXJF3vnCv1/5xulHSumUX3Nw8AhCIKDwD03zhJVepeBUmUtNp/+k+NpGf8t/fY45zr6PXnJknJ/q/PkXSapGIze8XMjgrkxf0fUh+W9DnrHqBwobo/WB9ISa+vi9X9N/t9jfXf1/M6Xf7HjdvHsfvS9/ENkvYE+Pixksqcc70/mBf3+jpP0nd63mf/ez1+P9/HQH4uWZKi9fH3ay//qXAbzKzW/9ypkjJ7HVLe53nj/WViX+6V9KykB637lMNfm1nMfo7tnWGhmb1kZhVmVqvulZieDGN753fONan759AjT9I/e703GyR1Shrd3zwAEIooPADQD2Z2hLo/wL8uqVLdp/vMdM6l+f9Jdc4lH/BJ/JxzK51zSyWNUvfpXA/v79B93HaPuldUFktqcs69dZCXG9/r61x1r1L1tUPdH4Yl7V0pGS+p7AA5DvT4JHWvFpTt9xH/Z6ekcf7X7J2zR4mkn/V6n9Occ4nOuQf28VwD+blUSOrQx9+vnu/pOHUPrjhf0kjnXJqkWkm9cx/IR95D/wrTj51zM9S9knaGuk9VO5j71X263HjnXKqkW3tl2Ckpp1fmBHX/HHqUSFrS572Md86VDSAPAIQcCg8AHAIzG2FmZ6j72oz7ek4nkvRXSb83s1H+48aZ2SkBPF+smV1sZqn+08fq1P237PuyS90X/O/lLzhdkn6rg6/uSNKPzCzRzGZKukLSQ/s45mFJp5vZYv/f6n9H3aeNvbm/HH3cL+kKMzvMuocS/FzSCudcUQD53lJ30fi6mUWb2WckLeh1/18lfdm/smFmluS/cD+l7xMN5OfiPw3tMUk3+t+vGeq+rqVHij9nhaRoM7tB0ogAvr8eH3kPzWyRmc32n0pXp+5Tyvb3e9BbiqQq51yLmS2QdFGv+x6RdKaZHe2/NurH+mghu1XSz8wsz58hy8yWDjAPAIQcCg8ABOZJM6tX99+KXy/pd+ouDD2ulbRF0nIzq5P0H330eo4DuURSkf9xX1avQQR9/ELSf/lPQfpur9v/Lmm2pEA2Dn3Fn/MFSf/tnHuu7wHOuU3+DH9W9yrJmeq+wL7n2qD95eh5/AuSfiTpUXWvMkzSR6+b2S//a3xG0uXqvoj+s+ouHj33r1L3dTk3++/f4j92fwbyc7lG3ae3lUu6W93XPPV4VtLTkjar+1S3Fn309LeD6fseZqu7oNSp+9SyVxTYz/Orkm7y/27eoF6rg865dZK+pu5yvlNSvaTd6i6vkvRHda8OPed//HJJC/339TcPAIQc++hp0gCA4cbMLpX0RefcsQc4Jl/SNkkxfa5ZQYQws2RJNZImO+e2eZ0HAIYKKzwAMIyZWaK6/5b/dq+zIPSY2Zn+U/KS1D1t7wNJRd6mAoChReEBgGHKfy1KhbqvB7nf4zgITUvVPURih7r3X7rAcWoHgAjDKW0AAAAAwhYrPAAAAADC1v42QPNMZmamy8/P9zoGAAAAgBC2evXqSudc1sGOC7nCk5+fr1WrVnkdAwAAAEAIM7PiQI7jlDYAAAAAYYvCAwAAACBsUXgAAAAAhC0KDwAAAICwReEBAAAAELYoPAAAAADCFoUHAAAAQNii8AAAAAAIWxQeAAAAAGGLwgMAAAAgbFF4AAAAAIQtCg8AAACAsEXhAQAAABC2KDwAAAAAwhaFBwAAAEDYivY6ANBfzjntqmvVh7vrlZEUpxljR3gdCQAAACGGwoNho6W9Uw+8vV3rdtRpy+4Gbd3doPrWjr33X7wwV9cumaYR8TEepgQAAEAoofBgWHDO6dpH39fj7+5QVkqcJo9K1qfnjVPBqGQVZCXrhY27ddcb2/T8+l26aelMnTprjNeRAQAAEAIoPBgWbn2lUI+/u0PfPXmKrjlx8sfuP7ogU0sPG6vrHv1AX75vjU6eMVo3LZ2l7NR4D9ICAAAgVDC0ACHvP+t36dfPbtQZc8bo6kUF+z1uTk6aHr/mGP1gyTS9+mGFPvW7V/Typt1DmBQAAAChhsKDkLZ5V72+8eA7mjU2Vb85d67M7IDHx0T59KVPTtKz3zxe49MTdc3972hTef0QpQUAAECoofAgZFU3tunz96xSQmy0br/0cCXERgX82LyMJP3t8vlKiI3SVfesVGVD6yAmBQAAQKii8CAktXd26er716i8tkW3X3q4xqQmHPJzjElN0B2XzldFfau+fO9qtXZ0DkJSAAAAhDIKD0LSL5/eqDe37tHPPzNb83JH9vt55o5P02/Pn6tVxdX6wWMfyDkXxJQAAAAIdUxpQ8ipqG/VPW8W6cIF43Xu4TkDfr4z5ozVlt0N+sN/PtTkUSn6ygmTgpASAAAAwwGFByHn0TWl6uhyuurYiUF7zm8snqytFY369bMbNTErSafMzA7acwMAACB0cUobQopzTg++vV0L8tNVMCo5aM9rZvrNuXM0JydN33roXZVUNQXtuQEAABC6KDwIKW8V7lHRniZdsGB80J87PiZKf7l4nkzSD//J9TwAAACRgMKDkPLg2yUaER+t02aPGZTnH5eWoO+fOk2vfVipx9aUDcprAAAAIHRQeBAyqhrb9Mzacn1mXo7iYwLfc+dQXXJknublpuknT61nfx4AAIAwR+FByHhsTanaOrsG5XS23nw+06/OmaOm1k79+Mn1g/paAAAA8BaFByHBOacHV5boE7lpmpY9YtBfb/LoFF29qEBPvrdDL2zYNeivBwAAAG9QeBASVhVXa8vuBl14RO6QveZXTpikKaOT9V//WquG1o4he10AAAAMHQoPQsIDb29Xcly0zpg7OMMK9iU22qdfnjNH5XUt+vUzG4fsdQEAADB0KDzwXG1Tu556f6eWHjZWibFDuxfuvNyRuvzofN27vFiriqqG9LUBAAAw+Cg88Ny/3i1Ta0eXLlwwdKez9fbdk6dqbGqCbnh8nTq72JsHAAAgnFB44CnnnB54e7tmjRuhWeNSPcmQFBeta5dM0/qddXp0TaknGQAAADA4KDzw1HultdpYXq8LhnBYwb6cOWeMPpGbpv9+dpMaGWAAAAAQNig88NTTa3cqJsq09LCxnuYwM/3X6TO0u75Vt71a6GkWAAAABA+FB55aXliluTlpSomP8TqKDs8bqTPmjNHtr25VeW2L13EAAAAQBBQeeKahtUNry2q1cGK611H2uvbUaerqkn7z7CavowAAACAIKDzwzOrianV2OR05McPrKHuNT0/UFcfm69E1pfqgtNbrOAAAABggCg88s7xwj6J9psPzRnod5SOuXlSg9KRY/fSp9XKOMdUAAADDGYUHnllRuEdzclKHfLPRgxkRH6NvnTRFK7ZV6bn1u7yOAwAAgAGg8MATTW0der+0VgtD6HS23i48YrwKRiXrF8s2qK2jy+s4AAAA6CcKDzyxurhaHSF2/U5v0VE+XX/adBXtadLDq0q8jgMAAIB+ovDAE8sL9ygqBK/f6e2EqVmanzdSf37xQ7W0d3odBwAAAP1A4YEnVhRWafa4VCXHhdb1O72Zmb5z8lTtqmvVfcuLvY4DAACAfqDwYMg1t3XqvdKakNp/Z3+OmpShYwoy9D8vb1Vja4fXcQAAAHCIKDwYcmu2V6u9M3Sv3+nr2ydN1Z7GNt39ZpHXUQAAAHCIKDwYcssL98hn0vwQvn6nt8PzRurEaaN02ytbVdvc7nUcAAAAHAIKD4Zcz/U7KfExXkcJ2LdPmqK6lg7d+fo2r6MAAADgEARUeMzsVDPbZGZbzOy6fdwfZ2YP+e9fYWb5fe7PNbMGM/tucGJjuGpp79S7JTUhu//O/swal6rTZmfrb69vU1Vjm9dxAAAAEKCDFh4zi5J0i6QlkmZIutDMZvQ57CpJ1c65Akm/l/SrPvf/XtLTA4+L4W7N9mq1dXbpyGEwsKCvb31qihrbOnTbK1u9jgIAAIAABbLCs0DSFudcoXOuTdKDkpb2OWappHv8Xz8iabGZmSSZ2dmSCiWtC05kDGfLC6u6r9/JH36FZ/LoFJ192Djd81aRdte1eB0HAAAAAQik8IyT1Hur+VL/bfs8xjnXIalWUoaZJUm6VtKPD/QCZvZFM1tlZqsqKioCzY5haEXhHs0cm6oRw+j6nd6+sXiy2jud/vIyqzwAAADDQSCFx/ZxmwvwmB9L+r1zruFAL+Ccu905N985Nz8rKyuASBiOWto79U5JjRZOGH6rOz3yM5N0zrxxuv/t7azyAAAADAOBFJ5SSeN7/TlH0o79HWNm0ZJSJVVJWijp12ZWJOmbkn5oZtcMMDOGqXdLatTW0TVs9t/Zn6+eUKCOzi4mtgEAAAwDgRSelZImm9kEM4uVdIGkJ/oc84Sky/xfnyvpRdftOOdcvnMuX9IfJP3cOXdzkLJjmFleuEdm0hHDeIVH6l7lOWPOWN23vFg1TUxsAwAACGUHLTz+a3KukfSspA2SHnbOrTOzm8zsLP9hd6r7mp0tkr4t6WOjq4EVhVWanj1CqQnD8/qd3q5eVKDGtk7d9UaR11EAAABwANGBHOScWyZpWZ/bbuj1dYuk8w7yHDf2Ix/CRFtHl9Zsr9ZFC3O9jhIUU7NTdNKM0br7zSJ94fiJSo4L6P9KAAAAGGIBbTwKDFRhZYNaO7p02Pg0r6MEzdWLClTb3K7/XV7sdRQAAADsB4UHQ2LjznpJ0rTsER4nCZ7Dxqfp2IJM/fW1bWpp7/Q6DgAAAPaBwoMhsaG8TjFRpolZSV5HCaqrFxWosqFV/1hVcvCDAQAAMOQoPBgSm8rrVTAqRTFR4fUrd+TEdB2eN1K3vlKo9s4ur+MAAACgj/D69ImQtXFnvaZlp3gdI+jMTNcsKlBZTbP+9U6Z13EAAADQB4UHg666sU3ldS1hWXgk6YSpWZoxZoT+55Wt6uxyXscBAABALxQeDLqN5f6BBWPCZ2BBb2amqxcVqLCiUc+uK/c6DgAAAHqh8GDQbSqvkyRND9MVHkk6dVa28jMS9dfXCr2OAgAAgF4oPBh0G8vrNTIxRlkpcV5HGTRRPtOVx07QO9trtLq42us4AAAA8KPwYNBtKK/XtOwRMjOvowyqcw/PUWpCjO58nVUeAACAUEHhwaDq6nLaXF6vaWPC93S2Homx0bpoYa6eWVuukqomr+MAAABAFB4Msu1VTWpu7wzbCW19XXZUvnxmuuuNIq+jAAAAQBQeDLKN/oEF07LDc0JbX9mp8Tpz7lg9tHK7apvbvY4DAAAQ8Sg8GFQby+tlJk0ZHRkrPJJ01bET1NjWqYdWbvc6CgAAQMSj8GBQbdxZr/yMJCXERnkdZcjMGpeqIyem6+43itTe2eV1HAAAgIhG4cGg2lheFzHX7/T2heMmakdti55ey0akAAAAXqLwYNA0tXWouKopYq7f6W3R1FGamJmkO14rlHPO6zgAAAARi8KDQbN5V4OcU0SMpO7L59+I9P3SWq0sYiNSAAAAr1B4MGg27uyZ0BZ5hUeSzpmXo7TEGN3xGhuRAgAAeIXCg0GzsbxeibFRGj8y0esonkiIjdLFC3P1/IZdbEQKAADgEQoPBs3G8jpNzU6Rz2deR/HMxQvzZJLuW1HsdRQAAICIROHBoHDOaWN5fcSeztZjbFqCTpoxWg+vLFFLe6fXcQAAACIOhQeDYnd9q2qa2iNyQltflx2Vr+qmdv37/Z1eRwEAAIg4FB4Mig0RPrCgt6MmZahgVLLufavI6ygAAAARh8KDQbGxvF6SWOGRZGa65Mg8vVdaq/dKaryOAwAAEFEoPBgUm8rrNSY1XqmJMV5HCQmfmTdOSbFR+vtbDC8AAAAYShQeDIoNO+s4na2XlPgYfXreOD35/g5VNbZ5HQcAACBiUHgQdO2dXdpa0aBpYzidrbdLj8pXW0eXHl5V4nUUAACAiEHhQdAVVjSqvdOxwtPHlNEpWjghXfctL1Znl/M6DgAAQESg8CDoNpb3TGhjhaevS4/KV2l1s17etNvrKAAAABGBwoOg27CzXjFRpolZSV5HCTknzxyt0SPiGF4AAAAwRCg8CLotuxs0ITNJMVH8evUVE+XThQty9crmChVVNnodBwAAIOzxiRRBV7SnUfkZrO7sz0ULchXtM/3vClZ5AAAABhuFB0HV2eW0fU+TJmRSePZn1Ih4nTxztB5ZXaqW9k6v4wAAAIQ1Cg+Camdts9o6u5THCs8BXbQgT9VN7Xp2XbnXUQAAAMIahQdBVbynSZKUn5nocZLQdvSkDOVlJOr+Fdu9jgIAABDWKDwIqm3+C/G5hufAfD7TBUfkasW2Km3Z3eB1HAAAgLBF4UFQFe9pVFy0T9kj4r2OEvLOm5+jmCjTA2+zygMAADBYKDwIqm2VTcrPSJLPZ15HCXmZyXE6eUa2Hl3D8AIAAIDBQuFBUBXvaVReBtfvBOqihbmqaWrXM2sZXgAAADAYKDwImq4up+IqRlIfiqMmZig/I1H3c1obAADAoKDwIGh21DarrYOR1IfC5zNdsCBXb2+r0pbd9V7HAQAACDsUHgQNI6n759zDu4cX3L+ixOsoAAAAYYfCg6BhJHX/ZCbH6ZSZDC8AAAAYDBQeBA0jqfvvogW5qm1u19Nrd3odBQAAIKxQeBA02yqblJeRyEjqfjhqkn94wQqGFwAAAAQThQdBU7ynkdPZ+snMdOGCXK0sqtaHuxheAAAAECwUHgRFz0jqfEZS99u5h+coNsrHiGoAAIAgovAgKHbWtaito4sVngHISI7TKbOy9diaMoYXAAAABAmFB0FRtHdCGyOpB+LCBeNV29yuZR8wvAAAACAYKDwIiqI9/sLDKW0DctTEDE3MTGJ4AQAAQJBQeBAURZWMpA6GnuEFq4qrtZnhBQAAAANG4UFQMJI6eM7pGV7AKg8AAMCAUXgQFMV7GpXHwIKgSE+K1amzsvXYmlKGFwAAAAwQhQcD1jOSegLX7wTNhQtyVdfSoafeZ3gBAADAQFB4MGCMpA6+Iyema2JWEnvyAAAADBCFBwPGSOrgMzNdtCBXq4urtamc4QUAAAD9ReHBgDGSenB8Zl738IIHWOUBAADoNwoPBoyR1IMjPSlWS2Zn69E1pWpuY3gBAABAf1B4MGBFexhJPVguXJCr+pYOPfUBwwsAAAD6g8KDASuqZCT1YFk4IV2TspL0vyuKvY4CAAAwLFF4MCCMpB5cZqaLF+bpne01WltW63UcAACAYYfCgwHpGUmdx4S2QXPO4TmKj/GxygMAANAPFB4MSM9I6gmc0jZoUhNidPZh4/Svd3aotrnd6zgAAADDCoUHA9IzkjqPU9oG1SVH5am5vVOPri71OgoAAMCwQuHBgBRVNio22qcxjKQeVDPHpmpebpruW14s55zXcQAAAIYNCg8GpGhPk/LSGUk9FC45Kk+FlY16c+ser6MAAAAMGxQeDEhRZaPyOZ1tSCyZNUbpSbG69y2GFwAAAASKwoN+6xlJnc+EtiERHxOl8+eP1/MbdmlnbbPXcQAAAIYFCg/6rWckNSs8Q+fihbnqck4PvF3idRQAAIBhgcKDfivumdCWTuEZKuPTE7Vo6ig98PZ2tXd2eR0HAAAg5FF40G+l1d2nVY1PT/A4SWS55Mg8VdS36rl1u7yOAgAAEPICKjxmdqqZbTKzLWZ23T7ujzOzh/z3rzCzfP/tC8zsXf8/75nZp4MbH14qrW6Wz6QxqRSeoXT8lCyNT0/QvcuLvI4CAAAQ8g5aeMwsStItkpZImiHpQjOb0eewqyRVO+cKJP1e0q/8t6+VNN85d5ikUyXdZmbRwQoPb5VWNyl7RLxio1koHEpRPtPnFuZpeWGVNu+q9zoOAABASAvkk+oCSVucc4XOuTZJD0pa2ueYpZLu8X/9iKTFZmbOuSbnXIf/9nhJ7JgYRkqrm5UzkgltXjhv/njFRft01xtFXkcBAAAIaYEUnnGSeo+EKvXfts9j/AWnVlKGJJnZQjNbJ+kDSV/uVYD2MrMvmtkqM1tVUVFx6N8FPFFW3ayckZzO5oX0pFh9Zl6OHltTqqrGNq/jAAAAhKxACo/t47a+KzX7PcY5t8I5N1PSEZJ+YGbxHzvQududc/Odc/OzsrICiASvtXd2aWcthcdLVx2br9aOLv3vcjYiBQAA2J9ACk+ppPG9/pwjacf+jvFfo5Mqqar3Ac65DZIaJc3qb1iEjp01Lepy4pQ2DxWMStEJU7N0z1vFau3o9DoOAABASAqk8KyUNNnMJphZrKQLJD3R55gnJF3m//pcSS8655z/MdGSZGZ5kqZKKgpKcniqtLpJkljh8djnj52oyoZWPfFu37+DAAAAgBRA4fFfc3ONpGclbZD0sHNunZndZGZn+Q+7U1KGmW2R9G1JPaOrj5X0npm9K+mfkr7qnKsM9jeBodezBw8rPN46piBD07JTdOfr2+QcM0EAAAD6CmhEtHNumaRlfW67odfXLZLO28fj7pV07wAzIgSVVjd178GT9rFLsjCEzExXHjtB33/kfb25dY+OKcj0OhIAAEBIYQMV9EtpdbPGpCYoJopfIa8tPWysMpPjdMdrhV5HAQAACDl8WkW/lFY3axzX74SEuOgoXXJknl7aVKEtu9mIFAAAoDcKD/qltLqJgQUh5HNH5io22qe/sREpAADAR1B4cMjaOrpUXtfCwIIQkpEcp898YpweXc1GpAAAAL1ReHDIymt79uBhhSeUXHnsBDYiBQAA6IPCg0NWwh48IWnK6BQdP6V7I9KWdjYiBQAAkCg86IeeTUfHc0pbyPnyJ7s3In14VYnXUQAAAEIChQeHrLS6WT6TslPZgyfUHDUxQ/PzRurWl7eqraPL6zgAAACeo/DgkLEHT+gyM11zYoF21Lbon++Ueh0HAADAc3xixSFjJHVo++SULM0el6q/vLxVHZ2s8gAAgMhG4cEhK61uZiR1COtZ5Sne06R/v7/T6zgAAACeovDgkPzfHjys8ISyk6aP1tTRKbr5pS3q6nJexwEAAPAMhQeHZGdtsxx78IQ8n8909YkF2rK7Qc+uK/c6DgAAgGcoPDgkpdXNksQpbcPA6bPHaEJmkv784hY5xyoPAACITBQeHJJSNh0dNqJ8pq+eMEnrd9bppU27vY4DAADgCQoPDklJVbOifKYx7MEzLJz9iXHKGZmgP73AKg8AAIhMFB4cktLqJo1JjVc0e/AMCzFRPn3lhEl6t6RGb2zZ43UcAACAIcenVhyS7pHUnM42nJx7eI7GpMbrd89vYpUHAABEHAoPDgl78Aw/cdFR+vriyVqzvUYvbOBaHgAAEFkoPAhYa0endtWzB89wdN7hOZqQmaTfPLtJnezLAwAAIgiFBwHbWdPi34OHFZ7hJjrKp2+fNEWbdtXriffKvI4DAAAwZCg8CNj/7cHDCs9wdPrsMZoxZoQifxHLAAAgAElEQVR+9/xmtXV0eR0HAABgSFB4EDD24BnefD7T906dqpKqZj20crvXcQAAAIYEhQcBK63u3oMnewR78AxXJ0zJ0oL8dP3pxS1qauvwOg4AAMCgo/AgYCXswTPsmZm+f+pUVdS36u43i7yOAwAAMOj45IqAlVY3azwDC4a9+fnpOnHaKN368lbVNrV7HQcAAGBQUXgQsNLqJq7fCRPfPXmq6lo6dNurW72OAgAAMKgoPAhIa0endtW1MpI6TMwYO0JnzR2ru94o0q66Fq/jAAAADBoKDwKyo6b7QzErPOHjOydPUWeX02+f2+R1FAAAgEFD4UFAGEkdfvIyknT5Mfn6x+pSrS2r9ToOAADAoKDwICB7Nx1N55S2cHL1ogKlJcToZ09tkHPO6zgAAABBR+FBQEqrmxTtM41OifM6CoIoNSFG3zppit4q3KPn1+/yOg4AAEDQUXgQkNLqZo1JYw+ecHTRglwVjErWL57eqLaOLq/jAAAABBWfXhGQ0upm5aRxOls4io7y6frTpmtbZaPuW17sdRwAAICgovAgIOzBE95OmJql4yZn6o8vfKiapjav4wAAAAQNhQcH1dbRpd31rRpH4QlbZqbrT5+u+pZ2/fGFD72OAwAAEDQUHhzUztpmOSeNS6PwhLNp2SP02SNyde9bxdpa0eB1HAAAgKCg8OCgyvwjqVnhCX/fPmmK4mOi9ItlG72OAgAAEBQUHhxUaY1/Dx6GFoS9rJQ4fXXRJP1nwy69uaXS6zgAAAADRuHBQZVWN8tMyk6N9zoKhsCVx0zQuLQE/eSpDersYjNSAAAwvFF4cFBl1c0anRKv2Gh+XSJBfEyUrlsyTRt21unR1aVexwEAABgQPsHioMpqmrh+J8KcMWeM5uWm6TfPbVJDa4fXcQAAAPqNwoODKqtpZkJbhDEz/dcZM1RR36rbXtnqdRwAAIB+o/DggDq7nHbWtLDCE4Hm5Y7UWXPH6vZXC1XmH1wBAAAw3FB4cEC761vU0eVY4YlQ1y6ZJkn6zTOMqQYAAMMThQcHxB48kW1cWoI+f9wE/evdHXq3pMbrOAAAAIeMwoMDKtu7Bw+FJ1J95YQCZSbH6Sf/Xi/nGFMNAACGFwoPDqiUFZ6IlxwXre+ePEWri6u17INyr+MAAAAcEgoPDqisplkjE2OUGBvtdRR46Lz54zUtO0W/fGaDWjs6vY4DAAAQMAoPDqisupnVHSjKZ7r+9OkqqWrWPW8WeR0HAAAgYBQeHBB78KDHcZOzdMLULP35xS2qamzzOg4AAEBAKDzYL+dc9wpPWqLXURAifnjadDW2duhPL3zodRQAAICAUHiwX9VN7Wpu7+SUNuw1ZXSKLliQq/uWF6uwosHrOAAAAAdF4cF+7d2Dh1Pa0Mu3PjVFcdE+/eJpNiMFAAChj8KD/SqraZIk5bDCg16yUuL01UUFen79Li0v3ON1HAAAgAOi8GC/evbgofCgr6uOnaCxqfH66VPr1dXFZqQAACB0UXiwX2U1zUqKjVJqQozXURBi4mOi9L1Tp2ptWZ3+9W6Z13EAAAD2i8KD/erZg8fMvI6CELR07jjNyUnVb57dpOY2NiMFAAChicKD/WIPHhyIz2e6/rTp2lnbojtfL/Q6DgAAwD5ReLBfZTXNjKTGAS2cmKFTZo7WX17eqt31LV7HAQAA+BgKD/apsbVDNU3tbDqKg7puyXS1dXTp989v9joKAADAx1B4sE9lNf49eFjhwUFMyEzSJUfl6aGVJdpUXu91HAAAgI+g8GCfSqu79+DhGh4E4huLJys5Llo/W7bB6ygAAAAfQeHBPpWxBw8OQVpirL6+eLJe3VyhVzZXeB0HAABgLwoP9qm0plmxUT5lJcd5HQXDxCVH5Sk3PVE/f2qDOtmMFAAAhAgKD/aprLpZY9Li5fOxBw8CExcdpeuWTNOmXfV6eFWJ13EAAAAkUXiwH+zBg/5YMitb8/NG6rfPbVZDa4fXcQAAACg82LeyagoPDp2Z6frTp6uyoVW3vbLV6zgAAAAUHnxca0endte3MpIa/fKJ3JE6a+5Y/fW1Qu3wjzcHAADwCoUHH7OzpkUSI6nRf98/daq6nPTfz27yOgoAAIhwFB58DJuOYqByRibqymMm6LF3yvRBaa3XcQAAQASj8OBj9u7Bk5bocRIMZ19dNEnpSbH66VPr5RxjqgEAgDcCKjxmdqqZbTKzLWZ23T7ujzOzh/z3rzCzfP/tJ5nZajP7wP+/JwY3PgZDaU2zzKTs1Hivo2AYGxEfo299arJWbKvS8+t3eR0HAABEqIMWHjOLknSLpCWSZki60Mxm9DnsKknVzrkCSb+X9Cv/7ZWSznTOzZZ0maR7gxUcg6esulmjU+IVG80CIAbmwgW5mpSVpF8+vVHtnV1exwEAABEokE+0CyRtcc4VOufaJD0oaWmfY5ZKusf/9SOSFpuZOefecc7t8N++TlK8mcUFIzgGT1lNE9fvICiio3z64WnTVVjZqP9dXux1HAAAEIECKTzjJPXeNr3Uf9s+j3HOdUiqlZTR55hzJL3jnGvt+wJm9kUzW2VmqyoqKgLNjkHCpqMIphOnjdLRkzL0xxc+VG1zu9dxAABAhAmk8Ng+but7BfIBjzGzmeo+ze1L+3oB59ztzrn5zrn5WVlZAUTCYOnsctpZ08IKD4KmZzPSmuZ23fLSFq/jAACACBNI4SmVNL7Xn3Mk7djfMWYWLSlVUpX/zzmS/inpUuccW6+HuN31Lerocsqh8CCIZo5N1bnzcnT3G0XaVtnodRwAABBBAik8KyVNNrMJZhYr6QJJT/Q55gl1DyWQpHMlveicc2aWJukpST9wzr0RrNAYPD0jqTmlDcH2vVOmKi7ap//3xDrGVAMAgCFz0MLjvybnGknPStog6WHn3Dozu8nMzvIfdqekDDPbIunbknpGV18jqUDSj8zsXf8/o4L+XSBoejYdZYUHwTZqRLy+ddIUvbq5Qs+uY0w1AAAYGtGBHOScWyZpWZ/bbuj1dYuk8/bxuJ9K+ukAM2IIlfpXeMaywoNBcOlReXp4VYluenKdjp+SqcTYgP4VBAAA0G9stIKPKKlqUmZyLB9EMSiio3z6ydmztKO2RTe/yAADAAAw+Cg8+IiS6ibljEz0OgbC2BH56TpnXo7++lqhtlY0eB0HAACEOQoPPqKkqlnj0yk8GFzXLZmm+Jgo/b/HGWAAAAAGF4UHe3V2Oe2oadZ4BhZgkGWlxOl7p0zV61sqteyDcq/jAACAMEbhwV47a5vV0eVY4cGQuHhhnmaOHaGf/Hu9Gls7vI4DAADCFIUHe5VUdU9oG881PBgCUT7TTUtnqbyuRb9/frPXcQAAQJii8GCvkuomSdL4dE5pw9A4PG+kLl6Yqzvf2KblhXu8jgMAAMIQhQd7lVY1yWfswYOh9cPTpisvPVHfefg91bW0ex0HAACEGQoP9iqpbtaY1ATFRPFrgaGTFBet33/2MJXXtejGJ9Z5HQcAAIQZPtlir5KqJuUwoQ0e+ETuSF29qECPrSnTsg92eh0HAACEEQoP9iqpbmJCGzzztRMLNDcnVT/85wfaVdfidRwAABAmKDyQJLW0d2pXXSsT2uCZmCiffvfZw9TS3qnvPfI+G5ICAICgoPBAklRW4x9JzYQ2eGhSVrKuP32GXt1cob+/Vex1HAAAEAYoPJDUff2OJE5pg+c+tzBXJ0zN0s+XbdD6HXVexwEAAMMchQeSuie0SWw6Cu+ZmX597hyNTIzVlXev1M7aZq8jAQCAYYzCA0nde/DERvs0KiXO6yiARqXE664rjlBja4cu/9tK9ucBAAD9RuGBpO4JbTlpCfL5zOsogCRp+pgR+p/PHa6tFQ36yn2r1dbR5XUkAAAwDFF4IEkqqWpWDtfvIMQcOzlTvzxnjt7YskfXPcbkNgAAcOiivQ6A0FBS3aQ5OalexwA+5tzDc7Sjplm/e36zxqUl6DsnT/U6EgAAGEYoPFB9S7tqmtqZ0IaQ9bUTC7Sjpll/fnGLslPjdfHCPK8jAQCAYYLCA5VUMaENoc3M9JOzZ6m8rkXX/3OtdtW16puLJ3PNGQAAOCiu4YFKqnv24GHTUYSumCifbrvkcJ13eI7+9MKHuuaBNWpu6/Q6FgAACHEUHvzfpqOs8CDExUVH6dfnztH1p03X02vLdd5tb7JPDwAAOCAKD1Ra3azkuGilJcZ4HQU4KDPTF46fqL9ddoSKKpt01s1v6J3t1V7HAgAAIYrCA5VUNSlnZILMuB4Cw8eiaaP02FePVnyMT5+9fbnueK2QvXoAAMDHUHigkuomJrRhWJoyOkWPX32sjpmUoZ8+tUGn/OFV/Wf9LvbrAQAAe1F4IpxzTiVVzVy/g2ErPSlWd12xQHddcYR8Jn3+76v0uTtXaGN5ndfRAABACKDwRLg9jW1qbu9kQhuGvUVTR+mZbx6vG8+cobVldTrtj6/p2kfe1/odFB8AACIZ+/BEOCa0IZzERPl0+TETdPYnxukP//lQ97+9XQ+tKtHcnFRdsCBXZ84dq+Q4/rUHAEAkYYUnwpVU+zcd5RoehJG0xFjdeNZMvf3DxbrhjBlqbu/UDx77QAt+9h9d+8j7Wl64Rx2dDDgAACAS8FedEa5nhSdnJKe0IfykJcbqymMn6Ipj8vVOSY0efHu7nnhvhx5aVaKRiTFaPH20Tp4xWsdNzlJCbJTXcQEAwCCg8ES40upmZSTFKonTfBDGzEzzckdqXu5I/b8zZ+qVzRV6bl25nl1XrkdWlyo+xqfjJ2fp5JnZWjxtlEYmxXodGQAABAmfciNcaXWTcjidDREkKS5ap80eo9Nmj1F7Z5dWFFbp+fXlem79Lj23fpd8Jh2Rn66TZ2br5BmjOd0TAIBhzkJtv4r58+e7VatWeR0jYpzwm5c0a1yqbr5ontdRAE8557S2rE7PrS/Xc+t2adOueknSrHEjdPZh43TW3LEaNSLe45QAAKCHma12zs0/2HGs8ESwzi6nsppmLZk9xusogOfMTLNzUjU7J1XfOXmqiiob9fz6XXry/R366VMb9PNlG3RMQaY+/YlxOmVmNqeBAgAwTPBf7Ai2q65F7Z2OkdTAPuRnJukLx0/UF46fqC27G/T4u2X65ztl+vbD7ykhZq3OnDtGlxyZr9k5qV5HBQAAB0DhiWB79+Bh01HggApGJes7J0/Vt0+aotXF1Xp0Tan+9c4OPbyqVIeNT9MlR+bp9DljFB/DpDcAAEIN+/BEsJ49eHJY4QECYmaan5+uX3xmjlZcv1j/78wZqmtp13f+8Z6O+sUL+sXTG7SjptnrmAAAoBdWeCJYSVWTzKSxaVyIDRyqEfExuuKYCbr86Hy9tXWP/v5Wsf76aqHueG2blszK1pXHTtC83JFexwQAIOJReCJYSXWTskfEKy6a03CA/jIzHV2QqaMLMlVa3aS/v1WsB97ern+/v1OHjU/TlcdO0JJZ2YqJYkEdAAAvUHgiWGlVMwMLgCDKGZmoH542Xd9YPFmPrC7VXW9s09cfeEejUuJ0wYJcXbhgvMakcs0cAABDicITwUqqm3TUpAyvYwBhJykuWpcdna9LjszTS5t2697lxfrzix/qlpe2aPG0Ubr4yDwdV5Apn8+8jgoAQNij8ESolvZOlde1KJdd5IFB4/OZFk8frcXTR6ukqkn3v71dD68s0XPrdyk3PVFnzh2jJbPGaObYETKj/AAAMBgoPBGqeE+TnJMmZCZ5HQWICOPTE3XtqdP0zU9N1jNry/WPVaW69ZVC3fLSVuVlJGrJrDE6bXa2Zo9LpfwAABBEFJ4Ita2yQZI0KSvZ4yRAZImLjtLSw8Zp6WHjVNXYpufWlWvZ2nLd8Vqhbn1lq7JS4jQ/b6Tm56drft5IzRg7goEHAAAMAIUnQm2taJTUvZs8AG+kJ8XqggW5umBBrqob2/T8hl16c0ulVhVX6+m15ZKkhJgozR2fqqmjUzQhM0kTspI1MTNJY9MSFMU1QAAAHBSFJ0Jtq2zU6BFxSo7jVwAIBSOTYnX+/PE6f/54SdKuuhatKqrWquIqrdleo8fWlKm+tWPv8bFRPuVlJGpCZpIm+kvQhKwkTchMUkZSLKfFAQDgx6fdCFVY0cD1O0AIGz0iXqfPGaPT54yRJDnnVNnQpm2VjSqsaOj+X/8/L23arfZOt/exmclxmpuTqjk5aZqTk6o5OanKSI7z6lsBAMBTFJ4IVVjZqNNmj/E6BoAAmZmyUuKUlRKnBRPSP3JfR2eXymqaVVjZqK27G7R+Z53eL63Vi5t2y/l70Pj0BC2eNlpLZmVrfn46p8MBACIGhScCVTe2qaapXRNZ4QHCQnSUT3kZScrLSNKiqaP23l7f0q51O+r0fmmNVhRW6f63t+vuN4uUmRyrk2Zka8msbB01KYOhCACAsEbhiUCF/gltE7MoPEA4S4mP0ZETM3TkxAx98fhJamjt0Esbd+uZteV6/N0yPfD2do0eEafLj56gixbmKjUhxuvIAAAEHYUnAhX6J7RNzGQkNRBJkuOidebcsTpz7li1tHfq5U0Vund5kX71zEbd/OKH+uwRubrimHyNZ0NiAEAYofBEoMLKRsVEmXJGJngdBYBH4mOidOqsbJ06K1try2p1x2uFuuetIt3zVpFOmz1G31g8WQWj+EsRAMDwx4nbEaiwokG56YmK5rx9AJJmjUvVHy74hF77/iJddewEvbRxt075w6v60b/Wak9Dq9fxAAAYED7xRqBtlY2awOlsAPoYm5agH542XS9/7wRdtCBX97+9XZ/8zcv6y8tb1NLe6XU8AAD6hcITYTq7nIr2NGkSAwsA7Edmcpx+cvYsPfvN47RwQrp+/cwmLf7tK3rivR1yzh38CQAACCEUngizo6ZZbR1dbDoK4KAKRqXozsuP0P2fX6jUhBh9/YF3dOnf3lbxnkavowEAEDAKT4TZWtEzkppT2gAE5uiCTD35tWP147Nm6p3tNTr596/qlpe2qL2zy+toAAAcFIUnwuwdSc0pbQAOQZTPdNnR+frPtz+pE6eN0m+e3aQz/vS6VhdXex0NAIADovBEmG2VjUqJj1ZGUqzXUQAMQ9mp8fqfzx2uOy6dr/qWdp1765u68Yl1am5jqAEAIDRReCJMYWWDJmYly8y8jgJgGPvUjNF6/tuf1GVH5evuN4t02p9eY7UHABCSKDwRZltFoyYysABAECTFRevGs2bq/i8sVFtHl8679U398umNau1gtQcAEDooPBGkqa1DO2pbKDwAguroSZl65pvH6fz543XrK1t11p/f0NqyWq9jAQAgicITUbZVdg8smMDAAgBBlhIfo1+eM0d3XX6EqpvadPYtb+iO1wrZtwcA4DkKTwTpKTwTMxlJDWBwLJo2Ss9963idOG2UfvrUBn3h76tV09TmdSwAQASj8ESQnpHUbDoKYDClJcbqtksO1w1nzNArm3fr9D+9rjXbGWgAAPAGhSeCbKts1NjUeCXERnkdBUCYMzNdeewEPfLlo2UmnX/rW/rrq5ziBgAYehSeCFJY0T2SGgCGytzxaXrq68fpU9NH62fLNuhL965WU1uH17EAABGEwhMhnHMqrGzkdDYAQy41IUb/87l5+q/Tp+s/G3bp/NveUnlti9exAAARgsITISob2lTf0qGJTGgD4AEz0+ePm6g7LpuvbRWNWnrL64yuBgAMCQpPhCisaJDEwAIA3jpx2mj948tHy2em8259S8+v3+V1JABAmKPwRIiekdSTuIYHgMdmjB2hx68+RpNHJ+uL965imAEAYFAFVHjM7FQz22RmW8zsun3cH2dmD/nvX2Fm+f7bM8zsJTNrMLObgxsdh6KwslGx0T6NTUvwOgoAaNSIeD30xaN06sxs/WzZBv3y6Y2UHgDAoDho4TGzKEm3SFoiaYakC81sRp/DrpJU7ZwrkPR7Sb/y394i6UeSvhu0xOiXwopG5WckKspnXkcBAElSQmyUbrlonj53ZK5ue7VQN/17PaUHABB00QEcs0DSFudcoSSZ2YOSlkpa3+uYpZJu9H/9iKSbzcycc42SXjezguBFRn8UVjZoyqgUr2MAwEf4fKafLJ2lmCif7nqjSO2dXbrprFny8ZczAIAgCaTwjJNU0uvPpZIW7u8Y51yHmdVKypBUGUgIM/uipC9KUm5ubiAPwSFo7+zS9j1NOmVmttdRAOBjzEw3nDFDsVE+3fZqoTo6nX7+6dmUHgBAUARSePb1X5y+5xwEcsx+Oedul3S7JM2fP5/zGYKstLpZHV1OE5nQBiBEmZmuWzJNMVE+3fzSFrV3Ov363DmchgsAGLBACk+ppPG9/pwjacd+jik1s2hJqZKqgpIQA9Yzkpo9eACEMjPTd0+Zqthon373/GZ1dnXpd+cfxkoPAGBAAik8KyVNNrMJksokXSDpoj7HPCHpMklvSTpX0ouOK09DRs9I6omZjKQGEPq+vniyonym3zy7SakJMbrxrJkyo/QAAPrnoIXHf03ONZKelRQl6W/OuXVmdpOkVc65JyTdKeleM9ui7pWdC3oeb2ZFkkZIijWzsyWd7Jxb3/d1MHi27G7QyMQYjUyK9ToKAATk6kUFqm1u1+2vFiojOU5fXzzZ60gAgGEqkBUeOeeWSVrW57Yben3dIum8/Tw2fwD5EATrdtRpxtgRXscAgENy3anTtKehTb97frNGJsXqkiPzvI4EABiGAtp4FMNXe2eXNpXXa9bYVK+jAMAh8flMvzxnthZPG6UbHl+rp97f6XUkAMAwROEJcx/ualBbZ5dmjqPwABh+YqJ8uvmieZqfN1LffOgdvf5hQLsdAACwF4UnzK3dUStJmskpbQCGqYTYKN1x6RGalJWsL927Sh+U1nodCQAwjFB4wty6slolxUZpQgYjqQEMX6mJMbrnygVKS4zVlfesVFlNs9eRAADDBIUnzK31DyxgHwsAw93oEfG6+4oj1NLWqavuXqn6lnavIwEAhgEKTxjr7HJav6NOMxlYACBMTB6dor98bp4+3N2ga+5/Rx2dXV5HAgCEOApPGNtW2ajm9k7NYmABgDBy3OQs/fTsWXplc4VufHKd2OcaAHAgAe3Dg+FpHQMLAISpCxfkqmhPo257pVD5GUn6/HETvY4EAAhRFJ4wtrasVrHRPhWMSvY6CgAE3bWnTNP2PU362bINyk1P1Mkzs72OBAAIQZzSFsbWltVpenaKYqL4MQMIPz6f6XfnH6Y5OWn6xoPvMq4aALBPfBIOU845rdtRy4ajAMJaQmyU/nrp4UpPitVV96zUDsZVAwD6oPCEqdLqZtW1dGgWE9oAhLlRKfH62+VHqLmtU1fevVINrR1eRwIAhBAKT5haW8bAAgCRY2p2im65uGdc9RrGVQMA9qLwhKm1O2oV5TNNzU7xOgoADInjp2TpJ0tn6eVNFbrp3+sZVw0AkMSUtrC1tqxOk0clKz4myusoADBkLlrYPa769le7x1VfeewEryMBADzGCk8Y6hlYwIajACLRdadO0ykzR+snT63X8+t3eR0HAOAxCk8Y2l3fqsqGNs3i+h0AEcjnM/3hs5/QnHGp+toDa7Rme7XXkQAAHqLwhKG9AwtY4QEQoRJio3Tn5Udo9Ih4XXX3ShVWNHgdCQDgEQpPGFpbViczafoYVngARK7M5Djdc8UC+cx02V1va3d9i9eRAAAeoPCEoXU7ajUhM0nJccykABDZ8jOTdOflR6iyvo09egAgQlF4wtC6HXVsOAoAfoeNT9NfLp6nDTvr9ZX7VqudPXoAIKJQeMJMVWObymqaNWscp7MBQI9F00bpF5+erdc+rNS1j77PHj0AEEE45ynMrNvhH1jACg8AfMT5R4xXeV2Lfvf8ZqUmxOiGM2bIzLyOBQAYZBSeMLO2rE6SNJOR1ADwMV87sUA1Te362xvbFBcdpWtPnUrpAYAwR+EJM+t21CpnZILSEmO9jgIAIcfM9KMzpqu1o1O3/v/27j0+qvrO//jrMzO5X4gJhEC4I3fkrmIERWytt0KtKPrT2nXt2u6lah/bbdfdttvr/sr+2pVaf1rrpba2q7bWVSoWrIICCyIg90sI90sgIUBuQEIm890/5gSSSCRKkpOZvJ+PRx5zzpnvOfNJch5n5j3ne77n3Z0kJwR46FND/S5LRETakQJPnNGABSIiH83M+MHM0dSGI8x9q4jkhCBfuXqw32WJiEg7UeCJI1U1dewuO8GtE/L9LkVEpFMLBIw5t47hdDjCj/+8jaRQgHuvHOh3WSIi0g4UeOLI2n3lAFzSJ8vnSkREOr9gwPjp7WOpDdfzvT9tISEY4O7J/f0uS0RE2piGpY4jS7YfITEU4LIB2X6XIiISExKCAX5+5wSmD8/lW69u4qklu/wuSURE2pgCTxxZUnSEywZkk5IY9LsUEZGYkRgK8Iu7J3LTJb340Rtb+cnCQt2nR0QkjqhLW5w4VHGK7SXVzJrYx+9SRERiTmIowKN3jiczJcRji3dQcaqO780YRSCgIatFRGKdAk+cWLq9DICrhvbwuRIRkdgUDBj/fsslZKYk8OS7u6isqeMnt40lIajOECIisUyBJ068W3SEnplJDOuZ4XcpIiIxy8x4+IYRdEtJ4D8WFFJVE+bxuyaQnKCuwiIisUpfW8WB+ohjWVEZU4f00B3DRUTawN9Nu5gf3TKaxYWlzH5yBSWVNX6XJCIin5ACTxzYcKCcilN1TB3S3e9SRETixl2X9+fJuydSVFrNjMeWsX5/ud8liYjIJ6DAEweWFpVhBlOH6PodEZG2dN2oPP74twWEAgFuf3IF89YX+12SiIh8TAo8cWDJ9iNckt+N7LREv0sREYk7I3plMu8frmRMn2488MJafvpmIZGIhq0WEYkVCjwxrrKmjrX7y7lKZ3dERNpNTnoSv/vSZG6f1IefL9rBV367hopTdX6XJSIiraDAE+OW71V9oxoAABQdSURBVCijPuI0HLWISDtLDAWYc+sYvn3zSBZtK+XGny1l9Z5jfpclIiLnocAT497dXkZ6Uojx/bL8LkVEJO6ZGfdNGcjLf1tAMGDc/uQK5r61nXB9xO/SRESkBQo8Mcw5x5LtRygYnKMb44mIdKBxfbOY/8AUZo7LZ+5bRdz51HscLD/ld1kiInIO+pQcw3aVneBg+Sl1ZxMR8UFGcgKPzB7HI7PHsvVQFTfMXcKraw/inAY0EBHpTBR4YtiS7UcAuFqBR0TEN7eM78P8B6YwODedh15ax93PrGTnkWq/yxIREY8CTwxbWlTGwO5p9M1O9bsUEZEurX9OGi9/pYAffm40Gw5UcMPcpfznm4XU1NX7XZqISJenwBOjasP1rNh5lKlDuvtdioiIAMGAcffk/iz6x2ncNKYXjy7awWfmLuGdwlK/SxMR6dIUeGLUmj3HOVVXr/vviIh0Mj0yknhk9jj+60uXEwwYf/WrVdz19Hus2ashrEVE/KDAE6PeLTpCQtC4YnCO36WIiMg5FFzcnT8/OJVv3TSCwsNV3PrECu559n3W7jvud2kiIl2KAk8MikQcb24uYVL/bNKSQn6XIyIiLUgKBfnS1EEs+cY1PHzDcDYeKOeWx5fz18+tUvAREekgCjwx6N3tR9hddoI7LuvrdykiItIKqYkhvnz1YJZ+czr/9JlhrNl7nFseX86Mx5bx+1X7OXVagxuIiLQX62z3C5g0aZJbvXq132V0al94ZiXbS6pY9s3puuGoiEgMqqqp45UPDvLb9/ZSVFpNZnKI2yb15a7L+zGoR7rf5YmIxAQzW+Ocm3S+duoPFWOKSqpYWlTGP31mmMKOiEiMykhO4IsFA7jniv6s3H2M59/by6+X7+GZZbuZ0C+Lm8f05qYxveiZmex3qSIiMU+BJ8b8avkekkIB7rysn9+liIjIBTIzJg/KYfKgHEqravjD6gP8aX0x3399Cz+Yv4VLB2Rz85he3DC6Fz0ykvwuV0QkJqlLWwwpP3mayf/3bWaOzWfOrDF+lyMiIu1kR2k1r28o5vUNh9hRWo0ZjO2TxbXDc5k+IpeRvTIxM7/LFBHxVWu7tCnwxJAn3tnJnAXbWPDQVIbnZfpdjoiItDPnHNtLqlmw6TCLCktZv78cgLzMZKaPyOXa4bkUDO5OSmLQ50pFRDqeruGJM+H6CM+v2EPB4ByFHRGRLsLMGJaXwbC8DB781BBKq2p4p/AIi7eV8trag/zXyn0khQIUDM5h+oieTB+eS35Wit9li4h0Kgo8MWLh5hKKK2r43szRfpciIiI+yc1I5vZJfbl9Ul9qw/Ws2n2ct7eV8PbWUhYXbuLbwPC8DK4dkcv04T0Z1zeLYEBd30Ska1OXthgx64nllFbVsvjr0/TmJSIiTTjn2HnkBIu3lfL2thJW7TlOfcSRnZbItKE9mD4il6uG9iAzOcHvUkVE2oy6tMWRDQfKWb33ON++eaTCjoiIfIiZcXFuOhfnpvM3Vw2i4lQdS7YfYdG2UhYXlvLK2oMkBgNMGdKdG0bn8emRPclKTfS7bBGRDqHAEwN+9T97SEsMctukPn6XIiIiMaBbSgKfHdubz47tTX3EsXbfcRZuPswbGw+zaFspoYBRcHF3bhydx/Wj8xR+RCSuqUtbJ1daWcOVcxZx1+X9+e6MUX6XIyIiMcw5x8aDFbyx8TBvbDzEvmMnSQgaVw/twYxx+XxqRC6pifouVERig7q0xQHnHN95bTPOwV8VDPC7HBERiXFmxpg+WYzpk8U3rx/G5uJK5q0vZt66Yt7aWkpqYpDrRvZk5rh8pgzpTkIw4HfJIiIXTIGnE3tu+R4WbD7Mt24awYDuaX6XIyIiccTMGJ3fjdH53fjm9cN5f/cx5q0/yPwNh3h1XTEXpSZw05hefG5cPhP6XURA15CKSIxSl7ZOat3+cm77xXKuHprLU/dM1B21RUSkQ9SG61myvYzX1h3kra0l1NRFyM9KYca43swc11v3ghORTqO1XdoUeDqhipN13PjoUgDmPzBFF5OKiIgvqmvD/GXLYV5bV8zSojLqI45hPTOYMa43M8b2pm92qt8likgXpsATo5xz3P/8Gt4pLOX3X76C8f0u8rskERERjlbXMn/jIV5bV8yavccBmNj/ImaM7c11o3rSq1uKzxWKSFejwBOjnl66ix/O38q3bx7JfVMG+l2OiIjIh+w/dpJ564t5bd1BtpdUAzCmTzeuG9mTT4/MY2jPdHXFFpF2p8ATgz7Yd5zbf7GC6cNzefILum5HREQ6v6KSKt7cUsJftpSwbn85AP1zUrlmWC4Fg3O4fFAO3VISfK5SROKRAk+MWb6zjIdeXEdiKMD8r06lW6reHEREJLaUVNbw1tZo+Hlv11Fq6iIEDEb17kbB4BwmD85hbJ8sstN0baqIXDgFnhhRU1fPTxYW8vSy3QzqnsYTd09kWF6G32WJiIhckNpwPev3V7B8ZxnLdx5l7b7j1NVHP3PkZ6UwqnemNyx2JsPzMsnLTNbQ1yLysSjwxIAtxZV87aV1FJZUcc8V/Xn4hhGkJAb9LktERKTNnTpdz9p9x9l4sIJNxZVsLq5gd9kJGj6GJIYC9MtOpX92Kv1yoo953VLokZFEj/QkemQk6T1SRJpobeDRjUd9UB9xPLV0Fz99s5Cs1ESeu/dSpg3L9bssERGRdpOSGKTg4u4UXNz9zLLq2jBbD1VSeLiKfcdOsvfoCfYePcmKXUc5ebr+Q9tISwySk55EZkqIjKQEMpJDZCRHHzMbTZ99jE43PJecEND1sSJdkAJPB4lEHB/sO878jYf488bDHK6s4fpRefz75y9RX2YREemS0pNCXDogm0sHZDdZ7pyjrPo0JZU1lFXXcqSqliPVtZRVneboiVqqasJU1dSx9+hJqmrqqKoJU306zPk6rYQCRnpDEEpKIP1DQSlEetLZ6cxzBKj0pJBCk0iMaVXgMbPrgZ8BQeBp59yPmz2fBPwGmAgcBWY75/Z4zz0M3AfUAw845xa2WfWdmHOO4yfrKDxcxcLNh1mwKRpyEkMBrh7ag+9OGMVnRvXUQVNERKQZM4t2ZctIavU6kYij+nT4TBhq/FjpTVfXNH8+zMHyGqpqqs4sj5wnNAUsGtTOnFlKOXsGqflZpsyU6GN6UpDkhOhPiveTnBAkKRTQdUsiHeC8gcfMgsD/Bz4NHABWmdk859yWRs3uA4475y42szuAOcBsMxsJ3AGMAnoDb5nZUOfch89Td0LOOcIRR7jeUReJEK53hOsj1IYjVNeGoz81YSpr6qiuDVNSUcPuo9FT8rvLTlBVEwai/ZKnDe3Bw2OGM314LhnJGoFNRESkLQUCRmZyApnJCcAnuwmqc45TdfVnwk/lhwJSHZWnmgapypq6jx2aGktOCDQJQomhAAnBAMGAkRA0QoEAoaARChjBQCC6LBggFIguOzMdPDuf4LVtsixoBANG0KKPoWC0zZn5gBEMRp+Pvla0TcCiNTSdb7yNhnUCBL3Xa2jT+DvdePyCt/F18M3PLrqW2jVZ3nydlrd3vuVN/9beI9Zo+uz/wBq3icP/y7m05gzPZcAO59wuADN7EZgJNA48M4HvetMvA49Z9C84E3jROVcL7DazHd72VrRN+e1r4g/f4tiJ061uHzDIvyiFATlp3DI+n/45aQzqnsalA7NJT1LvQRERkc7MzEhNDJGaGKJnZvIn2oZzjhOn68+GolPRL0Vr6iLUhus5dbqeU3X11NRFvMfoT8Py2nCEcH3kzBeu9RFHTbg++qVrxJ19ruGL2IZlDdORyJnR8Dq7Jh/Smyy3FpY3LGthxQatDBKtCSXN14lnZmf/nGbWaPrs33xi/4t44f7JvtR3IVrzKTwf2N9o/gBweUttnHNhM6sAcrzl7zVbN7/5C5jZ/cD93my1mRW2qvpOaDewzO8i2l53oMzvIqRL0T4nHUn7m3Q07XPSkdpsfysCXvxyW2ypzfRvTaPWBJ5WZOcW27RmXZxzvwR+2YpaxAdmtro1Q/6JtBXtc9KRtL9JR9M+Jx1J+xsEWtHmANC30XwfoLilNmYWAroBx1q5roiIiIiISLtoTeBZBQwxs4Fmlkh0EIJ5zdrMA77oTc8CFrloZ8h5wB1mlmRmA4EhwPttU7qIiIiIiMhHO2+XNu+anH8AFhIdlvpZ59xmM/s+sNo5Nw94BnjeG5TgGNFQhNfu90QHOAgDfx8rI7RJE+puKB1N+5x0JO1v0tG0z0lH6vL7m7muMvSEiIiIiIh0Oa3p0iYiIiIiIhKTFHhERERERCRuKfBIE2bW18wWm9lWM9tsZg96y7PN7C9mVuQ9XuR3rRI/zCxoZmvN7HVvfqCZrfT2t5e8AVNE2oSZZZnZy2a2zTvWXaFjnLQXM/ua9366ycxeMLNkHeOkLZnZs2ZWamabGi075zHNoh41sx1mtsHMJvhXecdR4JHmwsA/OudGAJOBvzezkcA/A28754YAb3vzIm3lQWBro/k5wCPe/nYcuM+XqiRe/QxY4JwbDowluu/pGCdtzszygQeASc650UQHf7oDHeOkbT0HXN9sWUvHtBuIjpo8BLgfeKKDavSVAo804Zw75Jz7wJuuIvpBIB+YCfzaa/Zr4HP+VCjxxsz6ADcBT3vzBkwHXvaaaH+TNmNmmcBVREcXxTl32jlXjo5x0n5CQIp3n8JU4BA6xkkbcs4tITpKcmMtHdNmAr9xUe8BWWbWq2Mq9Y8Cj7TIzAYA44GVQE/n3CGIhiIg17/KJM7MBb4BRLz5HKDcORf25g8QDd0ibWEQcAT4ldeN8mkzS0PHOGkHzrmDwE+AfUSDTgWwBh3jpP21dEzLB/Y3atcl9j8FHjknM0sH/gg85Jyr9LseiU9mdjNQ6pxb03jxOZpq/HxpKyFgAvCEc248cAJ1X5N24l03MRMYCPQG0oh2KWpOxzjpKF3yPVaBRz7EzBKIhp3fOede8RaXNJzy9B5L/apP4sqVwAwz2wO8SLSbx1yip9gbbozcByj2pzyJQweAA865ld78y0QDkI5x0h4+Bex2zh1xztUBrwAF6Bgn7a+lY9oBoG+jdl1i/1PgkSa86yeeAbY65/6z0VPzgC96018EXuvo2iT+OOceds71cc4NIHoh7yLn3F3AYmCW10z7m7QZ59xhYL+ZDfMWXQtsQcc4aR/7gMlmluq9vzbsbzrGSXtr6Zg2D7jHG61tMlDR0PUtnplzcX8WSz4GM5sCLAU2cvaain8heh3P74F+RA/gtznnml8gJ/KJmdk04OvOuZvNbBDRMz7ZwFrgbudcrZ/1Sfwws3FEB8lIBHYB9xL9AlDHOGlzZvY9YDbRUVDXAl8ies2EjnHSJszsBWAa0B0oAf4NeJVzHNO84P0Y0VHdTgL3OudW+1F3R1LgERERERGRuKUubSIiIiIiErcUeEREREREJG4p8IiIiIiISNxS4BERERERkbilwCMiIiIiInFLgUdEpIszs1vMzJnZ8A54rR5mttLM1prZ1I9oN83MXm/F9l4wsw1m9rU2qO05M5t1/pbnXHecmd14oTWIiEjbU+AREZE7gWVEb/7a3q4Ftjnnxjvnll7IhswsDyhwzo1xzj3SNuV9YuMABR4RkU5IgUdEpAszs3TgSuA+GgUeMwuY2eNmttnMXjezNxrOfpjZRDN718zWmNlCM+t1ju32N7O3vbMvb5tZP++Gn/8B3Ghm68wspdk615vZNjNbBny+0fI0M3vWzFZ5Z4Zmek+9CeR625pqZoPNbIFX19KGM1bemZtHzWy5me1q9HuYmT1mZlvMbD6Q2+g1v+O93iYz+6V3sz7M7B0zm2Nm75vZdu91E4HvA7O9WmZf8D9GRETajAKPiEjX9jlggXNuO3DMzCZ4yz8PDAAuIXpn+CsAzCwB+Dkwyzk3EXgW+NE5tvsY8Bvn3Bjgd8Cjzrl1wHeAl5xz45xzpxoam1ky8BTwWWAqkNdoW/8KLHLOXQpcA/w/M0sDZgA7vW0tBX4JfNWr6+vA44220QuYAtwM/NhbdgswzPsd/wYoaFy/c+5S59xoIMVbr0HIOXcZ8BDwb865081+r5fO8fcQERGfhPwuQEREfHUnMNebftGb/4BoOPiDcy4CHDazxV6bYcBo4C/eSY8gcOgc272Cs2dpnid6ZuejDAd2O+eKAMzst8D93nPXATPM7OvefDLQD2gcmNKJBpY/eHUBJDXa/qve77LFzHp6y64CXnDO1QPFZraoUftrzOwbQCqQDWwG/uQ994r3uIZoKBQRkU5MgUdEpIsysxxgOjDazBzR8OK8D/rW0mrAZufcFR/z5dwFtDHgVudcYZOFZgMazQaAcufcuBa2Udtsey2+pne26XFgknNuv5l9l2jIar6tevQ+KiLS6alLm4hI1zWLaLez/s65Ac65vsBuomd3lgG3etfy9ASmeesUAj3M7EwXNzMbdY5tL+fsNUF3edv7KNuAgWY22Ju/s9FzC4GvNrqOZnzzlZ1zlcBuM7vNa2NmNvY8r7kEuMPMgt51SNd4yxvCTZl35qg1I7dVARmtaCciIh1MgUdEpOu6E/jvZsv+CPwf7/EAsAl4ElgJVHjXq8wC5pjZemAdTa99afAAcK+ZbQC+ADz4UYU452qIdmGb7w1asLfR0z8AEoANZrbJmz+Xu4D7vLo2AzNbaNfgv4EiYCPwBPCuV0s50euJNgKvAqvOsx2AxcBIDVogItL5mHOt6WUgIiJdjZmlO+eqva5v7wNXOucO+12XiIjIx6G+xyIi0pLXzSwLSAR+oLAjIiKxSGd4REREREQkbukaHhERERERiVsKPCIiIiIiErcUeEREREREJG4p8IiIiIiISNxS4BERERERkbj1vxcr6sBDzcF0AAAAAElFTkSuQmCC\n",
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"sns.kdeplot(compas_raw.age.values)\n",
"plt.title(\"Density plot of defendants' ages\")\n",
"plt.xlabel(\"Age of defendant\")\n",
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>is_recid</th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" </tr>\n",
" <tr>\n",
" <th>age_cat</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>25 - 45</th>\n",
" <td>1784</td>\n",
" <td>1748</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Greater than 45</th>\n",
" <td>847</td>\n",
" <td>446</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Less than 25</th>\n",
" <td>551</td>\n",
" <td>796</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"is_recid 0 1\n",
"age_cat \n",
"25 - 45 1784 1748\n",
"Greater than 45 847 446\n",
"Less than 25 551 796"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>is_recid</th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" </tr>\n",
" <tr>\n",
" <th>sex</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Female</th>\n",
" <td>740</td>\n",
" <td>435</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Male</th>\n",
" <td>2442</td>\n",
" <td>2555</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"is_recid 0 1\n",
"sex \n",
"Female 740 435\n",
"Male 2442 2555"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>is_recid</th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" </tr>\n",
" <tr>\n",
" <th>race</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>African-American</th>\n",
" <td>1402</td>\n",
" <td>1773</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Asian</th>\n",
" <td>21</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Caucasian</th>\n",
" <td>1229</td>\n",
" <td>874</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hispanic</th>\n",
" <td>312</td>\n",
" <td>197</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Native American</th>\n",
" <td>5</td>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Other</th>\n",
" <td>213</td>\n",
" <td>130</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"is_recid 0 1\n",
"race \n",
"African-American 1402 1773\n",
"Asian 21 10\n",
"Caucasian 1229 874\n",
"Hispanic 312 197\n",
"Native American 5 6\n",
"Other 213 130"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"tab = compas.groupby(['age_cat', 'is_recid']).size()\n",
"display(tab.unstack())\n",
"\n",
"tab = compas.groupby(['sex', 'is_recid']).size()\n",
"display(tab.unstack())\n",
"\n",
"tab = compas.groupby(['race', 'is_recid']).size()\n",
"display(tab.unstack())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generate synthetic data set\n",
"\n",
"In the chunk below, we generate the synthetic data as described by Lakkaraju et al. The default values are as per their description. The definitions of $Y$ and $T$ values follow their description.\n",
"* M = `nJudges_M`, number of judges\n",
"* N = `nSubjects_N`, number of subjects assigned to each judge\n",
"* betas $\\beta_i$, where $i \\in \\{X, Z, W\\}$ are coefficients for the respected variables\n",
"* R = `acceptanceRate_R`, acceptance rates\n",
"* X = `X`, invidual's features observable to all (models and judges)\n",
"* Z = `Z`, information observable for judges only\n",
"* W = `W`, unobservable / inaccessible information\n",
"* T = `decision_T`, decisions where $T=0$ represents decision to deny and if $T=1$ then bail is granted.\n",
"* Y = `result_Y`, result variable, if $Y=0$ person will or would recidivate and if $Y=1$ person would not commit a crime."
]
},
{
"cell_type": "code",
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0 26137\n",
"1.0 23863\n",
"Name: decision_T, dtype: int64\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>decision_T</th>\n",
" <th>0.0</th>\n",
" <th>1.0</th>\n",
" </tr>\n",
" <tr>\n",
" <th>result_Y</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0.0</th>\n",
" <td>13119</td>\n",
" <td>12056</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1.0</th>\n",
" <td>13018</td>\n",
" <td>11807</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"decision_T 0.0 1.0\n",
"result_Y \n",
"0.0 13119 12056\n",
"1.0 13018 11807"
]
},
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
"# Set seed for reproducibility\n",
"npr.seed(0)\n",
"\n",
"def generateData(nJudges_M=100,\n",
" nSubjects_N=500,\n",
" beta_X=1.0,\n",
" beta_Z=1.0,\n",
" beta_W=0.2):\n",
"\n",
" # Assign judge IDs as running numbering from 0 to nJudges_M - 1\n",
" judgeID_J = np.repeat(np.arange(0, nJudges_M, dtype=np.int32), nSubjects_N)\n",
"\n",
" # Sample acceptance rates uniformly from a closed interval\n",
" # from 0.1 to 0.9 and round to tenth decimal place.\n",
" acceptance_rates = np.round(npr.uniform(.1, .9, nJudges_M), 10)\n",
"\n",
" # Replicate the rates so they can be attached to the corresponding judge ID.\n",
" acceptanceRate_R = np.repeat(acceptance_rates, nSubjects_N)\n",
"\n",
" # Sample the variables from standard Gaussian distributions.\n",
" X = npr.normal(size=nJudges_M * nSubjects_N)\n",
" Z = npr.normal(size=nJudges_M * nSubjects_N)\n",
" W = npr.normal(size=nJudges_M * nSubjects_N)\n",
"\n",
" probabilities_Y = 1 / (1 + np.exp(-(beta_X * X + beta_Z * Z + beta_W * W)))\n",
"\n",
" # 0 if P(Y = 0| X = x; Z = z; W = w) >= 0.5 , 1 otherwise\n",
" result_Y = 1 - probabilities_Y.round()\n",
"\n",
" probabilities_T = 1 / (1 + np.exp(-(beta_X * X + beta_Z * Z)))\n",
" probabilities_T += npr.normal(0, .1, nJudges_M * nSubjects_N)\n",
"\n",
" # Initialize decision values as -1\n",
" decision_T = np.zeros(nJudges_M * nSubjects_N) - 1\n",
"\n",
" # Initialize the dataframe\n",
" df_init = pd.DataFrame(\n",
" np.column_stack((judgeID_J, acceptanceRate_R, X, Z, W, result_Y,\n",
" probabilities_T, decision_T)),\n",
" columns=[\n",
" \"judgeID_J\", \"acceptanceRate_R\", \"X\", \"Z\", \"W\", \"result_Y\",\n",
" \"probabilities_T\", \"decision_T\"\n",
" ])\n",
"\n",
" # Sort by judges then probabilities\n",
" data = df_init.sort_values(\n",
" by=[\"judgeID_J\", \"probabilities_T\"], ascending=False)\n",
"\n",
" # Iterate over the data. Subject is in the top (1-r)*100% if\n",
" # his within-judge-index is over acceptance threshold times\n",
" # the number of subjects assigned to each judge. If subject\n",
" # is over the limit they are assigned a zero, else one.\n",
" for i in range(nJudges_M * nSubjects_N):\n",
" index = i % nSubjects_N\n",
" if index < (1 - data.acceptanceRate_R[i]) * nSubjects_N:\n",
" data.decision_T[i] = 0\n",
" else:\n",
" data.decision_T[i] = 1 # TARKISTA!!!!!!\n",
"\n",
" return data\n",
"\n",
"\n",
"df = generateData()\n",
"\n",
"# Basic stats of the created data set.\n",
"\n",
"print(df.decision_T.value_counts())\n",
"\n",
"tab = df.groupby(['result_Y', 'decision_T']).size()\n",
"tab.unstack()"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(25000, 8)\n",
"(25000, 8)\n",
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>decision_T</th>\n",