diff --git "a/new_symp2disease.ipynb" "b/new_symp2disease.ipynb" new file mode 100644--- /dev/null +++ "b/new_symp2disease.ipynb" @@ -0,0 +1,2903 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "authorship_tag": "ABX9TyMHvKnYH1nV6+05sjz3ESPf" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "code", + "source": [ + "pip install gradio" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Z7n__8gLD0Fi", + "outputId": "13bd2be3-8345-44d7-d942-f85a54e4cc4e" + }, + "execution_count": 1, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Collecting gradio\n", + " Downloading gradio-3.40.1-py3-none-any.whl (20.0 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m20.0/20.0 MB\u001b[0m \u001b[31m69.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting aiofiles<24.0,>=22.0 (from gradio)\n", + " Downloading aiofiles-23.2.1-py3-none-any.whl (15 kB)\n", + "Requirement already satisfied: aiohttp~=3.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.8.5)\n", + "Requirement already satisfied: altair<6.0,>=4.2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (4.2.2)\n", + "Collecting fastapi (from gradio)\n", + " Downloading fastapi-0.101.0-py3-none-any.whl (65 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m65.7/65.7 kB\u001b[0m \u001b[31m8.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting ffmpy (from gradio)\n", + " Downloading ffmpy-0.3.1.tar.gz (5.5 kB)\n", + " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "Collecting gradio-client>=0.4.0 (from gradio)\n", + " Downloading gradio_client-0.4.0-py3-none-any.whl (297 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m297.4/297.4 kB\u001b[0m \u001b[31m30.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting httpx (from gradio)\n", + " Downloading httpx-0.24.1-py3-none-any.whl (75 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.4/75.4 kB\u001b[0m \u001b[31m8.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting huggingface-hub>=0.14.0 (from gradio)\n", + " Downloading huggingface_hub-0.16.4-py3-none-any.whl (268 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m268.8/268.8 kB\u001b[0m \u001b[31m28.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: importlib-resources<7.0,>=1.3 in /usr/local/lib/python3.10/dist-packages (from gradio) (6.0.1)\n", + "Requirement already satisfied: jinja2<4.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.1.2)\n", + "Requirement already satisfied: markdown-it-py[linkify]>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.0.0)\n", + "Requirement already satisfied: markupsafe~=2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (2.1.3)\n", + "Requirement already satisfied: matplotlib~=3.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.7.1)\n", + "Collecting mdit-py-plugins<=0.3.3 (from gradio)\n", + " Downloading mdit_py_plugins-0.3.3-py3-none-any.whl (50 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.5/50.5 kB\u001b[0m \u001b[31m5.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: numpy~=1.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (1.23.5)\n", + "Collecting orjson~=3.0 (from gradio)\n", + " Downloading orjson-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (140 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m140.3/140.3 kB\u001b[0m \u001b[31m15.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from gradio) (23.1)\n", + "Requirement already satisfied: pandas<3.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (1.5.3)\n", + "Requirement already satisfied: pillow<11.0,>=8.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (9.4.0)\n", + "Requirement already satisfied: pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,<3.0.0,>=1.7.4 in /usr/local/lib/python3.10/dist-packages (from gradio) (2.1.1)\n", + "Collecting pydub (from gradio)\n", + " Downloading pydub-0.25.1-py2.py3-none-any.whl (32 kB)\n", + "Collecting python-multipart (from gradio)\n", + " Downloading python_multipart-0.0.6-py3-none-any.whl (45 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m45.7/45.7 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: pyyaml<7.0,>=5.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (6.0.1)\n", + "Requirement already satisfied: requests~=2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (2.31.0)\n", + "Collecting semantic-version~=2.0 (from gradio)\n", + " Downloading semantic_version-2.10.0-py2.py3-none-any.whl (15 kB)\n", + "Requirement already satisfied: typing-extensions~=4.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (4.7.1)\n", + "Collecting uvicorn>=0.14.0 (from gradio)\n", + " Downloading uvicorn-0.23.2-py3-none-any.whl (59 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m59.5/59.5 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting websockets<12.0,>=10.0 (from gradio)\n", + " Downloading websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (129 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m129.9/129.9 kB\u001b[0m \u001b[31m15.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (23.1.0)\n", + "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (3.2.0)\n", + "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (6.0.4)\n", + "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (4.0.2)\n", + "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (1.9.2)\n", + "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (1.4.0)\n", + "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp~=3.0->gradio) (1.3.1)\n", + "Requirement already satisfied: entrypoints in /usr/local/lib/python3.10/dist-packages (from altair<6.0,>=4.2.0->gradio) (0.4)\n", + "Requirement already satisfied: jsonschema>=3.0 in /usr/local/lib/python3.10/dist-packages (from altair<6.0,>=4.2.0->gradio) (4.19.0)\n", + "Requirement already satisfied: toolz in /usr/local/lib/python3.10/dist-packages (from altair<6.0,>=4.2.0->gradio) (0.12.0)\n", + "Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from gradio-client>=0.4.0->gradio) (2023.6.0)\n", + "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.14.0->gradio) (3.12.2)\n", + "Requirement already satisfied: tqdm>=4.42.1 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.14.0->gradio) (4.66.0)\n", + "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py[linkify]>=2.0.0->gradio) (0.1.2)\n", + "Requirement already satisfied: linkify-it-py<3,>=1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py[linkify]>=2.0.0->gradio) (2.0.2)\n", + "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (1.1.0)\n", + "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (0.11.0)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (4.42.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (1.4.4)\n", + "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (3.1.1)\n", + "Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (2.8.2)\n", + "INFO: pip is looking at multiple versions of mdit-py-plugins to determine which version is compatible with other requirements. This could take a while.\n", + "Collecting mdit-py-plugins<=0.3.3 (from gradio)\n", + " Downloading mdit_py_plugins-0.3.2-py3-none-any.whl (50 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.4/50.4 kB\u001b[0m \u001b[31m5.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading mdit_py_plugins-0.3.1-py3-none-any.whl (46 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.5/46.5 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading mdit_py_plugins-0.3.0-py3-none-any.whl (43 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m43.7/43.7 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading mdit_py_plugins-0.2.8-py3-none-any.whl (41 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m41.0/41.0 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading mdit_py_plugins-0.2.7-py3-none-any.whl (41 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m41.0/41.0 kB\u001b[0m \u001b[31m4.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading mdit_py_plugins-0.2.6-py3-none-any.whl (39 kB)\n", + " Downloading mdit_py_plugins-0.2.5-py3-none-any.whl (39 kB)\n", + "INFO: pip is looking at multiple versions of mdit-py-plugins to determine which version is compatible with other requirements. This could take a while.\n", + " Downloading mdit_py_plugins-0.2.4-py3-none-any.whl (39 kB)\n", + " Downloading mdit_py_plugins-0.2.3-py3-none-any.whl (39 kB)\n", + " Downloading mdit_py_plugins-0.2.2-py3-none-any.whl (39 kB)\n", + " Downloading mdit_py_plugins-0.2.1-py3-none-any.whl (38 kB)\n", + " Downloading mdit_py_plugins-0.2.0-py3-none-any.whl (38 kB)\n", + "INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. See https://pip.pypa.io/warnings/backtracking for guidance. If you want to abort this run, press Ctrl + C.\n", + " Downloading mdit_py_plugins-0.1.0-py3-none-any.whl (37 kB)\n", + "Collecting markdown-it-py[linkify]>=2.0.0 (from gradio)\n", + " Downloading markdown_it_py-3.0.0-py3-none-any.whl (87 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m87.5/87.5 kB\u001b[0m \u001b[31m10.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading markdown_it_py-2.2.0-py3-none-any.whl (84 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m84.5/84.5 kB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas<3.0,>=1.0->gradio) (2023.3)\n", + "Requirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,<3.0.0,>=1.7.4->gradio) (0.5.0)\n", + "Requirement already satisfied: pydantic-core==2.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,<3.0.0,>=1.7.4->gradio) (2.4.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (3.4)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (2.0.4)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (2023.7.22)\n", + "Requirement already satisfied: click>=7.0 in /usr/local/lib/python3.10/dist-packages (from uvicorn>=0.14.0->gradio) (8.1.6)\n", + "Collecting h11>=0.8 (from uvicorn>=0.14.0->gradio)\n", + " Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting starlette<0.28.0,>=0.27.0 (from fastapi->gradio)\n", + " Downloading starlette-0.27.0-py3-none-any.whl (66 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.0/67.0 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting httpcore<0.18.0,>=0.15.0 (from httpx->gradio)\n", + " Downloading httpcore-0.17.3-py3-none-any.whl (74 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m74.5/74.5 kB\u001b[0m \u001b[31m8.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from httpx->gradio) (1.3.0)\n", + "Requirement already satisfied: anyio<5.0,>=3.0 in /usr/local/lib/python3.10/dist-packages (from httpcore<0.18.0,>=0.15.0->httpx->gradio) (3.7.1)\n", + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (2023.7.1)\n", + "Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (0.30.2)\n", + "Requirement already satisfied: rpds-py>=0.7.1 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (0.9.2)\n", + "Requirement already satisfied: uc-micro-py in /usr/local/lib/python3.10/dist-packages (from linkify-it-py<3,>=1->markdown-it-py[linkify]>=2.0.0->gradio) (1.0.2)\n", + "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.7->matplotlib~=3.0->gradio) (1.16.0)\n", + "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5.0,>=3.0->httpcore<0.18.0,>=0.15.0->httpx->gradio) (1.1.2)\n", + "Building wheels for collected packages: ffmpy\n", + " Building wheel for ffmpy (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for ffmpy: filename=ffmpy-0.3.1-py3-none-any.whl size=5579 sha256=123cf75801dd455952791cdb1504beedda07f882e3c00eab584744f08413b59b\n", + " Stored in directory: /root/.cache/pip/wheels/01/a6/d1/1c0828c304a4283b2c1639a09ad86f83d7c487ef34c6b4a1bf\n", + "Successfully built ffmpy\n", + "Installing collected packages: pydub, ffmpy, websockets, semantic-version, python-multipart, orjson, markdown-it-py, h11, aiofiles, uvicorn, starlette, mdit-py-plugins, huggingface-hub, httpcore, httpx, fastapi, gradio-client, gradio\n", + " Attempting uninstall: markdown-it-py\n", + " Found existing installation: markdown-it-py 3.0.0\n", + " Uninstalling markdown-it-py-3.0.0:\n", + " Successfully uninstalled markdown-it-py-3.0.0\n", + " Attempting uninstall: mdit-py-plugins\n", + " Found existing installation: mdit-py-plugins 0.4.0\n", + " Uninstalling mdit-py-plugins-0.4.0:\n", + " Successfully uninstalled mdit-py-plugins-0.4.0\n", + "Successfully installed aiofiles-23.2.1 fastapi-0.101.0 ffmpy-0.3.1 gradio-3.40.1 gradio-client-0.4.0 h11-0.14.0 httpcore-0.17.3 httpx-0.24.1 huggingface-hub-0.16.4 markdown-it-py-2.2.0 mdit-py-plugins-0.3.3 orjson-3.9.4 pydub-0.25.1 python-multipart-0.0.6 semantic-version-2.10.0 starlette-0.27.0 uvicorn-0.23.2 websockets-11.0.3\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Import Libraries" + ], + "metadata": { + "id": "pfzy8WdkkjVZ" + } + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "kw5ABr7GzgbD", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "99aae0c7-722e-4e79-e169-ab2f5b4a002e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "[nltk_data] Downloading package punkt to /root/nltk_data...\n", + "[nltk_data] Unzipping tokenizers/punkt.zip.\n", + "[nltk_data] Downloading package stopwords to /root/nltk_data...\n", + "[nltk_data] Unzipping corpora/stopwords.zip.\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "import torch\n", + "import nltk_utils" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Data Exploration" + ], + "metadata": { + "id": "Y1RoA7N_kpfX" + } + }, + { + "cell_type": "code", + "source": [ + "# import data\n", + "df= pd.read_csv('Symptom2Disease.csv')\n", + "df.head()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "4lDtHIIczxMh", + "outputId": "fe1ccf94-39d6-4b90-991f-e64d6fc3cf47" + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " Unnamed: 0 label text\n", + "0 0 Psoriasis I have been experiencing a skin rash on my arm...\n", + "1 1 Psoriasis My skin has been peeling, especially on my kne...\n", + "2 2 Psoriasis I have been experiencing joint pain in my fing...\n", + "3 3 Psoriasis There is a silver like dusting on my skin, esp...\n", + "4 4 Psoriasis My nails have small dents or pits in them, and..." + ], + "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", + "
Unnamed: 0labeltext
00PsoriasisI have been experiencing a skin rash on my arm...
11PsoriasisMy skin has been peeling, especially on my kne...
22PsoriasisI have been experiencing joint pain in my fing...
33PsoriasisThere is a silver like dusting on my skin, esp...
44PsoriasisMy nails have small dents or pits in them, and...
\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + "
\n", + " \n", + "
\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df.info()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "5FDdahbZz0Wf", + "outputId": "3526cb7b-8e7c-49cd-a8a3-8f303b77b324" + }, + "execution_count": 4, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "RangeIndex: 1200 entries, 0 to 1199\n", + "Data columns (total 3 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 Unnamed: 0 1200 non-null int64 \n", + " 1 label 1200 non-null object\n", + " 2 text 1200 non-null object\n", + "dtypes: int64(1), object(2)\n", + "memory usage: 28.2+ KB\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Check for data classes\n", + "df['label'].nunique()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "XODx9gyQz3dy", + "outputId": "f1a9012f-e656-4a3d-d3ca-4283c139d635" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "24" + ] + }, + "metadata": {}, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "source": [ + "a= [df['label'].unique()]\n", + "print(a)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "RicfgpBfz62x", + "outputId": "99a3746f-9084-429b-8302-73b11a7d8c41" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[array(['Psoriasis', 'Varicose Veins', 'Typhoid', 'Chicken pox',\n", + " 'Impetigo', 'Dengue', 'Fungal infection', 'Common Cold',\n", + " 'Pneumonia', 'Dimorphic Hemorrhoids', 'Arthritis', 'Acne',\n", + " 'Bronchial Asthma', 'Hypertension', 'Migraine',\n", + " 'Cervical spondylosis', 'Jaundice', 'Malaria',\n", + " 'urinary tract infection', 'allergy',\n", + " 'gastroesophageal reflux disease', 'drug reaction',\n", + " 'peptic ulcer disease', 'diabetes'], dtype=object)]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# sort target data\n", + "target=['Psoriasis', 'Varicose Veins', 'Typhoid', 'Chicken pox',\n", + " 'Impetigo', 'Dengue', 'Fungal infection', 'Common Cold',\n", + " 'Pneumonia', 'Dimorphic Hemorrhoids', 'Arthritis', 'Acne',\n", + " 'Bronchial Asthma', 'Hypertension', 'Migraine',\n", + " 'Cervical spondylosis', 'Jaundice', 'Malaria',\n", + " 'urinary tract infection', 'allergy',\n", + " 'gastroesophageal reflux disease', 'drug reaction',\n", + " 'peptic ulcer disease', 'diabetes']\n", + "real_target= sorted(target)" + ], + "metadata": { + "id": "3lMkNCJjz-TK" + }, + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "real_target" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Fy-8tI6Lvl8L", + "outputId": "c606a4d7-4462-43ec-b417-e2ef437e29a1" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['Acne',\n", + " 'Arthritis',\n", + " 'Bronchial Asthma',\n", + " 'Cervical spondylosis',\n", + " 'Chicken pox',\n", + " 'Common Cold',\n", + " 'Dengue',\n", + " 'Dimorphic Hemorrhoids',\n", + " 'Fungal infection',\n", + " 'Hypertension',\n", + " 'Impetigo',\n", + " 'Jaundice',\n", + " 'Malaria',\n", + " 'Migraine',\n", + " 'Pneumonia',\n", + " 'Psoriasis',\n", + " 'Typhoid',\n", + " 'Varicose Veins',\n", + " 'allergy',\n", + " 'diabetes',\n", + " 'drug reaction',\n", + " 'gastroesophageal reflux disease',\n", + " 'peptic ulcer disease',\n", + " 'urinary tract infection']" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "source": [ + "target_dict= {i:j for i,j in enumerate(sorted(target))}\n", + "target_dict" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "zXKfP11m0CfF", + "outputId": "14a5a06f-db7d-42f8-c245-dc2847e30b21" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0: 'Acne',\n", + " 1: 'Arthritis',\n", + " 2: 'Bronchial Asthma',\n", + " 3: 'Cervical spondylosis',\n", + " 4: 'Chicken pox',\n", + " 5: 'Common Cold',\n", + " 6: 'Dengue',\n", + " 7: 'Dimorphic Hemorrhoids',\n", + " 8: 'Fungal infection',\n", + " 9: 'Hypertension',\n", + " 10: 'Impetigo',\n", + " 11: 'Jaundice',\n", + " 12: 'Malaria',\n", + " 13: 'Migraine',\n", + " 14: 'Pneumonia',\n", + " 15: 'Psoriasis',\n", + " 16: 'Typhoid',\n", + " 17: 'Varicose Veins',\n", + " 18: 'allergy',\n", + " 19: 'diabetes',\n", + " 20: 'drug reaction',\n", + " 21: 'gastroesophageal reflux disease',\n", + " 22: 'peptic ulcer disease',\n", + " 23: 'urinary tract infection'}" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df['label']= df['label'].replace({j:i for i,j in enumerate(sorted(target))})" + ], + "metadata": { + "id": "_jGNr54w0MG6" + }, + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "df.head()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "dZWf1flT0bBZ", + "outputId": "8ec9dfe3-3fd1-46e7-da3b-621ee01509e6" + }, + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " Unnamed: 0 label text\n", + "0 0 15 I have been experiencing a skin rash on my arm...\n", + "1 1 15 My skin has been peeling, especially on my kne...\n", + "2 2 15 I have been experiencing joint pain in my fing...\n", + "3 3 15 There is a silver like dusting on my skin, esp...\n", + "4 4 15 My nails have small dents or pits in them, and..." + ], + "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", + "
Unnamed: 0labeltext
0015I have been experiencing a skin rash on my arm...
1115My skin has been peeling, especially on my kne...
2215I have been experiencing joint pain in my fing...
3315There is a silver like dusting on my skin, esp...
4415My nails have small dents or pits in them, and...
\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + "
\n", + " \n", + "
\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df.drop('Unnamed: 0', axis= 1, inplace= True)" + ], + "metadata": { + "id": "J4rvU7zn0eTJ" + }, + "execution_count": 12, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "df.duplicated().sum()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "wYhQdWRW0jwy", + "outputId": "72434333-517f-4271-b868-f8296074df08" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "47" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df[df.duplicated]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "WTUzzKbb0ogZ", + "outputId": "4f7b0388-ba04-4629-ec50-358383d97306" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " label text\n", + "163 4 I'm feeling fatigued and have no energy. I can...\n", + "387 5 I've been quite exhausted and ill. My throat h...\n", + "430 14 I have a really high fever, and I have problem...\n", + "433 14 I'm having a hard time breathing and I feel re...\n", + "438 14 Lately I've been experiencing chills, fatigue,...\n", + "469 7 I've been constipated and it's really hard to ...\n", + "470 7 Since I've been constipated, using the restroo...\n", + "471 7 I've been constipated and it's really hard to ...\n", + "487 7 Lately I've been experiencing constipation and...\n", + "489 7 I've recently been suffering from constipation...\n", + "490 7 I've been experiencing a lot of bowel movement...\n", + "491 7 I'm having a lot of trouble with my bowel move...\n", + "492 7 My bowel motions have been really difficult fo...\n", + "493 7 I've been experiencing a lot of problems with ...\n", + "520 1 I've been feeling really weak in my muscles an...\n", + "521 1 My muscles have been feeling really weak, and ...\n", + "526 1 I've been experiencing stiffness and weakness ...\n", + "527 1 I've been feeling really weak in my muscles an...\n", + "563 0 A nasty rash has just appeared on my skin. Bla...\n", + "573 0 I just developed a really nasty rash on my ski...\n", + "574 0 I've been dealing with a really nasty rash on ...\n", + "580 0 A skin rash with several pus-filled pimples an...\n", + "647 2 I've been struggling with fatigue and a consta...\n", + "706 13 I've been facing visual disruptions, seeing th...\n", + "738 13 Along with excessive appetite, a stiff neck, h...\n", + "748 13 I have been experiencing acidity, indigestion,...\n", + "778 3 Back pain, a persistent cough, and numbness in...\n", + "821 11 I've been feeling extremely scratchy, sick, an...\n", + "822 11 I've been feeling extremely scratchy, sick, an...\n", + "834 11 I've been exhausted and experiencing nausea an...\n", + "835 11 I have been suffering from itching, vomiting, ...\n", + "836 11 I've been feeling scratchy, sick, and worn out...\n", + "837 11 The itch, the nausea, and the weariness have b...\n", + "838 11 I have been experiencing intense itching, vomi...\n", + "839 11 I've been feeling extremely scratchy, sick, an...\n", + "840 11 I've felt really scratchy, nauseated, and worn...\n", + "841 11 I have been having severe itching, vomiting, a...\n", + "842 11 I've been feeling really scratchy, dizzy, and ...\n", + "843 11 I've been experiencing intense itchiness, naus...\n", + "852 12 I've had a high temperature, vomiting, chills,...\n", + "859 12 I've been experiencing severe body itchiness, ...\n", + "866 12 I have a high fever, severe itching, chills, a...\n", + "867 12 I have a high temperature, vomiting, chills, a...\n", + "873 12 I've had a high temperature, vomiting, chills,...\n", + "894 12 I have a high fever, severe itching, chills, a...\n", + "1048 21 Even when I don't have anything acidic in my s...\n", + "1049 21 I'm not in the mood to eat, and swallowing is ..." + ], + "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", + " \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", + " \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", + "
labeltext
1634I'm feeling fatigued and have no energy. I can...
3875I've been quite exhausted and ill. My throat h...
43014I have a really high fever, and I have problem...
43314I'm having a hard time breathing and I feel re...
43814Lately I've been experiencing chills, fatigue,...
4697I've been constipated and it's really hard to ...
4707Since I've been constipated, using the restroo...
4717I've been constipated and it's really hard to ...
4877Lately I've been experiencing constipation and...
4897I've recently been suffering from constipation...
4907I've been experiencing a lot of bowel movement...
4917I'm having a lot of trouble with my bowel move...
4927My bowel motions have been really difficult fo...
4937I've been experiencing a lot of problems with ...
5201I've been feeling really weak in my muscles an...
5211My muscles have been feeling really weak, and ...
5261I've been experiencing stiffness and weakness ...
5271I've been feeling really weak in my muscles an...
5630A nasty rash has just appeared on my skin. Bla...
5730I just developed a really nasty rash on my ski...
5740I've been dealing with a really nasty rash on ...
5800A skin rash with several pus-filled pimples an...
6472I've been struggling with fatigue and a consta...
70613I've been facing visual disruptions, seeing th...
73813Along with excessive appetite, a stiff neck, h...
74813I have been experiencing acidity, indigestion,...
7783Back pain, a persistent cough, and numbness in...
82111I've been feeling extremely scratchy, sick, an...
82211I've been feeling extremely scratchy, sick, an...
83411I've been exhausted and experiencing nausea an...
83511I have been suffering from itching, vomiting, ...
83611I've been feeling scratchy, sick, and worn out...
83711The itch, the nausea, and the weariness have b...
83811I have been experiencing intense itching, vomi...
83911I've been feeling extremely scratchy, sick, an...
84011I've felt really scratchy, nauseated, and worn...
84111I have been having severe itching, vomiting, a...
84211I've been feeling really scratchy, dizzy, and ...
84311I've been experiencing intense itchiness, naus...
85212I've had a high temperature, vomiting, chills,...
85912I've been experiencing severe body itchiness, ...
86612I have a high fever, severe itching, chills, a...
86712I have a high temperature, vomiting, chills, a...
87312I've had a high temperature, vomiting, chills,...
89412I have a high fever, severe itching, chills, a...
104821Even when I don't have anything acidic in my s...
104921I'm not in the mood to eat, and swallowing is ...
\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + "
\n", + " \n", + "
\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df.drop_duplicates(inplace= True)" + ], + "metadata": { + "id": "LnR_tvss0riM" + }, + "execution_count": 15, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "df['label'].value_counts()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "P7Qv1XLn0v8g", + "outputId": "0061f0c5-df45-48fe-becd-cac01a2027b0" + }, + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "15 50\n", + "17 50\n", + "22 50\n", + "20 50\n", + "18 50\n", + "23 50\n", + "9 50\n", + "19 50\n", + "8 50\n", + "6 50\n", + "10 50\n", + "16 50\n", + "5 49\n", + "3 49\n", + "4 49\n", + "2 49\n", + "21 48\n", + "14 47\n", + "13 47\n", + "1 46\n", + "0 46\n", + "12 44\n", + "7 41\n", + "11 38\n", + "Name: label, dtype: int64" + ] + }, + "metadata": {}, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "source": [ + "train_data, test_data= train_test_split(df, test_size=0.15, random_state=42 )" + ], + "metadata": { + "id": "P6R_UB3p0zLG" + }, + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "train_data.info()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "SNi-gm0Z03Z6", + "outputId": "a91a0bc5-00dc-450f-cb37-b821aec82296" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "Int64Index: 980 entries, 618 to 1173\n", + "Data columns (total 2 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 label 980 non-null int64 \n", + " 1 text 980 non-null object\n", + "dtypes: int64(1), object(1)\n", + "memory usage: 23.0+ KB\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "test_data.info()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "QC_xSoD51CTL", + "outputId": "5a15326a-ba4c-4896-b428-7e175a1a67c3" + }, + "execution_count": 19, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "Int64Index: 173 entries, 794 to 139\n", + "Data columns (total 2 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 label 173 non-null int64 \n", + " 1 text 173 non-null object\n", + "dtypes: int64(1), object(1)\n", + "memory usage: 4.1+ KB\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "train_data['label'].value_counts().sort_index()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4FaxbciD1El2", + "outputId": "69423719-3cab-4122-cc7b-5abfdeddde49" + }, + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 37\n", + "1 41\n", + "2 41\n", + "3 40\n", + "4 44\n", + "5 42\n", + "6 41\n", + "7 32\n", + "8 40\n", + "9 43\n", + "10 45\n", + "11 32\n", + "12 40\n", + "13 41\n", + "14 37\n", + "15 45\n", + "16 41\n", + "17 41\n", + "18 40\n", + "19 46\n", + "20 44\n", + "21 38\n", + "22 45\n", + "23 44\n", + "Name: label, dtype: int64" + ] + }, + "metadata": {}, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "source": [ + "test_data['label'].value_counts().sort_index()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2y54iXig1LqJ", + "outputId": "ca536083-4ad4-4ba0-838f-3759eca9e552" + }, + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 9\n", + "1 5\n", + "2 8\n", + "3 9\n", + "4 5\n", + "5 7\n", + "6 9\n", + "7 9\n", + "8 10\n", + "9 7\n", + "10 5\n", + "11 6\n", + "12 4\n", + "13 6\n", + "14 10\n", + "15 5\n", + "16 9\n", + "17 9\n", + "18 10\n", + "19 4\n", + "20 6\n", + "21 10\n", + "22 5\n", + "23 6\n", + "Name: label, dtype: int64" + ] + }, + "metadata": {}, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Prepare data for training\n", + "\n", + "- Convert Text to TF-IDF Vectors\n", + "- Convert Vectors to Pytorch Tensors\n", + "- Convert tensors to pytorch dataloaders" + ], + "metadata": { + "id": "2PYVVpB2lBdh" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Convert text to vectors" + ], + "metadata": { + "id": "pmViJWyClSEL" + } + }, + { + "cell_type": "code", + "source": [ + "vectorizer= nltk_utils.vectorizer()" + ], + "metadata": { + "id": "P6bbmklS1q-q" + }, + "execution_count": 22, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "vectorizer.fit(train_data.text)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 271 + }, + "id": "5wCPe7oI2I8K", + "outputId": "0946fb17-7aa2-4dc9-9014-4717e2d3bfb7" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/feature_extraction/text.py:528: UserWarning: The parameter 'token_pattern' will not be used since 'tokenizer' is not None'\n", + " warnings.warn(\n", + "/usr/local/lib/python3.10/dist-packages/sklearn/feature_extraction/text.py:409: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens [\"'d\", \"'s\", 'abov', 'ani', 'becaus', 'befor', 'could', 'doe', 'dure', 'might', 'must', \"n't\", 'need', 'onc', 'onli', 'ourselv', 'sha', 'themselv', 'veri', 'whi', 'wo', 'would', 'yourselv'] not in stop_words.\n", + " warnings.warn(\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "TfidfVectorizer(stop_words=['i', 'me', 'my', 'myself', 'we', 'our', 'ours',\n", + " 'ourselves', 'you', \"you're\", \"you've\", \"you'll\",\n", + " \"you'd\", 'your', 'yours', 'yourself', 'yourselves',\n", + " 'he', 'him', 'his', 'himself', 'she', \"she's\",\n", + " 'her', 'hers', 'herself', 'it', \"it's\", 'its',\n", + " 'itself', ...],\n", + " tokenizer=)" + ], + "text/html": [ + "
TfidfVectorizer(stop_words=['i', 'me', 'my', 'myself', 'we', 'our', 'ours',\n",
+              "                            'ourselves', 'you', "you're", "you've", "you'll",\n",
+              "                            "you'd", 'your', 'yours', 'yourself', 'yourselves',\n",
+              "                            'he', 'him', 'his', 'himself', 'she', "she's",\n",
+              "                            'her', 'hers', 'herself', 'it', "it's", 'its',\n",
+              "                            'itself', ...],\n",
+              "                tokenizer=<function tokenize at 0x7cd239754d30>)
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.
" + ] + }, + "metadata": {}, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "source": [ + "vectorizer.get_feature_names_out()[: 100]\n", + "vectorizer= vectorizer" + ], + "metadata": { + "id": "Tatp2DyG2LQF" + }, + "execution_count": 24, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "vectorizer" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 179 + }, + "id": "Nql0ED231MlT", + "outputId": "bd9f5dd5-704e-4cb0-8a96-2f573630f474" + }, + "execution_count": 25, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "TfidfVectorizer(stop_words=['i', 'me', 'my', 'myself', 'we', 'our', 'ours',\n", + " 'ourselves', 'you', \"you're\", \"you've\", \"you'll\",\n", + " \"you'd\", 'your', 'yours', 'yourself', 'yourselves',\n", + " 'he', 'him', 'his', 'himself', 'she', \"she's\",\n", + " 'her', 'hers', 'herself', 'it', \"it's\", 'its',\n", + " 'itself', ...],\n", + " tokenizer=)" + ], + "text/html": [ + "
TfidfVectorizer(stop_words=['i', 'me', 'my', 'myself', 'we', 'our', 'ours',\n",
+              "                            'ourselves', 'you', "you're", "you've", "you'll",\n",
+              "                            "you'd", 'your', 'yours', 'yourself', 'yourselves',\n",
+              "                            'he', 'him', 'his', 'himself', 'she', "she's",\n",
+              "                            'her', 'hers', 'herself', 'it', "it's", 'its',\n",
+              "                            'itself', ...],\n",
+              "                tokenizer=<function tokenize at 0x7cd239754d30>)
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.
" + ] + }, + "metadata": {}, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "source": [ + "data_input= vectorizer.transform(train_data.text)\n", + "test_data_input= vectorizer.transform(test_data.text)" + ], + "metadata": { + "id": "-DWLYaEQ2iq-" + }, + "execution_count": 26, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "data_input.shape, test_data_input.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "PY58z-TP2nl9", + "outputId": "78f4a228-928b-417f-9b2c-4d43d490a4ba" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "((980, 1080), (173, 1080))" + ] + }, + "metadata": {}, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "source": [ + "data_input[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "arlW5Guj2uX9", + "outputId": "478cfdb0-0bd0-41b3-a8cc-8658fae3ee10" + }, + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "<1x1080 sparse matrix of type ''\n", + "\twith 23 stored elements in Compressed Sparse Row format>" + ] + }, + "metadata": {}, + "execution_count": 28 + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Convert vectors to tensors\n", + "input_data_tensors= torch.tensor(data_input.toarray()).to(torch.float32)\n", + "test_data_tensors= torch.tensor(test_data_input.toarray()).to(torch.float32)" + ], + "metadata": { + "id": "pk9EQnAD2ymM" + }, + "execution_count": 29, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "input_data_tensors.shape, input_data_tensors.dtype" + ], + "metadata": { + "id": "r3SVyRWnEkUU", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "9b01184a-5c6a-4e9d-f882-26a25175aa76" + }, + "execution_count": 30, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(torch.Size([980, 1080]), torch.float32)" + ] + }, + "metadata": {}, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "source": [ + "test_data_tensors.shape,test_data_tensors.dtype" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "UqcyhYtUGR7U", + "outputId": "a7b647a9-28d3-45a7-d19b-828851ebf3b7" + }, + "execution_count": 31, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(torch.Size([173, 1080]), torch.float32)" + ] + }, + "metadata": {}, + "execution_count": 31 + } + ] + }, + { + "cell_type": "code", + "source": [ + "train_data_output= torch.tensor(train_data['label'].values)\n", + "test_data_output= torch.tensor(test_data['label'].values)" + ], + "metadata": { + "id": "IA1WGNVnGVJY" + }, + "execution_count": 32, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "train_data_output.shape, test_data_output.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "tuXUxwpcGZVd", + "outputId": "2b53d03d-bbc6-4304-cc4c-f60691194d4e" + }, + "execution_count": 33, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(torch.Size([980]), torch.Size([173]))" + ] + }, + "metadata": {}, + "execution_count": 33 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Join input and target data together and create dataloaders" + ], + "metadata": { + "id": "vj0VK9NnGfCj" + } + }, + { + "cell_type": "code", + "source": [ + "import preprocess_data\n", + "import model" + ], + "metadata": { + "id": "CFXBkZuBGnpd" + }, + "execution_count": 34, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "train_dataset= preprocess_data.preprocess_data(input_data_tensors, train_data_output)\n", + "test_dataset= preprocess_data.preprocess_data(test_data_tensors, test_data_output)" + ], + "metadata": { + "id": "T8CCIT5yGshH" + }, + "execution_count": 35, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "train_dataset[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "gP8SZWE8Gvkv", + "outputId": "62bbcf77-8e89-4f08-e099-7e1a845fc357" + }, + "execution_count": 36, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(tensor([0., 0., 0., ..., 0., 0., 0.]), tensor(2))" + ] + }, + "metadata": {}, + "execution_count": 36 + } + ] + }, + { + "cell_type": "code", + "source": [ + "train_dataloader= preprocess_data.dataloader(dataset=train_dataset,\n", + " batch_size=32, shuffle= True, num_workers=2)\n", + "test_dataloader= preprocess_data.dataloader(dataset=test_dataset,\n", + " batch_size=32, shuffle= False, num_workers=2)" + ], + "metadata": { + "id": "wA6eMHITGzt8" + }, + "execution_count": 37, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "len(train_dataloader), len(test_dataloader)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "o_GMPlh-LIuU", + "outputId": "68c3229c-af7c-4dbc-ffbf-9fe40af61137" + }, + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(31, 6)" + ] + }, + "metadata": {}, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "source": [ + "text, target= next(iter(train_dataloader))" + ], + "metadata": { + "id": "Y26dkRSRLZsi" + }, + "execution_count": 39, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "text.shape, target.shape" + ], + "metadata": { + "id": "X1KEYvGILexu", + "outputId": "b3e108e3-d041-4489-9a4b-106e5dc75dee", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(torch.Size([32, 1080]), torch.Size([32]))" + ] + }, + "metadata": {}, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "source": [ + "device= 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "device" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 36 + }, + "id": "rkaKKB_e8y85", + "outputId": "522453b1-aadf-4814-ea78-06ede1a6273a" + }, + "execution_count": 41, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'cpu'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 41 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model= model.RNN_model()" + ], + "metadata": { + "id": "fUbWo4-M8zbQ" + }, + "execution_count": 42, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "dummy_x= torch.rand(size= [1,1080])\n", + "dummy_x.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "bMQUuV1Z8zq8", + "outputId": "d2bda840-01af-4186-ade5-d8089cdb8d46" + }, + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([1, 1080])" + ] + }, + "metadata": {}, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model(dummy_x)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZnvhejXE8z5x", + "outputId": "2d300e12-0a34-4aff-ff8d-c1f837d5deaa" + }, + "execution_count": 44, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 0.3610, 0.0999, -0.4230, -0.1520, -0.3612, 0.3440, 0.0806, -0.1656,\n", + " 0.1344, 0.0907, -0.2140, -0.0877, -0.5789, 0.1970, 0.3892, -0.1477,\n", + " 0.1714, -0.0009, -0.2150, -0.1346, -0.2228, 0.0901, -0.4715, -0.2032]],\n", + " grad_fn=)" + ] + }, + "metadata": {}, + "execution_count": 44 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Train data" + ], + "metadata": { + "id": "6m0rr8vllcV9" + } + }, + { + "cell_type": "code", + "source": [ + "# Import metrics\n", + "from sklearn.metrics import accuracy_score, f1_score" + ], + "metadata": { + "id": "Et9hV_E480JZ" + }, + "execution_count": 45, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Import loss function and optimizers\n", + "from torch.nn.modules.loss import CrossEntropyLoss\n", + "loss_fn= CrossEntropyLoss()\n", + "optimizer= torch.optim.SGD(model.parameters(), lr= 0.1, weight_decay=0)" + ], + "metadata": { + "id": "xa-GSB6l80V9" + }, + "execution_count": 46, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Train Model" + ], + "metadata": { + "id": "AS3AnXFwm1j5" + } + }, + { + "cell_type": "code", + "source": [ + "epoch= 500\n", + "\n", + "results= {\n", + " \"train_loss\": [],\n", + " \"train_accuracy\": [],\n", + " \"test_loss\": [],\n", + " \"test_accuracy\": []\n", + " }\n", + "\n", + "for i in range(epoch):\n", + " train_loss=0\n", + " train_acc=0\n", + " for batch, (X, y) in enumerate(train_dataloader):\n", + " X, y= X.to(device), y.to(device)\n", + " # Train the model\n", + " model.train()\n", + "\n", + " optimizer.zero_grad()\n", + "\n", + " y_logits= model(X)\n", + "\n", + " # Calculate the loss\n", + " loss= loss_fn(y_logits, y)\n", + " train_loss += loss\n", + "\n", + " # ypreds\n", + " y_preds= torch.argmax(torch.softmax(y_logits, dim=1), dim=1)\n", + " accuracy = accuracy_score(y, y_preds)\n", + " train_acc += accuracy\n", + "\n", + " # zero grad\n", + " #optimizer.zero_grad()\n", + "\n", + " # Loss backward\n", + " loss.backward()\n", + "\n", + " # Optimizer step\n", + " optimizer.step()\n", + "\n", + " train_loss /= len(train_dataloader)\n", + " train_acc /=len(train_dataloader)\n", + "\n", + " test_loss = 0\n", + " test_acc=0\n", + " model.eval()\n", + " with torch.inference_mode():\n", + " for X, y in test_dataloader:\n", + " X, y= X.to(device), y.to(device)\n", + " y_logits= model(X)\n", + " loss= loss_fn(y_logits, y)\n", + " test_loss += loss\n", + " test_preds= torch.argmax(torch.softmax(y_logits, dim=1), dim=1)\n", + " accuracy = accuracy_score(y, test_preds)\n", + " test_acc += accuracy\n", + " test_loss /= len(test_dataloader)\n", + " test_acc /= len(test_dataloader)\n", + "\n", + " results['train_loss'].append(train_loss.item())\n", + " results['train_accuracy'].append(train_acc.item())\n", + " results['test_loss'].append(test_loss.item())\n", + " results['test_accuracy'].append(test_acc.item())\n", + " if i % 50 == 0:\n", + " print(f\"\\nTrain loss: {train_loss:.5f} | Train Acc: {train_acc:.5f} | Test loss: {test_loss:.5f} | Test Acc: {test_acc:.5f} |\")\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Ppocdsju80iS", + "outputId": "486d6dfe-d85a-4e29-b939-d189ac518a15" + }, + "execution_count": 47, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "Train loss: 3.17753 | Train Acc: 0.03992 | Test loss: 3.16496 | Test Acc: 0.12179 |\n", + "\n", + "Train loss: 0.63488 | Train Acc: 0.95968 | Test loss: 0.75937 | Test Acc: 0.89343 |\n", + "\n", + "Train loss: 0.09802 | Train Acc: 1.00000 | Test loss: 0.22350 | Test Acc: 0.96875 |\n", + "\n", + "Train loss: 0.03849 | Train Acc: 1.00000 | Test loss: 0.14364 | Test Acc: 0.98438 |\n", + "\n", + "Train loss: 0.02220 | Train Acc: 1.00000 | Test loss: 0.12408 | Test Acc: 0.98438 |\n", + "\n", + "Train loss: 0.01508 | Train Acc: 1.00000 | Test loss: 0.10855 | Test Acc: 0.97917 |\n", + "\n", + "Train loss: 0.01129 | Train Acc: 1.00000 | Test loss: 0.09876 | Test Acc: 0.99479 |\n", + "\n", + "Train loss: 0.00890 | Train Acc: 1.00000 | Test loss: 0.08936 | Test Acc: 0.99479 |\n", + "\n", + "Train loss: 0.00731 | Train Acc: 1.00000 | Test loss: 0.08967 | Test Acc: 0.99479 |\n", + "\n", + "Train loss: 0.00626 | Train Acc: 1.00000 | Test loss: 0.08865 | Test Acc: 0.99479 |\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import matplotlib.pyplot as plt" + ], + "metadata": { + "id": "nO9wqwy-80v2" + }, + "execution_count": 48, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Plot Loss Curve" + ], + "metadata": { + "id": "PVg5tmJ8m5oK" + } + }, + { + "cell_type": "code", + "source": [ + "plt.figure(figsize=(10,5))\n", + "plt.subplot(1,2,1)\n", + "plt.plot(results['train_loss'], label= 'train')\n", + "plt.plot(results['test_loss'], label= 'test')\n", + "plt.title('loss curve for train and test')\n", + "plt.legend();\n", + "plt.subplot(1,2,2)\n", + "plt.plot(results['train_accuracy'], label= 'train')\n", + "plt.plot(results['test_accuracy'], label= 'test')\n", + "plt.title('accuracy score for train and test')\n", + "plt.legend();" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 468 + }, + "id": "ruvVWd05808i", + "outputId": "edbdc8b3-ab06-4c92-a6db-0bac83fdbf8d" + }, + "execution_count": 49, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzoAAAHDCAYAAADss29MAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACdtUlEQVR4nOzdd3hUZdrH8e/09EYaJfQuTcACCKIiWBbFgoiFYlsLrshalt0VFQu7NuxiR11dUayvuiIi2MCCiAJSpBchoSUhdTIz5/3jJJNMep8k/D7XNRdznnnOOfdMhjlzz9MshmEYiIiIiIiItCDWYAcgIiIiIiJS35ToiIiIiIhIi6NER0REREREWhwlOiIiIiIi0uIo0RERERERkRZHiY6IiIiIiLQ4SnRERERERKTFUaIjIiIiIiItjhIdERERERFpcZToNHHz58/HYrGwffv2YIfSomVlZXHVVVeRnJyMxWJh+vTpwQ6p1prze+auu+7CYrEEOwwRkRbp999/Z/To0URHR2OxWHj//feDHVKtTZkyhY4dOwY7jFoZOXIkI0eODHYYRwUlOiLA/fffz/z587nuuut47bXXuPzyyxv8fM35AhNsb7zxBo8++miDnuOPP/7grrvuYvXq1Q16HhGRxjJ58mTWrFnDfffdx2uvvcbgwYMb7Fz6DK27xviusHz5cu666y7S09Mb9DzBokRHBPjiiy848cQTufPOO7nssssYNGhQg56vIT+8Lr/8cnJzc+nQoUODHL8paKxE5+6779ZFWkRahNzcXFasWMGVV17JtGnTuOyyy2jXrl2Dna+hP0Off/55Nm7c2CDHbioaK9G5++67leiINKbs7OxGPV9aWhoxMTH1djyPx4Pb7a6XY9X0tbDZbISEhKgLmIg0S439+d8c1Mdrsn//foB6vdbV598qJyenRvUdDgcul6vezi8tlCFN2ssvv2wAxrZt2wLKn3rqKaN3796G0+k0WrdubVx//fXG4cOHA+ps2rTJOP/8842kpCTD5XIZbdu2NSZMmGCkp6f763z22WfGsGHDjOjoaCM8PNzo3r27MXPmzGrF9tprrxnHHXecERoaasTExBjDhw83Fi1a5H8cMO68884y+3Xo0MGYPHlymee4bNky47rrrjMSEhKMmJgY4+233/aXlzZv3jwDMNasWeMvW79+vXHBBRcYsbGxhsvlMgYNGmR88MEHlT6HpUuXGkCZW9HrnZqaalxxxRVGYmKi4XK5jH79+hnz588POMa2bdsMwHjwwQeNuXPnGp07dzasVqvx888/l3vO8s5X9HrceeedBmCsW7fOmDhxohETE2MMGDDAMAzD+OWXX4zJkycbnTp1Mlwul5GUlGRMnTrVOHDgQMDxy3vPdOjQwTj77LONr7/+2jjuuOMMl8tldOrUyXjllVcqfX2KPPjgg8aQIUOMuLg4IyQkxBg4cKDx9ttvl/vcbrjhBuO9994zjjnmGMPpdBq9e/c2/ve//5Wp+/XXXxuDBw82XC6X0blzZ2PevHn+51+Zk08+uczr16FDB//jeXl5xqxZs4wuXboYTqfTaNeunXHrrbcaeXl5Acep7L1f0fvi5ZdfrtbrJdKUbN++3bjuuuuM7t27GyEhIUZcXJxx4YUXlrmuGIZhHD582Jg+fbrRoUMHw+l0Gm3btjUuv/xyY//+/f46ubm5xp133ml069bNcLlcRnJysnHeeecZmzdvNgyj+P/P0qVLA45d9FlZ8v/R5MmTjfDwcGPz5s3GmWeeaURERBjnnnuuYRiG8dVXXxkXXnihkZKS4v+/PH36dCMnJ6dM3OvXrzfGjx9vxMfHGyEhIUb37t2Nv//974ZhGMYXX3xhAMa7775bZr/XX3/dAIzly5dX+Pq53W7jrrvuMrp27Wq4XC4jLi7OGDZsmPHZZ59VO4Yiq1atMs444wwjMjLSCA8PN0499VRjxYoVAXUquiYW+eSTT4yTTjrJCAsLMyIiIoyzzjrLWLt2bYXxG0bxtaWiz836iKukqj5DTz75ZOOYY44xVq5caQwfPtwIDQ01brrpJsMwDOP99983zjrrLKN169aG0+k0OnfubMyePdvweDwB55g8eXLAcyh5LX722WeNzp07G06n0xg8eLDxww8/VPr6GIZhHDx40PjrX/9q9OnTxwgPDzciIyONM844w1i9enW5z23BggXGvffea7Rt29ZwuVzGqaeeavz+++9ljlsUS0hIiHHccccZX331lXHyyScbJ598cqXxVPZdwTAMY/fu3cbUqVONxMRE/7X2xRdfLHOcxx9/3Ojdu7f/u9qgQYOM119/3TCM8t8X5X3nbM7s9ZcySWO56667uPvuuxk1ahTXXXcdGzdu5JlnnuHHH3/k22+/xeFw4Ha7GTNmDPn5+dx4440kJyezZ88ePvroI9LT04mOjmbdunX86U9/ol+/fsyePRuXy8XmzZv59ttvq4zh7rvv5q677mLo0KHMnj0bp9PJ999/zxdffMHo0aNr9byuv/56EhISmDVrFtnZ2Zx99tlERETw1ltvcfLJJwfUXbBgAccccwx9+vQBYN26dQwbNoy2bdvyt7/9jfDwcN566y3GjRvHO++8w3nnnVfuOXv16sVrr73GzTffTLt27fjrX/8KQEJCArm5uYwcOZLNmzczbdo0OnXqxNtvv82UKVNIT0/npptuCjjWyy+/TF5eHtdccw0ul4u4uLhyz/naa69x1VVXcfzxx3PNNdcA0KVLl4A648ePp1u3btx///0YhgHA4sWL2bp1K1OnTiU5OZl169bx3HPPsW7dOr777rsqW3A2b97MhRdeyJVXXsnkyZN56aWXmDJlCoMGDeKYY46pdN/HHnuMc845h0svvRS3282bb77J+PHj+eijjzj77LMD6n7zzTe8++67XH/99URGRvL4449zwQUXsHPnTlq1agXAmjVrGD16NAkJCdx11114PB7uvPNOkpKSKo0D4B//+AcZGRns3r2buXPnAhAREQGAz+fjnHPO4ZtvvuGaa66hV69erFmzhrlz57Jp0yZ/F4Cq3vu9evVi9uzZzJo1i2uuuYbhw4cDMHTo0CrjE2lqfvzxR5YvX87FF19Mu3bt2L59O8888wwjR47kt99+IywsDDAnZRk+fDjr16/niiuuYODAgRw4cIAPP/yQ3bt3Ex8fj9fr5U9/+hNLlizh4osv5qabbuLIkSMsXryYtWvXlvksqw6Px8OYMWM46aSTeOihh/zxvP322+Tk5HDdddfRqlUrfvjhB5544gl2797N22+/7d//119/Zfjw4TgcDq655ho6duzIli1b+L//+z/uu+8+Ro4cSUpKCq+//nqZa8Hrr79Oly5dGDJkSIXx3XXXXcyZM8f/uZ2ZmcnKlStZtWoVp59+erViAPNzZ/jw4URFRXHbbbfhcDh49tlnGTlyJF9++SUnnHBCwHlLXxPBvH5MnjyZMWPG8O9//5ucnByeeeYZTjrpJH7++ecKB+eff/75xMTEcPPNNzNx4kTOOuss/+dmfcRVWnU+Qw8ePMiZZ57JxRdfzGWXXeb//J8/fz4RERHMmDGDiIgIvvjiC2bNmkVmZiYPPvhghX+nIm+88QZHjhzhz3/+MxaLhQceeIDzzz+frVu34nA4Ktxv69atvP/++4wfP55OnTqRmprKs88+y8knn8xvv/1GmzZtAur/61//wmq1csstt5CRkcEDDzzApZdeyvfff++v8+KLL/LnP/+ZoUOHMn36dLZu3co555xDXFwcKSkplT6Pyr4rpKamcuKJJ2KxWJg2bRoJCQn873//48orryQzM9M/odLzzz/PX/7yFy688EJuuukm8vLy+PXXX/n++++55JJLOP/889m0aRP//e9/mTt3LvHx8YD5HajFCHamJZUr/et8Wlqa4XQ6jdGjRxter9df78knnzQA46WXXjIMwzB+/vlnAyj3V/cic+fONYCAX+qq4/fffzesVqtx3nnnBcRgGIbh8/n896lhi85JJ51U5hebiRMnGomJiQHle/fuNaxWqzF79mx/2WmnnWb07ds34Fd7n89nDB061OjWrVuVz6moxaOkRx991ACM//znP/4yt9ttDBkyxIiIiDAyMzMNwyj+FSkqKspIS0ur8lyGYRjh4eEBr0GRol9XJk6cWOax8n7F/O9//2sAxldffeUvq6hFp3S9tLQ0w+VyGX/961+rjLf0ud1ut9GnTx/j1FNPDSgHDKfT6f9l1zDMlijAeOKJJ/xl48aNM0JCQowdO3b4y3777TfDZrNV2aJjGIZx9tlnB/ySV+S1114zrFar8fXXXweUF7UAfvvtt4ZhVO+9/+OPP6oVR1qE8j47VqxYYQDGq6++6i+bNWtWhS0fRZ/tL730kgEYjzzySIV1atqiAxh/+9vfqhX3nDlzDIvFEvDZMWLECCMyMjKgrGQ8hmEYM2fONFwuV0CPhrS0NMNut5d7nSqpf//+Za4PpVUnhnHjxhlOp9PYsmWLv+yPP/4wIiMjjREjRvjLKromHjlyxIiJiTGuvvrqgHPs27fPiI6OLlNeWskWj5LqGldFKvsMLWqZnzdvXpnHyvu7//nPfzbCwsICrvEVtei0atXKOHTokL/8gw8+MADj//7v/yqNNy8vr8x3mm3bthkulyvg+0bR+7tXr15Gfn6+v/yxxx4L6GnidruNxMREY8CAAQH1nnvuOQOoskXHMCr+rnDllVcarVu3LtOj4+KLLzaio6P9r+G5555rHHPMMZWe48EHH2xxrTglaYxOM/P555/jdruZPn06Vmvxn+/qq68mKiqKjz/+GIDo6GgAFi1aVGG/16J+uh988AE+n6/aMbz//vv4fD5mzZoVEANQp3EhV199NTabLaBswoQJpKWlsWzZMn/ZwoUL8fl8TJgwAYBDhw7xxRdfcNFFF3HkyBEOHDjAgQMHOHjwIGPGjOH3339nz549NY7nk08+ITk5mYkTJ/rLHA4Hf/nLX8jKyuLLL78MqH/BBRfU268g1157bZmy0NBQ//28vDwOHDjAiSeeCMCqVauqPGbv3r39v6qB+YtNjx492Lp1a5X7ljz34cOHycjIYPjw4eWed9SoUQG/6vbr14+oqCj/ebxeL4sWLWLcuHG0b9/eX69Xr16MGTOmylgq8/bbb9OrVy969uzpfx8cOHCAU089FYClS5cCtX/vizRHJf//FhQUcPDgQbp27UpMTEzA/+F33nmH/v37l9sCXvTZ/s477xAfH8+NN95YYZ3auO666yqNOzs7mwMHDjB06FAMw+Dnn38GzHEnX331FVdccUXA50npeCZNmkR+fj4LFy70ly1YsACPx8Nll11WaWwxMTGsW7eO33//vdzHqxOD1+vls88+Y9y4cXTu3Nn/eOvWrbnkkkv45ptvyMzMDNi39DVx8eLFpKenM3HixIDPN5vNxgknnOD/fKuJ+oirtlwuF1OnTi1TXvLvXnRNHz58ODk5OWzYsKHK406YMIHY2Fj/dtF1r6prncvl8n+n8Xq9HDx4kIiICHr06FHutW7q1Kk4nc4Kz7Ny5UrS0tK49tprA+pNmTLF/x2tNgzD4J133mHs2LEYhhHwXhgzZgwZGRn+eGNiYti9ezc//vhjrc/X3CnRaWZ27NgBQI8ePQLKnU4nnTt39j/eqVMnZsyYwQsvvEB8fDxjxozhqaeeIiMjw7/PhAkTGDZsGFdddRVJSUlcfPHFvPXWW1V+8duyZQtWq5XevXvX63Pr1KlTmbIzzjiD6OhoFixY4C9bsGABAwYMoHv37oDZJcswDO644w4SEhICbnfeeSdgTjZQUzt27KBbt25lkrlevXr5H68q/toq71iHDh3ipptuIikpidDQUBISEvz1Sv5dK1L6AgwQGxvL4cOHq9z3o48+4sQTTyQkJIS4uDgSEhJ45plnyj1vVefZv38/ubm5dOvWrUy90u/rmvr9999Zt25dmfdB0Xul6H1Q2/e+SHOUm5vLrFmzSElJweVyER8fT0JCAunp6QH/h7ds2eLvDlyRLVu20KNHD+z2+uv5brfby539a+fOnUyZMoW4uDgiIiJISEjwd2MuirvoS2VVcffs2ZPjjjuO119/3V/2+uuvc+KJJ9K1a9dK9509ezbp6el0796dvn37cuutt/Lrr7/6H69ODPv37ycnJ6fcz7hevXrh8/nYtWtXQHnp60BRonXqqaeW+Yz77LPPanWdq4+4aqtt27YBCUCRdevWcd555xEdHU1UVBQJCQn+ZLQ217qipKeqa53P52Pu3Ll069Yt4P/Jr7/+Wq1rXenzFH1HKH2tczgcAUllTe3fv5/09HSee+65Mu+DosSx6L1w++23ExERwfHHH0+3bt244YYbqjU8oSXRGJ0W7OGHH2bKlCl88MEHfPbZZ/zlL39hzpw5fPfdd7Rr147Q0FC++uorli5dyscff8ynn37KggULOPXUU/nss8/q5Reb8ni93nLLS/6KU8TlcjFu3Djee+89nn76aVJTU/n222+5//77/XWKvpzecsstFbYIVHUhqw/lxV+fx7roootYvnw5t956KwMGDCAiIgKfz8cZZ5xRrS/oFf09jcIxQBX5+uuvOeeccxgxYgRPP/00rVu3xuFw8PLLL/PGG2/U23nqg8/no2/fvjzyyCPlPl7UJzpY732RYLjxxht5+eWXmT59OkOGDPEvFnnxxRc3SHJfUctORZ/9JX9JL1n39NNP59ChQ9x+++307NmT8PBw9uzZw5QpU2oV96RJk7jpppvYvXs3+fn5fPfddzz55JNV7jdixAi2bNniv5a+8MILzJ07l3nz5nHVVVfVOI7qKn0dKHrOr732GsnJyWXq12fyWZO46vM46enpnHzyyURFRTF79my6dOlCSEgIq1at4vbbb2/Qa93999/PHXfcwRVXXME999xDXFwcVquV6dOnl3veYF3rimK57LLLmDx5crl1+vXrB5jJ6saNG/noo4/49NNPeeedd3j66aeZNWsWd999d4PG2VQo0WlmitZG2bhxY8AvAm63m23btjFq1KiA+n379qVv377885//ZPny5QwbNox58+Zx7733AmC1WjnttNM47bTTeOSRR7j//vv5xz/+wdKlS8scq0iXLl3w+Xz89ttvDBgwoMJYY2Njy8zL7na72bt3b42e84QJE3jllVdYsmQJ69evxzAMf7c1wP86OByOCmOujQ4dOvDrr7/i8/kCLsJFTed1Waempl08Dh8+zJIlS7j77ruZNWuWv7yirhT16Z133iEkJIRFixYFTOX58ssv1+p4CQkJhIaGlht7dddEqOj169KlC7/88gunnXZala9xVe99Tc8tLcXChQuZPHkyDz/8sL8sLy+vzOdzly5dWLt2baXH6tKlC99//z0FBQUVDuwu+mW79PFLt4JXZs2aNWzatIlXXnmFSZMm+csXL14cUK/o87+quAEuvvhiZsyYwX//+19yc3NxOBwB15LKxMXFMXXqVKZOnUpWVhYjRozgrrvu4qqrrqpWDAkJCYSFhZX7GbdhwwasVmuVg9OLugQnJibW27WuPuKqSG0+Q5ctW8bBgwd59913GTFihL9827ZttYqhJhYuXMgpp5zCiy++GFCenp7uH6RfE0XfEX7//Xd/92kwu49u27aN/v37V3mM8l7DhIQEIiMj8Xq91XofhIeHM2HCBCZMmIDb7eb888/nvvvuY+bMmUfFUhTqutbMjBo1CqfTyeOPPx7wq8GLL75IRkaGfwaszMxMPB5PwL59+/bFarWSn58PmF2hSitKXIrqlGfcuHFYrVZmz55d5leOkjF16dKFr776KuDx5557rsJf9SoyatQo4uLiWLBgAQsWLOD4448PaDpPTExk5MiRPPvss+UmUUVrB9TUWWedxb59+wK6zXk8Hp544gkiIiLKzARXE+Hh4TVanKvol6PSvxQ19KKZRee2WCwBf7ft27fXehEzm83GmDFjeP/999m5c6e/fP369SxatKhaxwgPDy+3K8FFF13Enj17eP7558s8lpub658hqDrv/fDwcKDslzWR5sZms5X57HjiiSfKfBZfcMEF/PLLL7z33ntljlG0/wUXXMCBAwfKbQkpqtOhQwdsNluZz/+nn366RjGXPGbR/cceeyygXkJCAiNGjOCll14K+DwpvS9AfHw8Z555Jv/5z394/fXXOeOMM6r1BfbgwYMB2xEREXTt2tX/WVGdGGw2G6NHj+aDDz5g+/bt/sdTU1N54403OOmkk4iKiqo0jjFjxhAVFcX9999PQUFBmcdrc62rj7gqUpvP0PL+7m63u0bvndoq7//J22+/XasxvgCDBw8mISGBefPmBayrN3/+/Gq/JuV9V7DZbFxwwQW888475SbXJd8Hpd+7TqeT3r17YxiG/z3U0q91atFpZhISEpg5cyZ33303Z5xxBueccw4bN27k6aef5rjjjvP3Y/3iiy+YNm0a48ePp3v37ng8Hl577TX/fxAw+x1/9dVXnH322XTo0IG0tDSefvpp2rVrx0knnVRhDF27duUf//gH99xzD8OHD+f888/H5XLx448/0qZNG+bMmQPAVVddxbXXXssFF1zA6aefzi+//MKiRYtq/MuIw+Hg/PPP58033yQ7O5uHHnqoTJ2nnnqKk046ib59+3L11VfTuXNnUlNTWbFiBbt37+aXX36p0TkBrrnmGp599lmmTJnCTz/9RMeOHVm4cCHffvstjz76KJGRkTU+ZpFBgwbx+eef88gjj9CmTRs6depUZgrPkqKiohgxYgQPPPAABQUFtG3bls8++6xRfuU6++yzeeSRRzjjjDO45JJLSEtL46mnnqJr164B/dRr4u677+bTTz9l+PDhXH/99f4E8phjjqnWMQcNGsSCBQuYMWMGxx13HBEREYwdO5bLL7+ct956i2uvvZalS5cybNgwvF4vGzZs4K233mLRokUMHjy4Wu/9Ll26EBMTw7x584iMjCQ8PJwTTjihXsdiiTSGP/3pT7z22mtER0fTu3dvVqxYweeff+6f7r3IrbfeysKFCxk/fjxXXHEFgwYN4tChQ3z44YfMmzeP/v37M2nSJF599VVmzJjBDz/8wPDhw8nOzubzzz/n+uuv59xzzyU6Oprx48fzxBNPYLFY6NKlCx999FGNxpD07NmTLl26cMstt7Bnzx6ioqJ45513yh1n8fjjj3PSSScxcOBArrnmGjp16sT27dv5+OOPWb16dUDdSZMmceGFFwJwzz33VCuW3r17M3LkSAYNGkRcXBwrV65k4cKFTJs2rUYx3HvvvSxevJiTTjqJ66+/HrvdzrPPPkt+fj4PPPBAlXFERUXxzDPPcPnllzNw4EAuvvhiEhIS2LlzJx9//DHDhg2rVle80uoaV0Vq8xk6dOhQYmNjmTx5Mn/5y1+wWCy89tprjdL1+U9/+hOzZ89m6tSpDB06lDVr1vD666/XejyNw+Hg3nvv5c9//jOnnnoqEyZMYNu2bbz88svVPmZF3xX+9a9/sXTpUk444QSuvvpqevfuzaFDh1i1ahWff/65/8e80aNHk5yczLBhw0hKSmL9+vU8+eSTnH322f7vMIMGDQLMpRsuvvhi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IiIBlOhUk8caCkB+TlaQIxERkaONpXSLTn45iY66romIBFCiU00eu5nouHPVoiMiIo3MV40WHXVdExEJoESnmnz2MAAK8tSiIyIijetITm5ggScXxj4OiccUl6nrmohIACU61WQ4wgHwKtEREZFGlFfgxYq37AODJsPYx4q31aIjIhKgRonOnDlzOO6444iMjCQxMZFx48axcePGKvd7++236dmzJyEhIfTt25dPPvmk1gEHjdNs0fFpemkREWlE+R4fdnzlP2gtcRnXGB0RkQA1SnS+/PJLbrjhBr777jsWL15MQUEBo0ePJju74i//y5cvZ+LEiVx55ZX8/PPPjBs3jnHjxrF27do6B9+YrE6zRccoUKIjIiKNx+3xYaso0bGUSG7UdU1EJEA5K45V7NNPPw3Ynj9/PomJifz000+MGDGi3H0ee+wxzjjjDG699VYA7rnnHhYvXsyTTz7JvHnzahl247OGmIkO7pzgBiIiIkcPrwfnikeJspS69rQ7zvy3ZCuOuq6JiASo0xidjAxz8cy4uLgK66xYsYJRo0YFlI0ZM4YVK1bU5dSNzu6KAMDqUaIjIiKN5LuniF5+f9nyiW+a/1pL/F7pCGmcmEREmokateiU5PP5mD59OsOGDaNPnz4V1tu3bx9JSUkBZUlJSezbt6/CffLz88nPz/dvZ2aWM41mI7NGJAAQk783yJGIiMjRInvTl4SXLuw6CsLjzfslu645whorLBGRZqHWLTo33HADa9eu5c0336zPeABz0oPo6Gj/LSUlpd7PUVMFrQcC0MazC7L2BzkaERE5GqSlpZZTaim+W7LrmiO0weMREWlOapXoTJs2jY8++oilS5fSrl27SusmJyeTmhr4QZ2amkpycnKF+8ycOZOMjAz/bdeuXbUJs16FxSSywVeYcO36LrjBiIjIUSHUV86SBpYSiY6lxGXcrq5rIiIl1SjRMQyDadOm8d577/HFF1/QqVOnKvcZMmQIS5YsCShbvHgxQ4YMqXAfl8tFVFRUwC3YokIcbDbamhsZu4MbjIiIHBVCveWt3VZRi466romIlFSjMTo33HADb7zxBh988AGRkZH+cTbR0dGEhppN5pMmTaJt27bMmTMHgJtuuomTTz6Zhx9+mLPPPps333yTlStX8txzz9XzU2lY0WEODhvmhARGzqGSlxkREZEGEVJuolOCRV3XREQqUqMWnWeeeYaMjAxGjhxJ69at/bcFCxb46+zcuZO9e4sH7A8dOpQ33niD5557jv79+7Nw4ULef//9SicwaIqiQuykYyY63pzDQY5GRESOBi4jr2yhRWN0RESqo0YtOoZhVFln2bJlZcrGjx/P+PHja3KqJifCZSezcO6bgiMHaj9dnYiISH0pOb20xuiIiASo0zo6RxOLxUKeIwYAX86h4AYjIiJHsYomI3A1figiIk2YEp0a8DijzTu56romIiINrBq9KAK6rtmcDReLiEgzpESnBryuWAAseenBDURERFo+T3755QHTS5dIdNSiIyISQIlODfhCYwCw56cHNQ4RETkKeMqZiACocHppteiIiARQolMD1rA4ABwFR8DnDXI0IiLSotW0RUeJjohIACU6NeAIiwHAggHuKtY2EBGRRvXUU0/RsWNHQkJCOOGEE/jhhx8qrZ+ens4NN9xA69atcblcdO/enU8++aSRoq2GClt0SgiYdU1d10REStIsyTUQERZGgWHDYfGCOxtCooMdkoiIAAsWLGDGjBnMmzePE044gUcffZQxY8awceNGEhMTy9R3u92cfvrpJCYmsnDhQtq2bcuOHTuIiYlp/OArUlGLTkLP4vvWEr9X2hwNG4+ISDOjRKcGosKc5OAimhwz0RERkSbhkUce4eqrr2bq1KkAzJs3j48//piXXnqJv/3tb2Xqv/TSSxw6dIjly5fjcJgJQseOHRsz5KqV16Iz9EYY/tfy66vrmohIAHVdq4GoUAfZFC7Ipq5rIiJNgtvt5qeffmLUqFH+MqvVyqhRo1ixYkW5+3z44YcMGTKEG264gaSkJPr06cP999+P19uExl963QGbqdYkGH0vOMPKrx/VthGCEhFpPtSiUwNRIXZyjBBzwhu16IiINAkHDhzA6/WSlJQUUJ6UlMSGDRvK3Wfr1q188cUXXHrppXzyySds3ryZ66+/noKCAu68884y9fPz88nPL+5KlpmZWb9PojylWnQqXFXnsncg5xC06tLgIYmINCdKdGogOqBFR4mOiEhz5fP5SExM5LnnnsNmszFo0CD27NnDgw8+WG6iM2fOHO6+++7GDbJMomMpv17XUeWXi4gc5dR1rQaiQh1miw6o65qISBMRHx+PzWYjNTU1oDw1NZXk5ORy92ndujXdu3fHZiuenrlXr17s27cPt9tdpv7MmTPJyMjw33bt2lW/T6I8pSYjqDDRERGRcinRqQGzRadw+k616IiINAlOp5NBgwaxZMkSf5nP52PJkiUMGTKk3H2GDRvG5s2b8fl8/rJNmzbRunVrnM6yg/pdLhdRUVEBtwZX3a5rIiJSLiU6NRAV4iCnsOuaL18tOiIiTcWMGTN4/vnneeWVV1i/fj3XXXcd2dnZ/lnYJk2axMyZM/31r7vuOg4dOsRNN93Epk2b+Pjjj7n//vu54YYbgvUUyirVotMqXOvkiIjUhMbo1EB0qIMcw7zQ5OdkEhrkeERExDRhwgT279/PrFmz2LdvHwMGDODTTz/1T1Cwc+dOrCXWnElJSWHRokXcfPPN9OvXj7Zt23LTTTdx++23B+splOEtyMNWYjvEod8mRURqQolODTjtVgpsZnqTn31EiY6ISBMybdo0pk2bVu5jy5YtK1M2ZMgQvvvuuwaOqvZyc3KICCjRGB0RkZrQz0M15LWHA1CQeyTIkYiISEuWm1tqLKhFiY6ISE0o0akpp5noePKU6IiISMPJy80JdggiIs2aEp2acpmJji9PkxGIiEjDceeVTnTUoiMiUhNKdGrIEhJt3slvhFWxRUTkqOXOzw0sUNc1EZEaUaJTQ9bCRMfmVqIjIiINpyA/r1SJEh0RkZpQolNDjvAYAOwFGqMjIiINx+cu1XVNLToiIjWiRKeGnOGxALg8GqMjIiINx+LJrbqSiIhUSIlODTkj4wAI8SrRERGRhuPwlu66JiIiNaFEp4bCCxMdBwVQoIuQiIg0DLuv1DWm3eDgBCIi0kzZgx1AcxMZHYPPsGC1GJCXAY6QYIckIiItkNNndl1b2eVGBrdxwrCbghyRiEjzokSnhmLCQ8gilChyzEQnMinYIYmISAvk8OUDcDi2D5x2cZCjERFpftR1rYZiwhxkEgaANzcjyNGIiEhL5SjsuuazhwY5EhGR5kmJTg3FhDrINMIByMk8GORoRESkpXIaZosOSnRERGpFiU4N2W1Wsi2FiU7GgSBHIyIiLZWzsEXHcIQHORIRkeZJiU4tZNuiAMjPVKIjIiINw2kUJTqa9EZEpDaU6NRCniMaAE+WEh0REWkA3gLseM37jrDgxiIi0kwp0akFtzMWAF/OoSBHIiIiLVJBjv+uRYmOiEitKNGpBY/LTHQsuUp0RESkARSYa+h4DQsWuzPIwYiINE9KdGoj1Ex0bHmHgxyIiIi0SIUtOjmEYLfpUi0iUhv69KwFS3grABzu9OAGIiIiLZPbTHTycGKzWoIcjIhI86REpxZs4XEAuAq0YKiIiDSAwq5ruYYTu1WXahGR2tCnZy04oxIACPMo0RERkQbgNRcLdeNQi46ISC0p0amFsOh4818jBzzuIEcjIiItjs8DQAE27DYlOiIitaFEpxbCo+PxGYUXnlxNSCAiIvWsMNHxYlOLjohILSnRqYXo8FAyCDc3NMW0iIjUs6837gXAgxW7Eh0RkVpRolMLMWEODhsRAHizDwY5GhERaWle+3YLoBYdEZG6UKJTCzGhDtIxE52c9P1BjkZERFoaGz4APEp0RERqTYlOLdhtVo5YogDIy1SiIyIi9cuOFwCPYVPXNRGRWqpxovPVV18xduxY2rRpg8Vi4f3336+0/rJly7BYLGVu+/btq23MTUKO3Ux03EcOBDkSERFpaYoSHS9WbFpHR0SkVmr86ZmdnU3//v156qmnarTfxo0b2bt3r/+WmJhY01M3KfmOaAC8WRqjIyIi9ctuKWzRQS06IiK1Za/pDmeeeSZnnnlmjU+UmJhITExMjfdrqgpcsZAHvhzNuiYiIvVLY3REROqu0drDBwwYQOvWrTn99NP59ttvG+u0DcbjigXAoumlRUSkHhmGUTxGRy06IiK1VuMWnZpq3bo18+bNY/DgweTn5/PCCy8wcuRIvv/+ewYOHFjuPvn5+eTn5/u3MzMzGzrMmguLA8CepwVDRUSk/hR4jVJjdJToiIjURoMnOj169KBHjx7+7aFDh7Jlyxbmzp3La6+9Vu4+c+bM4e67727o0OrEGtYKAKc7PbiBiIhIi+Lx+bAFtOhoMgIRkdoIyqfn8ccfz+bNmyt8fObMmWRkZPhvu3btasToqscRYSY6IZ6MIEciIiItidmiUzhGx7Bhs6lFR0SkNhq8Rac8q1evpnXr1hU+7nK5cLlcjRhRzbmiEgAI82aCYYBFFyIREak7j7d0i46uLyIitVHjRCcrKyugNWbbtm2sXr2auLg42rdvz8yZM9mzZw+vvvoqAI8++iidOnXimGOOIS8vjxdeeIEvvviCzz77rP6eRRCEx5qJjg0f5GVAaExwAxIRkRbB4zNwaIyOiEid1TjRWblyJaeccop/e8aMGQBMnjyZ+fPns3fvXnbu3Ol/3O1289e//pU9e/YQFhZGv379+PzzzwOO0RxFRUaSY7gIs+RD7iElOiIiUi8KvD5sJdbRsanHgIhIrdQ40Rk5ciSGYVT4+Pz58wO2b7vtNm677bYaB9bUxYU5OUwEYeRDzmGIC3ZEIiLSEnhKjtHBhlUtOiIitaKpXGopNsxJhhEBgDv7YJCjERGRlqL0rGsiIlI7SnRqKTLETgbhAORkKNEREZH6UeANHKMjIiK1o0/QWrJaLeRazRadvCNKdEREpH54vAZRlhzzvlp0RERqTYlOHeTbI81/jxwOciQiItJSRG5ayIW2rwBzHR0REakdJTp1UOCMBsCbo0RHRETqR8evZvjve9WiIyJSa0p06sDrjALAl5Me3EBERKRF8ugyLSJSa/oErYsQs0WHvPSghiEiIi2HQfF00mrRERGpPSU6dWANiwXAlp8R5EhERKSl8Fkd/vsFSnRERGpNiU4d2MLNRMdekBnkSEREpKUwrMVreatFR0Sk9pTo1IEzIg6A8IJDYBhBjkZERFoCn6W4Refknq2DGImISPOmRKcOLIm9yDfsxHkPwP6NwQ5HRERaAF+JFp3RfdoGMRIRkeZNiU4dREbH8a2vj7mx6dPgBiMiIi2Cz1Kc6GBzVFxRREQqpUSnDmLDnKw32psbR/YGNxgREWkRAhIdq8boiIjUlhKdOogNd3DECAPAl6eZ10REpO68AYmOveKKIiJSKSU6dRAT6uQIZqLjyVaiIyIidedToiMiUi+U6NSB027FbY8AwJubHtxgRESkRfCWmHUNi7quiYjUlhKdOjJcUea/uWrRERGRuvOWTG58nuAFIiLSzCnRqSNLSLR5J1+LhoqISN0FjNHxuoMXiIhIM6dEp45sYWaiY3MfCXIkIiLSEhglF6BWi46ISK0p0akjZ1gMAA5PFpS8OImIiNSQYRgcycktLvAWBC8YEZFmTolOHYVExgJgNTxQkBPkaEREpDnbdiAbT0GJ5EazromI1JoSnTqKiYnFa1jMjTyN0xERkdrLyvdgw1tccMy4oMUiItLcKdGpo+ToUDIJNzdyDgY3GBERadbyCnw4ihKdKR+D3RXcgEREmjElOnWUHBXCNiPZ3Ni/IbjBiIgcxZ566ik6duxISEgIJ5xwAj/88EO19nvzzTexWCyMGzeuYQOshtwCb3GLjtVReWUREamUEp06SooO4TdfB3Nj35rgBiMicpRasGABM2bM4M4772TVqlX079+fMWPGkJaWVul+27dv55ZbbmH48OGNFGnl8gq82PGZGxqfIyJSJ0p06ig5KoT1hpnoePYq0RERCYZHHnmEq6++mqlTp9K7d2/mzZtHWFgYL730UoX7eL1eLr30Uu6++246d+7ciNFWLK/Ai91S1KJjq7yyiIhUSolOHYW77Oy1twPAd2hHkKMRETn6uN1ufvrpJ0aNGuUvs1qtjBo1ihUrVlS43+zZs0lMTOTKK69sjDCrxWzRKUx0bOq6JiJSF2oXrw9h8ZALltxDwY5EROSoc+DAAbxeL0lJSQHlSUlJbNhQ/tjJb775hhdffJHVq1dX6xz5+fnk5+f7tzMzG2aWzbwCX4kxOrpEi4jUhVp06oEtIh4Ae346+LyVVxYRkaA6cuQIl19+Oc8//zzx8fHV2mfOnDlER0f7bykpKQ0SW+LeL4izZJkbSnREROpEn6L1wBUdD/vBgg/yMiAsLtghiYgcNeLj47HZbKSmpgaUp6amkpycXKb+li1b2L59O2PHjvWX+XzmBAB2u52NGzfSpUuXgH1mzpzJjBkz/NuZmZkNkuycuebm4g0lOiIidaIWnXoQFxlOphFmbmgtHRGRRuV0Ohk0aBBLlizxl/l8PpYsWcKQIUPK1O/Zsydr1qxh9erV/ts555zDKaecwurVq8tNYFwuF1FRUQG3BqdER0SkTvQpWg/iI1wcMiKJsuQUJjrdgh2SiMhRZcaMGUyePJnBgwdz/PHH8+ijj5Kdnc3UqVMBmDRpEm3btmXOnDmEhITQp0+fgP1jYmIAypQHlRIdEZE60adoPYiPcHGYSDqSCtkHgh2OiMhRZ8KECezfv59Zs2axb98+BgwYwKeffuqfoGDnzp1Yrc2sE4NmXRMRqRMlOvUgPsLJISPS3FDXNRGRoJg2bRrTpk0r97Fly5ZVuu/8+fPrP6C60jo6IiJ10sx+3mqa4iNdxYlO9v7gBiMiIi2Duq6JiNSJEp16kBDhIo0YAIwj+4IbjIiItAxWdV0TEakLJTr1ID7CRZoRC4AnU4mOiIjUA7XoiIjUiRKdehDqtJFpM9fO8WbsDXI0IiLSIjS3yRNERJoYfYrWE3dYonknK7XyiiIiIiIi0uCU6NQTI9ycwtSRkwaGEeRoRESk2fF5gx2BiEiLokSnnlijkgGw+fIhLz24wYiISPPjLQh2BCIiLYoSnXoSFxNNphFmbhxR9zUREakhnxIdEZH6pESnnrSODiW1cOY1sjTzmoiI1FCJFp1dpz8XxEBERFoGJTr1pE1MCGlGjLmhFh0REakpn8d/N7/rmUEMRESkZVCiU0/axIT6Fw1Vi46IiNRYYYuO27Bht9mCHIyISPNX40Tnq6++YuzYsbRp0waLxcL7779f5T7Lli1j4MCBuFwuunbtyvz582sRatPWOrq4RcdYcg943MENSEREmheved3wYMduswQ5GBGR5q/GiU52djb9+/fnqaeeqlb9bdu2cfbZZ3PKKaewevVqpk+fzlVXXcWiRYtqHGxTlhQVwmGiALD4CmDDR0GOSEREmpXCrmsebDht6nAhIlJX9prucOaZZ3LmmdXvOzxv3jw6derEww8/DECvXr345ptvmDt3LmPGjKnp6Zssh83KbmcX8BUWHN4ezHBERKSZ8Xrc2IACbNiV6IiI1FmDf5KuWLGCUaNGBZSNGTOGFStWVLhPfn4+mZmZAbfmYHPk8Wz1mevp4M4ObjAiItKseAqKuq7ZcKjrmohInTV4orNv3z6SkpICypKSksjMzCQ3N7fcfebMmUN0dLT/lpKS0tBh1ov4yBA+9A01N3IPBzcYERFpVryFYzsLsONQi46ISJ01yU/SmTNnkpGR4b/t2rUr2CFVS0Kki3QjwtzIPRTcYEREpFnxFrboFBg27Fa16IiI1FWNx+jUVHJyMqmpgevKpKamEhUVRWhoaLn7uFwuXC5XQ4dW7+IjnOz3Jzpq0RERkerzeIpnXbMp0RERqbMGb9EZMmQIS5YsCShbvHgxQ4YMaehTN7r4CBfphJsbSnRERKQGfAXmOjpeiw2LRYmOiEhd1TjRycrKYvXq1axevRowp49evXo1O3fuBMxuZ5MmTfLXv/baa9m6dSu33XYbGzZs4Omnn+att97i5ptvrp9n0IQkRLrIKGrRyVGiIyIi1VeyRUdEROquxonOypUrOfbYYzn22GMBmDFjBsceeyyzZs0CYO/evf6kB6BTp058/PHHLF68mP79+/Pwww/zwgsvtKippYu0jwsjncJEJ2MnrHwpuAGJiEiz4fMUt+iIiEjd1fhno5EjR2IYRoWPz58/v9x9fv7555qeqtnp0CqcA0Z0ccFvH8DgK4IXkIiINBs+Tz4AXrXoiIjUiyY561pzFR/hxHBF8an3OLPA6wluQCIi0mx4/WN0HEGORESkZVCiU48sFgsdWoXxpvcUsyA/I7gBiYhIs+HzmmN01HVNRKR+KNGpZx3jw8k0wsyNvMzgBiMiIs1G0Rgdn0Vd10RE6oMSnXrWsVUYmRQmOvlKdEREpHoMrxIdEZH6pESnnnVsFc6Rki06lUzcICIiUsRXOL20z6pER0SkPijRqWcd48M5UtSiY3jBnR3cgEREpFmwZ6cC4LaGBjkSEZGWQYlOPevQKowcXHiMwpdW3ddERKQqhkHi7kUArHENDHIwIiItgxKdehYf7sJutRa36mhCAhERqUrOQcKzzcW2fw0bEuRgRERaBiU69cxqtRAf4eKIUdj1QC06IiJSlcLFQvMNO15HWJCDERFpGZToNICESBeZhJsbuelBjUVERJoBX+Fiodhw2ixBDkZEpGVQotMAEiJd7DXizI2MncENRkREmjzD6wHAgw2bVYmOiEh9UKLTABIiXGw3ks2Ng1uDG4yIiDR5+zOyAPBg5ZvfDwQ5GhGRlkGJTgNIiHSxw0gyNw4p0RERkcpl55ljdDzYmXh8+yBHIyLSMijRaQBJ0SHFLTr712vRUBERqVR2bh5gtujceFq3IEcjItIyKNFpAL2SI9noS8GLFQ5vhzULgx2SiIg0YTmFiY7V5iQ61BHkaEREWgYlOg2gd5soDlhimO8ZYxZs+Ci4AYmISJOWm2cmOobVFuRIRERaDiU6DSDMaadLQgRf+/qYBQc2BTcgERFp0nILx+hgtQc3EBGRFkSJTgPplhjBZqOtuXFwMxROHSoiIlJaXr4SHRGR+qZEp4F0TghnjxGP2+ICrxs2Lw52SCIi0kQVJzoanyMiUl+U6DSQLgkRGFj5xTXQLFg8K7gBiYhIk5WX7wbAYlOiIyJSX5ToNJDOCREA3Om5wiw4sAlyDgUxIhERaarcbrNFx2JT1zURkfqiRKeBtI8LA+C3rHCM2E5m4d7VwQtIRESarKJEx2pXi46ISH1RotNAYsMchDjMlzenVeHsa3tWBTEiERFpqjyeAkBd10RE6pMSnQZisVhoExMKQFps4TidbV8FMSIREWmqvAVmomNVoiMiUm+U6DSgNtFmovN7+GCzYOd3UJAbxIhERKQp8nmLWnQ0RkdEpL4o0WlAbWJCANjoSYawePDmw/6NQY5KRESaGl9h1zWN0RERqT9KdBpQu1hzQoKtB3MgtqNZmLEreAGJiEiT5POZiY5NXddEROqNEp0G1D8lBoBVOw9DTIpZmL4zeAGJiEjTVNiiY7M7gxyIiEjLoUSnAQ0oTHR2HMwhJ6ytWZiuFh0RESlW4PVhNbwA2NR1TUSk3ijRaUDRoQ66JIQDsNuINwv3rw9iRCIi0tTkuL3YKEx0HGrRERGpL0p0Gli3xEgAfjcKu65tXQbbvw1eQCIi0qTkFXhxWMxEx6pZ10RE6o0SnQbWJdFs0Vle0B06jzQLNy8OXkAiItKklGzR0YKhIiL1R4lOA+uSEAHAlgPZ0OMss/DA70GMSEREmpJctxd7YaKDVS06IiL1RYlOA+uaaCY6G/cdwWjV1SxUoiMiIoVyCzxKdEREGoASnQbWIzkSh83C4ZwC9joKx+kc2gKFq2CLiMjRLdftK0501HVNRKTeKNFpYC67jZ7JUQCsSg8DVxT4PLB/Y5AjExGRpiDH7cGhFh0RkXqnRKcR9E+JBuCnnRnQur9Z+MeqIEYkIiJNRW5B8WQESnREROqPEp1GcGLnVgAs33wQ2g40C/f8FMSIRESkqcj3+PzTSyvRERGpP0p0GsHQLvFYLLAx9QiZMceYhWlaOFRERMDrM4pbdDRGR0Sk3ijRaQRx4U66Fy4c+ps70Sw8uCWIEYmISFPh8fo065qISANQotNI+rUzx+l8n2H+S84ByMsIYkQiIi3LU089RceOHQkJCeGEE07ghx9+qLDu888/z/Dhw4mNjSU2NpZRo0ZVWr8heXwGdnzmhhIdEZF6o0SnkfRPiQFg5d4CCFerjohIfVqwYAEzZszgzjvvZNWqVfTv358xY8aQlpZWbv1ly5YxceJEli5dyooVK0hJSWH06NHs2bOnkSM3u67Z8ZgbSnREROqNEp1G0r9dDAC/7s7AaNXFLNy6LGjxiIi0JI888ghXX301U6dOpXfv3sybN4+wsDBeeumlcuu//vrrXH/99QwYMICePXvywgsv4PP5WLJkSSNHDokHf2SU7WdzQ2N0RETqjRKdRtIjORKn3UpGbgEHu15oFn79CHjcwQ1MRKSZc7vd/PTTT4waNcpfZrVaGTVqFCtWrKjWMXJycigoKCAuLq7cx/Pz88nMzAy41QuflzN+val4O6xV/RxXRERql+jUpB/0/PnzsVgsAbeQkJBaB9xcOe1Werc2Fw79NnIMhMaC+wjsWxPkyEREmrcDBw7g9XpJSkoKKE9KSmLfvn3VOsbtt99OmzZtApKlkubMmUN0dLT/lpKSUue4AfC6cfpyAfi/tjdDl9Pq57giIlLzRKem/aABoqKi2Lt3r/+2Y8eOOgXdXA0oHKfzy+4jkHKCWbjr++AFJCIi/Otf/+LNN9/kvffeq/CHuJkzZ5KRkeG/7dq1q35O7i1u1f85/hywaYyOiEh9qXGiU9N+0AAWi4Xk5GT/rfSvbkeLopnXft2dDu1PNAsXz4Lt3wQvKBGRZi4+Ph6bzUZqampAeWpqKsnJyZXu+9BDD/Gvf/2Lzz77jH79+lVYz+VyERUVFXCrF16P/67F7qyfY4qICFDDRKe2/aCzsrLo0KEDKSkpnHvuuaxbt67S8zRYX+ggK5p5be0fGRT0uxRc0eArgDcvAW9BcIMTEWmmnE4ngwYNCphIoGhigSFDhlS43wMPPMA999zDp59+yuDBgxsj1LIKW3Q8hhW7zRacGEREWqgaJTq16Qfdo0cPXnrpJT744AP+85//4PP5GDp0KLt3767wPA3WFzrIOrUKJybMQV6Bj7XpDrj0LfOBvAx1YRMRqYMZM2bw/PPP88orr7B+/Xquu+46srOzmTp1KgCTJk1i5syZ/vr//ve/ueOOO3jppZfo2LEj+/btY9++fWRlZTVu4D7zR64C7NislsY9t4hIC9fgs64NGTKESZMmMWDAAE4++WTeffddEhISePbZZyvcp8H6QgeZ1WrhxE7mjDrLtxw0u6/1vch8cMsXQYxMRKR5mzBhAg899BCzZs1iwIABrF69mk8//dT/w9zOnTvZu3evv/4zzzyD2+3mwgsvpHXr1v7bQw891LiBe4sSHRt2JToiIvWqRqMe69IPuojD4eDYY49l8+bNFdZxuVy4XK6ahNZsDO3aik/X7WPFloPccEpXaHccrHkL0jYEOzQRkWZt2rRpTJs2rdzHli1bFrC9ffv2hg+oOgq7rhVgx27Tig8iIvWpRp+qte0HXZLX62XNmjW0bt26ZpG2EEM6my06P24/RL7HC0WLhx6sOPETEZEWqrBFx4NNXddEROpZjX8+qmk/6NmzZ/PZZ5+xdetWVq1axWWXXcaOHTu46qqr6u9ZNCNdEyOIj3CR7/Hx8850iO9mPnBgI9yTCO9fDz5fUGMUEZFG4i0eo6OuayIi9avGE/ZPmDCB/fv3M2vWLPbt28eAAQPK9IO2Wovzp8OHD3P11Vezb98+YmNjGTRoEMuXL6d379719yyaEYvFwtAurfjwlz9YvuUgJ3bsCjYXePPN2+rXYcg0SDo6Xx8RkaNK4WQEbkOTEYiI1LdarUxWk37Qc+fOZe7cubU5TYtVlOis2HIATu8O8d0hdU1xhYO/K9ERETkaFE0vrckIRETqnUY+BsHQLvEA/Lwznex8D5z5L7CU+FMc+D1IkYmISKPSZAQiIg1Gn6pB0L5VGClxoXh8Bt9vOwgdT4LrlsMJ15kVNDGBiMjRwesBNL20iEhDUKITJCd1TQBg8W9pZkFiL+hQOHPdHz8HKSoREWlUJVp0NEZHRKR+KdEJkrH9zOm1F/60iz/Sc83CTiPA6oD9GyBtfRCjExGRRlE4GYHHsGO3KdEREalPSnSCZGjXeAZ1iKXAa7BkQ2GrTmgsdB1l3v9pftBiExGRRuKfXtqGzapLsohIfdKnahCN7G52X/tuy8HiwuOvNv9d9Rq4s4MQlYiINJrCrmtu7DjUdU1EpF4p0QmiE7u0AuCr3/dzONu82NHlVIhOgYJsuL8NHEkNYoQiItKgClt0PBqjIyJS75ToBNHA9rH0TI7kSJ6HF7/ZZhZaLNB+SHGlVa8GJzgREWl4JbquaYyOiEj9UqITRDarhetGdgEoHqcDMPDy4vtL74UvH/RPQSoiIi2IryjRsWuMjohIPdOnapAN75aAxQLr92aSmplnFnYaAZcuLK609F5Y81ZwAhQRkYZTNL20Ydc6OiIi9UyJTpDFhTvp1zYagK827S9+oOsoOOnm4u3vngZPfiNHJyIiDaqwtd6jBUNFROqdPdgBCJzcPYFfdmewbON+xg9OMQstFhh1F5xwLTw+EPatgSWzYcx9QY1VRETqUYlZ1zRGR6Rl8Xq9FBQUBDuMZsnhcGCz2ep8HCU6TcCpvZJ4/IvN/G/tXn7eeZhj28cWPxiZDBc8D29eAiuehJ3fQauucO6TYHMEL2gREam7oq5rGqMj0mIYhsG+fftIT08PdijNWkxMDMnJyVgstf8RSIlOEzAgJYZzB7Thg9V/cO/H61l47ZDAP2qPs6B1f9j7C+xZad66j4Y+FwQvaBERqTufuq6JtDRFSU5iYiJhYWF1+qJ+NDIMg5ycHNLSzIm6WrduXetjKdFpIv5+Vi8+XbuPn3YcZvWu9MBWHYsFUk40E50iC6+A3HQ47spGj1VEROpJiRYddV0Taf68Xq8/yWnVqlWww2m2QkNDAUhLSyMxMbHW3djUTt5EJEWFMOaYZAA+WP1H2Qr9LjL/tTmLyz6eAXt+aoToRESkQRSto2OoRUekJSgakxMWFhbkSJq/otewLuOclOg0Iecd2xaA//6wkw37MgMfbDcYrlgEN/0CEUnF5f+5ANLWN2KUIiJSZ+4cSN8JWamAxuiItDTqrlZ39fEa6lO1CRnZI4Hh3eLJ9/i47IUfyMovtUho+xMhqg1MeB26nAqOMMg9DAsuB5/XvJ+xJzjBi4hI9X1yKzzaFzZ9CmiMjohIQ1Ci04RYLBYev/hYUuJCOZCVz3+/31l+xZTj4PL3YPpaCI2Fg7/Dxv/Bq+fCk8dBZjld30REpOkIiw3YzCQMmxIdEWkhOnbsyKOPPhrsMJToNDWx4U5uPKUbAC98s5V8j7fiyuGtYNAU8/6imeZkBQXZ8Pvihg9URERqLzQuYDPNiNVkBCISVCNHjmT69On1cqwff/yRa665pl6OVRdKdJqgc49tQ1KUi9TMfD74uYrWmeOuAovN7Otd5MCmhg1QRETqJixwNqY0Iwa7xuiISBNmGAYej6fqikBCQkKTmJBBn6pNkMtu46qTOgPwzJdbKm/ViW4HfccHlu1YHrhtGPUcoYiI1ElYYIvOQUss4a66rwIuIlIbU6ZM4csvv+Sxxx7DYrFgsViYP38+FouF//3vfwwaNAiXy8U333zDli1bOPfcc0lKSiIiIoLjjjuOzz//POB4pbuuWSwWXnjhBc477zzCwsLo1q0bH374YYM/LyU6TdTEE9oTH+Fk24Fsnvxic+WVT/m7OVYnqp25/ccqeHYE/PA8vHw2PNgFtnwBvyyAR46BbV83/BMQEZGKlWjRKTBsxLRKxmVXoiPSEhmGQY7bE5SbUc0fux977DGGDBnC1Vdfzd69e9m7dy8pKSkA/O1vf+Nf//oX69evp1+/fmRlZXHWWWexZMkSfv75Z8444wzGjh3Lzp0VjC0vdPfdd3PRRRfx66+/ctZZZ3HppZdy6NChOr++ldGCoU1UhMvO7HP7cP3rq3h62RaOaRPFGX0qWBk2tgP8dSNY7bB4Fqx40hyvU3KB0dfOK77/9mS4bWvDPgEREalYiTE6B4imZ5uY4MUiIg0qt8BL71mLgnLu32aPIcxZ9df96OhonE4nYWFhJCeb6zpu2LABgNmzZ3P66af768bFxdG/f3//9j333MN7773Hhx9+yLRp0yo8x5QpU5g4cSIA999/P48//jg//PADZ5xxRq2eW3WoRacJO6tva84/ti1en8Etb/9adrrpkuwusNrg9Nlw3nNgDyl+zFLqz5xzEH77ENzZ8O3j8N0zDfMERESkfCVadNKMGHokRwYxGBGRig0ePDhgOysri1tuuYVevXoRExNDREQE69evr7JFp1+/fv774eHhREVFkZaW1iAxF1GLThP3wIX9+HlXOtsOZPPQoo3cObZ35QsoWW3Qf4I5bmfncrNLmyMU3rgYDmwsrvfW5YH7ffo3+MtqiOkAe1dD6/7msUREpP6FFk8v/YuvC0lRIZVUFpHmLNRh47fZY4J27roKDw8P2L7llltYvHgxDz30EF27diU0NJQLL7wQt9td6XEcDkfAtsViwefz1Tm+yijRaeLsNivTTunKX9/+hfnLt3Ns+xjOHdC26h2tVuh4UvH2tB8gbb25ON3mJXBwMxzZG7jPd0+D1QHfPQVnP2zO6CYiIvXPZgebE7xu3vaezE2hjqr3EZFmyWKxVKv7WLA5nU683komwCr07bffMmXKFM47zxwWkZWVxfbt2xs4utpp+q+6cMGgduakBEs3c+vCX4mPcDGsa3zND5TYy7yddDN4PeZYnQ0fmV3bDB/88Fxx3Y//Cvs3wab/QVJf6HM+eN2QdIzZ2iMiInXz56+58aUlrMnrSEyYEh0RCa6OHTvy/fffs337diIiIipsbenWrRvvvvsuY8eOxWKxcMcddzR4y0xtaYxOM/GX07oxqlcibo+PS1/4nqeXVTETW1VsdrjoNXMSg1mHYMClZev88Ky5Ps/Gj+GdK+H968zZ3P57CRxJhaz9dYtBRORoltiTr93mAtHRatERkSC75ZZbsNls9O7dm4SEhArH3DzyyCPExsYydOhQxo4dy5gxYxg4cGAjR1s9FqO6884FUWZmJtHR0WRkZBAVFRXscIImx+3h/KeXs2HfEWxWC/ec24eLBrfDbquHfNUw4KeX4Y+fYdWr1dsnJBqu/RayUiGpDzhK9DHftAi+fhj+9Cgk9a57fCISFPr8LV99vC4+n0GXf3yCYcAP/ziNxEiN0xFp7vLy8ti2bRudOnUiJET/p+uisteyup/B6rrWjIQ57Xx040lMnf8jX/9+gL+/t4blWw7wxMRjK5+goDosFhh8hXk/oRcsmmnev+g1iOtk9iX/fh6sfKl4n7wMeLRP8XbKidDzbOg6Ct64yCz78t9w0St1i01EpAU6ku/xr+esFh0RkfqnRKeZsdusvDB5MK+t2MG/P93AR7/uJdft5e5zj6FdbFj9nGTI9XDCtZBzACISi8vH3A9tjoV9a81WnN/eD9xv13fmbfEdxWW/vQ9fPmAmRb3Hma07O5ZDfDdwRZVZHVxE5GiRkVMAmLMiabFQEZH6p0SnGXLZbVw1vDNRoQ7+/u4almxIY9fhHN64+kTiI1z1cxKrNTDJAXOa6oGTircP/A7bvoS0DbDnJ3NWt5BoyNoH9lDw5Jr1lt5n/rviybLnaXecmVQl9DBbjXauAG+Bee52x0PmHlj3nvl4yonmlNdRbcDmMmOsSuYfZkzO8Krriog0ooxcM9FRa46ISMNQotOMXTQ4hd6to5j80g9sSs1iyJwlXHpCB87u15rBHWLr3p2tKvHdzFtp7hxzJrft38DHN0OrbuDJgx3flq27+0fzVlNR7SCqtXm/0wizy1xBnpkI7VsD3z4G+ZlmS5LFBuc9C7EdoVUXsxWpIBcWz4KEnnDclZCx2ywr7/mIiDSA9FxzzQnNuCYi0jCU6DRzfdpG89qVJ3DbO7+wdk8m85dvZ/7y7Zx3bFv+fUE/nPYgTKznLOxC120UTF9TXJ6+C9Z/aCYlGz4pHgfkiob8DPO+xQYRSeArgOz9YLWDz1P2HJm7zRuYidLXD1ccj+GFdwvXBLK5zFakQ1vhyB9m2fLH4fB2s0Xp3Kfg98+g/YnQ9XSzFSss3hzDlHPQbF3qNMJsYcrLNBM6V4R5nOwDsPET6HUOhMaYZT6vFl4VkXJtP5gDQHK0BiyLiDQEJTotQO82UXx043C+2JDKbQt/5UCWm/d+3sOaPRncMroHp/ZMDE7CU1pMCgy5wbw/5HroeRaEJ5iLlGbuMdfpielgzt7m88LBLWY3NYvVTGScYeCMgNS1ENkGfn3TTFBKKtllrojNZSYm+34Fbz7s+Cbw8aJjeN3w7tXm/TVvFz8ekWQmYEWJUWnhCebirOveM7eX/Rv+9AisfBl2fQ99LwQsENPeTKYydkFcZ7Mb4L41ZhfAnmfDwd/N5wXwxyozIcvYDcl9IfcwbPwfYJjniulgJl8VKRrhXN1WPZ/PPEd4q+rVF5E627TvCAA9kiODHImISMuk6aVbGMMwmPO/DTz31VZ/Wc/kSP5xdi+Gd0sIYmQNJD/LTFDyMsxFT6NTzAkR2h0fON01mF/+170Lu36EDkOgzUBY/TqsfQcObCquFxprfulvaBFJkJUGVPFfMKGXmWTlZZT/eFwXOLIXupxqJlLpO2D/RrCHmJM/JPWBvb+Y45XaHWeOfwqNMRPArFQzkVz7jnmMPheYXfgSekByP4jtAFFtzcdCYsyWsP0bYMtSs7WtzQDzvBYr5ByCTsPBk2+eP3s/dD8jcCyVz2vWtVjM+z4v2J2Bz2ffGnNcVUz72r+2DcXrAQywHT1djfT5W776eF0umreCH7YfYu6E/px3bLt6jlBEgkHTS9ef+pheWolOC7U5LYsXv9nKO6v24PaYq9X2axdNl4QIxg9qx9Cu8UGOsAkxDCgoHFd0YJP5Bf/gFjNRCo2F7d+aX9az0swv8yHRZutLj7OhVVc4sNGcRCH7IHQeaXbP+/k/+BMYRxgk9jJnmcvYDUf2gftIMJ9x44nrYrbEuXPM7ojpOyEiGdqfYM6+l3MIQqLAFWm2jLkiYesyc19XlNmaFR5vvrauCHPCC8NntvS17m/WsdrMZDfnoJkMunPMOhm7zEQ4rJU5NstqN5PLyCSzviMMQuOKz5tzENxZZsyOENj7q9k6GJ1ijjGzOuDTv5lJ8HFXmX/T7APmeaJTzLFf6TvM90xYKzPpBLObpivSTK4j2xR3yQxrBWm/md0jE3qYyWhUWzMOMBO9Vl3N5PLQNohMNmOO62Q+brGYzxXM53tgozlOrcNQM96038AZCYk9zfdsLenzt3z18boMvGcxh7LdfHTjSfRpW/u/kYg0HUp06o8SHanSptQjPPvlVt5fvQevr/hP3bFVGH3bxTB+UDuO7xRHiEPjSOpVVpr5q39IjLldugvZ4R2w+XNoPQAKss0v1Ye2mF/A+1xofrnPy4DoduZ03jYndD3NbEn58t9my0v6DvNYnU42u/PtXgnRbSHpGHOGuozd8NWDZoIR3c780t92EOxZaX55dkaaCVvbQZDYG3Z+Z37pzko1uxIavuJ4bS6z258j3Iy3qCy+m5m8eAvM2A1vQ7+yUmMWMym7dKH5/qghff6Wr66vixYLFWmZlOjUHy0YKlXqnhTJwxf15/YzerDot1S+23KQxb+lsv1gDtsP5vB/v/xBiMPKWX1bc07/NnRLiqRNdEjDz9jW0pWemru02A7mbG9FOo2opG7H4vvdRpm30nqcUbYsqTd0H115HD5f+dN0e/LNW0iUmXA5I81JIWwOsxtbVJvAY2CYLWNr3jITs+EzzPq/fwbubDNpstrNlol2g80kLX0X9BprJoV/rAIsZutK637mPuHxZutXVpp5LJ+nuBXn8DbY/rXZwlF07LB4syUm/4jZgoLFXPcpLx1S15nd5A5tMVuRXBFma4zNYbYW5Rwwz1MyUUvqayYG6TvN7nyefLObXpsBZqvTzu/MWfsSe5pTrGfvN5NMr9s8hyfXPGbmHvNvaHOZrS7RKeZzyM80W6MKcs2JLSIKu5Z6zJm48OabrUcRSWbrTu5h83U5srfs38tiM1uI3NnFiagzwky0M3ebiXVEUuXvBWlUJRcLjQo5erpCiog0JiU6R4nEqBAuP7EDl5/YgbQjeXzz+wG+33qIZZvSSM3M591Ve3h31R4AYsMcDOoQS0Kkiz5tozmuYxxdEyKwWpX8tDgVrUVkd5k3KO72ZC3silUyySl9jAGXBD5Wct2lygyYWL16RdqfAP0vrn79nmdXXccwiluxisYRVeT4q6t3Xp/P7EbmDDOPn32gOKGpTjxed/Hfoci+tWYS6IwwkzqLpXDCDIt5PneWeQtrZe6blQYHN4NNH/dNSWbhGjouu1Ut6iLSJIwcOZIBAwbw6KOP1svxpkyZQnp6Ou+//369HK82dOU7CiVGhnD+wHacP7AdhmGwelc6//luJ7/sTmf7gWwO5xTw+fq0wtq7AHOdh1bhTjrFh3NCp1a0iQklOTqEY9pE6SItLYPFYraM1CertXi6dYul+klOUf3SSQ5Acp/i+0VTm5c8X0iUeSsSkVh1C6M0usw8M9GJ0mKhIiINRonOUc5isXBs+1iObR8LgNvjY90fGazelc6BrHxW7Ujn512HSc8pID2ngC37s0skQWC3WmgfF0Z8hIv4SCcpcWG0jQmlb9toIkPsRIY4iA1zNo3prUVEmojMXHN9sKgQXYZFJPimTJnCl19+yZdffsljjz0GwLZt28jKyuLWW2/l66+/Jjw8nNGjRzN37v+3d+9BUZ3nH8C/5+xyVggCEgTEANKGXKyKBgJZnY6dyoCXpDVtU4ZxJoxt7aTFjg5JGjVRa5sJsY4J1jhh0oym/1hS02g6uVgZvOQiIQEl0Vww5ofBqSyiRpbrLrv7/P5Y9sDiGgWRvX0/Mzt79j3vec/7vLA883LOvvs8EhLci1q99tpr2LRpE06fPo2oqCjMmTMHb7zxBrZs2YJ//OMfAKB/HOLQoUP40Y9+NK5x8S8sedGMqtfEBwD6nS58fs6K5gvdONXWiZZLPbB09OHMxR5c6LLh/y504/8udH9nuxNNRsRHa4i/RcOtt7ifJ+nbJr0s/hYNcVERMBkNnBwRUcjq6OUVHaKw4Vnd1R8ioq7rO/W2bduGU6dOYcaMGfjzn//sPjQiArm5ufjNb36D559/Hr29vXjiiSfwy1/+EgcPHkRrayuKi4vx17/+FQ8++CA6Ozvx3nvvQUTw2GOP4YsvvoDVasWuXbsAAPHx8Tc1VF9GNdHZsWMHtmzZAovFgqysLGzfvh25ublXrb9nzx6sX78eZ86cQWZmJjZv3ozFixePutM0viIMKrJS45CVGudVLiI419GHs5d6cLHLjrPf9qDlUg++udiN5vZu9PQ70dnngNMl6LQ50Glz4JuL1/dGVxUgNjICUZoRRoOCKM2IiSYjJmgGxEZGuK8WmYy4xWTEhAj3Pe4TIgyI9Dw0w0CZqr+OHKijGVR+3oiI/Eq/dY0LERCFvv4e4JmUa9e7GdadA7RbrlktNjYWmqYhKioKycnJAICnn34ac+bMwTPPPKPX27lzJ1JTU3Hq1Cl0dXXB4XDgZz/7GdLT0wEAM2fO1OtGRkbCZrPp7fnDiCc6r776KsrKylBZWYm8vDxUVFSgsLAQTU1NSEy88j7wo0ePori4GOXl5bj//vuxe/duLF26FMeOHcOMGTN8nIGChaIomBoXialxkVet43IJrH39uNhtx6Vhj4tddlzqtuFST7/7ucuOi9122BwuuAT4tqcf3/b035S+G1UFJqMKbeDhuYKklxlUmAYmRaah5UYVqqJAUdwTQM3gLoswqIgwKDCqCowGVX92l6kwqO59BoMCg6LAoA4+VGVgn2fbMKxs4Fh12HEGRYGqQm+PK+URBQ/PYgSxvKJDRAHqk08+waFDhxAdHX3Fvq+//hoFBQVYsGABZs6cicLCQhQUFOAXv/gFJk2a5KM1/xjxROe5557DihUrsHz5cgBAZWUl3nrrLezcuRNr1qy5ov62bduwcOFCPP744wCAv/zlL6iursYLL7yAysrKG+w+BTpVVRAXpSEuSsP3r+Nz2CICm8OFzj4Hvu2xo8fuhMPpft1td6DX7kRHb7/7tc1dZut3obffib5+J3r7nejtd6HP7kSfw4leu1Pf1+8c/B4hh0vgsDvRbQ+t733xTIAUxcf2wGTIoChQFffPRvW1rQxOqlTFPaE1qAoUQJ/kKUPqKQN1VAVD6igDdeBVZ/i5FQy25Z6nDR6nDGy763i2h+zXjx9aD3q7ULz7rB8zpM7geYe2N/B6WNsY0ubQvgzWdZdhSJ+99g07xvc5vc/nGRPo7V/lOM+5B6r7Ov+87yfwSmYAsfYNfEYnkneQE4W8iCj3lRV/nXuUurq68MADD2Dz5s1X7JsyZQoMBgOqq6tx9OhRHDhwANu3b8eTTz6Juro6ZGRk3Eivx8yI/sLa7XY0NDRg7dq1epmqqsjPz0dtba3PY2pra1FWVuZVVlhY+J1LzdlsNthsNv211WodSTcpiCmKot+GNnmijxWnbkC/0wWbwwX7wMPmcA48D5Z7yuxOF2z97mev8oGrTS4ROFyi7+t3ChxOF/pd7menS9xlLpe+zynuK1wOlww8u9tyumTwIYPbnrpOGdy+FqdL4ETAfwcw+cGppxdB40QnYHiu6PDWNaIwoCjXdfuYv2maBqdz8B/A99xzD/79739j2rRpMBp9TxkURcG8efMwb948bNiwAenp6di7dy/KysquaM8fRjTRuXDhApxOJ5KSvL94LikpCV9++aXPYywWi8/6FovlqucpLy/Hpk2bRtI1omty316mAmM7fxpX+kRJBidGLs/EaGAC5pkoiUCfOInIkG0M1HcfIzJ4vKeepy33Pnd9wH2svg/u+u56g+UYeHYJIBhoa6APLn2fu10ZaFOGtOFVhoGvt4Gnf+5t6P0DBIPb0Ps02I57fujZHnKegfaHtuM5Xp8qDmkHQ/riXX+wfRl2/NCyocfr28NfD5xzoMXB8w5tY2jdgQO9zze8v268szGwJERruCt5IlK+49ZfIqLxNG3aNNTV1eHMmTOIjo5GaWkp/v73v6O4uBh//OMfER8fj9OnT6Oqqgovv/wy6uvrUVNTg4KCAiQmJqKurg7t7e24++679fb++9//oqmpCbfeeitiY2MRETG+/9wJyGvma9eu9boKZLVakZqa6sceEQUGVVX4X3miELDyx5lY+eNMf3eDiEj32GOPoaSkBNOnT0dvby+am5vxwQcf4IknnkBBQQFsNhvS09OxcOFCqKqKmJgYvPvuu6ioqIDVakV6ejq2bt2KRYsWAQBWrFiBw4cPIycnB11dXYG/vHRCQgIMBgPa2tq8ytva2q66okJycvKI6gOAyWSCyRTE/3YnIiIiIgoid9xxh8+Porz++us+6999993Yv3//VdubPHkyDhw4MGb9G40RfVGJpmnIzs5GTU2NXuZyuVBTUwOz2ezzGLPZ7FUfAKqrq69an4iIiIiI6EaN+Na1srIylJSUICcnB7m5uaioqEB3d7e+CtvDDz+MqVOnory8HACwatUqzJ8/H1u3bsWSJUtQVVWF+vp6vPTSS2MbCRERERER0YART3SKiorQ3t6ODRs2wGKxYPbs2di/f7++4EBLSwtUdfBC0dy5c7F792489dRTWLduHTIzM7Fv3z5+hw4REREREd00iniW8glgVqsVsbGx6OjoQExMjL+7Q0QUNvj31zeOCxH50tfXh+bmZmRkZGDChAn+7k5Q+66xvN6/wSP6jA4REREREVEw4ESHiIiIiGgMuVwuf3ch6I3FGAbk9+gQEREREQUbTdOgqirOnTuHyZMnQ9M0KPzG5hEREdjtdrS3t0NVVWiaNuq2ONEhIqKQsGPHDmzZsgUWiwVZWVnYvn07cnNzr1p/z549WL9+Pc6cOYPMzExs3rwZixcvHsceE1GoUVUVGRkZaG1txblz5/zdnaAWFRWFtLQ0r0XORooTHSIiCnqvvvoqysrKUFlZiby8PFRUVKCwsBBNTU1ITEy8ov7Ro0dRXFyM8vJy3H///di9ezeWLl2KY8eOcVVQIrohmqYhLS0NDocDTqfT390JSgaDAUaj8YavhnHVNSIiuqpg+fubl5eHe++9Fy+88AIA973dqamp+MMf/oA1a9ZcUb+oqAjd3d1488039bL77rsPs2fPRmVl5TXPFyzjQkQUirjqGhERhQW73Y6Ghgbk5+frZaqqIj8/H7W1tT6Pqa2t9aoPAIWFhVetb7PZYLVavR5ERBTYONEhIqKgduHCBTidTv2Lqz2SkpJgsVh8HmOxWEZUv7y8HLGxsfojNTV1bDpPREQ3DSc6RERE17B27Vp0dHToj7Nnz/q7S0REdA1BsRiB52NEvFWAiGh8ef7uBvLHORMSEmAwGNDW1uZV3tbWhuTkZJ/HJCcnj6i+yWSCyWTSXzMvERH5z/XmpqCY6HR2dgIAbxUgIvKTzs5OxMbG+rsbPmmahuzsbNTU1GDp0qUA3IsR1NTUYOXKlT6PMZvNqKmpwerVq/Wy6upqmM3m6zon8xIRkf9dKzcFxUQnJSUFZ8+excSJE0e1zJzVakVqairOnj0blqvjMH7Gz/jDN37gxsZARNDZ2YmUlJSb1LuxUVZWhpKSEuTk5CA3NxcVFRXo7u7G8uXLAQAPP/wwpk6divLycgDAqlWrMH/+fGzduhVLlixBVVUV6uvr8dJLL13X+ZiXbly4jwHjZ/yMf/TxX29uCoqJjqqquO222264nZiYmLD8ZfJg/Iyf8Ydv/MDoxyBQr+QMVVRUhPb2dmzYsAEWiwWzZ8/G/v379QUHWlpavL50bu7cudi9ezeeeuoprFu3DpmZmdi3b991f4cO89LYCfcxYPyMn/GPLv7ryU1BMdEhIiK6lpUrV171VrXDhw9fUfbQQw/hoYceusm9IiIif+Gqa0REREREFHLCYqJjMpmwceNGrxVzwgnjZ/yMP3zjBzgGgYg/E44B42f8jP/mx69IIK8ZSkRERERENAphcUWHiIiIiIjCCyc6REREREQUcjjRISIiIiKikMOJDhERERERhZyQn+js2LED06ZNw4QJE5CXl4ePPvrI310aE++++y4eeOABpKSkQFEU7Nu3z2u/iGDDhg2YMmUKIiMjkZ+fj6+++sqrzqVLl7Bs2TLExMQgLi4Ov/71r9HV1TWOUYxeeXk57r33XkycOBGJiYlYunQpmpqavOr09fWhtLQUt956K6Kjo/Hzn/8cbW1tXnVaWlqwZMkSREVFITExEY8//jgcDsd4hjIqL774ImbNmqV/0ZbZbMY777yj7w/l2H159tlnoSgKVq9erZeF+hj86U9/gqIoXo+77rpL3x/q8Qc75ibmplB8bzI3eQu33BSQeUlCWFVVlWiaJjt37pTPPvtMVqxYIXFxcdLW1ubvrt2wt99+W5588kl5/fXXBYDs3bvXa/+zzz4rsbGxsm/fPvnkk0/kJz/5iWRkZEhvb69eZ+HChZKVlSUffvihvPfee3L77bdLcXHxOEcyOoWFhbJr1y45efKkNDY2yuLFiyUtLU26urr0Oo888oikpqZKTU2N1NfXy3333Sdz587V9zscDpkxY4bk5+fL8ePH5e2335aEhARZu3atP0Iakf/85z/y1ltvyalTp6SpqUnWrVsnERERcvLkSREJ7diH++ijj2TatGkya9YsWbVqlV4e6mOwceNG+cEPfiCtra36o729Xd8f6vEHM+Ym5qZQfW8yNw0Kx9wUiHkppCc6ubm5Ulpaqr92Op2SkpIi5eXlfuzV2BueTFwulyQnJ8uWLVv0ssuXL4vJZJJ//vOfIiLy+eefCwD5+OOP9TrvvPOOKIoi//vf/8at72Pl/PnzAkCOHDkiIu54IyIiZM+ePXqdL774QgBIbW2tiLgTsqqqYrFY9DovvviixMTEiM1mG98AxsCkSZPk5ZdfDqvYOzs7JTMzU6qrq2X+/Pl6MgmHMdi4caNkZWX53BcO8Qcz5ibmpnB6bzI3hU9uCsS8FLK3rtntdjQ0NCA/P18vU1UV+fn5qK2t9WPPbr7m5mZYLBav2GNjY5GXl6fHXltbi7i4OOTk5Oh18vPzoaoq6urqxr3PN6qjowMAEB8fDwBoaGhAf3+/1xjcddddSEtL8xqDmTNnIikpSa9TWFgIq9WKzz77bBx7f2OcTieqqqrQ3d0Ns9kcVrGXlpZiyZIlXrEC4fPz/+qrr5CSkoLvfe97WLZsGVpaWgCET/zBiLmJuSlc3pvMTeGZmwItLxlvIJaAduHCBTidTq/BAoCkpCR8+eWXfurV+LBYLADgM3bPPovFgsTERK/9RqMR8fHxep1g4XK5sHr1asybNw8zZswA4I5P0zTExcV51R0+Br7GyLMv0J04cQJmsxl9fX2Ijo7G3r17MX36dDQ2NoZ87ABQVVWFY8eO4eOPP75iXzj8/PPy8vDKK6/gzjvvRGtrKzZt2oQf/vCHOHnyZFjEH6yYm5ibQv29ydwUvrkpEPNSyE50KHyUlpbi5MmTeP/99/3dlXF15513orGxER0dHXjttddQUlKCI0eO+Ltb4+Ls2bNYtWoVqqurMWHCBH93xy8WLVqkb8+aNQt5eXlIT0/Hv/71L0RGRvqxZ0QEMDcxN4VfbgrEvBSyt64lJCTAYDBcsZpDW1sbkpOT/dSr8eGJ77tiT05Oxvnz5732OxwOXLp0KajGZ+XKlXjzzTdx6NAh3HbbbXp5cnIy7HY7Ll++7FV/+Bj4GiPPvkCnaRpuv/12ZGdno7y8HFlZWdi2bVtYxN7Q0IDz58/jnnvugdFohNFoxJEjR/C3v/0NRqMRSUlJIT8Gw8XFxeGOO+7A6dOnw+J3IFgxNzE3hfp7k7mJuckjEPJSyE50NE1DdnY2ampq9DKXy4WamhqYzWY/9uzmy8jIQHJyslfsVqsVdXV1euxmsxmXL19GQ0ODXufgwYNwuVzIy8sb9z6PlIhg5cqV2Lt3Lw4ePIiMjAyv/dnZ2YiIiPAag6amJrS0tHiNwYkTJ7ySanV1NWJiYjB9+vTxCWQMuVwu2Gy2sIh9wYIFOHHiBBobG/VHTk4Oli1bpm+H+hgM19XVha+//hpTpkwJi9+BYMXcxNwUbu9N5qbwzU0BkZdGtYRBkKiqqhKTySSvvPKKfP755/Lb3/5W4uLivFZzCFadnZ1y/PhxOX78uACQ5557To4fPy7ffPONiLiX8IyLi5M33nhDPv30U/npT3/qcwnPOXPmSF1dnbz//vuSmZkZNEt4/u53v5PY2Fg5fPiw1zKGPT09ep1HHnlE0tLS5ODBg1JfXy9ms1nMZrO+37OMYUFBgTQ2Nsr+/ftl8uTJQbGE45o1a+TIkSPS3Nwsn376qaxZs0YURZEDBw6ISGjHfjVDV7YRCf0xePTRR+Xw4cPS3NwsH3zwgeTn50tCQoKcP39eREI//mDG3MTcFKrvTeamK4VTbgrEvBTSEx0Rke3bt0taWppomia5ubny4Ycf+rtLY+LQoUMC4IpHSUmJiLiX8Vy/fr0kJSWJyWSSBQsWSFNTk1cbFy9elOLiYomOjpaYmBhZvny5dHZ2+iGakfMVOwDZtWuXXqe3t1d+//vfy6RJkyQqKkoefPBBaW1t9WrnzJkzsmjRIomMjJSEhAR59NFHpb+/f5yjGblf/epXkp6eLpqmyeTJk2XBggV6IhEJ7divZngyCfUxKCoqkilTpoimaTJ16lQpKiqS06dP6/tDPf5gx9zE3BSK703mpiuFU24KxLykiIiM7loQERERERFRYArZz+gQEREREVH44kSHiIiIiIhCDic6REREREQUcjjRISIiIiKikMOJDhERERERhRxOdIiIiIiIKORwokNERERERCGHEx0iIiIiIgo5nOgQEREREVHI4USHiIiIiIhCDic6REREREQUcjjRISIiIiKikPP/uEUcbbsHe04AAAAASUVORK5CYII=\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Evaluate Model With New Data" + ], + "metadata": { + "id": "LW-zloram-qS" + } + }, + { + "cell_type": "code", + "source": [ + "new_data= 'I have been having burning pain anytime i am peeing, what could be the issue?'" + ], + "metadata": { + "id": "udn69qsD-bLp" + }, + "execution_count": 50, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "transformed_new= vectorizer.transform([new_data])\n", + "transformed_new= torch.tensor(transformed_new.toarray()).to(torch.float32)\n", + "transformed_new.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fuOiFXhL-bvV", + "outputId": "80c52b5c-d6ac-4260-a22c-096def5fffbc" + }, + "execution_count": 51, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([1, 1080])" + ] + }, + "metadata": {}, + "execution_count": 51 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.eval()\n", + "with torch.inference_mode():\n", + " y_logits=model(transformed_new)\n", + " test_preds= torch.argmax(torch.softmax(y_logits, dim=1), dim=1)\n", + " test_pred= target_dict[test_preds.item()]\n" + ], + "metadata": { + "id": "ZSf_POgB-b8H" + }, + "execution_count": 52, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "print(f'based on your symptoms, I believe you are having {test_pred}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "oZBcgT0o-lpY", + "outputId": "fa552ce8-c8c2-4e0a-c707-7b4e780aaabb" + }, + "execution_count": 53, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "based on your symptoms, I believe you are having urinary tract infection\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Save Model State Dict" + ], + "metadata": { + "id": "MnedOUcbnFQV" + } + }, + { + "cell_type": "code", + "source": [ + "from pathlib import Path" + ], + "metadata": { + "id": "f60umq-Z-pC1" + }, + "execution_count": 54, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "target_dir_path = Path('Models')\n", + "target_dir_path.mkdir(parents=True,\n", + " exist_ok=True)\n", + "model_path= target_dir_path / 'pretrained_symtom_to_disease_model.pth'\n", + "torch.save(obj=model.state_dict(),f= model_path)" + ], + "metadata": { + "id": "Tn467qOG-pRw" + }, + "execution_count": 55, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "target_dict" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "C_jzILVbvNX2", + "outputId": "7220d1f1-fbd2-47d7-e588-3996d9dae1a7" + }, + "execution_count": 56, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0: 'Acne',\n", + " 1: 'Arthritis',\n", + " 2: 'Bronchial Asthma',\n", + " 3: 'Cervical spondylosis',\n", + " 4: 'Chicken pox',\n", + " 5: 'Common Cold',\n", + " 6: 'Dengue',\n", + " 7: 'Dimorphic Hemorrhoids',\n", + " 8: 'Fungal infection',\n", + " 9: 'Hypertension',\n", + " 10: 'Impetigo',\n", + " 11: 'Jaundice',\n", + " 12: 'Malaria',\n", + " 13: 'Migraine',\n", + " 14: 'Pneumonia',\n", + " 15: 'Psoriasis',\n", + " 16: 'Typhoid',\n", + " 17: 'Varicose Veins',\n", + " 18: 'allergy',\n", + " 19: 'diabetes',\n", + " 20: 'drug reaction',\n", + " 21: 'gastroesophageal reflux disease',\n", + " 22: 'peptic ulcer disease',\n", + " 23: 'urinary tract infection'}" + ] + }, + "metadata": {}, + "execution_count": 56 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Deploy Model" + ], + "metadata": { + "id": "d32UI4vnnLSG" + } + }, + { + "cell_type": "code", + "source": [ + "# Import and class names setup\n", + "import gradio as gr\n", + "import os\n", + "import torch\n", + "import random\n", + "import nltk_utils\n", + "import pandas as pd\n", + "from sklearn.model_selection import train_test_split\n", + "import time\n", + "\n", + "from model import RNN_model\n", + "from timeit import default_timer as timer\n", + "from typing import Tuple, Dict\n", + "\n", + "# Import data\n", + "df= pd.read_csv('Symptom2Disease.csv')\n", + "df.drop('Unnamed: 0', axis= 1, inplace= True)\n", + "\n", + "# Preprocess data\n", + "df.drop_duplicates(inplace= True)\n", + "train_data, test_data= train_test_split(df, test_size=0.15, random_state=42 )\n", + "\n", + "# Setup class names\n", + "class_names= {0: 'Acne',\n", + " 1: 'Arthritis',\n", + " 2: 'Bronchial Asthma',\n", + " 3: 'Cervical spondylosis',\n", + " 4: 'Chicken pox',\n", + " 5: 'Common Cold',\n", + " 6: 'Dengue',\n", + " 7: 'Dimorphic Hemorrhoids',\n", + " 8: 'Fungal infection',\n", + " 9: 'Hypertension',\n", + " 10: 'Impetigo',\n", + " 11: 'Jaundice',\n", + " 12: 'Malaria',\n", + " 13: 'Migraine',\n", + " 14: 'Pneumonia',\n", + " 15: 'Psoriasis',\n", + " 16: 'Typhoid',\n", + " 17: 'Varicose Veins',\n", + " 18: 'allergy',\n", + " 19: 'diabetes',\n", + " 20: 'drug reaction',\n", + " 21: 'gastroesophageal reflux disease',\n", + " 22: 'peptic ulcer disease',\n", + " 23: 'urinary tract infection'\n", + " }\n", + "\n", + "vectorizer= nltk_utils.vectorizer()\n", + "vectorizer.fit(train_data.text)\n", + "\n", + "\n", + "\n", + "# Model and transforms preparation\n", + "model= RNN_model()\n", + "# Load state dict\n", + "model.load_state_dict(torch.load(\n", + " f= '/content/Models/pretrained_symtom_to_disease_model.pth',\n", + " map_location= torch.device('cpu')\n", + " )\n", + ")\n", + "# Disease Advice\n", + "disease_advice = {\n", + " 'Acne': \"Maintain a proper skincare routine, avoid excessive touching of the affected areas, and consider using over-the-counter topical treatments. If severe, consult a dermatologist.\",\n", + " 'Arthritis': \"Stay active with gentle exercises, manage weight, and consider pain-relief strategies like hot/cold therapy. Consult a rheumatologist for tailored guidance.\",\n", + " 'Bronchial Asthma': \"Follow prescribed inhaler and medication regimen, avoid triggers like smoke and allergens, and have an asthma action plan. Regular check-ups with a pulmonologist are important.\",\n", + " 'Cervical spondylosis': \"Maintain good posture, do neck exercises, and use ergonomic support. Physical therapy and pain management techniques might be helpful.\",\n", + " 'Chicken pox': \"Rest, maintain hygiene, and avoid scratching. Consult a doctor for appropriate antiviral treatment.\",\n", + " 'Common Cold': \"Get plenty of rest, stay hydrated, and consider over-the-counter remedies for symptom relief. Seek medical attention if symptoms worsen or last long.\",\n", + " 'Dengue': \"Stay hydrated, rest, and manage fever with acetaminophen. Seek medical care promptly, as dengue can escalate quickly.\",\n", + " 'Dimorphic Hemorrhoids': \"Follow a high-fiber diet, maintain good hygiene, and consider stool softeners. Consult a doctor if symptoms persist.\",\n", + " 'Fungal infection': \"Keep the affected area clean and dry, use antifungal creams, and avoid sharing personal items. Consult a dermatologist if it persists.\",\n", + " 'Hypertension': \"Follow a balanced diet, exercise regularly, reduce salt intake, and take prescribed medications. Regular check-ups with a healthcare provider are important.\",\n", + " 'Impetigo': \"Keep the affected area clean, use prescribed antibiotics, and avoid close contact. Consult a doctor for proper treatment.\",\n", + " 'Jaundice': \"Get plenty of rest, maintain hydration, and follow a doctor's advice for diet and medications. Regular monitoring is important.\",\n", + " 'Malaria': \"Take prescribed antimalarial medications, rest, and manage fever. Seek medical attention for severe cases.\",\n", + " 'Migraine': \"Identify triggers, manage stress, and consider pain-relief medications. Consult a neurologist for personalized management.\",\n", + " 'Pneumonia': \"Follow prescribed antibiotics, rest, stay hydrated, and monitor symptoms. Seek immediate medical attention for severe cases.\",\n", + " 'Psoriasis': \"Moisturize, use prescribed creams, and avoid triggers. Consult a dermatologist for effective management.\",\n", + " 'Typhoid': \"Take prescribed antibiotics, rest, and stay hydrated. Dietary precautions are important. Consult a doctor for proper treatment.\",\n", + " 'Varicose Veins': \"Elevate legs, exercise regularly, and wear compression stockings. Consult a vascular specialist for evaluation and treatment options.\",\n", + " 'allergy': \"Identify triggers, manage exposure, and consider antihistamines. Consult an allergist for comprehensive management.\",\n", + " 'diabetes': \"Follow a balanced diet, exercise, monitor blood sugar levels, and take prescribed medications. Regular visits to an endocrinologist are essential.\",\n", + " 'drug reaction': \"Discontinue the suspected medication, seek medical attention if symptoms are severe, and inform healthcare providers about the reaction.\",\n", + " 'gastroesophageal reflux disease': \"Follow dietary changes, avoid large meals, and consider medications. Consult a doctor for personalized management.\",\n", + " 'peptic ulcer disease': \"Avoid spicy and acidic foods, take prescribed medications, and manage stress. Consult a gastroenterologist for guidance.\",\n", + " 'urinary tract infection': \"Stay hydrated, take prescribed antibiotics, and maintain good hygiene. Consult a doctor for appropriate treatment.\"\n", + "}\n", + "\n", + "howto= \"\"\"Welcome to the Medical Chatbot, powered by Gradio.\n", + "Currently, the chatbot can WELCOME YOU, PREDICT DISEASE based on your symptoms and SUGGEST POSSIBLE SOLUTIONS AND RECOMENDATIONS, and BID YOU FAREWELL.\n", + "

\n", + "Here's a quick guide to get you started:

\n", + "How to Start: Simply type your messages in the textbox to chat with the Chatbot and press enter!

\n", + "The bot will respond based on the best possible answers to your messages. For now, let's keep it SIMPLE as I'm working hard to enhance its capabilities in the future.\n", + "\n", + "\"\"\"\n", + "\n", + "\n", + "# Create the gradio demo\n", + "with gr.Blocks(css = \"\"\"#col_container { margin-left: auto; margin-right: auto;} #chatbot {height: 520px; overflow: auto;}\"\"\") as demo:\n", + " gr.HTML('

Medical Chatbot: Your Virtual Health Guide 🌟🏥🤖\"

')\n", + " gr.HTML('

To know more about this project click, Here')\n", + " with gr.Accordion(\"Follow these Steps to use the Gradio WebUI\", open=True):\n", + " gr.HTML(howto)\n", + " chatbot = gr.Chatbot()\n", + " msg = gr.Textbox()\n", + " clear = gr.ClearButton([msg, chatbot])\n", + "\n", + " def respond(message, chat_history):\n", + " # Random greetings in list format\n", + " greetings = [\n", + " \"hello!\",'hello', 'hii !', 'hi', \"hi there!\", \"hi there!\", \"heyy\", 'good morning', 'good afternoon', 'good evening'\n", + " \"hey\", \"how are you\", \"how are you?\", \"how is it going\", \"how is it going?\",\n", + " \"what's up?\", \"how are you?\",\n", + " \"hey, how are you?\", \"what is popping\"\n", + " \"good to see you!\", \"howdy!\",\n", + " \"hi, nice to meet you.\", \"hiya!\",\n", + " \"hi\", \"hi, what's new?\",\n", + " \"hey, how's your day?\", \"hi, how have you been?\", \"greetings\",\n", + " ]\n", + " # Random Greetings responses\n", + " responses = [\n", + " \"Thank you for using our medical chatbot. Please provide the symptoms you're experiencing, and I'll do my best to predict the possible disease.\",\n", + " \"Hello! I'm here to help you with medical predictions based on your symptoms. Please describe your symptoms in as much detail as possible.\",\n", + " \"Greetings! I am a specialized medical chatbot trained to predict potential diseases based on the symptoms you provide. Kindly list your symptoms explicitly.\",\n", + " \"Welcome to the medical chatbot. To assist you accurately, please share your symptoms in explicit detail.\",\n", + " \"Hi there! I'm a medical chatbot specialized in analyzing symptoms to suggest possible diseases. Please provide your symptoms explicitly.\",\n", + " \"Hey! I'm your medical chatbot. Describe your symptoms with as much detail as you can, and I'll generate potential disease predictions.\",\n", + " \"How can I assist you today? I'm a medical chatbot trained to predict diseases based on symptoms. Please be explicit while describing your symptoms.\",\n", + " \"Hello! I'm a medical chatbot capable of predicting diseases based on the symptoms you provide. Your explicit symptom description will help me assist you better.\",\n", + " \"Greetings! I'm here to help with medical predictions. Describe your symptoms explicitly, and I'll offer insights into potential diseases.\",\n", + " \"Hi, I'm the medical chatbot. I've been trained to predict diseases from symptoms. The more explicit you are about your symptoms, the better I can assist you.\",\n", + " \"Hi, I specialize in medical predictions based on symptoms. Kindly provide detailed symptoms for accurate disease predictions.\",\n", + " \"Hello! I'm a medical chatbot with expertise in predicting diseases from symptoms. Please describe your symptoms explicitly to receive accurate insights.\",\n", + " ]\n", + " # Random goodbyes\n", + " goodbyes = [\n", + " \"farewell!\",'bye', 'goodbye','good-bye', 'good bye', 'bye', 'thank you', 'later', \"take care!\",\n", + " \"see you later!\", 'see you', 'see ya', 'see-you', 'thanks', 'thank', 'bye bye', 'byebye'\n", + " \"catch you on the flip side!\", \"adios!\",\n", + " \"goodbye for now!\", \"till we meet again!\",\n", + " \"so long!\", \"hasta la vista!\",\n", + " \"bye-bye!\", \"keep in touch!\",\n", + " \"toodles!\", \"ciao!\",\n", + " \"later, gator!\", \"stay safe and goodbye!\",\n", + " \"peace out!\", \"until next time!\", \"off I go!\",\n", + " ]\n", + " # Random Goodbyes responses\n", + " goodbye_replies = [\n", + " \"Take care of yourself! If you have more questions, don't hesitate to reach out.\",\n", + " \"Stay well! Remember, I'm here if you need further medical advice.\",\n", + " \"Goodbye for now! Don't hesitate to return if you need more information in the future.\",\n", + " \"Wishing you good health ahead! Feel free to come back if you have more concerns.\",\n", + " \"Farewell! If you have more symptoms or questions, don't hesitate to consult again.\",\n", + " \"Take care and stay informed about your health. Feel free to chat anytime.\",\n", + " \"Bye for now! Remember, your well-being is a priority. Don't hesitate to ask if needed.\",\n", + " \"Have a great day ahead! If you need medical guidance later on, I'll be here.\",\n", + " \"Stay well and take it easy! Reach out if you need more medical insights.\",\n", + " \"Until next time! Prioritize your health and reach out if you need assistance.\",\n", + " \"Goodbye! Your health matters. Feel free to return if you have more health-related queries.\",\n", + " \"Stay healthy and stay curious about your health! If you need more info, just ask.\",\n", + " \"Wishing you wellness on your journey! If you have more questions, I'm here to help.\",\n", + " \"Take care and remember, your health is important. Don't hesitate to reach out if needed.\",\n", + " \"Goodbye for now! Stay informed and feel free to consult if you require medical advice.\",\n", + " \"Stay well and stay proactive about your health! If you have more queries, feel free to ask.\",\n", + " \"Farewell! Remember, I'm here whenever you need reliable medical information.\",\n", + " \"Bye for now! Stay vigilant about your health and don't hesitate to return if necessary.\",\n", + " \"Take care and keep your well-being a priority! Reach out if you have more health questions.\",\n", + " \"Wishing you good health ahead! Don't hesitate to chat if you need medical insights.\",\n", + " \"Goodbye! Stay well and remember, I'm here to assist you with medical queries.\",\n", + " ]\n", + "\n", + " # Create couple of if-else statements to capture/mimick peoples's Interaction\n", + " if message.lower() in greetings:\n", + " bot_message= random.choice(responses)\n", + " elif message.lower() in goodbyes:\n", + " bot_message= random.choice(goodbye_replies)\n", + " else:\n", + " transform_text= vectorizer.transform([message])\n", + " transform_text= torch.tensor(transform_text.toarray()).to(torch.float32)\n", + " model.eval()\n", + " with torch.inference_mode():\n", + " y_logits=model(transform_text)\n", + " pred_prob= torch.argmax(torch.softmax(y_logits, dim=1), dim=1)\n", + "\n", + " test_pred= class_names[pred_prob.item()]\n", + " bot_message = f' Based on your symptoms, I believe you are having {test_pred} and I would advice you {disease_advice[test_pred]}'\n", + " chat_history.append((message, bot_message))\n", + " time.sleep(2)\n", + " return \"\", chat_history\n", + "\n", + " msg.submit(respond, [msg, chatbot], [msg, chatbot])\n", + "# Launch the demo\n", + "demo.launch()\n", + "\n" + ], + "metadata": { + "id": "otWWMGaZLimX", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 712 + }, + "outputId": "f46fbf9a-cc01-467c-f0ed-29d745091c20" + }, + "execution_count": 68, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/feature_extraction/text.py:528: UserWarning: The parameter 'token_pattern' will not be used since 'tokenizer' is not None'\n", + " warnings.warn(\n", + "/usr/local/lib/python3.10/dist-packages/sklearn/feature_extraction/text.py:409: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens [\"'d\", \"'s\", 'abov', 'ani', 'becaus', 'befor', 'could', 'doe', 'dure', 'might', 'must', \"n't\", 'need', 'onc', 'onli', 'ourselv', 'sha', 'themselv', 'veri', 'whi', 'wo', 'would', 'yourselv'] not in stop_words.\n", + " warnings.warn(\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Colab notebook detected. To show errors in colab notebook, set debug=True in launch()\n", + "Note: opening Chrome Inspector may crash demo inside Colab notebooks.\n", + "\n", + "To create a public link, set `share=True` in `launch()`.\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "application/javascript": [ + "(async (port, path, width, height, cache, element) => {\n", + " if (!google.colab.kernel.accessAllowed && !cache) {\n", + " return;\n", + " }\n", + " element.appendChild(document.createTextNode(''));\n", + " const url = await google.colab.kernel.proxyPort(port, {cache});\n", + "\n", + " const external_link = document.createElement('div');\n", + " external_link.innerHTML = `\n", + " \n", + " `;\n", + " element.appendChild(external_link);\n", + "\n", + " const iframe = document.createElement('iframe');\n", + " iframe.src = new URL(path, url).toString();\n", + " iframe.height = height;\n", + " iframe.allow = \"autoplay; camera; microphone; clipboard-read; clipboard-write;\"\n", + " iframe.width = width;\n", + " iframe.style.border = 0;\n", + " element.appendChild(iframe);\n", + " })(7871, \"/\", \"100%\", 500, false, window.element)" + ] + }, + "metadata": {} + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [] + }, + "metadata": {}, + "execution_count": 68 + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "FsgtBKB0v-ub" + }, + "execution_count": 57, + "outputs": [] + } + ] +} \ No newline at end of file