From 0985aaffe7ad49d99ec8a6a2d99d6704638b3744 Mon Sep 17 00:00:00 2001 From: "mikolaj.mierzejewski" Date: Fri, 18 Aug 2023 16:18:27 +0200 Subject: [PATCH] add frequency encoder --- examples/08_frequence_encoder.ipynb | 408 ++++++++++++++++++++++++++++ skrub/_frequency_encoder.py | 35 +++ 2 files changed, 443 insertions(+) create mode 100644 examples/08_frequence_encoder.ipynb create mode 100644 skrub/_frequency_encoder.py diff --git a/examples/08_frequence_encoder.ipynb b/examples/08_frequence_encoder.ipynb new file mode 100644 index 000000000..a74ac8c4c --- /dev/null +++ b/examples/08_frequence_encoder.ipynb @@ -0,0 +1,408 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from skrub.datasets import fetch_road_safety" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "road_safety_dataset = fetch_road_safety()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Vehicle_Type\n", + "9.0 271120\n", + "1.0 20281\n", + "19.0 19612\n", + "3.0 9966\n", + "5.0 8268\n", + "11.0 7758\n", + "8.0 7474\n", + "21.0 6785\n", + "4.0 2446\n", + "2.0 2392\n", + "20.0 2318\n", + "90.0 1740\n", + "10.0 906\n", + "98.0 790\n", + "17.0 650\n", + "97.0 301\n", + "22.0 226\n", + "16.0 119\n", + "18.0 20\n", + "23.0 9\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "road_safety_dataset.X.Vehicle_Type.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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v8s8FwAAYF9lDkKnTp1SmzZtNG/evFLbZ8+erRdffFELFizQp59+qurVqyshIUFnzpyxaoYMGaLt27crMzNTK1eu1Lp16zRq1Cir3e12q2fPnmrUqJFycnL0l7/8RdOnT9fChQutmvXr12vw4MFKSkrSF198of79+6t///7atm1bmeYCAADsy2GMMeV+sMOht99+W/3795f08xGYqKgoPfroo5owYYIkKT8/X/Xq1VNaWpoGDRqkHTt2qEWLFvrss8/Uvn17SVJGRoZ69+6tQ4cOKSoqSvPnz9cf/vAHuVwuBQUFSZImTZqkFStWaOfOnZKkgQMH6tSpU1q5cqU1n06dOqlt27ZasGDBZc3lUtxut8LDw5Wfny+n01nezQQAAC5T40npZarfP6tPifvK8v5doecI7du3Ty6XS/Hx8dZ94eHhio2NVXZ2tiQpOztbNWvWtEKQJMXHxysgIECffvqpVdO1a1crBElSQkKCdu3apR9++MGqOX+c4pricS5nLr9UUFAgt9vtsQAAgMqrQoOQy+WSJNWrV8/j/nr16lltLpdLERERHu1VqlRRrVq1PGpK6+P8MS5Uc377pebySzNnzlR4eLi1REdHX8ZaAwCAaxXfGjvP5MmTlZ+fby0HDx680lMCAAA+VKFBKDIyUpKUl5fncX9eXp7VFhkZqSNHjni0//TTTzp27JhHTWl9nD/GhWrOb7/UXH4pODhYTqfTYwEAAJVXhQahmJgYRUZGKisry7rP7Xbr008/VVxcnCQpLi5Ox48fV05OjlWzevVqFRUVKTY21qpZt26dzp49a9VkZmbq5ptv1nXXXWfVnD9OcU3xOJczFwAAYG9lDkInT55Ubm6ucnNzJf18UnJubq4OHDggh8OhcePG6emnn9a7776rrVu3aujQoYqKirK+Wda8eXP16tVLDz74oDZu3KhPPvlEKSkpGjRokKKioiRJ9913n4KCgpSUlKTt27dryZIlmjNnjlJTU615PPLII8rIyNCzzz6rnTt3avr06dq0aZNSUlIk6bLmAgAA7K1KWR+wadMm3X777dbt4nCSmJiotLQ0Pf744zp16pRGjRql48eP67bbblNGRoZCQkKsx/zjH/9QSkqKevTooYCAAA0YMEAvvvii1R4eHq4PPvhAycnJateunerUqaOpU6d6XGuoc+fOWrx4saZMmaInnnhC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WbNm2rlzp+bMmaOCggLdf//9leJ8qoMHD2ratGl69dVXy/X4TZs2KT4+Xk2aNFFoaKh2796t++67T4WFhZowYYJeffVVZWRkKCwsrGImfOW+sHbt27lzp2nUqJEJCAgwTZo0MXv37jXt2rUz1atXN9WqVTN16tQxX331ldfjvPfee+bJJ580H3/8sTHGmKysLHPHHXeYhIQE89///d9e93/w4EFz9OhR6/a6devMfffdZ2677TYzZMgQr79umZ+fb373u9+ZkJAQExERYZ588knz008/We0ul8sEBAR4NYbD4TCBgYEmPj7evPXWW6agoMCr/krz17/+1ezfv7/C+y22YMECU6VKFdOuXTvjdDrNG2+8YcLCwszIkSPNQw89ZEJDQ80LL7xQIWMVFBSYJUuWmHHjxplBgwaZQYMGmXHjxpmlS5d6ve12795tbrjhBhMSEmK6detm7r33XnPvvfeabt26mZCQENOkSROze/dur8bIy8szt912m3E4HKZRo0amY8eOpmPHjqZRo0bG4XCY2267zeTl5Xk1xq5du6z+AgICTNeuXc3hw4etdm+ftw6Hw7Rt29Z0797dY3E4HKZDhw6me/fu5vbbb/dqHS4lNzfX67+9p556yoSFhZkBAwaYyMhIM2vWLFO7dm3z9NNPmz//+c+mbt26ZurUqRU04wtzuVzmj3/8Y7kf37x5c/P9998bY4w5cOCAady4sQkPDzcdOnQwtWrVMhEREV5fnmHVqlUmKCjI1KpVy4SEhJhVq1aZunXrmvj4ePPrX//aBAYGmqysLK/GMMaYH3/80bzyyitm+PDhplevXqZ3794mJSXF/Oc///G678vh7fPq1ltvNdOnT7duv/HGGyY2NtYYY8yxY8dM27ZtzcMPP+z1PIsRhLzQr18/c9ddd5ktW7aYcePGmebNm5t+/fqZwsJCc+bMGdO3b19z//33ezWGP94cO3bsaN577z1jjDErVqwwAQEB5q677jITJ040v/3tb03VqlWt9vJ4+OGHzU033WSWLVtmXn75ZdOoUSPTp08f6w3X5XIZh8Ph1To4HA6zaNEi069fP1O1alVTu3Zt88gjj1z096jKM4Yvw1aLFi3MwoULjTHGrF692oSEhHhc2HDRokWmefPmXo/j66ASHx9v+vXrZ/Lz80u05efnm379+pmePXt6swpmwIABJi4u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VgZsp3K4koejrnX+uOCaPy5c5esx/HlhOl9egKuyXESsMqzHlbjY4bWoMm0nfz1vr3Vsp7LjZGkAAGBbfDQGAABsiyAEAABsiyAEAABsiyAEAABsiyAE4KrSuHFjvfDCCxds379/vxwOh3Jzcy+rv2HDhql///4VMjcAlQ9BCECF6du3r3r16lVq20cffSSHw6EtW7Z4NUZ0dLS+/fZbtWzZ0qt+ymr69OlyOBwXXQBcewhCACpMUlKSMjMzdejQoRJtixYtUvv27dW6dWuvxggMDFRkZGSJX9X2tQkTJujbb7+1lgYNGmjGjBke9wG49hCEAFSYO++8U3Xr1lVaWprH/SdPntSyZcuUlJSkjz/+WF26dFFoaKiio6P18MMP69SpUx71P/74o0aMGKGwsDA1bNhQCxcutNpK+2hs+/btuvPOO+V0OhUWFqYuXbro66+/LnWORUVFmjlzpmJiYhQaGqo2bdron//85yXXrUaNGoqMjLSWwMBAhYWFKTIyUgsXLlR8fHyJx7Rt21ZPPvmkpP/7iO6Pf/yj6tatK6fTqdGjR6uwsNDruQEoP4IQgApTpUoVDR06VGlpaR6X8V+2bJnOnTunuLg49erVSwMGDNCWLVu0ZMkSffzxx0pJSfHo59lnn1X79u31xRdf6Pe//73GjBmjXbt2lTrmN998o65duyo4OFirV69WTk6ORowYoZ9++qnU+pkzZ+r111/XggULtH37do0fP17333+/1q5dW+71HjFihHbs2KHPPvvMuu+LL77Qli1bNHz4cOu+rKws7dixQ2vWrNGbb76p5cuX649//KNP5wbgEq7wla0BVDI7duwwksyHH35o3delSxdz//33m6SkJDNq1CiP+o8++sgEBASY06dPG2N+/vX6+++/32ovKioyERERZv78+caYn3+9XpL54osvjDHGTJ482cTExJjCwsJS55OYmGj69etnjDHmzJkzplq1amb9+vUeNUlJSWbw4MFlWs9GjRqZ559/3rp9xx13mDFjxli3x44da7p37+4xj1q1aplTp05Z982fP9/UqFHDnDt3rkLnBuDycUQIQIVq1qyZOnfubP3Q6p49e/TRRx8pKSlJmzdvVlpammrUqGEtCQkJKioq0r59+6w+zj+PyOFwKDIyUkeOHCl1vNzcXHXp0kVVq1a95Nz27NmjH3/8Ub/5zW885vD6669f8KO0y/Xggw/qzTff1JkzZ1RYWKjFixdrxIgRHjVt2rRRtWrVrNtxcXE6efKkDh486NO5Abgw/55tCMAWkpKSNHbsWM2bN0+LFi3SjTfeqG7duunkyZN66KGH9PDDD5d4TMOGDa1//zLUOBwOFRUVlTpWaGjoZc/r5MmTkqT09HRdf/31Hm3BwcGX3U9p+vbtq+DgYL399tsKCgrS2bNndc8991wVcwNwYQQhABXu3nvv1SOPPKLFixfr9ddf15gxY+RwOHTLLbfoyy+/VJMmTSpsrNatW+u1117T2bNnL3lUqEWLFgoODtaBAwfUrVu3CpuD9PP5UYmJiVq0aJGCgoI0aNCgEiFt8+bNOn36tHX/hg0bVKNGDUVHR6tWrVo+mxuACyMIAahwNWrU0MCBAzV58mS53W4NGzZMkjRx4kR16tRJKSkpGjlypKpXr64vv/xSmZmZmjt3brnGSklJ0d/+9jcNGjRIkydPVnh4uDZs2KCOHTvq5ptv9qgNCwvThAkTNH78eBUVFem2225Tfn6+PvnkEzmdTiUmJnq13iNHjlTz5s0lSZ988kmJ9sLCQiUlJWnKlCnav3+/pk2bppSUFAUEBPh8bgBKRxAC4BNJSUl65ZVX1Lt3b0VFRUn6+ejN2rVr9Yc//EFdunSRMUY33nijBg4cWO5xateurdWrV+uxxx5Tt27dFBgYqLZt2+rWW28ttf6pp55S3bp1NXPmTO3du1c1a9bULbfcoieeeKLccyjWtGlTde7cWceOHVNsbGyJ9h49eqhp06bq2rWrCgoKNHjwYE2fPt0vcwNQOocx533HFQBQbsYYNW3aVL///e+Vmprq0TZs2DAdP35cK1asuDKTA1AqjggBQAU4evSo3nrrLblcLo9rBwG4uvH1eQD4X6NHj/b46vr5y+jRoy/62IiICM2YMUMLFy7Udddd56cZA/AWH40BwP86cuSI3G53qW1Op1MRERF+nhEAXyMIAQAA2+KjMQAAYFsEIQAAYFsEIQAAYFsEIQAAYFsEIQAAYFsEIQAAYFsEIQAAYFv/H5vrHfE24PqZAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "employee_salaries.X.Vehicle_Type.value_counts().sort_values().plot(kind=\"bar\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's say we want to group together the values basing on their frequencies so in the end we will end with 6 values instead of 20. That will reduce the number of features when we want to perform other operations - like one-hot encoding and clustering. " + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Vehicle_Type\n", + "23.0 9\n", + "18.0 20\n", + "16.0 119\n", + "22.0 226\n", + "97.0 301\n", + "17.0 650\n", + "98.0 790\n", + "10.0 906\n", + "90.0 1740\n", + "20.0 2318\n", + "2.0 2392\n", + "4.0 2446\n", + "21.0 6785\n", + "8.0 7474\n", + "11.0 7758\n", + "5.0 8268\n", + "3.0 9966\n", + "19.0 19612\n", + "1.0 20281\n", + "9.0 271120\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "road_safety_dataset.X.Vehicle_Type.value_counts().sort_values()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's say we want to prepare ranges for the bins basing on their counts. We see that there are vehicle types that could be grouped into similiar categories based on the frequencies. Our bins would look like this:\n", + "[9, 650, 1740, 6785, 19612, 271120]\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "from _frequency_encoder import FrequencyEncoder" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "# you need to put np.inf at the end of the list. " + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "fe = FrequencyEncoder(column = \"Vehicle_Type\", bins = [9, 650, 1740, 6785, 19612, 271120, np.inf])" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
FrequencyEncoder(bins=[9, 650, 1740, 6785, 19612, 271120, inf],\n",
+       "                 column='Vehicle_Type')
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": [ + "FrequencyEncoder(bins=[9, 650, 1740, 6785, 19612, 271120, inf],\n", + " column='Vehicle_Type')" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fe.fit(X=road_safety_dataset.X)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 [19612.0, 271120.0)\n", + "1 [271120.0, inf)\n", + "2 [271120.0, inf)\n", + "3 [271120.0, inf)\n", + "4 [19612.0, 271120.0)\n", + " ... \n", + "363238 [271120.0, inf)\n", + "363239 [271120.0, inf)\n", + "363240 [271120.0, inf)\n", + "363241 [271120.0, inf)\n", + "363242 [271120.0, inf)\n", + "Name: Vehicle_Type, Length: 363243, dtype: category\n", + "Categories (6, interval[float64, left]): [[9.0, 650.0) < [650.0, 1740.0) < [1740.0, 6785.0) < [6785.0, 19612.0) < [19612.0, 271120.0) < [271120.0, inf)]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fe.transform(road_safety_dataset.X)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 [19612.0, 271120.0)\n", + "1 [271120.0, inf)\n", + "2 [271120.0, inf)\n", + "3 [271120.0, inf)\n", + "4 [19612.0, 271120.0)\n", + " ... \n", + "363238 [271120.0, inf)\n", + "363239 [271120.0, inf)\n", + "363240 [271120.0, inf)\n", + "363241 [271120.0, inf)\n", + "363242 [271120.0, inf)\n", + "Name: Vehicle_Type, Length: 363243, dtype: category\n", + "Categories (6, interval[float64, left]): [[9.0, 650.0) < [650.0, 1740.0) < [1740.0, 6785.0) < [6785.0, 19612.0) < [19612.0, 271120.0) < [271120.0, inf)]" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fe.transform(employee_salaries.X)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Vehicle_Type\n", + "[271120.0, inf) 271120\n", + "[6785.0, 19612.0) 40251\n", + "[19612.0, 271120.0) 39893\n", + "[1740.0, 6785.0) 8896\n", + "[650.0, 1740.0) 2346\n", + "[9.0, 650.0) 675\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fe.transform(road_safety_dataset.X).value_counts()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Voila, now you have values encoded according to chosen ranges basing on frequencies.\n", + "Soon we will have automatic way to compute this basing on the quantiles. " + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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eXmYMmWKNpOPjw8CAgJgYWEBMzMzzJo1C66urmVeMUZERETyU6kitHXrVgB/XSL/rF27dsHb2xsGBgb46aeftKXEzs4OY8eOxfLly7Vz9fX1cfToUcycOROurq4wNjaGl5cXgoKCtHMcHR0RHh6OefPmYf369WjevDm2b98OpVKpnTNu3Djcv38fgYGBUKlU6Nq1KyIiInQWUAcHB0OhUGDs2LEoKCiAUqnEli1bKnWAiIiIqO56pX2E6rrK7ENARERUG3EfoWrcR4iIiIhIyliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLZYhIiIiEi2WISIiIhItliEiIiISLYqVYTWrl2LN954A6amprC0tMTo0aORlJSkM+fJkyfw8/ND48aNYWJigrFjxyIzM1NnTlpaGjw8PNCgQQNYWlpiwYIFKC4u1plz8uRJdO/eHYaGhmjdujVCQ0NL5dm8eTNatGgBIyMjuLi4IDY2ttJZiIiISL4qVYROnToFPz8/nD17FpGRkSgqKsKQIUOQl5ennTNv3jwcOXIEBw4cwKlTp5Ceno4xY8Zox0tKSuDh4YHCwkKcOXMGu3fvRmhoKAIDA7VzUlJS4OHhgYEDByI+Ph5z586Fr68vjh8/rp2zb98+BAQEYOXKlfjtt9/QpUsXKJVK3Lt3r8JZiIiISN70BEEQXvaT79+/D0tLS5w6dQpubm7IyclB06ZNERYWhnfeeQcAcP36dXTo0AExMTHo1asXjh07hhEjRiA9PR1WVlYAgJCQECxatAj379+HgYEBFi1ahPDwcFy5ckX7tcaPH4/s7GxEREQAAFxcXPDGG29g06ZNAACNRgM7OzvMmjULixcvrlCWF1Gr1TA3N0dOTg7MzMxe9jARERGJpsXicLEjVEjqvz2q7LUq8/v7ldYI5eTkAAAsLCwAAHFxcSgqKoK7u7t2Tvv27WFvb4+YmBgAQExMDDp16qQtQQCgVCqhVquRmJionfPsazyd8/Q1CgsLERcXpzNHoVDA3d1dO6ciWf6uoKAAarVa50FERER110sXIY1Gg7lz56JPnz7o2LEjAEClUsHAwAANGzbUmWtlZQWVSqWd82wJejr+dOx5c9RqNR4/fowHDx6gpKSkzDnPvsaLsvzd2rVrYW5urn3Y2dlV8GgQERGRFL10EfLz88OVK1fwzTffVGUeUS1ZsgQ5OTnax507d8SORERERNWo3st8kr+/P44ePYrTp0+jefPm2uetra1RWFiI7OxsnTMxmZmZsLa21s75+9VdT6/kenbO36/uyszMhJmZGerXrw99fX3o6+uXOefZ13hRlr8zNDSEoaFhJY4EERERSVmlzggJggB/f3989913iI6OhqOjo864s7MzXnvtNURFRWmfS0pKQlpaGlxdXQEArq6uuHz5ss7VXZGRkTAzM4OTk5N2zrOv8XTO09cwMDCAs7OzzhyNRoOoqCjtnIpkISIiInmr1BkhPz8/hIWF4fvvv4epqal2rY25uTnq168Pc3Nz+Pj4ICAgABYWFjAzM8OsWbPg6uqqvUpryJAhcHJywqRJk7Bu3TqoVCosX74cfn5+2rMxM2bMwKZNm7Bw4UJMnToV0dHR2L9/P8LD/2/le0BAALy8vNCjRw/07NkTX3zxBfLy8jBlyhRtphdlISIiInmrVBHaunUrAGDAgAE6z+/atQve3t4AgODgYCgUCowdOxYFBQVQKpXYsmWLdq6+vj6OHj2KmTNnwtXVFcbGxvDy8kJQUJB2jqOjI8LDwzFv3jysX78ezZs3x/bt26FUKrVzxo0bh/v37yMwMBAqlQpdu3ZFRESEzgLqF2UhIiIieXulfYTqOu4jREREUsd9hKpxHyEiIiIiKWMRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZYhEiIiIi2WIRIiIiItliESIiIiLZqnQROn36NEaOHAlbW1vo6enh0KFDOuPe3t7Q09PTeQwdOlRnTlZWFiZOnAgzMzM0bNgQPj4+yM3N1ZmTkJCAfv36wcjICHZ2dli3bl2pLAcOHED79u1hZGSETp064YcfftAZFwQBgYGBsLGxQf369eHu7o7ff/+9st8yERER1VGVLkJ5eXno0qULNm/eXO6coUOHIiMjQ/vYu3evzvjEiRORmJiIyMhIHD16FKdPn8b06dO142q1GkOGDIGDgwPi4uLwySefYNWqVfjqq6+0c86cOQNPT0/4+Pjg4sWLGD16NEaPHo0rV65o56xbtw4bNmxASEgIzp07B2NjYyiVSjx58qSy3zYRERHVQXqCIAgv/cl6evjuu+8wevRo7XPe3t7Izs4udaboqWvXrsHJyQnnz59Hjx49AAAREREYPnw47t69C1tbW2zduhXLli2DSqWCgYEBAGDx4sU4dOgQrl+/DgAYN24c8vLycPToUe1r9+rVC127dkVISAgEQYCtrS0+/PBDzJ8/HwCQk5MDKysrhIaGYvz48S/8/tRqNczNzZGTkwMzM7OXOURERESiarE4XOwIFZL6b48qe63K/P6uljVCJ0+ehKWlJdq1a4eZM2fizz//1I7FxMSgYcOG2hIEAO7u7lAoFDh37px2jpubm7YEAYBSqURSUhIePnyonePu7q7zdZVKJWJiYgAAKSkpUKlUOnPMzc3h4uKinfN3BQUFUKvVOg8iIiKqu6q8CA0dOhR79uxBVFQUPv74Y5w6dQrDhg1DSUkJAEClUsHS0lLnc+rVqwcLCwuoVCrt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AGDChAkwMDCAj48PEhMTsW/fPqxfvx4BAQHaHHPmzEFERAQ+++wzXL9+HatWrcKFCxfg7+8PABXKQkRERPJWr7KfcOHCBQwcOFD78dNy4uXlhdDQUCxcuBB5eXmYPn06srOz0bdvX0RERMDIyEj7OV9//TX8/f0xaNAgKBQKjB07Fhs2bNCOm5ub48cff4Sfnx+cnZ3RpEkTBAYG6uw11Lt3b4SFhWH58uVYunQp2rRpg0OHDqFjx47aORXJQkRERPL1SvsI1XXcR4iIiKSO+wjV4D5CRERERFLCIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREssUiRERERLLFIkRERESyxSJEREREslXlRWjVqlXQ09PTebRv3147/uTJE/j5+aFx48YwMTHB2LFjkZmZqfMaaWlp8PDwQIMGDWBpaYkFCxaguLhYZ87JkyfRvXt3GBoaonXr1ggNDS2VZfPmzWjRogWMjIzg4uKC2NjYqv52iYiISMKq5YzQ66+/joyMDO3jl19+0Y7NmzcPR44cwYEDB3Dq1Cmkp6djzJgx2vGSkhJ4eHigsLAQZ86cwe7duxEaGorAwEDtnJSUFHh4eGDgwIGIj4/H3Llz4evri+PHj2vn7Nu3DwEBAVi5ciV+++03dOnSBUqlEvfu3auOb5mIiIgkSE8QBKEqX3DVqlU4dOgQ4uPjS43l5OSgadOmCAsLwzvvvAMAuH79Ojp06ICYmBj06tULx44dw4gRI5Ceng4rKysAQEhICBYtWoT79+/DwMAAixYtQnh4OK5cuaJ97fHjxyM7OxsREREAABcXF7zxxhvYtGkTAECj0cDOzg6zZs3C4sWLK/S9qNVqmJubIycnB2ZmZq9yWIiIiETRYnG42BEqJPXfHlX2WpX5/V0tZ4R+//132NraomXLlpg4cSLS0tIAAHFxcSgqKoK7u7t2bvv27WFvb4+YmBgAQExMDDp16qQtQQCgVCqhVquRmJionfPsazyd8/Q1CgsLERcXpzNHoVDA3d1dO6csBQUFUKvVOg8iIiKqu6q8CLm4uCA0NBQRERHYunUrUlJS0K9fPzx69AgqlQoGBgZo2LChzudYWVlBpVIBAFQqlU4Jejr+dOx5c9RqNR4/fowHDx6gpKSkzDlPX6Msa9euhbm5ufZhZ2f3UseAiIiIpKFeVb/gsGHDtP/duXNnuLi4wMHBAfv370f9+vWr+stVqSVLliAgIED7sVqtZhkiIiKqw6r98vmGDRuibdu2uHnzJqytrVFYWIjs7GydOZmZmbC2tgYAWFtbl7qK7OnHL5pjZmaG+vXro0mTJtDX1y9zztPXKIuhoSHMzMx0HkRERFR3VXsRys3NRXJyMmxsbODs7IzXXnsNUVFR2vGkpCSkpaXB1dUVAODq6orLly/rXN0VGRkJMzMzODk5aec8+xpP5zx9DQMDAzg7O+vM0Wg0iIqK0s4hIiIiqvIiNH/+fJw6dQqpqak4c+YM3n77bejr68PT0xPm5ubw8fFBQEAATpw4gbi4OEyZMgWurq7o1asXAGDIkCFwcnLCpEmTcOnSJRw/fhzLly+Hn58fDA0NAQAzZszArVu3sHDhQly/fh1btmzB/v37MW/ePG2OgIAAbNu2Dbt378a1a9cwc+ZM5OXlYcqUKVX9LRMREZFEVfkaobt378LT0xN//vknmjZtir59++Ls2bNo2rQpACA4OBgKhQJjx45FQUEBlEoltmzZov18fX19HD16FDNnzoSrqyuMjY3h5eWFoKAg7RxHR0eEh4dj3rx5WL9+PZo3b47t27dDqVRq54wbNw73799HYGAgVCoVunbtioiIiFILqImIiEi+qnwfobqE+wgREZHUcR8hEfYRIiIiIpICFiEiIiKSLRYhIiIiki0WISIiIpItFiEiIiKSrSq/fJ6IiKgqSOFqp6q80onEwSJERFSF+MubSFr41hgRERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREclWPbEDEJH4WiwOFztChaT+20PsCERUx/CMEBEREckWixARERHJFosQERERyRaLEBEREckWixARERHJFosQERERyRaLEBEREcmWLIrQ5s2b0aJFCxgZGcHFxQWxsbFiRyIiIqJaoM5vqLhv3z4EBAQgJCQELi4u+OKLL6BUKpGUlARLS0ux49ErksJGgNwEkIio9qrzZ4Q+//xzTJs2DVOmTIGTkxNCQkLQoEED7Ny5U+xoREREJLI6fUaosLAQcXFxWLJkifY5hUIBd3d3xMTElJpfUFCAgoIC7cc5OTkAALVaXaW5Oq48XqWvVx2urFaKHaFCNAX5Ykd4oar+91MdpHAcAR7LqiKF4wjwWFYVKRxHoGqP5dPXEgThhXPrdBF68OABSkpKYGVlpfO8lZUVrl+/Xmr+2rVrsXr16lLP29nZVVvG2sr8C7ET1B08llWHx7Jq8DhWHR7LqlMdx/LRo0cwNzd/7pw6XYQqa8mSJQgICNB+rNFokJWVhcaNG0NPT0/EZM+nVqthZ2eHO3fuwMzMTOw4ksXjWHV4LKsOj2XV4HGsOlI4loIg4NGjR7C1tX3h3DpdhJo0aQJ9fX1kZmbqPJ+ZmQlra+tS8w0NDWFoaKjzXMOGDaszYpUyMzOrtf8opYTHserwWFYdHsuqweNYdWr7sXzRmaCn6vRiaQMDAzg7OyMqKkr7nEajQVRUFFxdXUVMRkRERLVBnT4jBAABAQHw8vJCjx490LNnT3zxxRfIy8vDlClTxI5GREREIqvzRWjcuHG4f/8+AgMDoVKp0LVrV0RERJRaQC1lhoaGWLlyZam39ahyeByrDo9l1eGxrBo8jlWnrh1LPaEi15YRERER1UF1eo0QERER0fOwCBEREZFssQgRERGRbLEIERERkWyxCBEREZFs1fnL5+uaa9eu4ZtvvsHPP/+M27dvIz8/H02bNkW3bt2gVCoxduzYOnNJY00oKiqCSqXSHkcLCwuxI0leQUEB/w2+JI1Gg1OnTpX58+3u7i7L+x6+Cv58vzo5/M7h5fMS8dtvv2HhwoX45Zdf0KdPH/Ts2RO2traoX78+srKycOXKFfz8889Qq9VYuHAh5s6dK/l/nNXl0aNH+O9//4tvvvkGsbGxKCwshCAI0NPTQ/PmzTFkyBBMnz4db7zxhthRJeHYsWPa/1HeuXMHGo0GxsbG6NatG4YMGYIpU6ZU6H4/cvb48WN89tln2Lp1K7KystC1a9dSP9/p6ekYMmQIAgMD0atXL7Ej11r8+a4acvqdwyIkEY6OjliwYAEmTJjw3PufxcTEYP369ejcuTOWLl1acwEl4vPPP8c///lPtGrVCiNHjiz3h/vQoUNwcXHBxo0b0aZNG7Fj10rfffcdFi1ahEePHmH48OHlHsuYmBh4e3tjzZo1aNq0qdixayU7Ozu4urrC29sbgwcPxmuvvVZqzu3btxEWFoYvv/wSy5Ytw7Rp00RIWrvx57vqyOl3DouQRBQVFZX5P8eqmi8Xnp6eWL58OV5//fXnzisoKMCuXbtgYGCAqVOn1lA6aXF1dcXy5csxbNgwKBTlLzf8448/sHHjRlhZWWHevHk1mFA6rl27hg4dOlRoblFREdLS0tCqVatqTiU9/PmuOnL6ncMiRERERDosLCxw48YNNGnSBFOnTsX69ethamoqdqxqwSIkMQ8ePMDOnTsRExMDlUoFALC2tkbv3r3h7e3Ntx5eQkFBAQBI9v1tqltiY2NL/Xy7urqiZ8+eIieTJv58vxwTExMkJCSgZcuW0NfXh0qlqrO/X1iEJOT8+fNQKpVo0KAB3N3dtTeOzczMRFRUFPLz83H8+HH06NFD5KS1X2RkJIKDgxETEwO1Wg0AMDMzg6urKwICAuDu7i5yQum4evUqNm3aVOYvb39/fzg5OYmcUBru3buHsWPH4tdff4W9vb3Oz3daWhr69OmD//3vf7C0tBQ5ae3Hn+9XN3jwYGRmZsLZ2Rm7d+/GuHHjUL9+/TLn7ty5s4bTVS0WIQnp1asXunTpgpCQEOjp6emMCYKAGTNmICEhATExMSIllIbdu3fD19cX77zzDpRKpc4vnB9//BHffvstduzYgUmTJomctPY7duwYRo8eje7du5c6lpGRkYiLi8P3338PpVIpctLa75133kF6ejp27dqFdu3a6YwlJSVh6tSpsLW1xYEDB0RKKA38+a4amZmZCA4ORnJyMg4ePAilUlnuWbXvvvuuhtNVMYEkw8jISLh27Vq549euXROMjIxqMJE0tWnTRti0aVO545s3bxZat25dg4mkq3PnzsKKFSvKHV+5cqXQqVOnGkwkXSYmJsJvv/1W7viFCxcEExOTGkwkTfz5rnotWrQQHjx4IHaMasOdpSXE2toasbGx5Y7HxsZq//qh8qWlpT331PigQYNw9+7dGkwkXTdu3MDEiRPLHff09MTvv/9eg4mky9DQUPs2TlkePXrEdS4VwJ/vqpeSkoLGjRuLHaPacGdpCZk/fz6mT5+OuLg4DBo0qNQaoW3btuHTTz8VOWXt9/rrr2PHjh1Yt25dmeM7d+7kupYKatGiBcLDw0u9lfNUeHg4HBwcajiVNI0bNw5eXl4IDg7GoEGDYGZmBgBQq9WIiopCQEAAPD09RU5Z+/Hnu3pERUUhKioK9+7dg0aj0RmT+hohFiEJ8fPzQ5MmTRAcHIwtW7agpKQEAKCvrw9nZ2eEhobivffeEzll7ffZZ59hxIgRiIiIKHPR+a1btxAeHi5ySmkICgrChAkTcPLkyTKPZUREBMLCwkROKQ2ff/45NBoNxo8fj+LiYhgYGAAACgsLUa9ePfj4+PAPnQrgz3fVW716NYKCgtCjRw/Y2NiUWqMqdVwsLVFFRUV48OABAKBJkyaS3chKLKmpqdi6dSvOnj1b6kqnGTNmoEWLFuIGlJAzZ85gw4YNZV41NmfOHLi6uoqcUFrUajXi4uJ0jqWzs7P2DBG9GH++q5aNjQ3WrVtXZxeYswgRERFRuRo3bozY2Ng6u5s5F0vXIVu2bEFQUJDYMYioGly4cAGnT58WOwbJkK+vb51+i5tnhOqQQYMGISUlBbdu3RI7iqR5eXnhzp07iI6OFjuK5C1duhQqlUryiylrgw4dOuDGjRvatYH0cvjzXXlz5szBnj170LlzZ3Tu3LnUUozPP/9cpGRVg4ul65CoqCixI9QJzZo1e+5NRKni/vjjD9y5c0fsGHVCVFQUioqKxI4hefz5rryEhAR07doVAHDlyhWdsbqwcJpnhIiIiEi2eEZIYgoLC3Ho0KEyb7o6atQo7SW3RCRNKpUK586d0/n5dnFxgbW1tcjJiOomnhGSkJs3b0KpVCI9PR0uLi46+2OcO3cOzZs3x7Fjx9C6dWuRk9Z+vFFo9cjLy8P+/ftx8+ZN2NjYwNPTs07vSFuV8vLy8I9//APffPMN9PT0YGFhAQDIysqCIAjw9PTEl19+iQYNGoictPbLyMhAVFQULCws4O7urvMHYl5eHj777DMEBgaKmLD2GzNmDEJDQ2FmZoYxY8Y8d+7BgwdrKFX1YBGSkMGDB8PY2Bh79uwptaeIWq3G5MmT8fjxYxw/flykhNLAG4VWHScnJ/zyyy+wsLDAnTt34ObmhocPH6Jt27ZITk5GvXr1cPbsWTg6Ooodtdbz9fXF6dOnsXHjRri7u0NfXx8AUFJSgqioKMyaNQtubm7Ytm2byElrt/Pnz2PIkCHQaDQoKipCs2bNcOjQIbz++usA/vo5t7W15aLzF5gyZQo2bNgAU1NTTJky5blzd+3aVUOpqgeLkIQ0aNAAsbGx6NixY5njly9fhouLC/Lz82s4mbR06dIFo0aNKnergVWrVuHgwYNISEio4WTSo1AooFKpYGlpiffffx8pKSn44YcfYG5ujtzcXLz99tto2rRpnb70tqo0atQI4eHh6N27d5njv/76K0aMGIGHDx/WcDJpGTx4MOzs7LB9+3bk5eVh0aJF2L9/PyIjI9GtWzcWISqFS+clpGHDhkhNTS13PDU1FQ0bNqyxPFLFG4VWj5iYGKxatQrm5uYAABMTE6xevRq//PKLyMmkQaPRPHeNn4GBQal7PFFpcXFxWLx4MRQKBUxNTbFlyxbMnz8fgwYNwvnz58WOR7UQi5CE+Pr6YvLkyQgODkZCQgIyMzORmZmJhIQEBAcHw9vbG9OnTxc7Zq339Eah5eGNQivn6eWzT548gY2Njc5Ys2bNcP/+fTFiSc6IESMwffp0XLx4sdTYxYsXMXPmTIwcOVKEZNLz5MkTnY8XL16MpUuXYsiQIThz5oxIqai24lVjEhIUFARjY2N88skn+PDDD7W/gARBgLW1NRYtWoSFCxeKnLL2441Cq9agQYNQr149qNVqJCUl6bx1e/v2bS6WrqBNmzZhwoQJcHZ2RqNGjWBpaQkAuHfvHrKzs6FUKrFp0yaRU9Z+HTt2xJkzZ9C5c2ed5+fPnw+NRgNPT0+RklFtxTVCEpWSkqJztRMXo1YObxRaNVavXq3zca9evXQWmS9YsAB3797F3r17azqaZF27dq3Mm4W2b99e5GTSsH37dpw6dQr/+c9/yhz/+OOPERISgpSUlBpORrUVixARERHJFtcISVh6ejpWrlyJiRMnYv78+bh+/brYkSQtNDQUOTk5YseoM/g31su5e/cucnNzSz1fVFTEm65SrbNnzx4kJyeLHeOVsAhJSIMGDbQLT69evQonJyeEhYWhqKgI4eHhcHZ25iXfr2D69OlIT08XO4akFBQUYP78+XBzc8PHH38MAPjoo49gYmICU1NTTJgwAWq1WuSU0pCRkYGePXvCwcEBDRs2xOTJk3UKUVZWFgYOHChiwrrh2rVraNmypdgx6gxvb284OTlh1qxZYkd5aSxCEvLkyRPtX9lLly6Fm5sbrl27hv379yMxMRFvvfUWli1bJnLK2s/CwqLMR3FxMVxdXbUf04stWbIEe/fuRc+ePbF79274+flh27Zt+PLLL7Ft2zacP38ey5cvFzumJDy95PvcuXOIiIjA1atXMXDgQJ19g3iW7dUVFhbi9u3bYseoMzQaDa5fv44OHTqIHeWlcY2QhDy7eZ29vT2+/vpr9OvXTzt+8eJFeHh48KzGC5iamqJ///549913tc8JggBfX18EBQWhWbNmAAAvLy+xIkqGvb09du7cCXd3d9y6dQtt2rTBwYMHMWrUKABAZGQkpk2b9tz9r+gvzZo1w3fffYeePXsC+Ots27vvvos7d+5o7zzPjQBfLCAg4Lnj9+/fR1hYGI8jafHyeQnR09PTXjKvUCi0G9c91bBhQ+46WwEXL17EhAkTEB0djc2bN8PExAQAMG3aNIwePZr3GauEBw8eoG3btgCAli1bQl9fX+ded23atOE+QhWUk5ODRo0aaT82NDTEwYMH8e6772LgwIH473//K2I66Vi/fj26du1a6jZET5W1/oqer67fCJhFSEIEQUDbtm2hp6eH3NxcJCQk6OyVcfPmzTrzD7M6tW7dGmfOnMGyZcvQtWtX7N69G3369BE7liTZ29sjJiYG9vb2OH/+PPT09BAbG6u9r9O5c+e0Z9jo+Vq2bImEhAS0adNG+1y9evVw4MABvPvuuxgxYoSI6aSjdevWmDdvHt5///0yx+Pj4+Hs7FzDqaRJLjcCZhGSkL/f2O7vd5k/e/Ys3n777ZqMJFn16tXDxx9/DKVSiQkTJmDixInas21UcTNmzIC3tze2b9+OuLg4fPrpp1i6dCmuX78OhUKBrVu34sMPPxQ7piQMGzYMX331FcaOHavz/NMyNHbsWNy9e1ekdNLRo0cPxMXFlVuE9PT0uNaqgubMmYPY2FiEh4eXeyPgOXPmSP5GwFwjRLL3559/Ytq0aThx4gTOnj2Ldu3aiR1JUsLCwhATE4PevXvD09MTJ0+eRGBgIPLz8zFy5EisWLECCgWvy3iR4uJi5Ofnl/uWTnFxMf744w/e/uUFVCoVCgoKeJyqgFxuBMwiJHEFBQW4e/cumjdvDkNDQ7HjEBFRHWFubo6oqCj06NGjzPHz58/D3d1d8vuv8c80CQkNDUVMTAyAvy6l9/HxgbGxMdq2bQsTExPMmDEDBQUFIqes/eLi4sSOQFRpd+7cwdSpU8WOIUm///47oqKicPPmTbGjSIpcbgTMIiQhQUFB2rcYVqxYgejoaBw4cACJiYn49ttvceLECaxYsULklLXfG2+8gdatW+Nf//oXtxp4RaampvDx8eEdvWtAVlYWdu/eLXaMWm/t2rWIiooCADx8+BDu7u5o164dBg8ejHbt2mHYsGHIzs4WN6REbNq0CVZWVnB2dkbjxo3RoUMHdOjQAY0bN0aPHj1gaWlZJ24EzLfGJMTIyAg3btyAvb092rVrh/Xr12Po0KHa8dOnT2PSpEncLOwFFAoFfH198f333yMrKwtKpRK+vr4YOXKkdjEgVYxCoYCTkxOuXr2Kdu3awdfXF5MnT0bTpk3FjiY5hw8ffu74rVu38OGHH3L/mxews7PD4cOH0a1bN0ybNg1xcXHYsWMHOnTogKSkJMyYMQOvv/46tm/fLnZUybh+/XqZN6iuMzcCFkgyHBwchOjoaEEQBKFZs2bC+fPndcavXr0qGBsbixFNUvT09ITMzEyhqKhI+Pbbb4Xhw4cL+vr6gpWVlbBw4UIhKSlJ7IiS8fRYxsfHC/7+/oKFhYVgYGAgjBkzRvjhhx8EjUYjdkTJ0NPTExQKhaCnp1fuQ6FQiB2z1jM0NBRSU1MFQRCEFi1aCKdOndIZv3DhgmBjYyNGNKql+NaYhEycOBHLli1DdnY2Jk2ahKCgIO3mYPn5+Vi1ahX3w6mEevXqYezYsQgPD8ft27fh5+eHb7/9Fh06dICbm5vY8SSlS5cu2LhxI9LT07U3rx0xYgTs7e0RGBgodjxJsLGxwcGDB6HRaMp8/Pbbb2JHlAQHBwdcuXIFwF+Xyterp7tLjL6+PvLy8sSIVudkZGQgLS1N7BivjEVIQlauXImmTZuiZcuWiIuLQ2RkJKysrNC2bVtYWlri7Nmz2Lhxo9gxa72y9gtq1qwZVqxYgeTkZPz444+ws7MTIZn0/P1YGhoawtPTEz/99BOSk5Ph7e2N0NBQccJJjLOz83MX8nP/m4qZNm0aFixYgJs3b8Lf3x/z58/X3h09JSUF8+bNw5AhQ0ROWTe8+eabcHR0FDvGK+MaIQmKiIjAkSNHcOvWLWg0GtjY2KBPnz6YMGECjI2NxY5X6z17zzZ6NRU5loIgcLPKCvj555+Rl5ens+7vWXl5ebhw4QL69+9fw8mkZ/bs2QgJCUGrVq2QmpqKwsJC1KtXD8XFxejevTuOHDnCXfirwPnz55Gfny/5f5MsQiQ7p06dQp8+fUqdMqfKW716NRYsWCD5Lfap7rl27RqOHj1a6g9Gd3d3FnPSwSJERERE5SouLkZiYqLOVWNOTk547bXXRE5WNfgnMdHfPHz4EEeOHMHkyZPFjiI5xcXFOHHiBNLS0uDg4ICBAwdyS4IqkpycjGnTpiE6OlrsKJKQl5eHuLg4ZGRkQKFQoGXLlujevTvPBlWCRqNBYGAgNm/eXGr3aHNzc/j7+2P16tXSv4WOeBesEdVO8fHxvEy5gvz9/YUjR44IgiAId+7cEdq3b6/dikBfX1/o1KmTcPfuXZFT1g38d1kxJSUlwoIFC4T69esLCoVCZ0sCBwcH4fDhw2JHlIwFCxYITZs2FUJCQoSUlBQhPz9fyM/PF1JSUoQvv/xSsLS0FBYuXCh2zFfGt8ZIdtRq9XPHExIS0L9/f25cVwHW1tb46aef0LFjR4wbNw5ZWVnYu3cvmjRpgqysLHh5ecHIyAgHDhwQO2qtt2HDhueO//HHH/j000/57/IFFi9ejMOHD2PdunUwMjLCmjVr4OHhgbfeegthYWFYt24dDh8+zCvHKsDa2hq7d++GUqksc/z48eOYPHkyMjMzazhZ1WIRItlRKBTPPT0u/P+rnPgL58Xq16+Pq1evwtHREXZ2dvjf//6Hnj17asevXLmCgQMH4v79+yKmlAaFQgEbGxsYGBiUOV5YWAiVSsV/ly9ga2uLffv2oV+/fgD+KpDt27fHgwcPYGhoiDVr1uDYsWO8LUwFGBsb4+zZs+jUqVOZ4wkJCejdu7d2Pzup4hqhOiYoKAgDBw7U/k+ASjM1NcWyZcvg4uJS5vjvv/+Of/zjHzWcSpratm2L2NhYODo6wtTUtNTZtkePHkGj0YiUTlocHBzw8ccf47333itzPD4+Hs7OzjWcSnpyc3PRrFkz7cc2NjZ48uQJHj58CGtra4wdOxb//ve/RUwoHQMGDMD8+fPx9ddfo0mTJjpjDx48wKJFizBgwABxwlUhFqE6ZteuXfj3v/+NQYMG4ciRI2LHqZW6d+8OAOXufdGwYUNuXFdB8+bNw/z582FlZYUlS5Zg9uzZ2Lhxo/a+TnPmzMGYMWPEjikJTzdULK8IcUPFiunUqRP27t2LZcuWAQD2798PExMT7b5BGo0GhoaGYkaUjJCQEAwfPhw2Njbo1KkTrKysAACZmZm4fPkynJyccPToUZFTvjoWoTomJSUFjx8/xokTJ8SOUmtNmDABjx8/Lnfc2toaK1eurMFE0uXt7Y2srCx4eHhAEASUlJTorL146623EBwcLGJC6QgKCkJ+fn65405OTkhJSanBRNIUFBQEDw8PHD58GEZGRjhz5gw++eQT7XhERAS6desmYkLpsLOzw6VLl3D8+HGcPXtWe/l8z5498a9//QtDhgyR/hVj4BohIqoC2dnZiIyMLLV5XZs2bcSORjJ06dIl7N+/HwUFBVAqlRg8eLDYkagWYxGSoNjYWMTExOhsbuXq6qqzSJWIiKgqaDSaMs/8aDQa3L17F/b29iKkqjrSP6clI/fu3UO/fv3Qq1cvBAcHIzo6GtHR0QgODkavXr3Qr18/3Lt3T+yYRPQSTE1N4ePjw6uZqlleXh5Onz4tdgxJUKvVeO+992BsbAwrKysEBgbqXLV4//79OnHTVRYhCfnggw9QUlKCa9euITU1FefOncO5c+eQmpqKa9euQaPRwM/PT+yYRPQS8vLycO7cOfTt2xcdOnTAZ599xm0HqsHNmzcxcOBAsWNIwooVK3Dp0iX85z//wT//+U/s2bMHo0aNQmFhoXZOXXhTiW+NSYipqSlOnz5d7kK/uLg4DBgwAI8eParhZET0qhQKBVQqFTIyMrB9+3aEhYUhNzcXI0aMgK+vL4YOHcrbQ1SBS5cuoXv37tyPqQIcHBywe/du7SXyDx48gIeHBxo2bIjDhw8jOzsbtra2kj+WPCMkIYaGhs/dFfnRo0e8LJRI4rp06YKNGzciPT0doaGhyMnJwYgRI2Bvb4/AwECx49V6FhYWz324ubmJHVEy7t+/DwcHB+3HTZo0wU8//YRHjx5h+PDhz73KUUp4RkhC/Pz8EB4ejuDgYAwaNAhmZmYA/nofNyoqCgEBARgxYgQ2btwoclIiqix9fX1kZGTA0tKy1Fhqaip27NiB3bt3Iy0tTYR00mFsbIyZM2eWuxvy7du3sXr1asmfxagJ7du3x+eff47hw4frPJ+bm4shQ4YgPz8fly9flvyxZBGSkIKCAsydOxc7d+5EcXGxdiv+wsJC1KtXDz4+PggODuZZoSqgUCgwYMAAfPLJJ9zN9xW9+eabGDhwID788EM0aNBA7Di11tO3xsoqQk89vf0Lla9Pnz547733MGfOnDLH+dZYxc2ePRsZGRll3ivw0aNHGDx4MM6fPy/5Y8kNFSXE0NAQW7duxccff4y4uDidy+ednZ21Z4jo1e3cuROpqanw8/PD2bNnxY4jafb29oiKisK2bdt4NuM5Vq5cCRMTk+fOYQl6MQ8PD2RnZ5c7bmFhgcmTJ9dcIAlbvXo10tPTyxwzNTVFZGQkfvvttxpOVfV4RoiIaoRarWZZJ6Jah4ul65ALFy5wf4yXUFBQgIKCArFj1HksQUR1S2ZmJoKCgsSO8cpYhOqQSZMmcX+MCoqMjMTw4cPRqFEjNGjQAA0aNECjRo0wfPhw/PTTT2LHk5QHDx5g3bp1ePvtt+Hq6gpXV1e8/fbb+OSTT7gPTiUUFRVh4cKFaN26NXr27ImdO3fqjGdmZkJfX1+kdESlqVQqrF69WuwYr4xvjdUh6enpKCoq0rnckUrbvXs3fH198c4770CpVOrcUfnHH3/Et99+ix07dmDSpEkiJ639zp8/D6VSiQYNGsDd3V3nWEZFRSE/Px/Hjx9Hjx49RE5a+61atQohISGYP38+srOzsWnTJowbNw5ffvklgL+OqY2NDTQajchJSS4SEhKeO379+nV4enpKfrE0ixDJTtu2bTFnzpxyd+HesmULgoOD8fvvv9dwMunp1asXunTpgpCQkFILeQVBwIwZM5CQkICYmBiREkpHmzZtEBwcjBEjRgD4awfkYcOGoW/fvti5cyfu3btXJzavI+lQKBTQ09Mrc/fop8/r6elJ/t8ki5AE5eXlIS4uDhkZGVAoFGjZsiW6d+/OK0oqyMjICJcuXUK7du3KHE9KSkLXrl3x+PHjGk4mPfXr18fFixfRvn37MsevX7+Obt268VhWQIMGDXD16lW0aNFC+9wff/yBN998E2+88QbWrVsHOzs7yf/SIelo0qQJ1q1bh0GDBpU5npiYiJEjR0r+3yQvn5cQjUaDxYsXY/PmzXjy5AmA/7vPi729PTZu3IiRI0eKGVESXn/9dezYsQPr1q0rc3znzp1wcnKq4VTSZG1tjdjY2HKLUGxsrPbtMno+a2trJCcn6xShZs2a4cSJExg4cCC8vb1Fy0by5OzsjPT09HKXW2RnZ9eJe42xCEnI0qVLcfToUezbtw9GRkZYs2YNPDw88NZbbyEsLAzvvvsuDh8+jCFDhogdtVb77LPPMGLECERERJS5ruXWrVsIDw8XOaU0zJ8/H9OnT0dcXBwGDRpU6lhu27YNn376qcgppeHNN99EWFhYqb++bW1tER0drb3fE706R0dHvPnmm1izZg1sbW3FjlNrzZgxA3l5eeWO29vbY9euXTWYqHrwrTEJsbW1xb59+9CvXz8Af502b9++PR48eABDQ0OsWbMGx44dw5kzZ0ROWvulpqZi69atOHv2rM7GlK6urpgxY4bOX+X0fPv27UNwcDDi4uK0p8j19fXh7OyMgIAAvPfeeyInlIbbt2/j+vXrUCqVZY6np6cjMjISXl5eNZys7lm1ahVSU1Nx6tQppKSkiB2HRMYiJCFmZmaIj49Hy5YtAfz1VpmhoSHu3LkDa2trXL16FW+88cZzGzxRdSkqKsKDBw8A/LW24LXXXhM5ERHRi3EfIQnp1KkT9u7dq/14//79MDExgbW1NYD/K0ZEYnjttddgY2MDGxsbliAiGbhz5w6mTp0qdoxXxiIkIUFBQVizZg1cXFzQv39/TJo0CStXrtSOR0REoFu3biImrBu8vLzw5ptvih2jTtiyZUud2HmWpOXq1av44IMP0K1bN20579atGz744ANcvXpV7Hh1RlZWFnbv3i12jFfGt8Yk5tKlS9i/fz8KCgqgVCoxePBgsSPVOUuXLkVGRkadWAQotkGDBiElJQW3bt0SOwrJxLFjxzB69Gh079691IapkZGRiIuLw/fff1/uWiz6P4cPH37u+K1bt/Dhhx9K/vJ5FiEiIqozunTpglGjRpV7JnLVqlU4ePDgC3dNpudvqPhUXdhQkW+NSURCQkKlttZPTExEcXFxNSYiIqp9bty4gYkTJ5Y77unpyV3jK8jGxgYHDx6ERqMp8/Hbb7+JHbFKsAhJRLdu3fDnn39WeL6rqyvS0tKqMZG0cQ1B1SksLMT+/fsxb948eHp6wtPTE/PmzcOBAwdQWFgodrw6xdHRET4+PkhPTxc7Sq3VokWL5+4DFh4ezvsxVpCzszPi4uLKHX/R2SKp4IaKEiEIAlasWIEGDRpUaD5/AZXv2TUEo0aNKrWGoHv37lxDUEE3b96EUqlEeno6XFxctMfy4sWLCAkJQfPmzXHs2DG0bt1a5KR1g5eXF1JTU9GnTx/uf1OOoKAgTJgwASdPnixzw9SIiAiEhYWJnFIaFixY8NztWFq3bo0TJ07UYKLqwTVCEjFgwIBK30ssLCwMNjY21ZRIuriGoOoMHjwYxsbG2LNnD8zMzHTG1Go1Jk+ejMePH+P48eMiJSQ5OnPmDDZs2ICYmJhSG6bOmTMHrq6uIiek2oRFiGSnfv36iI+P501Xq0CDBg0QGxuLjh07ljl++fJluLi4ID8/v4aTERFVDNcIkexwDUHVadiwIVJTU8sdT01NRcOGDWssj9Rx7RrVJp06dcKaNWtw584dsaNUK54RItk5cOAAJkyYgGHDhj13DcHYsWNFTlr7BQYGYtOmTVixYkWZN1396KOPMGvWLKxatUrcoBLA/W9qxtKlS6FSqbBz506xo9R6CoUCFhYWyM7Ohru7O6ZNm4ZRo0ahXr26tbyYRYhkiWsIqs7HH3+M9evXQ6VSadexCYIAa2trzJ07FwsXLhQ5oTRw7VrN8PLywp07dxAdHS12lFpPoVDg7t27iI2Nxc6dO3Hs2DE0atQIkydPho+PDzp06CB2xCrBIkREVSIlJUWnVDo6OoqcSFq4do1qG4VCAZVKBUtLSwBARkYGQkNDsWvXLiQnJ8PFxQW+vr6Sv98Y1wgRUZVwdHSEq6ur9mwaN/SsHK5do9rm71cq29jYYMmSJbhx4waioqLQqlUrzJ49W6R0VYdnhEh2YmNj4ezsDH19fQDA0aNH8cknn+DmzZuwsbHB7NmzMXnyZJFTSpuBgQEuXbpUZ06d1wSuXaseeXl52L9/v/bn29PTE40bNxY7liT8/YxQWdRqdamtM6SGRYhkR19fHxkZGbC0tMSRI0cwevRovP/++3BxccHFixcRGhqK/fv34+233xY7aq03ZsyYMp///vvv8eabb8LU1BQAcPDgwZqMJVlcu/bqnJyc8Msvv8DCwgJ37tyBm5sbHj58iLZt2yI5ORn16tXD2bNn+dZtBUyZMgUbNmzQ/hzXVSxCJDvP/pXTr18/9O3bF2vXrtWO/+tf/8KRI0cQExMjYkppUCgUcHNzK/VLZc+ePXjrrbe0l87v2rVLhHQkR8/+fL///vtISUnBDz/8AHNzc+Tm5uLtt99G06ZNubs0abEIkew8+z9KKysr/PDDD3B2dtaOJyUloVevXnj48KGIKaXhm2++wYIFCxAUFIQpU6Zon3/ttddw6dIlODk5iZiO5OjZn+9WrVohJCQEgwcP1o6fOXMG48eP570YSYuLpUmWrl69ioSEBNSvXx8ajabUOBf6Vsz48ePx888/Y8eOHRg7dizLYzVaunSp5K/OqSlPF/k+efKk1G2GmjVrhvv374sRS5K2bNkCd3d3vPfee4iKitIZe/DgAVq2bClSsqrDIkSyNGjQIHTt2hVpaWn49ddfdcYuXrwIe3t7kZJJT4sWLXD69Gl07NgRXbp0wfHjxyt9Xzx6sT/++OO5u3jT/xk0aBC6d+8OtVqNpKQknbHbt29zsXQFbdiwAQsWLED79u1haGiI4cOH6ywjKCkpwe3bt0VMWDXq1vaQRBXw97t2m5iY6HxcWFiIRYsW1WQkyVMoFFi9ejUGDx6MyZMno6SkROxIdc7u3bvFjiAJK1eu1Pn47z/fR44cQb9+/WoykmR9+eWX2LZtGyZMmAAAmDlzJkaPHo3Hjx+Xu/GnFHGNEBFVqdzcXCQnJ6NDhw4wMDAQOw4RvaQGDRrg6tWraNGihfa5K1euwN3dHVOmTMHcuXNha2sr+T98eEaIZK+4uBgnTpxAWloaHBwcMHDgQO0eQ1R5JiYm6NKli9gxJOnx48eIi4uDhYVFqYXmT548wf79+7nH1SsQBIFv21ZCkyZNcOfOHZ0i1LFjR0RHR+PNN99Eenq6eOGqENcIkezMmjULR48eBQDcvXsXnTp1wrBhw7Bs2TIMHToU3bp1wx9//CFySmkwNTWFj48Pzpw5I3YUybtx4wY6dOgANzc3dOrUCf3790dGRoZ2PCcnR+fKPCpbQUEB5s+fDzc3N3z88ccAgI8++ggmJiYwNTXFhAkToFarRU4pDX379i1zDzAnJydERUXh2LFjIqSqeixCJDsHDhzQ/oXz4Ycfonnz5lCpVFCpVLh37x4cHBwwd+5cUTNKRV5eHs6dO4e+ffuiQ4cO+Oyzz3hFzktatGgROnbsiHv37iEpKQmmpqbo06cPL/OupCVLlmDv3r3o2bMndu/eDT8/P2zbtk273uX8+fNYvny52DElYfHixejcuXOZY6+//jqio6MRGBhYw6mqgUAkM0ZGRsKtW7cEQRCE5s2bC+fOndMZv3z5stCkSRMxokmOnp6ekJmZKcTHxwv+/v6ChYWFYGBgIIwZM0b44YcfBI1GI3ZEybC0tBQSEhK0H2s0GmHGjBmCvb29kJycLKhUKkGhUIiYUBrs7OyEyMhIQRAEITk5WVAoFMKhQ4e04z/++KPg4OAgUjqqjXhGiGSnbdu2iI2NBfDXWzt/P03+6NGjMvcWovJ16dIFGzduRHp6OkJDQ5GTk4MRI0bA3t6+bvzFWAMeP36MevX+b9mmnp4etm7dipEjR6J///64ceOGiOmk48GDB2jbti0AoGXLltDX10fr1q21423atOFZywpISEio1P8HExMTJbv/GosQyc68efMwf/58nDx5EkuWLMHs2bMRFRWF9PR0nDhxAv/4xz/KvYcW6fr7wlNDQ0N4enrip59+QnJyMry9vREaGipOOIlp3749Lly4UOr5TZs2YdSoUXjrrbdESCU99vb22tvjnD9/Hnp6eto/fADg3LlzaNasmVjxJKNbt274888/Kzzf1dVVsm/j8qoxkh1vb29kZWXBw8MDgiCgpKQEQ4YM0Y6/9dZbCA4OFjGhdAjP2X2jRYsWWLNmTZ3ab6Q6vf3229i7dy8mTZpUamzTpk3QaDQICQkRIZm0zJgxA97e3ti+fTvi4uLw6aefYunSpbh+/ToUCgW2bt2KDz/8UOyYtZ4gCFixYgUaNGhQofmFhYXVnKj6cB8hkq3s7GxERkbi1q1b0Gg0sLGxQZ8+fdCmTRuxo0nG6tWrsWDBggr/z5KoJoSFhSEmJga9e/eGp6cnTp48icDAQOTn52PkyJFYsWIFFAq+IfI8AwYMqPRWA2FhYaVuaSIFLEJEREQkW6zEJCtyWgBYGxQXF0t23UBtk5ycjDfffFPsGER1DosQyYqcFgDWBomJiXB0dBQ7Rp2Qm5uLU6dOiR2j1uMmn1RZXCxNsiKnBYAkLRs2bHjuOHc7r5inm3zu2rUL7dq1g6+vLyZPnoymTZuKHY1qKa4RIlmR0wLAmtC9e/fnjj9+/Bg3btyQ/E0Za4JCoYCNjU25N6otLCyESqXisXwBhUIBlUqFjIwMbN++HWFhYcjNzcWIESPg6+uLoUOH8n5jpINFiIhempGREcaPH1/u218ZGRnYtm0bf3lXgKOjIz7++GO89957ZY7Hx8fD2dmZx/IFnhYhS0tLAH/de+zgwYPYsWMHTpw4AVtbW0yZMoXbOpAWixARvbQePXrAx8cHM2fOLHOcv7wr7p133kGrVq20Nwr9u0uXLqFbt27c9fwF9PX1kZGRoS1Cz0pNTcWOHTuwe/durv0jLRYhInppc+bMgZ6eHr744osyx5OTk+Hr64sTJ07UbDAJunr1KvLz89GjR48yx4uKipCeng4HB4caTiYtfz8jVBZBEPj2GGmxCBERUZ3BTT6psliEiIhqqYKCAty9exfNmzeHoaGh2HGI6iTuI0REL4WbU1at0NBQ7c1Cnzx5Ah8fHxgbG6Nt27YwMTHBjBkzUFBQIHJK6SkuLkZkZCR27NiBn376ievVqBQWISJ6KdycsmoFBQVp73+1YsUKREdH48CBA0hMTMS3336LEydOYMWKFSKnrP1mzZqFo0ePAgDu3r2LTp06YdiwYVi2bBmGDh2Kbt26cU8m0sG3xojopSgUCkyfPr3CazG2bNmCq1evomXLltWcTJqMjIxw48YN2Nvbo127dli/fj2GDh2qHT99+jQmTZqE27dvi5iy9rO2tsZPP/2Ejh07Yty4ccjKysLevXvRpEkTZGVlwcvLC0ZGRjhw4IDYUamW4M7SRPRS3NzckJSUVOH5rq6uqF+/fjUmkjZra2skJyfD3t4eeXl5aNKkic5406ZNK3UGTq5ycnJgbGwMADhz5gz+97//aY+lhYUF1q5di4EDB4oZkWoZFiEieiknT54UO0KdMnHiRCxbtgw//PADJk2ahKCgIISFhcHExAT5+flYtWoV+vTpI3bMWq9t27aIjY2Fo6MjTE1NoVardcYfPXrEvZhIB4sQEVEtsHLlSly5cgUtW7ZEjx498PPPP8PKygrNmjVDeno6GjdujMjISLFj1nrz5s3D/PnzYWVlhSVLlmD27NnYuHEjOnTogKSkJMyZMwdjxowROybVIlwjRERUi0RERODIkSO4desWNBoNbGxs0KdPH0yYMEH7lg893+eff44VK1ZAEASUlJToXK341ltv4T//+Q9MTExETEi1CYsQERHVOdnZ2YiMjCxVKNu0aSN2NKplWISIiGqZtLQ0ZGRkQKFQoGXLlmjcuLHYkYjqLO4jRERUS2zZsgUODg5wdHRE79690atXL1haWqJv376Ii4sTO16tx00+6WWwCBER1QKffvop/vnPf2LBggX48ssv0a5dO6xatQrh4eFo2bIl3NzccOHCBbFj1mrc5JNeBq8aIyKqBTZv3ozt27dj2LBhAP7ap6l3795QqVQYOnQoGjVqhKVLl+LHH38UOWntJQgCVqxYUeFNPgsLC6s5EUkB1wgREdUCxsbGSExMRIsWLQD89UvdwMAAaWlpsLGxwaVLl9C3b188evRI3KC12IABA6Cnp1epzwkLC4ONjU01JSIp4BkhIqJaoG3btoiMjMS0adMAACdOnICBgQGsra0B/HULjsr+kpcbbvJJL4NFiIioFliyZAnef/99/PTTTzAyMsLBgwcxe/Zsbfk5efIkOnbsKHJKorqHb40REdUSx44dw3//+18UFBRAqVRqzw4B0C4C5qX0RFWLRYiIiIhki5fPExFJQHFxMS/1JqoGLEJERBKQmJgIR0dHsWMQ1TksQkRERCRbvGqMiKgW6N69+3PHHz9+XENJiOSFRYiIqBa4evUqxo8fX+7bXxkZGbhx40YNpyKq+1iEiIhqgY4dO8LFxQUzZ84sczw+Ph7btm2r4VREdR/XCBER1QJ9+vRBUlJSueOmpqZwc3OrwURE8sB9hIiIiEi2eEaIiIiIZItFiIhIZAkJCdBoNBWen5iYiOLi4mpMRCQffGuMiEhk+vr6UKlUaNq0aYXmm5mZIT4+Hi1btqzmZER1H68aIyISmSAIWLFiBRo0aFCh+YWFhdWciEg+WISIiETm5ub23CvG/s7V1RX169evxkRE8sG3xoiIiEi2uFiaiIiIZItFiIiIiGSLRYiIiIhki0WIiIiIZItFiIiIiGSLRYiIapUWLVrgiy++KHc8NTUVenp6iI+Pr9DreXt7Y/To0VWSjYjqHhYhIqoyI0eOxNChQ8sc+/nnn6Gnp4eEhIRX+hp2dnbIyMhAx44dX+l1KmvVqlXQ09N77oOIpIdFiIiqjI+PDyIjI3H37t1SY7t27UKPHj3QuXPnV/oa+vr6sLa2Rr16Nbsf7Pz585GRkaF9NG/eHEFBQTrPEZH0sAgRUZUZMWIEmjZtitDQUJ3nc3NzceDAAfj4+OCXX35Bv379UL9+fdjZ2WH27NnIy8vTmZ+fn4+pU6fC1NQU9vb2+Oqrr7RjZb01lpiYiBEjRsDMzAympqbo168fkpOTy8yo0Wiwdu1aODo6on79+ujSpQu+/fbbF35vJiYmsLa21j709fVhamoKa2trfPXVV3B3dy/1OV27dsWKFSsA/N9bdKtXr0bTpk1hZmaGGTNm6Nwu42WzEdHLYxEioipTr149TJ48GaGhoXh20/oDBw6gpKQErq6uGDp0KMaOHYuEhATs27cPv/zyC/z9/XVe57PPPkOPHj1w8eJFfPDBB5g5c2a5t6D4448/4ObmBkNDQ0RHRyMuLg5Tp04t9+7sa9euxZ49exASEoLExETMmzcP77//Pk6dOvXS3/fUqVNx7do1nD9/XvvcxYsXkZCQgClTpmifi4qKwrVr13Dy5Ens3bsXBw8exOrVq6s1GxG9gEBEVIWuXbsmABBOnDihfa5fv37C+++/L/j4+AjTp0/Xmf/zzz8LCoVCePz4sSAIguDg4CC8//772nGNRiNYWloKW7duFQRBEFJSUgQAwsWLFwVBEIQlS5YIjo6OQmFhYZl5vLy8hFGjRgmCIAhPnjwRGjRoIJw5c0Znjo+Pj+Dp6Vmp79PBwUEIDg7Wfjxs2DBh5syZ2o9nzZolDBgwQCeHhYWFkJeXp31u69atgomJiVBSUlKl2Yio4nhGiIiqVPv27dG7d2/s3LkTAHDz5k38/PPP8PHxwaVLlxAaGgoTExPtQ6lUQqPRICUlRfsaz64j0tPTg7W1Ne7du1fm14uPj0e/fv3w2muvvTDbzZs3kZ+fj8GDB+tk2LNnT7lvpVXUtGnTsHfvXjx58gSFhYUICwvD1KlTdeZ06dJF5w7zrq6uyM3NxZ07d6o1GxGVj3efJ6Iq5+Pjg1mzZmHz5s3YtWsXWrVqhf79+yM3Nxf/+Mc/MHv27FKfY29vr/3vv5caPT09aDSaMr9WZe7CnpubCwAIDw9Hs2bNdMYMDQ0r/DplGTlyJAwNDfHdd9/BwMAARUVFeOedd2pFNiIqH4sQEVW59957D3PmzEFYWBj27NmDmTNnQk9PD927d8fVq1fRunXrKvtanTt3xu7du1FUVPTCs0JOTk4wNDREWloa+vfvX2UZgL/WR3l5eWHXrl0wMDDA+PHjS5W0S5cu4fHjx9rnz549CxMTE9jZ2cHCwqLashFR+ViEiKjKmZiYYNy4cViyZAnUajW8vb0BAIsWLUKvXr3g7+8PX19fGBsb4+rVq4iMjMSmTZte6mv5+/tj48aNGD9+PJYsWQJzc3OcPXsWPXv2RLt27XTmmpqaYv78+Zg3bx40Gg369u2LnJwc/PrrrzAzM4OXl9crfd++vr7o0KEDAODXX38tNV5YWAgfHx8sX74cqampWLlyJfz9/aFQKKo9GxGVjUWIiKqFj48PduzYgeHDh8PW1hbAX2dvTp06hWXLlqFfv34QBAGtWrXCuHHjXvrrNG7cGNHR0ViwYAH69+8PfX19dO3aFX369Clz/po1a9C0aVOsXbsWt27dQsOGDdG9e3csXbr0pTM81aZNG/Tu3RtZWVlwcXEpNT5o0CC0adMGbm5uKCgogKenJ1atWlUj2YiobHqC8Mw1rkRE9NIEQUCbNm3wwQcfICAgQGfM29sb2dnZOHTokDjhiKhMPCNERFQF7t+/j2+++QYqlUpn7yAiqt14+TwR0f83Y8YMnUvXn33MmDHjuZ9raWmJoKAgfPXVV2jUqFENJSaiV8W3xoiI/r979+5BrVaXOWZmZgZLS8saTkRE1Y1FiIiIiGSLb40RERGRbLEIERERkWyxCBEREZFssQgRERGRbLEIERERkWyxCBEREZFssQgRERGRbP0/3soQ6MUJw78AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fe.transform(road_safety_dataset.X).value_counts().sort_values().plot(kind=\"bar\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "next: one-hot encoding and clustering" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv2", + "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.11.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/skrub/_frequency_encoder.py b/skrub/_frequency_encoder.py new file mode 100644 index 000000000..646c71921 --- /dev/null +++ b/skrub/_frequency_encoder.py @@ -0,0 +1,35 @@ +""" +Implements the Frequency Encoder, a transformer that allows +encoding a feature using it's frequency. +""" + + + +import numpy as np +import pandas as pd +from sklearn.base import BaseEstimator, TransformerMixin + + +class FrequencyEncoder(TransformerMixin, BaseEstimator): + def __init__( + self, + column, + bins + ): + + self.column = column + self.bins = bins + self.uniques_to_map = None + + + + + def fit(self, X:pd.DataFrame, y=None): + value_counts_series = X[self.column].value_counts() + self.uniques_to_map = pd.cut(value_counts_series, self.bins, right=False) + + return self + + + def transform(self, X) -> pd.DataFrame: + return X[self.column].map(self.uniques_to_map)