{ "cells": [ { "cell_type": "markdown", "id": "96263cc4-e4f1-4f42-94cb-14b2d2d35302", "metadata": {}, "source": [ "# Automatic tagging" ] }, { "cell_type": "code", "execution_count": 1, "id": "a6d0b19f-9d89-4260-8662-a0f5683d0ec2", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "from pathlib import Path\n", "from sklearn.pipeline import Pipeline\n", "from matplotlib import pyplot as plt " ] }, { "cell_type": "markdown", "id": "1585b7a5-d0b9-4781-accd-ee36dddd7bae", "metadata": {}, "source": [ "## Import des données" ] }, { "cell_type": "code", "execution_count": 2, "id": "0751d414-f28e-4e9a-9151-3a1dc1b05f3c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2020.csv'),\n", " PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2018.csv'),\n", " PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2022.csv'),\n", " PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2021.csv'),\n", " PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2023.csv'),\n", " PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2019.csv'),\n", " PosixPath('../PLESNA Compta SYSTEM/staging/CRG/2017.csv')]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "staging_path = Path(\"../PLESNA Compta SYSTEM/staging/CRG/\")\n", "assert staging_path.exists()\n", "files = list(staging_path.glob(\"*.csv\"))\n", "files" ] }, { "cell_type": "code", "execution_count": 3, "id": "f88989ca-968b-4c97-849b-ef12ab24f0ee", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
RégieImmeublePorteLotAnnéeMoisCatégorieFournisseurLibelléDébitCréditImpact
0Imi GéranceB9B0920201Loyer ChargeNaNRègl. Loyer 01/20200.0100.48100.48
1Imi GéranceS5S0520201Loyer ChargeNaNRègl. Prov. Char 01/20200.0191.00191.00
2Imi GéranceS5S0520201Loyer ChargeNaNRègl. Loyer 01/20200.0745.39745.39
3Imi GéranceS2S0220201Loyer ChargeNaNRègl. Prov. Char 01/20200.0519.00519.00
4Imi GéranceS2S0220201Loyer ChargeNaNRègl. Loyer 01 à 03/20200.03473.793473.79
\n", "
" ], "text/plain": [ " Régie Immeuble Porte Lot Année Mois Catégorie Fournisseur \\\n", "0 Imi Gérance B 9 B09 2020 1 Loyer Charge NaN \n", "1 Imi Gérance S 5 S05 2020 1 Loyer Charge NaN \n", "2 Imi Gérance S 5 S05 2020 1 Loyer Charge NaN \n", "3 Imi Gérance S 2 S02 2020 1 Loyer Charge NaN \n", "4 Imi Gérance S 2 S02 2020 1 Loyer Charge NaN \n", "\n", " Libellé Débit Crédit Impact \n", "0 Règl. Loyer 01/2020 0.0 100.48 100.48 \n", "1 Règl. Prov. Char 01/2020 0.0 191.00 191.00 \n", "2 Règl. Loyer 01/2020 0.0 745.39 745.39 \n", "3 Règl. Prov. Char 01/2020 0.0 519.00 519.00 \n", "4 Règl. Loyer 01 à 03/2020 0.0 3473.79 3473.79 " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dfs = []\n", "for file in files:\n", " dfs.append(pd.read_csv(file))\n", "df = pd.concat(dfs)\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 4, "id": "012dcdaf-83de-44e3-b480-c5498421dc8f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
RégieImmeublePorteLotAnnéeMoisCatégorieFournisseurLibelléDébitCréditImpact
0Imi GéranceB9B0920201Loyer ChargeRègl. Loyer 01/20200.0100.48100.48
1Imi GéranceS5S0520201Loyer ChargeRègl. Prov. Char 01/20200.0191.00191.00
2Imi GéranceS5S0520201Loyer ChargeRègl. Loyer 01/20200.0745.39745.39
3Imi GéranceS2S0220201Loyer ChargeRègl. Prov. Char 01/20200.0519.00519.00
4Imi GéranceS2S0220201Loyer ChargeRègl. Loyer 01 à 03/20200.03473.793473.79
\n", "
" ], "text/plain": [ " Régie Immeuble Porte Lot Année Mois Catégorie Fournisseur \\\n", "0 Imi Gérance B 9 B09 2020 1 Loyer Charge \n", "1 Imi Gérance S 5 S05 2020 1 Loyer Charge \n", "2 Imi Gérance S 5 S05 2020 1 Loyer Charge \n", "3 Imi Gérance S 2 S02 2020 1 Loyer Charge \n", "4 Imi Gérance S 2 S02 2020 1 Loyer Charge \n", "\n", " Libellé Débit Crédit Impact \n", "0 Règl. Loyer 01/2020 0.0 100.48 100.48 \n", "1 Règl. Prov. Char 01/2020 0.0 191.00 191.00 \n", "2 Règl. Loyer 01/2020 0.0 745.39 745.39 \n", "3 Règl. Prov. Char 01/2020 0.0 519.00 519.00 \n", "4 Règl. Loyer 01 à 03/2020 0.0 3473.79 3473.79 " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = df[~df[\"Libellé\"].isna()]\n", "df = df.assign(\n", " Fournisseur = df[\"Fournisseur\"].fillna(\"\")\n", ")\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 13, "id": "396257d6-77bc-4fc7-9347-29698e1d2399", "metadata": {}, "outputs": [], "source": [ "X = df[\"Libellé\"]# + df[\"Fournisseur\"]\n", "y = df[\"Catégorie\"]" ] }, { "cell_type": "code", "execution_count": 14, "id": "5c63ad34-5fe9-41ab-8a34-c9a6003f77e3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "31929\n", "5857 Honoraires Bien COP33M- 15\n", "5858 Honoraires Bien COP33M- 16\n", "5859 Honoraires Bien COP33M- 17\n", "5860 Honoraires Bien COP33M- 18\n", "5861 Honoraires Bien COP33M- 19\n", "Name: Libellé, dtype: object\n" ] } ], "source": [ "print(len(X))\n", "print(X.tail())" ] }, { "cell_type": "markdown", "id": "273daee3-b0e2-4adf-8c0a-b1152e139abb", "metadata": {}, "source": [ "## Exploration de l'actuel" ] }, { "cell_type": "code", "execution_count": 7, "id": "76fa04a7-7087-4af3-a05d-e5de591f1cd2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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md4x/fz8EBkZ+dq2ZGRkIC0tTW8hIiIibXrvMznv49mzZxg/fjy6du0KW1tbaf3w4cNRvXp1FC5cGMeOHcPEiRORlJSEBQsWAACSk5Ph7u6udyxHR0dpm4ODA5KTk6V1ufdJTk5+bXtmz56NqVOnyvX0iIiI6F9MsZDz4sULdOrUCUIIrFy5Um9bYGCg9G8fHx+Ympris88+w+zZs2FmZqZUkzBx4kS92mlpaXBxcVGsHhEREalHkZCTE3Bu3ryJ/fv3653FyU/t2rWRmZmJGzduoHz58ihRogTu3r2rt0/O45x+PK/b53X9fADAzMxM0RBFRERE/x6y98nJCTjx8fHYt28fihQp8tafiY6OhpGREYoXLw4A8PX1RUREBF68eCHtExYWhvLly8PBwUHaJzw8XO84YWFh8PX1lfHZEBERUUH13mdy0tPTkZCQID2+fv06oqOjUbhwYTg5OeF///sfzpw5gx07diArK0vqI1O4cGGYmpoiMjISJ06cQOPGjWFjY4PIyEiMGjUK3bt3lwJMt27dMHXqVAQEBGD8+PGIjY3F4sWLsXDhQqnuiBEj0LBhQ8yfPx+tW7fGpk2bcPr0ab3bzImIiOi/SyeEEO/zAwcPHkTjxo3zrO/VqxemTJmSp8NwjgMHDqBRo0Y4c+YMBg8ejLi4OGRkZMDd3R09evRAYGCg3qWkc+fOYciQITh16hSKFi2KYcOGYfz48XrH/PHHHzFp0iTcuHEDZcuWxdy5c9GqVat3fi5paWmws7PDw4cP872k5jZh5zsfK7cbc1r/rZ8jIiKit3vb53eO9w45WsKQQ0REVPC8a8jh3FVERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEnvHXIiIiLQpk0bODs7Q6fTYdu2bXrbhRAICgqCk5MTLCws0KxZM8THx+vtk5KSAn9/f9ja2sLe3h4BAQFIT0/X2+fcuXOoX78+zM3N4eLigrlz5+Zpy48//ogKFSrA3Nwc3t7e2LVr1/s+HSIiItKo9w45jx8/RpUqVbB8+fJ8t8+dOxdLlixBcHAwTpw4ASsrK/j5+eHZs2fSPv7+/rhw4QLCwsKwY8cOREREYMCAAdL2tLQ0NG/eHK6uroiKisK8efMwZcoUrFq1Strn2LFj6Nq1KwICAnD27Fm0b98e7du3R2xs7Ps+JSIiItIgnRBC/O0f1unwyy+/oH379gBensVxdnbG6NGjMWbMGADAw4cP4ejoiJCQEHTp0gWXLl2Cl5cXTp06hZo1awIAdu/ejVatWuH27dtwdnbGypUr8cUXXyA5ORmmpqYAgAkTJmDbtm2Ii4sDAHTu3BmPHz/Gjh07pPbUqVMHVatWRXBw8Du1Py0tDXZ2dnj48CFsbW3zbHebsPNv/V5uzGn9t36OiIiI3u5tn985ZO2Tc/36dSQnJ6NZs2bSOjs7O9SuXRuRkZEAgMjISNjb20sBBwCaNWsGIyMjnDhxQtqnQYMGUsABAD8/P1y+fBkPHjyQ9sldJ2efnDr5ycjIQFpamt5CRERE2iRryElOTgYAODo66q13dHSUtiUnJ6N48eJ6201MTFC4cGG9ffI7Ru4ar9snZ3t+Zs+eDTs7O2lxcXF536dIREREBcR/6u6qiRMn4uHDh9Jy69YttZtERERECpE15JQoUQIAcPfuXb31d+/elbaVKFEC9+7d09uemZmJlJQUvX3yO0buGq/bJ2d7fszMzGBra6u3EBERkTbJGnLc3d1RokQJhIeHS+vS0tJw4sQJ+Pr6AgB8fX2RmpqKqKgoaZ/9+/cjOzsbtWvXlvaJiIjAixcvpH3CwsJQvnx5ODg4SPvkrpOzT04dIiIi+m9775CTnp6O6OhoREdHA3jZ2Tg6OhqJiYnQ6XQYOXIkZsyYge3bt+P8+fPo2bMnnJ2dpTuwKlasiBYtWqB///44efIkjh49iqFDh6JLly5wdnYGAHTr1g2mpqYICAjAhQsXsHnzZixevBiBgYFSO0aMGIHdu3dj/vz5iIuLw5QpU3D69GkMHTr0n/9WiIiIqMAzed8fOH36NBo3biw9zgkevXr1QkhICMaNG4fHjx9jwIABSE1NxYcffojdu3fD3Nxc+pkNGzZg6NChaNq0KYyMjNCxY0csWbJE2m5nZ4e9e/diyJAhqFGjBooWLYqgoCC9sXTq1q2LH374AZMmTcLnn3+OsmXLYtu2bahcufLf+kUQERGRtvyjcXIKOo6TQ0REVPCoMk4OERER0b8FQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaZKJ2g0gfW4Tdv7tn70xp7WMLSEiIirYeCaHiIiINIkhh4iIiDSJIYeIiIg0iSGHiIiINIkhh4iIiDRJ9pDj5uYGnU6XZxkyZAgAoFGjRnm2DRw4UO8YiYmJaN26NSwtLVG8eHGMHTsWmZmZevscPHgQ1atXh5mZGTw9PRESEiL3UyEiIqICTPZbyE+dOoWsrCzpcWxsLD766CN8+umn0rr+/ftj2rRp0mNLS0vp31lZWWjdujVKlCiBY8eOISkpCT179kShQoUwa9YsAMD169fRunVrDBw4EBs2bEB4eDj69esHJycn+Pn5yf2UiIiIqACSPeQUK1ZM7/GcOXNQpkwZNGzYUFpnaWmJEiVK5Pvze/fuxcWLF7Fv3z44OjqiatWqmD59OsaPH48pU6bA1NQUwcHBcHd3x/z58wEAFStWxJEjR7Bw4UKGHCIiIgKgcJ+c58+f4/vvv0ffvn2h0+mk9Rs2bEDRokVRuXJlTJw4EU+ePJG2RUZGwtvbG46OjtI6Pz8/pKWl4cKFC9I+zZo106vl5+eHyMjIN7YnIyMDaWlpegsRERFpk6IjHm/btg2pqano3bu3tK5bt25wdXWFs7Mzzp07h/Hjx+Py5cvYunUrACA5OVkv4ACQHicnJ79xn7S0NDx9+hQWFhb5tmf27NmYOnWqXE+PiIiI/sUUDTlr1qxBy5Yt4ezsLK0bMGCA9G9vb284OTmhadOmuHr1KsqUKaNkczBx4kQEBgZKj9PS0uDi4qJoTSIiIlKHYiHn5s2b2Ldvn3SG5nVq164NAEhISECZMmVQokQJnDx5Um+fu3fvAoDUj6dEiRLSutz72NravvYsDgCYmZnBzMzsvZ8LERERFTyK9clZt24dihcvjtat3zxpZHR0NADAyckJAODr64vz58/j3r170j5hYWGwtbWFl5eXtE94eLjeccLCwuDr6yvjMyAiIqKCTJGQk52djXXr1qFXr14wMfm/k0VXr17F9OnTERUVhRs3bmD79u3o2bMnGjRoAB8fHwBA8+bN4eXlhR49eiAmJgZ79uzBpEmTMGTIEOkszMCBA3Ht2jWMGzcOcXFxWLFiBbZs2YJRo0Yp8XSIiIioAFIk5Ozbtw+JiYno27ev3npTU1Ps27cPzZs3R4UKFTB69Gh07NgRv/32m7SPsbExduzYAWNjY/j6+qJ79+7o2bOn3rg67u7u2LlzJ8LCwlClShXMnz8fq1ev5u3jREREJFGkT07z5s0hhMiz3sXFBYcOHXrrz7u6umLXrl1v3KdRo0Y4e/bs324jERERaRvnriIiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTZI95EyZMgU6nU5vqVChgrT92bNnGDJkCIoUKQJra2t07NgRd+/e1TtGYmIiWrduDUtLSxQvXhxjx45FZmam3j4HDx5E9erVYWZmBk9PT4SEhMj9VIiIiKgAU+RMTqVKlZCUlCQtR44ckbaNGjUKv/32G3788UccOnQIf/zxBz755BNpe1ZWFlq3bo3nz5/j2LFjWL9+PUJCQhAUFCTtc/36dbRu3RqNGzdGdHQ0Ro4ciX79+mHPnj1KPB0iIiIqgEwUOaiJCUqUKJFn/cOHD7FmzRr88MMPaNKkCQBg3bp1qFixIo4fP446depg7969uHjxIvbt2wdHR0dUrVoV06dPx/jx4zFlyhSYmpoiODgY7u7umD9/PgCgYsWKOHLkCBYuXAg/Pz8lnhIREREVMIqcyYmPj4ezszM8PDzg7++PxMREAEBUVBRevHiBZs2aSftWqFABpUuXRmRkJAAgMjIS3t7ecHR0lPbx8/NDWloaLly4IO2T+xg5++Qc43UyMjKQlpamtxAREZE2yR5yateujZCQEOzevRsrV67E9evXUb9+fTx69AjJyckwNTWFvb293s84OjoiOTkZAJCcnKwXcHK252x70z5paWl4+vTpa9s2e/Zs2NnZSYuLi8s/fbpERET0LyX75aqWLVtK//bx8UHt2rXh6uqKLVu2wMLCQu5y72XixIkIDAyUHqelpTHoEBERaZTit5Db29ujXLlySEhIQIkSJfD8+XOkpqbq7XP37l2pD0+JEiXy3G2V8/ht+9ja2r4xSJmZmcHW1lZvISIiIm1SPOSkp6fj6tWrcHJyQo0aNVCoUCGEh4dL2y9fvozExET4+voCAHx9fXH+/Hncu3dP2icsLAy2trbw8vKS9sl9jJx9co5BREREJHvIGTNmDA4dOoQbN27g2LFj6NChA4yNjdG1a1fY2dkhICAAgYGBOHDgAKKiotCnTx/4+vqiTp06AIDmzZvDy8sLPXr0QExMDPbs2YNJkyZhyJAhMDMzAwAMHDgQ165dw7hx4xAXF4cVK1Zgy5YtGDVqlNxPh4iIiAoo2fvk3L59G127dsX9+/dRrFgxfPjhhzh+/DiKFSsGAFi4cCGMjIzQsWNHZGRkwM/PDytWrJB+3tjYGDt27MCgQYPg6+sLKysr9OrVC9OmTZP2cXd3x86dOzFq1CgsXrwYpUqVwurVq3n7OBEREUl0QgihdiPUkpaWBjs7Ozx8+DDf/jluE3b+rePemNP6b7fp79b8p3WJiIgKird9fufg3FVERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJsoec2bNn44MPPoCNjQ2KFy+O9u3b4/Lly3r7NGrUCDqdTm8ZOHCg3j6JiYlo3bo1LC0tUbx4cYwdOxaZmZl6+xw8eBDVq1eHmZkZPD09ERISIvfTISIiogJK9pBz6NAhDBkyBMePH0dYWBhevHiB5s2b4/Hjx3r79e/fH0lJSdIyd+5caVtWVhZat26N58+f49ixY1i/fj1CQkIQFBQk7XP9+nW0bt0ajRs3RnR0NEaOHIl+/fphz549cj8lIiIiKoBM5D7g7t279R6HhISgePHiiIqKQoMGDaT1lpaWKFGiRL7H2Lt3Ly5evIh9+/bB0dERVatWxfTp0zF+/HhMmTIFpqamCA4Ohru7O+bPnw8AqFixIo4cOYKFCxfCz89P7qdFREREBYzifXIePnwIAChcuLDe+g0bNqBo0aKoXLkyJk6ciCdPnkjbIiMj4e3tDUdHR2mdn58f0tLScOHCBWmfZs2a6R3Tz88PkZGRr21LRkYG0tLS9BYiIiLSJtnP5OSWnZ2NkSNHol69eqhcubK0vlu3bnB1dYWzszPOnTuH8ePH4/Lly9i6dSsAIDk5WS/gAJAeJycnv3GftLQ0PH36FBYWFnnaM3v2bEydOlXW50hERET/ToqGnCFDhiA2NhZHjhzRWz9gwADp397e3nByckLTpk1x9epVlClTRrH2TJw4EYGBgdLjtLQ0uLi4KFaPiIiI1KPY5aqhQ4dix44dOHDgAEqVKvXGfWvXrg0ASEhIAACUKFECd+/e1dsn53FOP57X7WNra5vvWRwAMDMzg62trd5CRERE2iR7yBFCYOjQofjll1+wf/9+uLu7v/VnoqOjAQBOTk4AAF9fX5w/fx737t2T9gkLC4OtrS28vLykfcLDw/WOExYWBl9fX5meCRERERVksoecIUOG4Pvvv8cPP/wAGxsbJCcnIzk5GU+fPgUAXL16FdOnT0dUVBRu3LiB7du3o2fPnmjQoAF8fHwAAM2bN4eXlxd69OiBmJgY7NmzB5MmTcKQIUNgZmYGABg4cCCuXbuGcePGIS4uDitWrMCWLVswatQouZ8SERERFUCyh5yVK1fi4cOHaNSoEZycnKRl8+bNAABTU1Ps27cPzZs3R4UKFTB69Gh07NgRv/32m3QMY2Nj7NixA8bGxvD19UX37t3Rs2dPTJs2TdrH3d0dO3fuRFhYGKpUqYL58+dj9erVvH2ciIiIACjQ8VgI8cbtLi4uOHTo0FuP4+rqil27dr1xn0aNGuHs2bPv1T4iIiL6b+DcVURERKRJDDlERESkSQw5REREpEmKDgZIBYPbhJ1/+2dvzGktY0uIiIjkwzM5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJDDlERESkSQw5REREpEkMOURERKRJnLuKVMH5soiISGk8k0NERESaxJBDREREmsSQQ0RERJrEkENERESaxJBDREREmsSQQ0RERJrEkENERESaxJBDREREmsTBAOk/5e8OQsgBCImICh6eySEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNYsghIiIiTWLIISIiIk1iyCEiIiJNKvAhZ/ny5XBzc4O5uTlq166NkydPqt0kIiIi+hco0HNXbd68GYGBgQgODkbt2rWxaNEi+Pn54fLlyyhevLjazSMCwPmyiIjUUqBDzoIFC9C/f3/06dMHABAcHIydO3di7dq1mDBhgsqtI1LP3w1WwN8PV6ypXE0i+nsKbMh5/vw5oqKiMHHiRGmdkZERmjVrhsjIyHx/JiMjAxkZGdLjhw8fAgDS0tLy3T8748nfatvrjvcu/m7Nf1L3v1Lzn9T9r9T8J3VZU7maAFD5yz1/6+dip/r97ZpE/1Y5f0tCiDfvKAqoO3fuCADi2LFjeuvHjh0ratWqle/PfPnllwIAFy5cuHDhwkUDy61bt96YFQrsmZy/Y+LEiQgMDJQeZ2dnIyUlBUWKFIFOp3vn46SlpcHFxQW3bt2Cra2tEk39V9RUqy5rsmZBrcuarFlQ6xa0mkIIPHr0CM7Ozm/cr8CGnKJFi8LY2Bh3797VW3/37l2UKFEi358xMzODmZmZ3jp7e/u/3QZbW1uDvvDVqqlWXdZkzYJalzVZs6DWLUg17ezs3rpPgb2F3NTUFDVq1EB4eLi0Ljs7G+Hh4fD19VWxZURERPRvUGDP5ABAYGAgevXqhZo1a6JWrVpYtGgRHj9+LN1tRURERP9dBTrkdO7cGX/++SeCgoKQnJyMqlWrYvfu3XB0dFS0rpmZGb788ss8l760VlOtuqzJmgW1LmuyZkGtq9WaOiHedv8VERERUcFTYPvkEBEREb0JQw4RERFpEkMOERERaRJDDhEREWkSQ857eP78OS5fvozMzEy1m6KKJ0/+/pw9pK7/+muXqKBJTU1VuwmaUKBvITeUJ0+eYNiwYVi/fj0A4MqVK/Dw8MCwYcNQsmRJxWY8T01NxcmTJ3Hv3j1kZ2frbevZs6ciNZs2bYrQ0FCULFlSb/3JkyfRvXt3XLlyRZG6hnLlyhWkpqaiVq1a0rrw8HDMmDEDjx8/Rvv27fH555+r2EJ5qfXafRMhxHtNo/Jv9eLFC3z22WeYPHky3N3dVWnDs2fPYG5ursixz5079877+vj4KNKGQ4cO4euvv8alS5cAAF5eXhg7dizq16+vSD21fPXVV3Bzc0Pnzp0BAJ06dcLPP/+MEiVKYNeuXahSpYrKLZRPfHw8Dhw4kO/nWlBQkPwFZZktU+OGDx8uatSoIQ4fPiysrKzE1atXhRBCbNu2TVStWlWRmtu3bxc2NjZCp9MJOzs7YW9vLy0ODg6K1BRCiFatWonChQuLTZs2CSGEyMrKEl9++aUoVKiQGDFihGJ1DaV9+/Zi8uTJ0uNr164JCwsL0bx5czF8+HBhbW0tFi5cqF4DZabGa1cIIXr16iXS09PzrL9+/br48MMPFatraLa2tuLatWsGrZmVlSWmTZsmnJ2dhbGxsfR/OmnSJLF69WrZ6uh0OmFkZCR0Ol2+S842IyMj2Wrm9t133wkTExPRqVMnsXjxYrF48WLRqVMnUahQIbFhwwZFaqrFzc1NHD16VAghxN69e4W9vb3Ys2ePCAgIEB999JGita9cuSK++eYbMX36dDF16lS9RW6rVq0SxsbGwtHRUVSpUkVUrVpVWqpVqyZ7PSGEYMh5B6VLlxaRkZFCCCGsra2lN5X4+HhhY2OjSM2yZcuKESNGiMePHyty/DdZtmyZsLS0FF27dhW+vr7C2dlZ7NmzR/G6hvhjK1WqlN7M9dOnTxdVqlSRHq9evVrvsdx+//13cfjwYenxsmXLRJUqVUTXrl1FSkqK7PXUeO0KIUTVqlWFh4eH3u86JCRE2Nraivbt2ytWd9iwYWLx4sV51i9dulSRkN6zZ0+xYMEC2Y/7JlOnThUeHh7i+++/FxYWFtL/6aZNm0SdOnVkq3Pjxo13XpRQoUKFfH+38+fPFxUqVFCkZg43Nzfh7u7+2kVu5ubmIjExUQjx8ovJgAEDhBBCXL58Wdjb28teL4ehQ0fp0qXFnDlzZD/umzDkvIPcbyS5Pyiio6OFra2tIjUtLS2lOmqYMGGC0Ol0olChQtI3DCUZ6o8t95uJEEI0adJETJo0SXqckJAg7OzsZKv3qsqVK4udO3cKIYQ4d+6cMDMzExMnThR16tQRvXv3lr2eGq9dIYR4/vy5GDNmjDA1NRUTJ04Un376qbC2tharVq1SrKYQQjg7O4vTp0/nWR8VFSVKliwpe73p06cLe3t70bFjRzFr1izpjEPOooQyZcqIffv2CSH0/08vXbqk6AeioZmamor4+Pg86+Pj44WZmZmitRctWqS3zJs3T3Tr1k0ULlxYzJ49W/Z6Tk5O0vtsuXLlxJYtW4QQQsTFxSn6ZcTQocPGxsbgn2sMOe+gfv36YsmSJUKIl28qOaenhw4dKvz8/BSp2aFDB7F582ZFjv0mKSkp4pNPPhF2dnZi1apVwt/fX1hZWYnly5crWtdQf2zOzs7ixIkTQoiXp/1tbW3Fjh07pO0XL15U9MPfyspKXL9+XQghxJdffik6duwohHj5Iezo6Ch7PTVeu7kFBQVJYTn3WR2lmJmZGfSD0c3N7bWLEt/4hXgZ1HPOnuQOORcuXBBWVlaK1BRCiNDQUFG3bl3h5OQk1V+4cKHYtm2bIvXKlCkjgoOD86xfuXKl8PT0VKTm2yxbtkyRLyNDhgwRrq6uolmzZqJIkSLi0aNHQgghNm7cqNhlHCEMHzr69u0rVq5cabB6QgjBjsfvYNasWWjZsiUuXryIzMxMLF68GBcvXsSxY8dw6NAhRWq2bt0aY8eOxcWLF+Ht7Y1ChQrpbW/btq0idStXrgx3d3ecPXsW7u7u6N+/PzZv3ozBgwdj586d2LlzpyJ1Hzx4gE8//VSRY+fWqFEjTJ8+HStWrMCPP/6I7OxsNGrUSNp+8eJFuLm5KVbf1NRUuktt3759UgfywoULIy0tTfZ6arx2gZedcidMmIDly5dj4sSJOHLkCD755BOsWbMGrVq1Uqyup6cndu/ejaFDh+qt//333+Hh4SF7vevXr8t+zLfx8vLC4cOH4erqqrf+p59+QrVq1RSpuXLlSgQFBWHkyJGYOXMmsrKyAAD29vZYtGgR2rVrJ3vN0aNHY/jw4YiOjkbdunUBAEePHkVISAgWL14se7130bJlS0ycOBHr1q2T9bgLFy6Em5sbbt26hblz58La2hoAkJSUhMGDB8taK7dPP/0Ue/fuxcCBAxWrkZunpycmT56M48eP5/u5Nnz4cPmLGjRSFWAJCQmiX79+4oMPPhAVK1YU/v7+4ty5c4rVe11nPyU7+gkhxLRp00RWVlae9bdu3RLNmjVTrK6hEv7169dFmTJlhE6nEyYmJmLFihV629u1aydGjhypWP02bdoIPz8/MW3aNFGoUCFx+/ZtIYQQe/bsEWXLllWkpqFfu0II4ePjIzw9PaX+QNnZ2WLOnDnCzMxMDBo0SLG6a9asERYWFiIoKEgcPHhQHDx4UEyePFlYWloqfqnMULZt2ybs7OzEnDlzhKWlpZg3b57o16+fMDU1FXv37lWkZsWKFcUvv/wihNA/e3T+/HlRpEgRRWoKIcTWrVtFvXr1ROHChUXhwoVFvXr1FDtz9C6++uor4erqqlp9uc2aNUsULVpU9OrVS3z99deKX25V48wnJ+ikf4XZs2djwYIFaN26teIJPzMzExcuXECxYsXg7Oysty0mJgalSpVCkSJFZKuXW2JiIgYPHoxbt25h+PDhCAgIAACMGjUKWVlZWLJkiSJ1DS0gIABLliyBlZWV3vqzZ8+iR48eiI2NVaz2ypUrMXPmTPzxxx8AADc3N0yZMkWRYRf69u37xu1r166VvSYAHD58GNOmTUNMTAzS09NRvXp1BAUFoXnz5orUs7CwQFxcHFxdXWFjY4OYmBh4eHggPj4ePj4+ePr0qSJ11VKtWjW9YQ6EEEhOTsaff/6JFStWYMCAAbLX/O677/DNN9/g2rVriIyMhKurKxYtWgR3d3dFzpQBeOPQBzqdDteuXVOkriEx5LyD111G0Ol0MDMzg6mpqYFbpJyIiIg3bm/QoIEidQ31x1a/fn20b98ebdq0Qbly5WQ55r/N+1z2srW1VbAl+cvIyICZmZnidf78809YWFhIp/6V0KFDB73HL168QGxsLFJTU9GkSRNs3bpVsdqG5OXlhdmzZ6Ndu3Z6IWfp0qVYt24dzpw5I3vNW7duQafToVSpUgBejtX1ww8/wMvLS5GQkdvUqVP1HhsZGaFYsWJo1KgRKlSoIHu9Vy8HxsbGwsPDAyEhIVi/fj0OHDgge0215UQPxcfMUuT8kMbkXCJ63VK6dGkRFBSU72Wef+LgwYPi448/FmXKlBFlypQRbdq0EREREbLWeNXrLo/lLAXd+vXrxSeffCKsra1FhQoVxLhx48SRI0dEdna2Qerv3LlT7N69O8/6PXv2iF27dslS422vV6XHNxFCiJs3b75xUdKLFy9EWFiYCA4OFmlpaUIIIe7cuSN15lRaVlaWGDBggPjqq68UOf7JkyfF8ePH86w/fvy4OHXqlKy1pk6dKh4/fiy+/fZbUbJkSbFp0yZhZWUlNm7cKGbMmCH9WwkffvihCA0NFUIIkZSUJGxsbISvr68oWrSoImO4qEmty4G5ZWdnG+R9cP369aJy5crCzMxMmJmZCW9vb+n/WQkMOe9g/fr1olSpUmLSpEli+/btYvv27WLSpEnCxcVFfPPNN2LGjBnC3t5ezJw5U7aaag2ElZqaqrf8+eefYu/evaJ27drSbatKysjIEHFxceLFixeK1nn27JnYuXOnGDBggHBychLFixcXffr0Eb/88ot48uSJYnW9vb2lW8hz+/3334WPj48sNXL6orzLopS3BS2l3LhxQ1SoUEFYWlrqDZQ3fPhw8dlnnylW91VxcXGiRIkSihz7gw8+ED/++GOe9T///LOoVauWrLWMjIzE3bt3hRBCfP/998LT01P68lOyZElZBx98lb29vYiLixNCCLF48WJRt25dIcTLLwRK9d/Iz9OnT8XDhw/1Frm97o65K1euCHNzc9nr5WbI0DF//nxhaWkpxo0bJ3799Vfx66+/irFjxwpLS0vFxptiyHkHTZo0yfd27s2bN4smTZoIIV7eXlm+fHnZaqo5EFZ+Dh48KKpXr67Y8R8/fiz69u0rjI2N9T6chg4dqsi4FK86fvy4+Pzzz0XlypWFhYWFaN26tThy5IjsdczNzaVbyHO7fv26sLS0lL2eWqKjo/WWU6dOiVWrVokKFSqIn3/+WbG67dq1E927dxcZGRl6HxYHDhww6G3HO3fuFEWLFlXk2LlHrs7t2rVrwtraWtZaOp1OCjk5Hj9+nGedEnIPt9CmTRtpiImbN28q/sGfnp4uhgwZIooVK2aQkF6xYkWpQ3Xu1+2SJUsUvYXc0KHDzc1NrF+/Ps/6kJAQ4ebmJns9IRhy3om5ubm4cuVKnvVXrlwRFhYWQoj/mx5ALmoOhJWfS5cuKToGh1rTD+Tn6tWrYsGCBfl+W/6nHB0dRXh4eJ71YWFholixYrLXE+Ll2Efz5s0Tffv2FX379hVff/21uH//viK13mbHjh2iYcOGih2/cOHC0rf/3B8W169fl/XvM8eoUaP0lpEjR4rOnTsLa2trMWTIENnrCfHyOeY35tDRo0dlHwxQp9OJe/fuyXrMd1WrVi0xfvx4ERERIczNzUV0dLQQQojIyEhFBnbMbfDgwaJixYrip59+EhYWFmLt2rVi+vTpolSpUuL777+XvZ4alwOFMHzoeN04VleuXFHsc40h5x2ULVtWjB8/Ps/68ePHi3LlygkhhDh16pRwdnaWraZaA2HFxMToLdHR0eL3338XDRs2FPXq1VOsrqGmHzhx4oTIzMx87fZnz54pOgjjgAEDhLe3t0hISJDWxcfHCx8fHxEQECB7vUOHDglbW1vh4uIiOnToIDp06CBKly4tbG1txaFDh2Sv9zbx8fGKnrGyt7cXFy5cEELov44OHz4sihcvLnu9Ro0a6S1NmjQRnTt3Ft98841il1y7dOkiGjZsKFJTU6V1Dx48EA0bNhSffvqprLV0Op00X96bFiUcOHBA2NvbCyMjI9GnTx9p/cSJE0WHDh0UqZnDxcVFHDhwQAjxcsC8nA/m0NBQ0bJlS0VqGvpyoBCGDx2VKlXKt1vH9OnTReXKlWWvJwRDzjv59ddfhampqfRBFBAQIKpUqSLMzMzEb7/9JoQQYsWKFWLUqFGy1VyxYoUwNTUVAwcOFKGhoSI0NFR89tlnwszMLN/wI5fXTcrn6+srLl26pFhdQ00/kLuPgRB5R/xMTk5WtM9IamqqqFOnjjAxMZHGhzAxMRGNGzcWDx48kL1e5cqVRf/+/fWCXWZmphgwYIBibypCiDx9GFJTU8WlS5dE586dFZ0brFOnTqJ///5CiP8b4fnRo0eiSZMmioxUq4bbt28LDw8PYWdnJ4Ure3t7Ub58eb0pS+Sg0+nE4sWLRUhIyBsXpWRmZuaZ0+369euKXy6zsrKSOsiXLFlSGiX92rVrip7RFsJwlwOFMHzo+Omnn4SxsbE0Vti0adOEn5+fMDExEVu3bpW9nhAcJ+ed3bhxA9988w0uX74MAChfvjw+++wzRUfH/eWXXzB//nxcunQJAFCxYkWMHTtWsTETAODmzZt6j3NunTQ3N1esJvDy1vRPP/0Uw4YNg42NDc6dOwd3d3cMGzYM8fHx2L17tyx1jIyMkJycjOLFiwOA3u2wAHD37l04OTkhOztblnr5EUIgLCwMMTExsLCwgI+Pj2K35ltYWCA6Ohrly5fXW3/58mVUrVpVsfFNjIyM8twaKoSAi4sLNm3aBF9fX0Xq3r59G35+fhBCID4+HjVr1kR8fDyKFi2KiIgI6f9dTpmZmTh48CCuXr2Kbt26wcbGBn/88QdsbW0Vu3398ePH2LBhg95rqGvXrnnGl/qnXv17MTQ1frcA4OPjg6VLl6Jhw4Zo1qwZqlatiq+//hpLlizB3Llzcfv2bcVqG9LPP/+Mzp07o1mzZqhXrx6Al6NKh4eHY8uWLXmGSJBDVFQUFi5cqPe5Nnr0aMVG62bIeYsXL16gRYsWCA4ORtmyZdVujmYdOXIELVu2RPfu3RESEoLPPvtMb/qBGjVqyFLnXUKOs7OzNGx9QVevXj2MHTsW7du311u/bds2zJkzB8ePH1ek7qtTRuSEZU9PT5iYKDubTGZmJjZt2oRz585JA+X5+/vDwsJC9lo3b95EixYtkJiYiIyMDFy5cgUeHh4YMWIEMjIyEBwcLHtNQzI2NkZSUpJBQs6TJ09gaWkpPVbzd7tw4UIYGxtj+PDh2LdvH9q0aQMhBF68eIH58+dj5MiR/7jGqwMOvokS4xDlMHToMDTOXfUWhQoVwrlz59RuhkE9fvwYhw4dQmJiIp4/f663TZG5RQB8+OGHiI6Oxpw5c+Dt7Y29e/eievXqiIyMhLe3tyI1DWXJkiUYMGAAzM3N3zqisRy/39yv1+HDh2PEiBFISEhAnTp1AADHjx/H8uXLMWfOnH9c63UaNmyo2LHfxsTEBN27dzdIrREjRqBmzZqIiYnRGyW7Q4cO6N+/v2J14+PjceDAAdy7dy/PWcegoCDZ6hjyO/DChQtRrFgxaaA/tX63wMsRyHM0a9YMcXFxiIqKgqenJ3x8fGSp8eoXD7XUqFED33//vWLHT0tLkwYdfdtApUoMTsozOe9g1KhRMDMzU/RDAXg5SeOVK1dQtGhRODg4vDHlp6SkKNKGs2fPolWrVnjy5AkeP36MwoUL46+//oKlpSWKFy9e4If5NjIywv79+1G4cGEAQN26dbFlyxZpVNW//voLH330kaxnctzd3XH69GkUKVLEICM751wqetuftk6nU/SM1XfffYfg4GBcv35dGqZ+4cKF8PDwkPWS6/bt2995X7knti1SpAiOHTuG8uXL650VvHHjBry8vKTJWOX07bffYtCgQShatChKlCih9z6h0+kU/davpJs3b+LTTz9FixYtMG3aNFV+t61atcLGjRthZ2cHAJgzZw4GDhwIe3t7AMD9+/dRv359XLx4UfbahmLo0JH7bGB+l7GBl2Faqfcjnsl5B5mZmVi7di327duHGjVq5JmPZ8GCBbLUWbhwIWxsbKR/Kz7cdT5GjRqFNm3aIDg4GHZ2djh+/DgKFSqE7t27Y8SIEbLWUivhN23aVC8AfPzxxwAgBQO5f++5Z6o2xKzVasyM/arXzVrt4OAg+6zV7/qNWIk30ezs7HyPefv2belvWW4zZszAzJkzMX78eEWOrxZXV1ccPnwYgYGBANT53e7ZswcZGRnS41mzZqFTp05SyMnMzJT6ZSrh9OnT0mUjLy8v2S7T5+bg4CCFDnt7e8VDR+4vlWpMT8EzOe+gcePGr92m0+mwf/9+A7ZGWfb29jhx4gTKly8Pe3t7REZGomLFijhx4gR69eqFuLg42WqpkfBf7Vj9Oq6urrLUe9W0adMwZswYvb4HAPD06VPMmzdP1ksNavLy8sKsWbPQvn17vW/hsbGxaNSoEf766y+1myiLzp07w87ODqtWrZI6zBcrVgzt2rVD6dKlsW7dOtlr2traIjo6WupHplVq/G7V6rN3+/ZtdO3aFUePHpUCVWpqKurWrYtNmzZJZ5rlcOjQIdSrVw8mJiZ5+s69Su7LzomJiXBxccn3poRbt26hdOnSstYDGHL+tV7X4e/+/fsoXry4YpcZihUrhmPHjqFs2bIoV64cli5dCj8/P8TFxaFGjRp4/PixbLXU/GNTi1r/rxcvXsy3j5Xcl29yGHrWarUuM6hxN1dAQAA++OADDBw4UPZj/5vcunULLVq0MOjvVq2Q06JFC6SmpmL9+vXSnZCXL19Gnz59YGtrK9vdpa8ydOhQ4/2Pl6v+pV6XPTMyMhSd9bxatWo4deoUypYti4YNGyIoKAh//fUXvvvuO1SuXFnWWrmDi7u7+xv/2LTidZfDYmJipFO6crp27Ro6dOiA8+fP6/XTyWmDUqHK3d0d0dHRec6I7d69GxUrVpS93u7du1W5zFCqVCnExMRg8+bNiImJQXp6OgICAhS7mwsAPD09MXnyZBw/fhze3t55bhtX6uYAQ3NxcTH471an0+X5+zREt4FDhw5J/Y9ylC9fHkuXLkX9+vUVq+vu7p5v6EhJSYG7u7vs7w+ve/9LT09XbJgShpx3dPr0aWzZsiXfb8Nbt26VrU7O3Tc6nQ6rV6/WGwsiKysLERERqFChgmz1XjVr1iw8evQIADBz5kz07NkTgwYNQtmyZbF27VrF6hr6j83QcjqS63Q6lCtXTu8PPSsrC+np6Yp8Mx8xYgTc3d0RHh4Od3d3nDx5Evfv38fo0aPx9ddfy14vR2BgIIYMGYJnz55BCIGTJ09i48aNmD17NlavXq1Y3RyGPEFtYmICf39/+Pv7G6TeqlWrYG1tjUOHDuU5A6rT6TQRcl68eIEKFSpgx44dBv3dCiHQu3dvmJmZAQCePXuGgQMHSv0wcwdpObm4uODFixd51mdlZcHZ2VmRmoDhQkdOPyudTofJkyfrXa7PysrCiRMnULVqVdnq5caQ8w42bdqEnj17ws/PD3v37kXz5s1x5coV3L17V/bBkhYuXAjg5YsvODgYxsbG0jZTU1O4ubkpOj5EzZo1pX8XL15csdOkr1Ij4RvSokWLIIRA3759MXXqVOmyCvB//69KDJAXGRmJ/fv3o2jRojAyMoKRkRE+/PBDzJ49G8OHD8fZs2dlrwkA/fr1g4WFBSZNmoQnT56gW7ducHZ2xuLFi9GlSxdFaqph/fr1KFq0KFq3bg0AGDduHFatWgUvLy9s3LhRkb5d/4aO5UorVKgQnj17ZvC6vXr10nuc31AEPXv2lL3uvHnzMGzYMCxfvlx6Dz59+jRGjBihyJcRQ4eOnPcZIQTOnz+vdzXC1NQUVapUwZgxY2Srlxv75LwDHx8ffPbZZxgyZIh0jdbd3R2fffYZnJycMHXqVNlrNm7cGFu3boWDg4Psx36TGTNmwN/f/423Ossp549t8eLF6N+/f75/bMbGxjh69KhB2qO0Q4cOoW7durKPTPs6Dg4OOHPmDNzd3VGmTBmsXr0ajRs3xtWrV+Ht7a3IbbivevLkCdLT0xUdUM7Y2BjJyckoVqwYAOiNmg0o15eifPnyWLlyJZo0aYLIyEg0bdoUixYtwo4dO2BiYiLrWd7/mlmzZuHKlStYvXq14gNIquHVYUIeP36MzMxM6bnm/NvKykr2IUNybqY5dOgQfH1984QONzc3jBkzRvYBcPv06YPFixcrMh7O6zDkvAMrKytcuHABbm5uKFKkCA4ePAhvb29cunQJTZo0QVJSkuJtyMrKwvnz5+Hq6qpo8KlSpQpiY2NRu3ZtdO/eHZ06dULRokUVq6fWH1uOP//8U2+qjpwPSSVlZWVh27Zt0q2ilSpVQtu2bfXO2smlfv36GD16NNq3b49u3brhwYMHmDRpElatWoWoqCjExsbKXlMNRkZGaNmypXSZ4bfffkOTJk30LjPs3r1b9pBjaWmJuLg4lC5dGuPHj0dSUhJCQ0Nx4cIFNGrUCH/++aes9XLcvn0b27dvz/fyuVxDWqglMTERpUqVQseOHREeHg5ra2t4e3vnGbqjoAfI9evXv/O+r55hkosaoSO3tLQ07N+/HxUqVFCsG4b24rECHBwcpH4qJUuWRGxsLLy9vZGamqrYN+GRI0fC29sbAQEByMrKQoMGDRAZGQlLS0vs2LEDjRo1UqRuTEwMLly4gA0bNuDrr7/GyJEj8dFHH8Hf3x/t27fPc+vzP5UzboKh/9geP36MYcOG4bvvvpM++IyNjdGzZ08sXbpU9ueZIyEhAa1atcKdO3ekToazZ8+Gi4sLdu7ciTJlyshab9KkSdIdcdOmTcPHH3+M+vXro0iRIti0aZOstapXr47w8HA4ODi8dch6uQesU+syg7W1Ne7fv4/SpUtj79690plJc3NzxeYFCw8PR9u2beHh4YG4uDhUrlwZN27cgBAC1atXV6SmIeX0z7O3t0fHjh3Vbo5ilAou70OJ2/DfpFOnTmjQoAGGDh2Kp0+fombNmtJrd9OmTYr8f/NMzjvo1q0batasicDAQEyfPh1Lly5Fu3btEBYWhurVqyvyjaJkyZL49ddfUbNmTWzbtg1DhgzBgQMH8N1332H//v0Gu3xz9OhR/PDDD/jxxx/x7Nmztw7a908lJCTg6tWraNCgASwsLBQZnA8APvvsM+zbtw/Lli2TJqY7cuQIhg8fjo8++ggrV66UvSbw8lZnIQQ2bNgg3U11//59dO/eHUZGRti5c6cidXNLSUl564jaf8fUqVMxduxYWFpaYsqUKW88/pdffilrbbX4+/sjLi4O1apVw8aNG5GYmIgiRYpg+/bt+PzzzxU5U1arVi20bNkSU6dOlS6fFy9eHP7+/mjRogUGDRoke01DUntSUDUkJia+cbsS48cAQJMmTd64Xe4x4EqUKIE9e/agSpUq+OGHH/Dll18iJiYG69evx6pVq5TpIyj/xObac//+fXHnzh0hhBBZWVli9uzZok2bNiIwMFCkpKQoUtPMzEzcunVLCCFE//79xYgRI4QQQly7dk3Y2NgoUjM/Z8+eFaNHjxYlS5YU5ubmitW5f/++aNKkidDpdMLIyEhcvXpVCCFEnz59RGBgoOz1ihQpIg4cOJBn/f79+0XRokVlr5fD0tJSnDt3Ls/66OhoYWVlJXu9Pn36iLS0tDzr09PTRZ8+fWSv91/z4MEDMWTIENG2bVvx+++/S+uDgoLEjBkzFKlpbW0tEhIShBBC2Nvbi9jYWCHEy9eQq6urIjUNSafTiXv37qndDIPKed973aKUkSNH6i1DhgwR9erVE3Z2dmL48OGy1zM3NxeJiYlCCCF69Oghxo8fL4QQ4ubNm4q8/wkhBC9XvYPc45cYGRlhwoQJitd0dHTExYsX4eTkhN27d0tnFp48eaJI343crl+/jh9++AE//PADLl++jIYNG2Lq1Kn43//+p1jNkSNHolChQkhMTNQbR6Vz584IDAzE/PnzZa335MkTODo65llfvHhxRTvjmpmZSZc+c0tPT1dk/KP169djzpw5eYbBf/r0KUJDQxUbFsDDwwOnTp3Sm1gReDmKa/Xq1Qv8HGg57O3tsWzZsjzrlbgZIYeVlZXUD8fJyQlXr15FpUqVAEAzI0m/esdPfgp636PcXj2D8eLFC5w9exYLFizAzJkzFaubczfvq6ZMmYL09HTZ67m4uCAyMhKFCxfG7t27pUvmDx484Dg5asvOzkZCQkK+s/42aNBA9np9+vRBp06d4OTkBJ1Oh2bNmgEATpw4oeg4OXXq1MGpU6fg4+ODPn36oGvXrihZsqRi9XLs3bsXe/bsyTN8edmyZd95Kob34evriy+//BKhoaHSH9fTp08xdepURW7lzvHxxx9jwIABWLNmDWrVqgXg5f/pwIEDZR19OC0tDUIICCHw6NEjvTeQrKws7Nq1S9HLATdu3Mi3k29GRgZu376tWF01pKam4uTJk3neG3Q6HXr06CF7vTp16uDIkSOoWLEiWrVqhdGjR+P8+fPYunWrNNN8QffqbcavUmNePyVVqVIlz7qaNWvC2dkZ8+bNwyeffGLQ9nTv3h21atWS/fb1kSNHwt/fH9bW1ihdurTUtzQiIgLe3t6y1srBkPMOjh8/jm7duuHmzZt5BhlTaubUKVOmoHLlyrh16xY+/fRT6a4RY2NjRc8kNW3aFGvXroWXl5diNfLz+PHjfL+5paSkSM9dTosXL4afnx9KlSolvcHExMTA3Nwce/bskb1ejiVLlqBXr17w9fWVbiPPzMxE27ZtsXjxYtnq5Ey8lzP44Kt0Op0iZxtyzwi+Z88evfGAsrKypEEJteK3336Dv78/0tPTYWtrm2dGcCVCzoIFC6Rv2VOnTkV6ejo2b96MsmXLaubsxi+//PKf6pPzOuXLl8epU6cMXjcyMlKRMyuDBw9GrVq1cOvWLXz00UcwMjIC8PLM74wZM2SvB7Dj8TupWrUqypUrh6lTp0pnVnLL/UauhGfPnmliQLw3adWqFWrUqIHp06dLY5y4urqiS5cuyM7Oxk8//SR7zSdPnmDDhg3SpKMVK1ZUdMj43OLj4/Xqenp6ynr8Q4cOQQiBJk2a4Oeff9a75GpqagpXV1dFRlLNedPKPYVEjkKFCsHNzQ3z58+XZn4v6MqVK4dWrVph1qxZit2Rl1tWVhaOHj0KHx8facoKrXnd/EZa9uoNHUIIJCUlYcqUKYiLi0N0dLQidV89Q5RT9/Tp05g8ebJiNwg8f/4c169fR5kyZRQfA4kh5x1YWVkhJiZG9g+iN8nKysKsWbMQHByMu3fv4sqVK/Dw8MDkyZPh5uaGgIAAxWqrMQZHbGwsmjZtiurVq2P//v1o27YtLly4gJSUFBw9elT2W6v/K27evAkXFxcpfBiKu7s7Tp06pegYS/8GVlZWOH/+vEFnBDc3N8elS5c0dUYst//i3VVGRkb5ztvn4uKCTZs2KXYJvU+fPnnaUaxYMTRp0gTNmzeXvd6TJ08wbNgwaYygnM+1YcOGoWTJkopcpeDlqndQu3ZtJCQkGDTkzJw5E+vXr8fcuXPRv39/aX3lypWxaNEixUKOWmNwVK5cGVeuXMGyZctgY2OD9PR0fPLJJxgyZAicnJwUqRkfH48DBw7k288qKChIkZpZWVkICQlBeHh4vnXlvmXT1dUVDx48wJo1a6TBB728vNCnTx9FJgTN8V+YegAA/Pz8cPr0aYOGnMqVK+PatWuaDTnr1q1T/Oz4v03OeGE5csKGp6enomc6DD1OzsSJExETE4ODBw+iRYsW0vpmzZphypQpioQcnsl5jXPnzkn/vnr1KiZNmoSxY8fmO+uvj4+P7PU9PT3xzTffoGnTptJYGDnBw9fXFw8ePJC9JqDOGBwvXrxAixYtEBwcrNjIxq/69ttvMWjQIBQtWhQlSpTI05dC7sHqcgwdOhQhISFo3bp1vpc+X3e3w98VERGBNm3awM7OTpoTJyoqCqmpqfjtt98U6TSfIzw8/LVhTsnJXg1pzZo1mDZtGvr06ZPve4Ocnclz7N69GxMnTsT06dNRo0aNPCMBqzV6LdHbuLq6YvPmzahTp47e51pCQgKqV6+uzDhsityYrgE54xbodLp8l5xtSo1hYG5uLm7cuCGEeDkuRs64MRcuXFBsPIGcWmqMwVG0aFFx5coVxY7/qtKlS4s5c+YYrF6OIkWKiJ07dxqsXuXKlUX//v1FZmamtC4zM1MMGDBAVK5cWbG6U6ZMEUZGRqJWrVqiXbt2on379nqLVrzu/UHJ94ZXa+QsStYk5YWGhoq6desKJycn6b1/wYIFYtu2bYrVzMzMFPPmzRMffPCBcHR0FA4ODnqL3CwsLKTPstyfa9HR0cLW1lb2ekJwnJzXUvt0u5eXFw4fPpxnFuOffvoJ1apVU6yuWmNwdO/eHWvWrMGcOXMUq5HbgwcP8OmnnxqkVm6mpqYGveyZkJCAn376SW9sJWNjYwQGBiI0NFSxusHBwQgJCVHk7qJ/k1fPUBnCq5c2qOBbuXIlgoKCMHLkSMycOVO6Y9fBwQGLFi1Cu3btFKk7depUrF69GqNHj8akSZPwxRdf4MaNG9i2bZsil+xr1qyJnTt3YtiwYQD+byiA1atXK9bviCHnNV4NF4YWFBSEXr164c6dO8jOzsbWrVtx+fJlhIaGYseOHYrVVWsMjszMTKxduxb79u3L9xS83B2eP/30U+zduxcDBw6U9bhvM3r0aCxevBjLli0zyFgf1atXx6VLl6R5snJcunQp37E55PL8+XPUrVtXseP/GxnqLsiGDRsqXoMMa+nSpfj222/Rvn17vS96NWvWxJgxYxSru2HDBnz77bdo3bo1pkyZgq5du6JMmTLw8fHB8ePHMXz4cFnrzZo1Cy1btsTFixeRmZmJxYsX4+LFizh27BgOHToka60cDDlvEBUVhTFjxuDXX3/Nc5374cOHaN++PRYtWqTIh0W7du3w22+/Ydq0abCyskJQUBCqV6+O3377DR999JHs9XKoNQZHbGys1LH5ypUritXJ4enpicmTJ+P48eP59qWQ+487x5EjR3DgwAH8/vvvqFSpUp66cs+DNnz4cIwYMQIJCQlSSD1+/DiWL1+OOXPm6PU9k7NvWb9+/fDDDz9g8uTJsh3z30iNuyAjIiLeuF3JflaG9F8ZNRt4eeUgvzP0ZmZm0gS7SkhOTpYG4bO2tsbDhw8BvBy0VIm/3Q8//BDR0dGYM2cOvL29sXfvXlSvXh2RkZEcDFAN8+fPR5MmTfLtyGdnZ4ePPvoI8+bNw/fff69I/fr16yMsLEyRY+cnKysLt2/flj7srKysEBwcbJDahj4Fv2rVKlhbW+PQoUN5vkHodDrFQo69vT06dOigyLHz07VrVwDAuHHj8t2WM56N3INaPnv2DKtWrcK+ffvg4+OTJ8xpZdA6Ne6CzBklNrfcZwWVGJxUDW8aNfvOnTsqtEg57u7uiI6OznMFYffu3XrT3MitVKlSSEpKQunSpVGmTBkpdJw6dUqRQVgBoEyZMvj2228VOXZ+GHLe4MSJE2+8pa1NmzZYvXq1om149OiR3qBqRkZGsLa2VqSWsbExmjdvjkuXLhl8oLG+ffti8eLFeeZYevz4MYYNGyb73Thq9bky9C2baj3Pc+fOoWrVqgCQZyZuLQ3JHxoailWrVqFp06Z6lz6rVKkiDfYot1fvrMyZ52jy5MmKznNkKO8yarabm5sKLVNOYGAghgwZgmfPnkEIgZMnT2Ljxo2YPXu2op8xHTp0QHh4OGrXro1hw4ZJfSMTExMxatQoxepeuHBBL8AaGxtLfT9lp0h3Zo0wMzMT165de+32a9euyT4z99mzZ0XLli2lx9bW1np3UBgbG4uTJ0/KWjO3GjVqiH379il2/NcxMjISd+/ezbP+zz//FMbGxorWzs7OFtnZ2YrWIG1S6y7I/Bw8eFBUr17doDWV8KY71kxNTUW5cuXEb7/9pnYzZff9998LT09P6bmWLFlSrF692qBtiIyMFPPnzxfbt2+X9bgRERGiZs2a0uOcz7XcdwmGhYXJWjMHz+S8QbFixXD58uXXDroVFxcn+4iuS5cuxYcffqi37rvvvkPJkiUhhMDatWuxZMkSfPfdd7LWzTFjxgyMGTPGYGNwqDmRZGhoKObNm4f4+HgAL4foHzt2rKJ3BFWrVi3fMxk6nQ7m5ubw9PRE79690bhxY9lq/vHHHzhy5Ei+49UodVkuR0JCAq5evYoGDRrAwsJCujSmFWrdBZkfR0dHXL582aA1lZDzGnV3d8fp06fz9MnRKn9/f/j7++PJkydIT083yIjPs2fPhqOjI/r27Qvg5Y0nderUwdq1a/HVV19h/PjxstRZsWJFnvfVAwcOwNXVFUIILFmyBCtXrpQmopaVItFJI3r37i0+/PDDfLdlZ2eLevXqid69e8tas0KFCuLMmTPS49zfDoUQ4vjx46J06dKy1hRCiKlTp4r09HSDj8Hxap1XF2NjYzFjxgzZ686fP19YWlqKcePGiV9//VX8+uuvYuzYscLS0lIsWLBA9no5JkyYIOzs7MSHH34oAgMDRWBgoKhfv76ws7MTI0aMEB999JEwMjKSbWyMdevWCVNTU2FtbS1cXV2Fm5ubtLi7u8tSIz9//fWXaNKkifT/m/Ma7tOnjwgMDFSsrqFt27ZN2NnZiTlz5ghLS0sxb9480a9fP2Fqair27t2rSM2YmBi9JTo6Wvz++++iYcOGol69eorUNLTnz5+LJk2aGHTsrP8iV1dXcfTo0Tzrjx8/Ltzc3GSr4+npKc6fPy89fvVz7cyZM8LJyUm2erkx5LxBQkKCsLOzE7Vq1RKbN28W0dHRIjo6WmzatEl88MEHws7OTsTHx8ta08LCQty6dUt6vGDBAvHw4UPp8c2bN4WZmZmsNYX4v8tFBw8efOMit4MHD4oDBw4InU4ntm7dqlfr2LFj4s6dO7LXFEIINzc3sX79+jzrQ0JCZP3jflW/fv3EtGnT8qyfPn266NevnxBCiKCgIFGjRg1Z6pUqVUrMmDFDZGVlyXK8d9WjRw/h5+cnbt26pfeGtnv3buHl5WXQtigtIiJCNGvWTBQrVkxYWFiIevXqiT179ihW73UDlfr6+opLly4pVtfQDD1AqJr++usvMXjwYFGxYkVRpEgRxQfly/G6LhlXr16V9XPG3NxcJCYmSo9//vln8fjxY+nxjRs3hKmpqWz1cuPlqjcoU6YM9u3bh969e6NLly7SaXYhBLy8vBAWFib7wG7m5ua4efMmSpUqBQB5On/dunVLkdmOxf/v3GzoMThy6l2/ft2gE0kmJSXlO45L3bp1kZSUpFjdLVu2ICoqKs/6Ll26oEaNGvj222/RtWtX2e4+evLkCbp06WLwCTr37t2LPXv2SK/jHGXLlsXNmzcN2halGfouyFc7k+fMc2SIMXoMydADhKqpR48eSEhIQEBAABwdHQ12SdfFxQVHjx7N0yXj6NGjcHZ2lq2OjY0Nrl69ChcXFwB5Zz+/fv26YtORMOS8Rc2aNREbG4vo6GjEx8dDCIFy5cpJd47IrVq1ati2bRvq1auX7/atW7cqdq1fzb4Srq6uSE1NxcmTJ/PtO9KzZ09Z63l6emLLli34/PPP9dbnjAmkFHNzcxw7dixPOD527Jj0IZWdnS3bB1ZAQAB+/PFHRSa+e5PHjx/nG8ZTUlIUuzVVDadOnUJ2djZq166tt/7EiRMwNjaW5guTU34Dlaampmou5Bh6gFA1HT58GEeOHFF0gM789O/fHyNHjsSLFy/QpEkTAC/nnBs3bhxGjx4tW53atWsjNDQ03+EPACAkJCTP35BcGHLeUdWqVRULNrkNHjwYXbp0gZubGwYNGiR9A8/KysKKFSuwdOlS/PDDD4rULleu3FuDTkpKiiK1f/vtN/j7+yM9PR22trZ5JsyUO+RMnToVnTt3RkREhBQojx49ivDwcGzZskXWWrkNGzYMAwcORFRUFD744AMALz8oV69eLQWuPXv2yPZamz17Nj7++GPs3r0730EPlfqgqF+/PkJDQzF9+nQAL/8Ps7OzMXfuXFk7VattyJAhGDduXJ436Dt37uCrr77CiRMnZK/51Vdfwc3NDZ07dwYAdOrUCT/99BOcnJywa9cug39QKuVNA4RqqfM6AFSoUAFPnz41eN2xY8fi/v37GDx4sDSdj7m5OcaPH4+JEyfKVicwMBDNmjVDkSJFMHbsWKlT9b179/DVV1/h+++/x969e2WrlxtnIf8XGj9+PObNmwcbGxt4eHgAAK5du4b09HQEBgZi3rx5stc0MjLCokWL9MakyE+vXr1krw28DFitWrXCrFmzFLkcl5+oqCgsXLgQly5dAgBUrFgRo0ePVvyumA0bNmDZsmXSnTDly5fHsGHD0K1bNwDA06dPpbut/qkZM2YgKCgI5cuXz3MaXKfTYf/+/f+4Rn5iY2PRtGlTVK9eHfv370fbtm1x4cIFpKSk4OjRoyhTpowidQ3N2toa586dk/5Oc1y/fh0+Pj549OiR7DXd3d2xYcMG1K1bF2FhYejUqRM2b96MLVu2IDExUbEPC1LOqVOnMGHCBAQFBaFy5cp5vowoPbN8eno6Ll26BAsLC5QtW1aRs60rVqzAqFGjkJmZKX2RffjwIUxMTDB//nwMHTpU9poAQ86/1vHjx7Fx40bp9uayZcuia9euis0fZWRkhOTkZIPctpgfKysrnD9/Ps+HBf0zDg4OWLhwIXr37m3w2g8fPsSyZcsQExOD9PR0VK9eHUOGDIGTk5PB26KUIkWKYMeOHXkmFzx27Bhat26dZ+A+OVhYWODKlStwcXHBiBEj8OzZM3zzzTe4cuUKateurUhNNWl9GAIAiI+PR7du3XDmzBm99UKB0cjVdOvWLfz00096n2v/+9//pL46SuDlqn+pnPEKDEXtNw0/Pz+cPn1a8ZCTlpb2Tvsp/c3JUMzMzF7bv0tJiYmJcHFxwRdffJHvttKlSxu8TUpo3rw5Jk6ciF9//VU6C5qamorPP/9csTnmHBwccOvWLbi4uGD37t2YMWMGgJcfiFr5MASA+/fvo1OnTjhw4AB0Oh3i4+Ph4eGBgIAAODg4YP78+Wo3UTb+/v4oVKgQfvjhB4N2PDY0FxcXRUdSzg9DzltkZmZi1qxZ6Nu3b547RbRE7RN6rVu3xtixY3Hx4sV8+460bdtWljr29vZvfANR+ptTVlYWFi5cKF1ayLkOnkPuPk8jRozA0qVLsWTJElmP+zbu7u5ISkrKc2bw/v37cHd318yH8ddff40GDRrA1dVVuswZHR0NR0dHxQbs/OSTT9CtWzeULVsW9+/fR8uWLQEAZ8+elf1uTzWNGjUKhQoVQmJiot78TZ07d0ZgYKCmQk5sbCzOnj2L8uXLq90UzWHIeQsTExPMmzdP9o6v/zav3s1kaDmTG06bNi3PNjlDR+6JQIUQaNWqFVavXo2SJUvKcvy3mTp1KlavXo3Ro0dj0qRJ+OKLL3Djxg1s27YNQUFBstc7efIk9u/fjx07dhhk1vMcr7ukkJ6erqm7gEqWLIlz585hw4YNiImJgYWFBfr06YOuXbvm+V3LZeHChXBzc8OtW7cwd+5caS67pKQkDB48WJGaavgvDUNQs2ZN3Lp1iyFHAQw576BJkyY4dOiQ5iaF+zcxVMh6dRwgY2Nj1KlTx2B9gTZs2IBvv/0WrVu3xpQpU9C1a1eUKVMGPj4+OH78uOzTLNjb2+cZk0JJgYGBAF4G08mTJ+t1Is/KysKJEycMcpeiIVlZWWHAgAEGq1eoUCGMGTMmz3pDXwZQ2n9lGALg5V2XI0aMwNixY/M9k+3j46NSywo+hpx30LJlS0yYMAHnz5/Pd7wGuS6l/Be1atUKGzdulPozzJkzBwMHDpRmQb9//z7q16+PixcvqthK+SQnJ8Pb2xvAyztzHj58CAD4+OOPMXnyZNnrGXrW87NnzwJ4eSbn/PnzMDU1lbaZmpqiSpUq+X5AF1Tr169H0aJF0bp1awDAuHHjsGrVKnh5eWHjxo35jmlTEGuq4b8yDAEAaTiAnDmkgJfPV0sdj7OysnD06FH4+PhI7+8Gocg4yhrzpllxlZjPKbd79+6Jw4cPi8OHD4t79+4pWksNr84+bmNjozenSXJysqK/41fnUFFauXLlxPHjx4UQQtSrV0/Mnj1bCCHEpk2bRLFixRSra+jXUe/evfWmI9GqcuXKifDwcCGEEMeOHRMWFhbim2++EW3atBEdOnQwSE1LS0vFa6rh/Pnzonjx4qJFixbC1NRU/O9//xMVK1YUjo6OIiEhQe3myerGjRtvXLTiddNIKIkh518qPT1d9OnTR5iYmEiBysTERPTt21dvzo+CTqfT6YWcV0OHIUKOIf/oxo8fL2bOnCmEeBlsTExMhKenpzA1NRXjx4+XvV7O68jY2FjTryO1WFhYiJs3bwohhBg3bpzo0aOHEEKI2NhYUbRoUc3UVEtqaqqYMWOG+PTTT0XLli3FF198If744w+1m0V/U40aNcS+ffsMWpOXq97Ts2fPDNJxMjAwEIcOHcL27dulW4CPHDmC4cOHY/To0Vi5cqXibdCiV/unPHv2DAMHDsxzCVKpDrm55+Hp3LkzSpcujcjISJQtWxZt2rSRvV7O6+i3334z6Ovo8ePHmDNnDsLDw/OdpuPatWuK1DU0a2tr3L9/H6VLl8bevXulPknm5uaKjWCrRk1D+eSTTxASEgJbW1uEhoaic+fO+Q5DoEV//PEHjhw5ku/fi9x99dQyY8YMjBkzBtOnT8+364cSQ3dwMMB3kJWVhVmzZiE4OBh3797FlStX4OHhgcmTJ8PNzQ0BAQGy1yxatCh++umnPHN9HDhwAJ06dcKff/4pe001GBsbIzk5GcWKFQPwciK3c+fOSRPG3b17F87OzrJdk+7Tp8877WfovixKUet11LVrVxw6dAg9evSAk5NTnjutRowYoUhdQ/P390dcXByqVauGjRs3IjExEUWKFMH27dsxceJEXLhwQRM1DcXU1BQ3b96Ek5MTjI2N8x2GQItCQkLw2WefwdTUFEWKFMkzMrlWvhTknig493MUCvY94pmcdzBz5kysX78ec+fOlW51BoDKlStj0aJFioScJ0+ewNHRMc/64sWL48mTJ7LXU4sQAr1795bulnj1zEpGRoas9dQIL9u3b0fLli1RqFAhbN++/Y37yt2JXa3X0e+//46dO3eqMhChIS1fvhyTJk3CrVu38PPPP6NIkSIAXk4Z0rVrV83UNJQKFSpg4sSJaNy4MYQQ2LJly2u/3WtpWI/JkycjKCgIEydO1AsCWpN7CA9D4Zmcd+Dp6YlvvvkGTZs2hY2NDWJiYuDh4YG4uDj4+voqMox606ZNUaRIEYSGhkqXx54+fYpevXohJSUF+/btk72mGv4LZ1ZyT5nxpjcwJb7JqPU6cnd3x65du/QGcfsvePToETZu3IjVq1cjKirKIHfFqFFTKceOHUNgYCCuXr2KlJQU2NjY5Dvekk6nU2yyYDUUKVIEJ0+e1Mycbv8mDDnvwMLCAnFxcXB1ddULORcvXkStWrWQnp4ue83Y2Fj4+fkhIyNDmlU4JiYG5ubm2LNnDypVqiR7TdIetV5H33//PX799VesX7/eYBOuqikiIgJr1qzBzz//DGdnZ3zyySfo2LGjNNO8Vmoaktrz6RnSuHHjULhwYUyYMEHtpiguNTUVa9askSZGrlSpEvr27fvWyaH/Loacd1CjRg2MGjUK3bt31ws506ZNQ1hYGA4fPqxI3SdPnmDDhg2Ii4sD8HKWbH9/f1hYWChSj5SVnZ2NkJAQbN26FTdu3IBOp4OHhwc6duyIHj16KDZfjRqvo2rVquHq1asQQsDNzS3P4GavTkRYECUnJyMkJARr1qxBWloaOnXqhODgYMTExMDLy0szNdVy8+ZNlC5dWrPzOOWWlZWFjz/+GE+fPs13MMAFCxao1DJ5nT59Gn5+frCwsECtWrUAvJyB/enTp9i7dy+qV68ue032yXkHQUFB6NWrF+7cuYPs7Gxs3boVly9fRmhoKHbs2KFYXUtLS70+QFRwCSHQtm1b7Nq1C1WqVIG3tzeEELh06RJ69+6NrVu3Ytu2bYrUVuN11L59e4PWM7Q2bdogIiICrVu3xqJFi9CiRQsYGxsjODhYUzXVMHnyZHz55ZevHdQwMTERAQEBCAsLM3DLlDN79mzs2bNHmtbh1Y7HWjFq1Ci0bdsW3377LUxMXsaPzMxM9OvXDyNHjkRERIT8RQ16w3oBFhERIZo1ayaKFSsmLCwsRL169cSePXsUrXnlyhXxzTffiOnTp4upU6fqLVSwrF27VtjY2Ij9+/fn2RYeHi5sbGzE+vXrZat3+vRp0ahRo3wH5EtNTRWNGjUS0dHRstX7rzE2NhajRo0SV65c0VtvYmIiLly4oJmaanBxcRFVq1YV58+fz7MtODhY2NjYiBYtWqjQMuXY29uLdevWqd0MxZmbm4tLly7lWX/hwgVhYWGhSE3tduOWWf369REWFoZ79+7hyZMnOHLkCJo3b65YvW+//RYVK1ZEUFAQfvrpJ/zyyy/SotQ3flLOxo0b8fnnn+c7HH2TJk0wYcIEbNiwQbZ68+fPR5MmTfK9M8XOzg4fffQR5s2bJ1u914mKisL333+P77//XpryQQuOHDmCR48eoUaNGqhduzaWLVuGv/76S3M11RAbGwtvb2/UrFkTs2fPRnZ2NhITE9GsWTOMGzcOX3/9NX7//Xe1mykrMzMzzd+JCLwcBycxMTHP+lu3bsHGxkaZoopEJ43p2bOnOHTokEFrli5dWsyZM8egNUk5jo6O4uzZs6/dfubMGeHo6ChbPQ8PDxETE/Pa7efOnRPu7u6y1XvV3bt3RePGjYVOpxMODg7CwcFB6HQ60aRJE01NT5Keni7WrFkj6tWrJwoVKiSMjIzEokWLRFpamqZqqmHbtm3C0dFRVKlSRdja2opmzZppaoqD3GbNmiWGDRumdjMUN2zYMFGqVCmxadMmkZiYKBITE8XGjRtFqVKlxIgRIxSpyZDzDtq1aycKFSokPD09xcyZM8Xt27cVr/nqHE5UsBUqVOiNw9HfuXNHmJqaylbvbXPEXLt2TZibm8tW71WdOnUSNWvWFBcvXpTWXbhwQdSsWVN06dJFsbpqiouLE2PHjhUlSpQQ5ubmok2bNpqsaSjJycmiWbNmQqfTCWtra3Hw4EG1m6SY9u3bC1tbW+Hu7i4+/vhj0aFDB71FKzIyMsTw4cOFqampMDIyEkZGRsLMzEyMHDlSPHv2TJGavFz1DrZt24Y7d+5g0KBB2Lx5M9zc3NCyZUv89NNPePHihSI1P/30U+zdu1eRY5PhZWVlSR3t8mNsbIzMzEzZ6hUrVgyXL19+7fa4uDgULVpUtnqv2r17N1asWKE3To6XlxeWL1+uuUsNOcqXL4+5c+fi9u3b2Lhxo2ZrGsLGjRvh5eWF7OxsXLp0CYMGDULz5s0xatQoPHv2TO3myc7e3h6ffPIJGjZsiKJFi8LOzk5v0QpTU1MsXrwYDx48QHR0NKKjo5GSkoKFCxdKA8LKjbeQ/w1nzpzBunXrsHr1alhbW6N79+4YPHgwypYtK1uN2bNnY8GCBWjdunW+txRqZS6T/wojIyO0bNnytX/IGRkZ2L17t6zTVyQkJOQ7vIEQAvXr10fZsmUVG2TRxsYGhw8fRtWqVfXWnz17Fg0bNkRaWpoidang69ixI/bs2YPZs2dj2LBh0vpjx45Jg4eGhITA19dXrSZSAcKQ856SkpIQGhqKdevW4fbt2+jYsSPu3LmDQ4cOYe7cuRg1apQsdXLmbsqPluYy+a8w9MjOV69eRY0aNVC+fHmMHj1aujU1Li4O8+fPx5UrV3D69Gl4enrKUu9V7dq1Q2pqKjZu3AhnZ2cAwJ07d+Dv7w8HBwf88ssvitSlgq9evXoICQnJ90vj06dPMWHCBKxcuRLPnz9XoXX0T6gxcS9Dzjt48eIFtm/fjnXr1mHv3r3w8fFBv3790K1bN+nulV9++QV9+/ZVZIoHor/j9OnT6N27Ny5evCiNtSGEgJeXF9atW6foyLi3bt1C27ZtceHCBbi4uEjrKleujO3bt6NUqVKK1aaCLTs7+63zN0VERKBBgwYGapEyqlevjvDwcDg4OKBatWpvHA9HC4NnAupM3MvBAN+Bk5MTsrOz0bVrV5w8eTLPKXgAaNy4Mezt7RWpn5NDtTQoFCmvZs2aiI2NRXR0NOLj4yGEQLly5fJ9/crNxcUFZ86cwb59+/RGWm7WrJnitalge5cJKgt6wAFenu3MuXyt9cEzc6gxcS/P5LyD7777Dp9++qk0waGhhIaGYt68eYiPjwcAlCtXDmPHjkWPHj0M2g6id7V//34MHToUx48fzzNGz8OHD1G3bl0EBwejfv36KrWQiNSixsS9vLvqHfTo0UMKOLdv38bt27cVr7lgwQIMGjQIrVq1wpYtW7Blyxa0aNECAwcOxMKFCxWvT/R3LFq0CP3793/tIISfffaZZubhIaL3M336dAQFBeHJkycGq8kzOe8gOzsbM2bMwPz586UZx21sbDB69Gh88cUX73R69X25u7tj6tSp6Nmzp9769evXY8qUKbh+/brsNYn+KVdXV+zevfu139Ti4uLQvHnzfEc9JSJtU2PiXvbJeQdffPEF1qxZgzlz5kjXEo8cOYIpU6bg2bNnmDlzpuw1k5KSULdu3Tzr69ati6SkJNnrEcnh7t27ed64cjMxMcGff/5pwBYR0b+FGn2PGHLewfr167F69Wq0bdtWWufj44OSJUti8ODBioQcT09PbNmyBZ9//rne+s2bN8s6Hg+RnEqWLInY2NjX3pp+7tw5ODk5GbhVRPRv8OWXXxq8JkPOO0hJSUGFChXyrK9QoQJSUlIUqTl16lR07twZERER0tmjo0ePIjw8HFu2bFGkJmnT4cOH8c033+Dq1av46aefULJkSXz33Xdwd3fHhx9+KGutVq1aYfLkyWjRokWejvpPnz7Fl19+iY8//ljWmkRUsERFReHSpUsAgEqVKqFatWqK1WKfnHdQu3Zt1K5dG0uWLNFbP2zYMJw6dQrHjx9XpG5UVBQWLlwovRgqVqyI0aNHK/qCIG35+eef0aNHD/j7++O7777DxYsX4eHhgWXLlmHXrl3YtWuXrPXu3r2L6tWrw9jYGEOHDtUbhHD58uXIysrCmTNn4OjoKGtdooLu9u3b2L59OxITE/MMdKiVzvr37t1Dly5dcPDgQWnIldTUVDRu3BibNm1CsWLF5C+qyIxYGnPw4EFhZWUlKlasKPr27Sv69u0rKlasKKytrUVERITazSN6rapVq4r169cLIYSwtraWJn2Ve9bz3G7cuCFatmwpjIyMhE6nEzqdThgZGYmWLVu+cdJQov+qffv2CUtLS1G5cmVhYmIiqlatKuzt7YWdnZ1o3Lix2s2TjRoT9/JMzjv6448/sHz5cr2BzQYPHiwNWS+Xd53TJ79bdIleZWlpiYsXL8LNzQ02NjaIiYmBh4cHrl27Bi8vL0UnO3zw4AESEhIghEDZsmXh4OCgWC2igqxWrVpo2bIlpk6dKv2dFi9eHP7+/mjRogUGDRqkdhNlYWdnh3379uUZbf3kyZNo3rw5UlNTZa/JPjnvyNnZOU8H49u3b2PAgAFYtWqVbHXs7e3fOLKxEAI6nU62iRxJ20qUKIGEhAS4ubnprT9y5Ag8PDwUre3g4KDo1BFEWnHp0iVpFnkTExM8ffoU1tbWmDZtGtq1a6eZkJOdnZ3v3ZeFChXKM4+VXBhy/oH79+9jzZo1soacAwcOSP8WQqBVq1ZYvXo1SpYsKVsN+u/o378/RowYgbVr10Kn0+GPP/5AZGQkxowZg8mTJ6vdPCICYGVlJfXDcXJywtWrV1GpUiUAwF9//aVm02TVpEkTjBgxIs/EvaNGjULTpk0VqcmQ8y/TsGFDvcfGxsaoU6eO4t+6SZsmTJiA7OxsNG3aFE+ePEGDBg1gZmaGMWPGYNiwYWo3j4gA1KlTB0eOHEHFihXRqlUrjB49GufPn8fWrVtRp04dtZsnm2XLlqFt27Zwc3PLM3Hv999/r0hN9sn5B2JiYlC9enVFLx3l7kdB9Hc9f/4cCQkJSE9Ph5eXF6ytrdVuEhH9f9euXUN6ejp8fHzw+PFjjB49GseOHUPZsmWxYMECuLq6qt1E2QghDDpxL0POP8CQQ0RE9O/Fy1Vv8Mknn7xxuxI9wfPzpo7IRK962+s2t61btyrYEiJ6H6dPn5bGRfPy8kKNGjVUbpH8wsPDER4ejnv37uXpbLx27VrZ6zHkvIGdnd1bt786geY/9eoH1LNnzzBw4EBYWVnpreeHE71O7tetEAK//PIL7OzsULNmTQAvB5lMTU19rzBERMq5ffs2unbtiqNHj+oNkle3bl1s2rQJpUqVUreBMpk6dSqmTZuGmjVrwsnJySBf4Hm56l+mT58+77TfunXrFG4JacH48eORkpKC4OBgGBsbAwCysrIwePBg2NraYt68eSq3kIhatGiB1NRUrF+/Xhol/PLly+jTpw9sbW2xe/dulVsoDycnJ8ydOxc9evQwWE2GHCINK1asGI4cOSK9cea4fPky6tati/v376vUMiLKYWFhgWPHjuWZsicqKgr169fHkydPVGqZvIoUKYKTJ0+iTJkyBqtpZLBKRGRwmZmZ0l0MucXFxSk2+BYRvR8XFxe8ePEiz/qsrCzZR9VXU79+/fDDDz8YtCb75BBpWJ8+fRAQEICrV6+iVq1aAIATJ05gzpw573xplIiUNW/ePAwbNgzLly+X+s6dPn0aI0aMwNdff61y6/6ZwMBA6d/Z2dlYtWoV9u3bBx8fnzyjHysxESkvVxFpWHZ2Nr7++mssXrwYSUlJAF5eFx8xYgRGjx4t9dMhIvU4ODjgyZMnyMzMhInJy3MPOf9+9aaTlJQUNZr4tzVu3Pid9tPpdNi/f7/s9RlyiP4jciZ/5eSuRP8u69evf+d9e/XqpWBLtIchh4iIiDSJfXKINKZatWrvPP7EmTNnFG4NEb2re/fu5TtIno+Pj0otKvgYcog0pn379mo3gYjeQ1RUFHr16oVLly7h1YsrOp1O0amDtI6Xq4iIiFRUpUoVlClTBuPHj4ejo2OeM7FamqDT0BhyiP4DoqKipDlxKlWqlGfQMSJSj42NDc6ePQtPT0+1m6I5vFxFpGH37t1Dly5dcPDgQb05cRo3boxNmzahWLFi6jaQiNC0aVPExMQw5CiAZ3KINKxz5864du0aQkNDUbFiRQDAxYsX0atXL3h6emLjxo0qt5CI/vrrL/Tq1Qu1atVC5cqV8wyS17ZtW5VaVvAx5BBpmJ2dHfbt24cPPvhAb/3JkyfRvHlzpKamqtMwIpL89ttv6NGjhzSWVW7sePzPcO4qIg3Lzs7O860QAAoVKsS5q4j+JYYNG4bu3bsjKSkJ2dnZegsDzj/DMzlEGtauXTukpqZi48aN0kR/d+7cgb+/PxwcHPDLL7+o3EIisrGxQXR0tEFn5/6v4JkcIg1btmwZ0tLS4ObmhjJlyqBMmTJwd3dHWloali5dqnbziAjAJ598ggMHDqjdDE3i3VVEGubi4oIzZ85g3759iIuLAwBUrFgRzZo1U7llRJSjXLlymDhxIo4cOQJvb+88l5iHDx+uUssKPl6uIiIiUpG7u/trt+l0Oly7ds2ArdEWhhwiDYqMjMT9+/fx8ccfS+tCQ0Px5Zdf4vHjx2jfvj2WLl0KMzMzFVtJRKQs9skh0qBp06bhwoUL0uPz588jICAAzZo1w4QJE/Dbb79h9uzZKraQiPIjhMgzfxX9fQw5RBoUHR2Npk2bSo83bdqE2rVr49tvv0VgYCCWLFmCLVu2qNhCIsotNDQU3t7esLCwgIWFBXx8fPDdd9+p3awCjx2PiTTowYMHcHR0lB4fOnQILVu2lB5/8MEHuHXrlhpNI6JXLFiwAJMnT8bQoUNRr149AMCRI0cwcOBA/PXXXxg1apTKLSy4GHKINMjR0RHXr1+Hi4sLnj9/jjNnzmDq1KnS9kePHuU7SCARGd7SpUuxcuVK9OzZU1rXtm1bVKpUCVOmTGHI+Qd4uYpIg1q1aoUJEybg8OHDmDhxIiwtLVG/fn1p+7lz5zjwGNG/RFJSEurWrZtnfd26dZGUlKRCi7SDIYdIg6ZPnw4TExM0bNgQ3377Lb799luYmppK29euXYvmzZur2EIiyuHp6ZlvH7nNmzejbNmyKrRIO3gLOZGGPXz4ENbW1jA2NtZbn5KSAmtra73gQ0Tq+Pnnn9G5c2c0a9ZM6pNz9OhRhIeHY8uWLejQoYPKLSy4GHKIiIhUFhUVhYULF+LSpUsAXo5MPnr0aFSrVk3llhVsDDlERESkSeyTQ0REpKJdu3Zhz549edbv2bMHv//+uwot0g6GHCIiIhVNmDABWVlZedYLITBhwgQVWqQdDDlEREQqio+Ph5eXV571FSpUQEJCggot0g6GHCIiIhXZ2dnlO9N4QkICrKysVGiRdjDkEBERqahdu3YYOXIkrl69Kq1LSEjA6NGj0bZtWxVbVvDx7ioiIiIVPXz4EC1atMDp06dRqlQpAMDt27dRv359bN26Ffb29uo2sABjyCEiIlKZEAJhYWGIiYmRZiFv0KCB2s0q8BhyiIiISJPYJ4eIiIg0iSGHiIiINIkhh4iIiDSJIYeIiIg0iSGHiIhIZVevXsWkSZPQtWtX3Lt3DwDw+++/48KFCyq3rGBjyCEiIlLRoUOH4O3tjRMnTmDr1q1IT08HAMTExODLL79UuXUFG0MOERGRiiZMmIAZM2YgLCwMpqam0vomTZrg+PHjKras4GPIISIiUtH58+fRoUOHPOuLFy+Ov/76S4UWaQdDDhERkYrs7e2RlJSUZ/3Zs2dRsmRJFVqkHQw5REREKurSpQvGjx+P5ORk6HQ6ZGdn4+jRoxgzZgx69uypdvMKNE7rQEREpKLnz59jyJAhCAkJQVZWFkxMTJCVlYVu3bohJCQExsbGajexwGLIISIiUokQArdu3UKxYsXw119/4fz580hPT0e1atVQtmxZtZtX4DHkEBERqSQ7Oxvm5ua4cOECQ40C2CeHiIhIJUZGRihbtizu37+vdlM0iSGHiIhIRXPmzMHYsWMRGxurdlM0h5eriIiIVOTg4IAnT54gMzMTpqamsLCw0NuekpKiUssKPhO1G0BERPRftnDhQuh0OrWboUk8k0NERESaxD45REREKjI2NpZmHs/t/v37HCPnH2LIISIiUtHrLqhkZGToTdhJ7499coiIiFSwZMkSAIBOp8Pq1athbW0tbcvKykJERAQqVKigVvM0gX1yiIiIVODu7g4AuHnzJkqVKqV3acrU1BRubm6YNm0aateurVYTCzyGHCIiIhU1btwYW7duhYODg9pN0RyGHCIiItIk9skhIiJSUVZWFkJCQhAeHo579+4hOztbb/v+/ftValnBx5BDRESkohEjRiAkJAStW7dG5cqVOTCgjHi5ioiISEVFixZFaGgoWrVqpXZTNIfj5BAREanI1NQUnp6eajdDkxhyiIiIVDR69GgsXrz4tYMC0t/Hy1VEREQq6tChAw4cOIDChQujUqVKKFSokN72rVu3qtSygo8dj4mIiFRkb2+PDh06qN0MTeKZHCIiItIk9skhIiJSWWZmJvbt24dvvvkGjx49AgD88ccfSE9PV7llBRvP5BAREano5s2baNGiBRITE5GRkYErV67Aw8MDI0aMQEZGBoKDg9VuYoHFMzlEREQqGjFiBGrWrIkHDx7AwsJCWt+hQweEh4er2LKCjx2PiYiIVHT48GEcO3YMpqameuvd3Nxw584dlVqlDTyTQ0REpKLs7GxkZWXlWX/79m3Y2Nio0CLtYMghIiJSUfPmzbFo0SLpsU6nQ3p6Or788ktO9fAPseMxERGRim7fvg0/Pz8IIRAfH4+aNWsiPj4eRYsWRUREBIoXL652EwsshhwiIiKVZWZmYvPmzYiJiUF6ejqqV68Of39/vY7I9P4YcoiIiEiT2CeHiIiINIkhh4iIiDSJIYeIiIg0iSGHiIiINIkhh4iISEUeHh64f/9+nvWpqanw8PBQoUXawZBDRESkohs3buQ74nFGRgandfiHOHcVERGRCrZv3y79e8+ePbCzs5MeZ2VlITw8HG5ubiq0TDs4Tg4REZEKjIxefzGlUKFCcHNzw/z58/Hxxx8bsFXawpBDRESkInd3d5w+fRpFihRRuymawz45REREKnnx4gU8PDyQkpKidlM0iSGHiIhIJYUKFcK5c+fUboZmMeQQERGpqHv37lizZo3azdAk3l1FRESkoszMTKxduxb79u1DjRo1YGVlpbd9wYIFKrWs4GPIISIiUlFsbCyqV68OALhy5YreNp1Op0aTNIN3VxEREZEmsU8OERHRv0BCQgL27NmDp0+fAgB4DuKfY8ghIiJS0f3799G0aVOUK1cOrVq1QlJSEgAgICAAo0ePVrl1BRtDDhERkYpGjRqFQoUKITExEZaWltL6zp07Y/fu3Sq2rOBjx2MiIiIV7d27F3v27EGpUqX01pctWxY3b95UqVXawDM5REREKnr8+LHeGZwcKSkpMDMzU6FF2sGQQ0REpKL69esjNDRUeqzT6ZCdnY25c+eicePGKras4OMt5ERERCqKjY1F06ZNUb16dezfvx9t27bFhQsXkJKSgqNHj6JMmTJqN7HAYsghIiJS2cOHD7Fs2TLExMQgPT0d1atXx5AhQ+Dk5KR20wo0hhwiIiID++STTxASEgJbW1uEhoaic+fO7H+jAIYcIiIiAzM1NcXNmzfh5OQEY2NjJCUloXjx4mo3S3N4CzkREZGBVahQARMnTkTjxo0hhMCWLVtga2ub7749e/Y0cOu0g2dyiIiIDOzYsWMIDAzE1atXkZKSAhsbm3wn49TpdEhJSVGhhdrAkENERKQiIyMjJCcn83KVAjhODhERkYquX7+OYsWKqd0MTWLIISIiUsHkyZORmZkJV1fXfC9VJSYm4qOPPlKhZdrBkENERKSC9evX44MPPkBsbGyebd988w0qV64MExPeH/RPMOQQERGpIDY2Ft7e3qhZsyZmz56N7OxsJCYmolmzZhg3bhy+/vpr/P7772o3s0Bjx2MiIiIV/frrr/jss89QokQJXL9+HbVq1cLq1avh6uqqdtMKPJ7JISIiUlGdOnXg7e2Nc+fOITs7G5MmTWLAkQlDDhERkUo2btwILy8vZGdn49KlSxg0aBCaN2+OUaNG4dmzZ2o3r8Dj5SoiIiIVdOzYEXv27MHs2bMxbNgwaf2xY8fQp08fAEBISAh8fX3VamKBx27bREREKkhOTsbZs2dRtmxZvfV169ZFdHQ0JkyYgIYNG+L58+cqtbDg45kcIiIiFWRnZ8PI6M29RiIiItCgQQMDtUh7GHKIiIhIk9jxmIiIiDSJIYeIiIg0iSGHiIiINIkhh4gKtOfPn2PWrFm4dOmS2k0hon8ZhhwiKtBGjx6N8+fPo0KFCgapd/DgQeh0OqSmphqkHhH9fQw5RKSY5ORkDBs2DB4eHjAzM4OLiwvatGmD8PDwd/r5kJAQ2Nvbv3b7li1bcOHCBaxfvx46nU6mVr9Z3bp1kZSUBDs7O4PUI6K/j4MBEpEibty4gXr16sHe3h7z5s2Dt7c3Xrx4gT179mDIkCGIi4v7xzU6deqETp06ydDad/PixQuYmpqiRIkSBqtJRH8fz+QQkSIGDx4MnU6HkydPomPHjihXrhwqVaqEwMBAHD9+HACwYMECeHt7w8rKCi4uLhg8eDDS09MBvLws1KdPHzx8+BA6nQ46nQ5TpkwBAGRkZGDMmDEoWbIkrKysULt2bRw8eFCv/rfffgsXFxdYWlqiQ4cOWLBgQZ6zQitXrkSZMmVgamqK8uXL47vvvtPbrtPpsHLlSrRt2xZWVlaYOXNmvperjhw5gvr168PCwgIuLi4YPnw4Hj9+LOvvk4j+BkFEJLP79+8LnU4nZs2a9cb9Fi5cKPbv3y+uX78uwsPDRfny5cWgQYOEEEJkZGSIRYsWCVtbW5GUlCSSkpLEo0ePhBBC9OvXT9StW1dERESIhIQEMW/ePGFmZiauXLkihBDiyJEjwsjISMybN09cvnxZLF++XBQuXFjY2dlJtbdu3SoKFSokli9fLi5fvizmz58vjI2Nxf79+6V9AIjixYuLtWvXiqtXr4qbN2+KAwcOCADiwYMHQgghEhIShJWVlVi4cKG4cuWKOHr0qKhWrZro3bu3jL9RIvo7GHKISHYnTpwQAMTWrVvf6+d+/PFHUaRIEenxunXr9IKJEELcvHlTGBsbizt37uitb9q0qZg4caIQQojOnTuL1q1b62339/fXO1bdunVF//799fb59NNPRatWraTHAMTIkSP19nk15AQEBIgBAwbo7XP48GFhZGQknj59+vYnTUSK4eUqIpKdeMfZYvbt24emTZuiZMmSsLGxQY8ePXD//n08efLktT9z/vx5ZGVloVy5crC2tpaWQ4cO4erVqwCAy5cvo1atWno/9+rjS5cuoV69enrr6tWrl+dW9Jo1a77xOcTExCAkJESvLX5+fsjOzsb169ff+jsgIuWw4zERya5s2bLQ6XRv7Fx848YNfPzxxxg0aBBmzpyJwoUL48iRIwgICMDz589haWmZ78+lp6fD2NgYUVFRMDY21ttmbW0t6/MAACsrqzduT09Px2effYbhw4fn2Va6dGnZ20NE744hh4hkV7hwYfj5+WH58uUYPnx4nqCQmpqKqKgoZGdnY/78+dJMzFu2bNHbz9TUFFlZWXrrqlWrhqysLNy7dw/169fPt3758uVx6tQpvXWvPq5YsSKOHj2KXr16SeuOHj0KLy+v93qu1atXx8WLF+Hp6fleP0dEyuPlKiJSxPLly5GVlYVatWrh559/Rnx8PC5duoQlS5bA19cXnp6eePHiBZYuXYpr167hu+++Q3BwsN4x3NzckJ6ejvDwcPz111948uQJypUrB39/f/Ts2RNbt27F9evXcfLkScyePRs7d+4EAAwbNgy7du3CggULEB8fj2+++Qa///673lg6Y8eORUhICFauXIn4+HgsWLAAW7duxZgxY97reY4fPx7Hjh3D0KFDER0djfj4ePz6668YOnToP/8lEtE/o3anICLSrj/++EMMGTJEuLq6ClNTU1GyZEnRtm1bceDAASGEEAsWLBBOTk7CwsJC+Pn5idDQUL1OvUIIMXDgQFGkSBEBQHz55ZdCCCGeP38ugoKChJubmyhUqJBwcnISHTp0EOfOnZN+btWqVaJkyZLCwsJCtG/fXsyYMUOUKFFCr30rVqwQHh4eolChQqJcuXIiNDRUbzsA8csvv+ite7XjsRBCnDx5Unz00UfC2tpaWFlZCR8fHzFz5sx//Psjon9GJ8Q79hAkIirA+vfvj7i4OBw+fFjtphCRgbBPDhFp0tdff42PPvoIVlZW+P3337F+/XqsWLFC7WYRkQHxTA4RaVKnTp1w8OBBPHr0CB4eHhg2bBgGDhyodrOIyIAYcoiIiEiTeHcVERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFpEkMOERERaRJDDhEREWkSQw4RERFp0v8DBoSzfl58FMQAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df.Catégorie.value_counts().plot.bar()" ] }, { "cell_type": "code", "execution_count": null, "id": "1a8120d1-5c88-4e31-a4e0-0857309e0c9b", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "3db38e8c-4f5d-4823-954a-18300de9074d", "metadata": {}, "source": [ "## Découpage des datas" ] }, { "cell_type": "code", "execution_count": 7, "id": "8295411a-1f7e-43c7-ba19-a5a835a09223", "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import train_test_split" ] }, { "cell_type": "code", "execution_count": 8, "id": "d7b1dbf9-e068-4a75-b714-d9bf88f7d028", "metadata": {}, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)" ] }, { "cell_type": "markdown", "id": "5e65fd83-a6ad-4f7c-b00c-9b9cda448074", "metadata": {}, "source": [ "## Tokenisation des Libellé" ] }, { "cell_type": "code", "execution_count": 9, "id": "962a08a1-2dd1-4da3-bcf1-1e5f3f741a24", "metadata": {}, "outputs": [], "source": [ "from nltk.stem import SnowballStemmer\n", "from sklearn.feature_extraction.text import CountVectorizer" ] }, { "cell_type": "code", "execution_count": 10, "id": "7f39c305-25a6-4ac1-9e1c-e0337f2783b8", "metadata": {}, "outputs": [], "source": [ "stemmer = SnowballStemmer('french')\n", "analyzer = CountVectorizer().build_analyzer()" ] }, { "cell_type": "code", "execution_count": 11, "id": "98b52881-6d37-4802-9a70-3963b6f03eae", "metadata": {}, "outputs": [], "source": [ "def stemmed_words(doc):\n", " return (stemmer.stem(w) for w in analyzer(doc))" ] }, { "cell_type": "code", "execution_count": 12, "id": "5ff329eb-b7b8-48e1-95f8-dfde26285be1", "metadata": {}, "outputs": [], "source": [ "vectorizer = CountVectorizer(analyzer=stemmed_words)" ] }, { "cell_type": "markdown", "id": "ccc1eba6-439a-4bf9-87df-a2b225079ae7", "metadata": {}, "source": [ "## Créations de modèles" ] }, { "cell_type": "code", "execution_count": 13, "id": "71da2f84-b75a-4adc-8533-956312c3fd94", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Pipeline(steps=[('vect',\n",
       "                 CountVectorizer(analyzer=<function stemmed_words at 0x7017e451cfe0>)),\n",
       "                ('clf', MultinomialNB())])
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": [ "Pipeline(steps=[('vect',\n", " CountVectorizer(analyzer=)),\n", " ('clf', MultinomialNB())])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.naive_bayes import MultinomialNB\n", "\n", "mnb_pipeline = Pipeline([\n", " ('vect', vectorizer),\n", " ('clf', MultinomialNB())\n", "])\n", "mnb_pipeline.fit(X_train, y_train)" ] }, { "cell_type": "code", "execution_count": 14, "id": "c5cc500a-5e49-4e07-9a9f-e410dd35b69e", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/svm/_classes.py:31: FutureWarning: The default value of `dual` will change from `True` to `'auto'` in 1.5. Set the value of `dual` explicitly to suppress the warning.\n", " warnings.warn(\n" ] }, { "data": { "text/html": [ "
Pipeline(steps=[('vect',\n",
       "                 CountVectorizer(analyzer=<function stemmed_words at 0x7017e451cfe0>)),\n",
       "                ('clf', LinearSVC())])
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": [ "Pipeline(steps=[('vect',\n", " CountVectorizer(analyzer=)),\n", " ('clf', LinearSVC())])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.svm import LinearSVC\n", "\n", "svc_pipeline = Pipeline([\n", " ('vect', vectorizer),\n", " ('clf', LinearSVC())\n", "])\n", "svc_pipeline.fit(X_train, y_train)" ] }, { "cell_type": "code", "execution_count": 15, "id": "72387f32-b462-4113-8292-c5e88ffd5712", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Pipeline(steps=[('vect',\n",
       "                 CountVectorizer(analyzer=<function stemmed_words at 0x7017e451cfe0>)),\n",
       "                ('clf', SGDClassifier())])
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": [ "Pipeline(steps=[('vect',\n", " CountVectorizer(analyzer=)),\n", " ('clf', SGDClassifier())])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.linear_model import SGDClassifier\n", "\n", "\n", "svm_pipeline = Pipeline([\n", " ('vect', vectorizer),\n", " ('clf', SGDClassifier())\n", "])\n", "svm_pipeline.fit(X_train, y_train)" ] }, { "cell_type": "markdown", "id": "93cde7ff-1ecd-4c2e-a2c8-3fabb914c78f", "metadata": {}, "source": [ "## Évaluation" ] }, { "cell_type": "code", "execution_count": 16, "id": "cbbc44ed-74ab-407e-8acf-e668513498aa", "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import accuracy_score" ] }, { "cell_type": "code", "execution_count": 17, "id": "f5450692-99d9-4080-b0a6-75b73cb9146e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MNB ccuracy: 94.15%\n" ] } ], "source": [ "y_pred = mnb_pipeline.predict(X_test)\n", "accuracy = accuracy_score(y_test, y_pred)\n", "print(\"MNB ccuracy: {:.2f}%\".format(accuracy * 100))" ] }, { "cell_type": "code", "execution_count": 18, "id": "0fd79ffb-752b-4886-994d-ed489b1950d1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "742 33BLO- DIAG LOT 4\n", "928 33BLO- PLAQUES LOC\n", "3466 4SER-lot 1 FRAIS COMM DIAG\n", "65 FORFAIT REGLAGE HORLOGE\n", "219 PC - ENTRETIEN ELECTRICITE\n", " ... \n", "51 Solde Départ - Remboursement Solde D.G. Du 120...\n", "669 Gestion impaye locataire ALUR Du 28/09/2\n", "2188 4SER - Mise en demeure KALAI\n", "3251 33BLO-LOT REMISE GESTION\n", "1665 1MAR - MAINTENANCE ELECTRIQUE\n", "Length: 186, dtype: object" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_test[y_test!=y_pred]" ] }, { "cell_type": "code", "execution_count": 19, "id": "17191e07-3a77-415b-947e-2475c0e42e08", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SVC Accuracy: 95.85%\n" ] } ], "source": [ "y_pred = svc_pipeline.predict(X_test)\n", "accuracy = accuracy_score(y_test, y_pred)\n", "print(\"SVC Accuracy: {:.2f}%\".format(accuracy * 100))" ] }, { "cell_type": "code", "execution_count": 20, "id": "cbcaf96f-56ce-4618-b578-d1498fe78d20", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3062 33BLO- LOT 15 PLAQUES\n", "928 33BLO- PLAQUES LOC\n", "268 1MAR-CONSOMMATION EAU\n", "440 PC - CONTRAT ASCENSEUR\n", "2085 vac hor INST COMPTEUR ELEC\n", " ... \n", "1057 Accès Extranet 2020\n", "51 Solde Départ - Remboursement Solde D.G. Du 120...\n", "2188 4SER - Mise en demeure KALAI\n", "3162 1MAR- SUIVI TRAVAUX DEBARRASS\n", "1665 1MAR - MAINTENANCE ELECTRIQUE\n", "Length: 132, dtype: object" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_test[y_test!=y_pred]" ] }, { "cell_type": "code", "execution_count": 21, "id": "8367c994-de9e-4977-b703-cd26ee4f9eb9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SVC Accuracy: 95.97%\n" ] } ], "source": [ "y_pred = svm_pipeline.predict(X_test)\n", "accuracy = accuracy_score(y_test, y_pred)\n", "print(\"SVC Accuracy: {:.2f}%\".format(accuracy * 100))" ] }, { "cell_type": "code", "execution_count": 22, "id": "d5c458d1-4b2b-410a-8d77-fffea9f6a46e", "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "3062 33BLO- LOT 15 PLAQUES\n", "928 33BLO- PLAQUES LOC\n", "268 1MAR-CONSOMMATION EAU\n", "65 FORFAIT REGLAGE HORLOGE\n", "123 1MAR- dossier Grosjean\n", " ... \n", "1057 Accès Extranet 2020\n", "51 Solde Départ - Remboursement Solde D.G. Du 120...\n", "2188 4SER - Mise en demeure KALAI\n", "3162 1MAR- SUIVI TRAVAUX DEBARRASS\n", "1665 1MAR - MAINTENANCE ELECTRIQUE\n", "Length: 128, dtype: object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(X_test[y_test!=y_pred])" ] }, { "cell_type": "code", "execution_count": 23, "id": "6e71a627-8bb6-470e-aba8-cb82c42b4fda", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3062 33BLO- LOT 15 PLAQUES\n", "928 33BLO- PLAQUES LOC\n", "268 1MAR-CONSOMMATION EAU\n", "65 FORFAIT REGLAGE HORLOGE\n", "123 1MAR- dossier Grosjean\n", "440 PC - CONTRAT ASCENSEUR\n", "3078 33BLO- VAC HOR PB CANALISA OFF\n", "1662 4SER - MAINTENANCE ELECTRIQUE\n", "85 DESINSECTISATION PUNAISES\n", "1550 4 SER - EDF ASCENSEUR\n", "1710 Extranet gestion locative 2017\n", "1061 Accès Extranet 2020\n", "2530 1MAR- RAMONAGE\n", "3800 1MAR- lot 6 plaques\n", "3766 1MAR- lot 6 SUIVI TRAVAUX\n", "1998 4SER- PLAQUES LOT 7\n", "1865 Frais suivi d'impaye Du 01052020 Au 3105\n", "4246 33blo- LOGE SUIVI TRAVAUX\n", "3160 Suivi travaux debarrassage\n", "144 S3 - Reception travaux\n", "1285 1 MAR - Eau gd Lyon\n", "1708 Extranet gestion locative 2017\n", "1716 4SER - Contrat ascenseur\n", "2855 33BLO- TT COMM DIAG LOT 4\n", "167 4SER- SUIVI REPAR ASCENSEUR\n", "3532 4SER- NETTOYAGE VITRAGES\n", "1107 1MAR- lOT 13 GROSJEAN HUISSIER\n", "518 4SER-TEL ASCENSEUR 1TRIM2019\n", "1345 33BLO- LOT 18 COMM DIAGNOSTICS\n", "2555 Accès Extranet 2018\n", "598 20 - PLAQUES BAL\n", "1011 Accès Extranet 2020\n", "747 33BLO- LOT 17 RED NVEAU BAIL\n", "1730 4 SER - Tél ascenseur\n", "1183 4SER - EDF ASCENSEUR\n", "1632 4S-CONTRAT ASCENSEUR-3TRIM\n", "2007 1MAR- PLAQUES LOT 9\n", "1704 Extranet gestion locative 2017\n", "1056 Accès Extranet 2020\n", "1644 4SER - Contrat ascenseur\n", "2839 4SER- LOT 9PLAQUES\n", "516 4SER - Travaux tél ascenseur\n", "2488 1MAR- ENTRETIEN ASCENSEUR\n", "749 4 SER - TELEPHONE ASCENSEUR\n", "1991 33blo- lot 17 PLAQUES\n", "298 7 - REMISE AUX NORMES ELECTRCITE\n", "800 Avis de valeur\n", "79 1MAR - Huissier doss. Grosjean\n", "38 1MAR - LARMIERS CAVES\n", "4473 33MB-Lot11 -Sommation huissier\n", "4455 4SER - Mise en demeure KALAI\n", "211 Honoraires suivi recouvrement GROSJEAN S\n", "1236 33MB- Plaque signalétique\n", "508 1MAR- suivi trx ascen 1h offer\n", "364 1MAR-Travaux fuite ascenseur\n", "2016 Commde diagnostic Lot 19-33MBL\n", "343 Etat des risques 33M - LOT 6\n", "750 4SER - MAINTENANCE ELECTRIQUE\n", "3636 Rembt Annul frais impayé\n", "364 PC CONTRAT REGLAGE HORLOGE\n", "3174 33BLO- SUIVI TRAVAUX\n", "4594 33MB - Plaques lot 4\n", "92 RAMONAGE 1ER SEMESTRE 2017\n", "1700 Extranet gestion locative 2017\n", "2520 Accès Extranet 2018\n", "2850 1MAR- LOT 8 VAC HOR TRAVAUX\n", "2289 1MAR - LARMIERS CAVES\n", "1053 Accès Extranet 2020\n", "121 1MAR-Contrat ascenseur 1T 2020\n", "2554 Accès Extranet 2018\n", "3632 4SER-LOT 9 PLAQUES\n", "2533 Accès Extranet 2018\n", "1406 4SER- lot 8 COURR AVOCAT NUISA\n", "4366 4SER- LOT 12 PLAQUES\n", "4357 vac hor install compteur elec\n", "4450 4 SER - CT Ascenseur 1T2020\n", "3163 33BLO- SUIVI TRAVAUX DEBARRASS\n", "2318 Accès Extranet 2019\n", "1992 ESTIMATION VALEUR VENALE\n", "2775 1MAR - MAINTENANCE ELECTRICITE\n", "292 DESOURISATION PARTIES PRIVATIVES\n", "2556 Accès Extranet 2018\n", "1706 Extranet gestion locative 2017\n", "1475 33M-Lot11- Affaire PICARD\n", "4082 4SER - Sommation Versini\n", "1647 1MAR - Contrat ascenseur\n", "177 1 MAR - Eau Gd LYON\n", "685 PC - CONTRAT ASCESENEUR\n", "2540 Accès Extranet 2018\n", "2179 4SER - Réparation ascenseur\n", "2296 Accès Extranet 2019\n", "1408 33BLO- lot 16 FRAIS COMM DIAG\n", "4247 33blo- LOGE SUIVI TRAVAUX\n", "1975 33blo- LOGE SUIVI TRX offert\n", "510 1MAR- LOT 2 SUIVI TRX\n", "1714 1MAR-Lot 13-Frais huissier\n", "4300 TT COMMANDE DIAGNOSTICS\n", "917 4SER- LOT 8 FRAIS AVOCAT\n", "228 4 SER - TELEPHONE ASCENSEUR\n", "78 1MAR - Huissier doss. Grosjean\n", "2006 33MB- PLAQUES LOT 6\n", "1854 PC - 3ème trimestre 2020\n", "1002 33MB-Lot 17 - Plaques BAL\n", "2221 Forfait nego loyers suite COV1 Loc ASSOCIES A2...\n", "1167 33BLO- LOT 12 REDACTION BAIL\n", "1043 Accès Extranet 2020\n", "1073 1 MAR - Entretien ascenseur\n", "3169 Rbst soc ADICTUM-4SER\n", "385 Honoraires suivi de procedure GROSJEAN S\n", "1169 1MAR - Lot 6 -Frais diagnostic\n", "1937 Remboursement Solde D.G. Du 06082020\n", "143 Distribution cle/badge aux loc suite nouvelles...\n", "753 1MAR - MAINTENANCE ELECTRIQUE\n", "2532 Accès Extranet 2018\n", "534 Commde diagnostic Lot 7-4SERV\n", "3 4 SER - CT ASCENSEUR 1T2018\n", "1387 1MAR- LOT 10 PLAQUES\n", "2205 1MAR - Plaques lot 13\n", "1703 Extranet gestion locative 2017\n", "3644 1MAR- LOT 6 SUIVI TRAVAUX\n", "360 vacation horaire travaux\n", "98 PC - TELEPHONIE ASCENSEUR\n", "842 3 - RACORDEMENT ELECTRIQUE SRUDIO RDC\n", "1057 Accès Extranet 2020\n", "51 Solde Départ - Remboursement Solde D.G. Du 120...\n", "2188 4SER - Mise en demeure KALAI\n", "3162 1MAR- SUIVI TRAVAUX DEBARRASS\n", "1665 1MAR - MAINTENANCE ELECTRIQUE\n", "dtype: object\n" ] } ], "source": [ "with pd.option_context('display.max_rows', None, 'display.max_columns', None): # more options can be specified also\n", " print(X_test[y_test!=y_pred])" ] }, { "cell_type": "markdown", "id": "61a935da-40fd-4043-9109-ec97635dfc00", "metadata": {}, "source": [ "## Optimisations\n" ] }, { "cell_type": "code", "execution_count": 24, "id": "5321423f-55d4-4241-815c-22a516460bf6", "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import GridSearchCV" ] }, { "cell_type": "markdown", "id": "fac29ae8-a68b-434f-82d4-865856222222", "metadata": {}, "source": [ "### Modèle Naive Bayes" ] }, { "cell_type": "code", "execution_count": 25, "id": "366e66d6-5bcf-4000-85d5-6d488220070f", "metadata": {}, "outputs": [], "source": [ "from sklearn.naive_bayes import MultinomialNB\n", "from sklearn.feature_extraction.text import TfidfTransformer\n", "\n", "\n", "mnb_pipeline = Pipeline([\n", " ('vect', CountVectorizer()),\n", " #('tfid', TfidfTransformer()),\n", " ('clf', MultinomialNB())\n", "])" ] }, { "cell_type": "code", "execution_count": 26, "id": "008f18a2-5538-412e-8863-c287aef8af0d", "metadata": {}, "outputs": [], "source": [ "parameters = {\n", " 'vect__ngram_range': [(1, 1), (1, 2), (2,2)],\n", " #'tfidf__use_idf': (True, False),\n", " 'clf__alpha': (1, 1e-1,1e-2, 1e-3,),\n", "}" ] }, { "cell_type": "code", "execution_count": 27, "id": "70fe6252-a653-4cfe-89d4-809518e7968b", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/model_selection/_split.py:737: UserWarning: The least populated class in y has only 1 members, which is less than n_splits=5.\n", " warnings.warn(\n" ] } ], "source": [ "gs_clf = GridSearchCV(mnb_pipeline, parameters, n_jobs=-1)\n", "gs_clf = gs_clf.fit(X, y)" ] }, { "cell_type": "code", "execution_count": 28, "id": "f5a9281a-a37d-4373-8710-9ea089d39ddb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9446366782006921" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gs_clf.best_score_" ] }, { "cell_type": "code", "execution_count": 29, "id": "2d84af17-194e-4718-9b96-94cb1b5330e1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'clf__alpha': 0.001, 'vect__ngram_range': (1, 2)}" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gs_clf.best_params_" ] }, { "cell_type": "markdown", "id": "ac0800c5-58f3-4ee7-876c-9d3e4e9eed57", "metadata": {}, "source": [ "### Linear SVC" ] }, { "cell_type": "code", "execution_count": 34, "id": "f4e02729-9559-4579-b4a7-f875a3becb72", "metadata": {}, "outputs": [], "source": [ "from sklearn.feature_extraction.text import TfidfTransformer\n", "from sklearn.svm import LinearSVC\n", "\n", "svc_pipeline = Pipeline([\n", " ('vect', CountVectorizer()),\n", " #('tfid', TfidfTransformer()),\n", " ('clf', LinearSVC())\n", "])" ] }, { "cell_type": "code", "execution_count": null, "id": "578baa50-8d47-4a1a-a5f3-f2f992245693", "metadata": {}, "outputs": [], "source": [ "parameters = {\n", " 'vect__ngram_range': [(1, 1), (1, 2), (2,2)],\n", " #'tfidf__use_idf': (True, False),\n", " 'clf__alpha': (1, 1e-1,1e-2, 1e-3,),\n", "}" ] }, { "cell_type": "markdown", "id": "e894aebd-b0d8-4ce9-900b-0a6afb7e10bd", "metadata": {}, "source": [ "### SGD" ] }, { "cell_type": "code", "execution_count": 35, "id": "6a793449-8540-43e2-9683-f81cfe47488b", "metadata": {}, "outputs": [], "source": [ "from sklearn.linear_model import SGDClassifier\n", "\n", "\n", "sgd_pipeline = Pipeline([\n", " ('vect', vectorizer),\n", " ('clf', SGDClassifier())\n", "])" ] }, { "cell_type": "code", "execution_count": 36, "id": "a871784a-05f6-471b-a972-d154db3ed181", "metadata": {}, "outputs": [], "source": [ "parameters = {\n", " 'vect__ngram_range': [(1, 1), (1, 2), (2,2)],\n", " #'tfidf__use_idf': (True, False),\n", " 'clf__tol': (1, 1e-1,1e-2, 1e-3,),\n", "}" ] }, { "cell_type": "code", "execution_count": 37, "id": "9efff414-1052-4e42-b60d-a6955ccacfa4", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/model_selection/_split.py:737: UserWarning: The least populated class in y has only 1 members, which is less than n_splits=5.\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n", "/home/commun/scripts/Plesna/.venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:541: UserWarning: The parameter 'ngram_range' will not be used since 'analyzer' is callable'\n", " warnings.warn(\n" ] } ], "source": [ "gs_clf = GridSearchCV(sgd_pipeline, parameters, n_jobs=-1)\n", "gs_clf = gs_clf.fit(X, y)" ] }, { "cell_type": "code", "execution_count": 38, "id": "eb47b8c4-5eca-4e54-93e2-7a932261aedb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9485372758729159" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gs_clf.best_score_" ] }, { "cell_type": "code", "execution_count": 39, "id": "e9920e95-7720-48cd-83f8-a650a12d9639", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'clf__tol': 0.001, 'vect__ngram_range': (1, 1)}" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gs_clf.best_params_" ] }, { "cell_type": "code", "execution_count": null, "id": "2d5b30f5-3114-4559-8a77-e30d716134a3", "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.11.6" } }, "nbformat": 4, "nbformat_minor": 5 }