diff --git a/test.ipynb b/test.ipynb
index 138c081..a919fa7 100644
--- a/test.ipynb
+++ b/test.ipynb
@@ -2,84 +2,203 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 46,
"source": [
"# This Notebook is created with VS Code on Windows\r\n",
"# Create python virtual environment\r\n",
- "#!python -m venv .venv\r\n",
+ "!python -m venv .venv\r\n",
"# If you want to use it on macOS/Linux\r\n",
"# You may need to run sudo apt-get install python3-venv first\r\n",
"#python3 -m venv .venv\r\n",
"\r\n",
"# Install Python Packages\r\n",
"!pip install --user --upgrade pip\r\n",
+ "!pip install --upgrade setuptools\r\n",
"!pip install --user seaborn\r\n",
"!pip install --user numpy\r\n",
"!pip install --user pandas\r\n",
"!pip install --user matplotlib\r\n",
"!pip install --user plotly\r\n",
- "!pip install --user nbformat\r\n"
+ "!pip install --user nbformat\r\n",
+ "!pip install --user surprise\r\n"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
- "Requirement already satisfied: pip in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (21.2.4)\n",
+ "Requirement already satisfied: pip in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (21.2.4)\n",
"Requirement already satisfied: seaborn in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (0.11.2)\n",
"Requirement already satisfied: matplotlib>=2.2 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (3.3.4)\n",
- "Requirement already satisfied: numpy>=1.15 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.20.1)\n",
+ "Requirement already satisfied: numpy>=1.15 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.19.5)\n",
"Requirement already satisfied: scipy>=1.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.6.1)\n",
"Requirement already satisfied: pandas>=0.23 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.2.2)\n",
"Requirement already satisfied: cycler>=0.10 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (0.10.0)\n",
- "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (2.8.1)\n",
"Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (1.3.1)\n",
"Requirement already satisfied: pillow>=6.2.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (8.1.0)\n",
- "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from matplotlib>=2.2->seaborn) (2.4.6)\n",
- "Requirement already satisfied: six in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from cycler>=0.10->matplotlib>=2.2->seaborn) (1.15.0)\n",
+ "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (2.4.7)\n",
+ "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from matplotlib>=2.2->seaborn) (2.8.1)\n",
+ "Requirement already satisfied: six in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from cycler>=0.10->matplotlib>=2.2->seaborn) (1.15.0)\n",
"Requirement already satisfied: pytz>=2017.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas>=0.23->seaborn) (2021.1)\n",
- "Requirement already satisfied: numpy in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.20.1)\n",
+ "Requirement already satisfied: numpy in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.19.5)\n",
"Requirement already satisfied: pandas in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.2.2)\n",
- "Requirement already satisfied: numpy>=1.16.5 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (1.20.1)\n",
"Requirement already satisfied: pytz>=2017.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2021.1)\n",
- "Requirement already satisfied: python-dateutil>=2.7.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2.8.1)\n",
- "Requirement already satisfied: six>=1.5 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)\n",
+ "Requirement already satisfied: python-dateutil>=2.7.3 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from pandas) (2.8.1)\n",
+ "Requirement already satisfied: numpy>=1.16.5 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (1.19.5)\n",
+ "Requirement already satisfied: six>=1.5 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)\n",
"Requirement already satisfied: matplotlib in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (3.3.4)\n",
- "Requirement already satisfied: numpy>=1.15 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (1.20.1)\n",
- "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from matplotlib) (2.4.6)\n",
- "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (2.8.1)\n",
- "Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (1.3.1)\n",
- "Requirement already satisfied: pillow>=6.2.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (8.1.0)\n",
"Requirement already satisfied: cycler>=0.10 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (0.10.0)\n",
- "Requirement already satisfied: six in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from cycler>=0.10->matplotlib) (1.15.0)\n",
+ "Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (1.3.1)\n",
+ "Requirement already satisfied: numpy>=1.15 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (1.19.5)\n",
+ "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (2.4.7)\n",
+ "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from matplotlib) (2.8.1)\n",
+ "Requirement already satisfied: pillow>=6.2.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (8.1.0)\n",
+ "Requirement already satisfied: six in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from cycler>=0.10->matplotlib) (1.15.0)\n",
"Requirement already satisfied: plotly in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (5.3.0)\n",
- "Requirement already satisfied: six in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from plotly) (1.15.0)\n",
+ "Requirement already satisfied: six in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from plotly) (1.15.0)\n",
"Requirement already satisfied: tenacity>=6.2.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from plotly) (8.0.1)\n",
- "Collecting nbformat\n",
- " Downloading nbformat-5.1.3-py3-none-any.whl (178 kB)\n",
- "Requirement already satisfied: ipython-genutils in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (0.2.0)\n",
+ "Requirement already satisfied: nbformat in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (5.1.3)\n",
"Requirement already satisfied: traitlets>=4.1 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (5.0.5)\n",
- "Collecting jsonschema!=2.5.0,>=2.4\n",
- " Downloading jsonschema-3.2.0-py2.py3-none-any.whl (56 kB)\n",
+ "Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (3.2.0)\n",
+ "Requirement already satisfied: ipython-genutils in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (0.2.0)\n",
"Requirement already satisfied: jupyter-core in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (4.7.1)\n",
- "Requirement already satisfied: six>=1.11.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (1.15.0)\n",
- "Requirement already satisfied: attrs>=17.4.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (19.3.0)\n",
+ "Requirement already satisfied: six>=1.11.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (1.15.0)\n",
"Requirement already satisfied: setuptools in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (49.2.1)\n",
- "Collecting pyrsistent>=0.14.0\n",
- " Downloading pyrsistent-0.18.0-cp38-cp38-win_amd64.whl (62 kB)\n",
+ "Requirement already satisfied: pyrsistent>=0.14.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (0.18.0)\n",
+ "Requirement already satisfied: attrs>=17.4.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (21.2.0)\n",
"Requirement already satisfied: pywin32>=1.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jupyter-core->nbformat) (300)\n",
- "Installing collected packages: pyrsistent, jsonschema, nbformat\n",
- "Successfully installed jsonschema-3.2.0 nbformat-5.1.3 pyrsistent-0.18.0\n"
+ "Collecting surprise\n",
+ " Downloading surprise-0.1-py2.py3-none-any.whl (1.8 kB)\n",
+ "Collecting scikit-surprise\n",
+ " Downloading scikit-surprise-1.1.1.tar.gz (11.8 MB)\n",
+ "Requirement already satisfied: joblib>=0.11 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from scikit-surprise->surprise) (1.0.1)\n",
+ "Requirement already satisfied: numpy>=1.11.2 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from scikit-surprise->surprise) (1.19.5)\n",
+ "Requirement already satisfied: scipy>=1.0.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from scikit-surprise->surprise) (1.6.1)\n",
+ "Requirement already satisfied: six>=1.10.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from scikit-surprise->surprise) (1.15.0)\n",
+ "Building wheels for collected packages: scikit-surprise\n",
+ " Building wheel for scikit-surprise (setup.py): started\n",
+ " Building wheel for scikit-surprise (setup.py): finished with status 'error'\n",
+ " Running setup.py clean for scikit-surprise\n",
+ "Failed to build scikit-surprise\n",
+ "Installing collected packages: scikit-surprise, surprise\n",
+ " Running setup.py install for scikit-surprise: started\n",
+ " Running setup.py install for scikit-surprise: finished with status 'error'\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
- " WARNING: The script jsonschema.exe is installed in 'C:\\Users\\Oli\\AppData\\Roaming\\Python\\Python38\\Scripts' which is not on PATH.\n",
- " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n",
- " WARNING: The script jupyter-trust.exe is installed in 'C:\\Users\\Oli\\AppData\\Roaming\\Python\\Python38\\Scripts' which is not on PATH.\n",
- " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n"
+ " ERROR: Command errored out with exit status 1:\n",
+ " command: 'c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\Oli\\\\AppData\\\\Local\\\\Temp\\\\pip-install-jibnz200\\\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\Oli\\\\AppData\\\\Local\\\\Temp\\\\pip-install-jibnz200\\\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' bdist_wheel -d 'C:\\Users\\Oli\\AppData\\Local\\Temp\\pip-wheel-dz4_1ymq'\n",
+ " cwd: C:\\Users\\Oli\\AppData\\Local\\Temp\\pip-install-jibnz200\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\n",
+ " Complete output (49 lines):\n",
+ " running bdist_wheel\n",
+ " running build\n",
+ " running build_py\n",
+ " creating build\n",
+ " creating build\\lib.win-amd64-3.8\n",
+ " creating build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\accuracy.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\builtin_datasets.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\dataset.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\dump.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\reader.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\trainset.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\utils.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\__init__.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\__main__.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " creating build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\search.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\split.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\validation.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\__init__.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " creating build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\algo_base.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\baseline_only.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\knns.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\predictions.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\random_pred.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\__init__.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " running egg_info\n",
+ " writing scikit_surprise.egg-info\\PKG-INFO\n",
+ " writing dependency_links to scikit_surprise.egg-info\\dependency_links.txt\n",
+ " writing entry points to scikit_surprise.egg-info\\entry_points.txt\n",
+ " writing requirements to scikit_surprise.egg-info\\requires.txt\n",
+ " writing top-level names to scikit_surprise.egg-info\\top_level.txt\n",
+ " reading manifest file 'scikit_surprise.egg-info\\SOURCES.txt'\n",
+ " reading manifest template 'MANIFEST.in'\n",
+ " writing manifest file 'scikit_surprise.egg-info\\SOURCES.txt'\n",
+ " copying surprise\\similarities.c -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\similarities.pyx -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\prediction_algorithms\\co_clustering.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\matrix_factorization.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\optimize_baselines.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\slope_one.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\co_clustering.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\matrix_factorization.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\optimize_baselines.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\slope_one.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " running build_ext\n",
+ " building 'surprise.similarities' extension\n",
+ " error: Microsoft Visual C++ 14.0 is required. Get it with \"Build Tools for Visual Studio\": https://visualstudio.microsoft.com/downloads/\n",
+ " ----------------------------------------\n",
+ " ERROR: Failed building wheel for scikit-surprise\n",
+ " ERROR: Command errored out with exit status 1:\n",
+ " command: 'c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\Oli\\\\AppData\\\\Local\\\\Temp\\\\pip-install-jibnz200\\\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\Oli\\\\AppData\\\\Local\\\\Temp\\\\pip-install-jibnz200\\\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' install --record 'C:\\Users\\Oli\\AppData\\Local\\Temp\\pip-record-ivcio2vz\\install-record.txt' --single-version-externally-managed --user --prefix= --compile --install-headers 'C:\\Users\\Oli\\AppData\\Roaming\\Python\\Python38\\Include\\scikit-surprise'\n",
+ " cwd: C:\\Users\\Oli\\AppData\\Local\\Temp\\pip-install-jibnz200\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\n",
+ " Complete output (49 lines):\n",
+ " running install\n",
+ " running build\n",
+ " running build_py\n",
+ " creating build\n",
+ " creating build\\lib.win-amd64-3.8\n",
+ " creating build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\accuracy.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\builtin_datasets.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\dataset.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\dump.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\reader.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\trainset.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\utils.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\__init__.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\__main__.py -> build\\lib.win-amd64-3.8\\surprise\n",
+ " creating build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\search.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\split.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\validation.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " copying surprise\\model_selection\\__init__.py -> build\\lib.win-amd64-3.8\\surprise\\model_selection\n",
+ " creating build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\algo_base.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\baseline_only.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\knns.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\predictions.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\random_pred.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\__init__.py -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " running egg_info\n",
+ " writing scikit_surprise.egg-info\\PKG-INFO\n",
+ " writing dependency_links to scikit_surprise.egg-info\\dependency_links.txt\n",
+ " writing entry points to scikit_surprise.egg-info\\entry_points.txt\n",
+ " writing requirements to scikit_surprise.egg-info\\requires.txt\n",
+ " writing top-level names to scikit_surprise.egg-info\\top_level.txt\n",
+ " reading manifest file 'scikit_surprise.egg-info\\SOURCES.txt'\n",
+ " reading manifest template 'MANIFEST.in'\n",
+ " writing manifest file 'scikit_surprise.egg-info\\SOURCES.txt'\n",
+ " copying surprise\\similarities.c -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\similarities.pyx -> build\\lib.win-amd64-3.8\\surprise\n",
+ " copying surprise\\prediction_algorithms\\co_clustering.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\matrix_factorization.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\optimize_baselines.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\slope_one.c -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\co_clustering.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\matrix_factorization.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\optimize_baselines.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " copying surprise\\prediction_algorithms\\slope_one.pyx -> build\\lib.win-amd64-3.8\\surprise\\prediction_algorithms\n",
+ " running build_ext\n",
+ " building 'surprise.similarities' extension\n",
+ " error: Microsoft Visual C++ 14.0 is required. Get it with \"Build Tools for Visual Studio\": https://visualstudio.microsoft.com/downloads/\n",
+ " ----------------------------------------\n",
+ "ERROR: Command errored out with exit status 1: 'c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\Oli\\\\AppData\\\\Local\\\\Temp\\\\pip-install-jibnz200\\\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\Oli\\\\AppData\\\\Local\\\\Temp\\\\pip-install-jibnz200\\\\scikit-surprise_07dc192d3cf347769fae216d5b05a944\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' install --record 'C:\\Users\\Oli\\AppData\\Local\\Temp\\pip-record-ivcio2vz\\install-record.txt' --single-version-externally-managed --user --prefix= --compile --install-headers 'C:\\Users\\Oli\\AppData\\Roaming\\Python\\Python38\\Include\\scikit-surprise' Check the logs for full command output.\n"
]
}
],
@@ -87,10 +206,10 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 3,
"source": [
- "import numpy as np # linear algebra\r\n",
- "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\r\n",
+ "import numpy as np # maths\r\n",
+ "import pandas as pd # data processing\r\n",
"import matplotlib.pyplot as plt\r\n",
"import seaborn as sns\r\n",
"import os\r\n",
@@ -137,12 +256,12 @@
},
{
"cell_type": "code",
- "execution_count": 23,
+ "execution_count": 4,
"source": [
"# Import Tables\r\n",
- "reviews = pd.read_csv('./ml-latest-small/ratings.csv', names=['userId', 'movieId', 'rating', 'timestamp'], delimiter=',', engine='python')\r\n",
- "movies = pd.read_csv('./ml-latest-small/movies.csv', names=['movieId', 'title', 'genres'], delimiter=',', engine='python')\r\n",
- "users = pd.read_csv('./ml-latest-small/users.csv', names=['userId', 'gender', 'age', 'occupation', 'zip'], delimiter='::', engine='python')\r\n",
+ "reviews = pd.read_csv('./ml-1m/ratings.dat', names=['userId', 'movieId', 'rating', 'timestamp'], delimiter='::', engine='python')\r\n",
+ "movies = pd.read_csv('./ml-1m/movies.dat', names=['movieId', 'title', 'genres'], delimiter='::', engine='python')\r\n",
+ "users = pd.read_csv('./ml-1m/users.dat', names=['userId', 'gender', 'age', 'occupation', 'zip'], delimiter='::', engine='python')\r\n",
"\r\n",
"# Print Table shape\r\n",
"print('Reviews shape:', reviews.shape)\r\n",
@@ -154,9 +273,9 @@
"output_type": "stream",
"name": "stdout",
"text": [
- "Reviews shape: (100836, 4)\n",
- "Users shape: (610, 5)\n",
- "Movies shape: (9742, 3)\n"
+ "Reviews shape: (1000209, 4)\n",
+ "Users shape: (6040, 5)\n",
+ "Movies shape: (3883, 3)\n"
]
}
],
@@ -164,7 +283,7 @@
},
{
"cell_type": "code",
- "execution_count": 25,
+ "execution_count": 5,
"source": [
"# Drop unused Attributes\r\n",
"reviews.drop(['timestamp'], axis=1, inplace=True) # Time\r\n",
@@ -178,9 +297,9 @@
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": 6,
"source": [
- "# print movie table\r\n",
+ "# Print movie table\r\n",
"movies.head()"
],
"outputs": [
@@ -188,19 +307,19 @@
"output_type": "execute_result",
"data": {
"text/plain": [
- " movieId title \\\n",
- "0 1 Toy Story (1995) \n",
- "1 2 Jumanji (1995) \n",
- "2 3 Grumpier Old Men (1995) \n",
- "3 4 Waiting to Exhale (1995) \n",
- "4 5 Father of the Bride Part II (1995) \n",
+ " movieId title genres \\\n",
+ "0 1 Toy Story (1995) Animation|Children's|Comedy \n",
+ "1 2 Jumanji (1995) Adventure|Children's|Fantasy \n",
+ "2 3 Grumpier Old Men (1995) Comedy|Romance \n",
+ "3 4 Waiting to Exhale (1995) Comedy|Drama \n",
+ "4 5 Father of the Bride Part II (1995) Comedy \n",
"\n",
- " genres release_year \n",
- "0 Adventure|Animation|Children|Comedy|Fantasy 1995 \n",
- "1 Adventure|Children|Fantasy 1995 \n",
- "2 Comedy|Romance 1995 \n",
- "3 Comedy|Drama|Romance 1995 \n",
- "4 Comedy 1995 "
+ " release_year \n",
+ "0 1995 \n",
+ "1 1995 \n",
+ "2 1995 \n",
+ "3 1995 \n",
+ "4 1995 "
],
"text/html": [
"
\n",
@@ -232,14 +351,14 @@
"
0 | \n",
"
1 | \n",
"
Toy Story (1995) | \n",
- "
Adventure|Animation|Children|Comedy|Fantasy | \n",
+ "
Animation|Children's|Comedy | \n",
"
1995 | \n",
" \n",
"
\n",
" | 1 | \n",
" 2 | \n",
" Jumanji (1995) | \n",
- " Adventure|Children|Fantasy | \n",
+ " Adventure|Children's|Fantasy | \n",
" 1995 | \n",
"
\n",
"
\n",
@@ -253,7 +372,7 @@
" | 3 | \n",
" 4 | \n",
" Waiting to Exhale (1995) | \n",
- " Comedy|Drama|Romance | \n",
+ " Comedy|Drama | \n",
" 1995 | \n",
"
\n",
"
\n",
@@ -269,16 +388,16 @@
]
},
"metadata": {},
- "execution_count": 26
+ "execution_count": 6
}
],
"metadata": {}
},
{
"cell_type": "code",
- "execution_count": 27,
+ "execution_count": 7,
"source": [
- "# changed feature values based on README_users.txt\r\n",
+ "# Changed feature values based on README_users.txt\r\n",
"\r\n",
"ages_map = {1: 'Under 18',\r\n",
" 18: '18 - 24',\r\n",
@@ -321,16 +440,16 @@
},
{
"cell_type": "code",
- "execution_count": 28,
+ "execution_count": 8,
"source": [
+ "# Plot age kategories\r\n",
+ "\r\n",
"age_reindex = ['Under 18', '18 - 24', '25 - 34', '35 - 44', '45 - 49', '50 - 55', '56+']\r\n",
- "\r\n",
"age_counts = users['age'].value_counts().reindex(age_reindex)\r\n",
- "\r\n",
"sns.barplot(x=age_counts.values,\r\n",
" y=age_counts.index,\r\n",
" palette='magma').set_title(\r\n",
- " 'Users age', fontsize=24)\r\n",
+ " 'Users age', fontsize=12)\r\n",
"\r\n",
"plt.show()"
],
@@ -341,13 +460,1214 @@
"text/plain": [
""
],
- "image/svg+xml": "\r\n\r\n\r\n\r\n",
- "image/png": "iVBORw0KGgoAAAANSUhEUgAABL4AAAILCAYAAADmNVXwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABBXElEQVR4nO3df/xX8/0//luKaoVXKi+Vfqhe+dEPUcj2Zn4kM8SG+TXbaNqij5kfo9H8HBqiWYsLi80whPnN2EiI/CzDp3eWQpG8pugn1ev7x76en73W79Wrl07X6+XyvFyccx7nPO7ndXns7DxvnfN41pk1a1ZVAAAAAKBgNqrtAgAAAACgJgi+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwCAJF27dk1ZWVkuvfTStdoWAIDaI/gCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEArEVTpkzJaaedlh49emSrrbZKixYt0qVLlxx44IEZOnRoKisrl7nf1KlTc+aZZ6Znz55p0aJFtt5663z961/P1Vdfnblz5y5zn7KyspSVlWXq1KmZOHFifvzjH6dz585p1qxZjjnmmFK7mTNnZvDgwdl9993TsmXLlJeXp3PnzunTp09++ctf5p133lmtc5w2bVquueaaHHbYYdl5553TokWLtG7dOnvssUcuueSSzJo1a6X7Dxw4MNtvv33Ky8uz4447ZtCgQZk1a1ZuueWWlJWV5cADD1zu/mPHjs0JJ5yQHXbYIVtuuWW22WabHHLIIRk1alSqqqpW61wAgGKrV9sFAAAUxauvvpqDDz44n376aZJk4403zle+8pW89957ee+99/LMM8+kW7du6d27d7X97rvvvvTv3z8LFixIknzlK1/JwoULM378+IwfPz533HFH/vznP2fLLbdcZr9jx47Naaedlnnz5mXTTTdNvXr/7xbvnXfeSZ8+ffLBBx8kSerWrZtNN90006dPz7Rp0zJu3Li0aNEiJ5xwwiqf56BBg3LfffclSTbZZJM0atQos2fPzmuvvZbXXnstd955Zx544IG0atVqqX3//ve/5+CDD87HH3+cJGncuHE+/PDDjBgxIo888kj69eu3wr7PO++8DBs2rLS82WabZdasWRk9enRGjx6dhx9+ONdff3022si/7wIAnvgCAFhrBg8enE8//TQ9e/bM6NGjM3PmzEydOjXTp0/PE088kQEDBmSzzTarts/LL7+cfv36ZdGiRTnjjDPyxhtvZPr06fnggw/yl7/8JTvttFPeeOON/PjHP15uv2eccUZ22mmnPPvss3n33Xfz/vvv55e//GWSZMiQIfnggw/Svn37PPTQQ5k5c2amTJmSDz74IM8++2zOOOOM5QZqy9OpU6cMGTIkL730Uj744IO8/fbbmTFjRh544IHsvPPOefvtt/PTn/50qf0WLlyYH/zgB/n444/ToUOHPPLII3nvvfcybdq03HHHHZk3b14uv/zy5fY7YsSIDBs2LFtuuWWGDRuWqVOn5p133sn06dMzcuTIlJeX56677srVV1+9WucDABRXnVmzZnkeHADY4HXt2jXvvvtuzjrrrAwaNOi/atuiRYvMnz8/jz/+eHr27LlK/X7jG9/Ic889l6uuuirHH3/8Uts//vjj7L777vnggw/yxBNPZKeddiptKysrS5K0a9cuY8eOTcOGDZfaf7fddsvEiRMzcuTIfPvb316lmtbExx9/nF122SWVlZV59dVX07Zt29K2P/7xjxk4cGAaNGiQ5557Lu3atau274svvpj99tsvVVVV+drXvpYHH3ywtG3WrFnp0qVLFi1alMceeyxdu3Zdqu9x48Zl//33z+abb57//d//zSabbFJj5wkArB888QUAsJZsuummSVJ6rXBl3n777Tz33HPZfPPNc9xxxy2zTZMmTUqvRj7xxBPLbHPiiScuM/T6b2paU02aNMmuu+6aqqqqjBs3rtq2+++/P0nSt2/fpUKvJOnZs2f+53/+Z5nHve+++zJnzpx8/etfX2bolSS77rpr2rZtm1mzZuXVV19do/MAAIrBHF8AAGvJfvvtl1tuuSUDBgzIiy++mAMPPDDdu3fPxhtvvMz2zz//fJJk7ty52WGHHZZ73C8mt582bdoyt++6664rrOnFF1/M+eefn8mTJ6dv377ZZZddlhuUraqXXnopI0eOzLhx4zJ9+vRlTsD/n2Hba6+9liTZfffdl3vc3XffPWPGjFlq/Rch2pgxY9KpU6fl7v/F3GHL+1sBABsWwRcAwFpy0UUX5a233srzzz+fq6++OldffXUaNGiQXXbZJYceemiOOeaYaoHTjBkzkiSLFi3Khx9+uNLjz5s3b5nrmzVrttx9Tj311Lz66qt5+OGHc8MNN+SGG25IvXr1svPOO+eggw7K9773vdIrk6vqmmuuyS9+8YvSLyjWrVs3ZWVlpVcLP/nkkyxYsGCpMOyLX7QsLy9f7rFbtGixzPVf/K3mzZu33L/Dv1uVNgBA8Qm+AACSNGjQIElKv6y4IvPnz0+SpZ6a2mKLLfLII4+Ufl1w7Nix+fvf/54xY8ZkzJgxueaaa/Lggw+Wfu1wyZIlSZIuXbrk6aef/q9rX9EvGNavXz+33XZbXnjhhTzwwAN59tln8+qrr2bcuHEZN25cfv3rX+eee+5Z7uuD/+nNN9/Meeedl6qqqpx44onp169fKioqUrdu3VKb/v3754477igFY2vDF3+rH//4x7nsssvW2nEBgGIzxxcAQP4VWiUrnwtr4cKFpdfpvtjn39WpUyd77bVXhgwZkqeeeiqTJ0/O1VdfnSZNmmTKlCn5+c9/XmrbvHnzJOvmtbxddtklF1xwQR577LFMmTIlv/vd77L11lvno48+yimnnLLKx7nvvvuyZMmS7Lvvvrn88suz3XbbVQu9kmTmzJnL3Ldp06ZJ/t/TW8uyvL//F3+r9957b5VrBQAQfAEAJOnWrVuS5IUXXlhhu5deeimLFy+uts+KlJWV5Qc/+EF+8YtfJEmeeeaZ0rYv5ub6+OOP8+KLL/5Xdf83GjVqlMMOOyzDhg1Lkrz66qvLnKNrWaZPn55k+ec+d+7c5Z7LF0+VjR07drnHX962L/5WTz/9dOmJOwCAlRF8AQAkOfjgg5MkkydPzoMPPrjcdsOHD0+StG3btlr4s2TJkixatGi5+33xKuVnn31WWtepU6fssssuSZJf/OIX+fzzz5e7//z587Nw4cJVOJPq/r2/5dVUVVW1wr7/3WabbZYkeeONN5a5/corr8ynn366zG0HHXRQkn/9uuPUqVOX2v7yyy8vc2L7JDn00EPTqFGjzJo1K7/61a9WWOOsWbNWuB0A2HAIvgAAkuy5557Ze++9kyQ/+tGPcuONN2b27Nml7ZMmTUr//v1Lodi5555bbW6tTz75JDvttFOuuOKKvP7666WnwpYsWZLRo0fn4osvTpLss88+1fodMmRI6tevn2effTZ9+/bN2LFjS/NZLV68OK+//nqGDBmS7t27r/Q1zGXZfffdc+GFF+bll18uhWBVVVV56aWX8rOf/SxJsvPOO6/yBPdf/I0effTRDB06tDSJ/EcffZTBgwdn6NChy3wFNEmOOOKItG/fPvPnz8/hhx9e+qXGqqqqPP744zn22GNLwdp/2mKLLUpPzV111VU55ZRT8tZbb5W2z58/P88++2xOO+209OnTZ5XOBQAovjqzZs1ae7OOAgCsxyorK3PMMcfk+eefT/Kv+bo233zzfP7556VXAevUqZNzzjknZ5xxRrV9Z82alXbt2pWWN9544zRu3DiffPJJKQRr165dtcntv/DYY4+lX79++eSTT5L8a0L6Ro0a5dNPP632JNaECRPSpk2b0vIXYdX48ePTtm3bZZ5TmzZtSsetW7duNttss8yZM6d03KZNm+bee+9Nly5dVvnvdNxxx+X++++v9jeaPXt2qqqqctxxx2XRokW57bbbctZZZ2XQoEHV9p0wYUIOPvjgUqjYuHHjLF68OPPnz0/Hjh3zgx/8IOeee2722Wef3H333Uv1ffnll+eSSy4pTZzfqFGjbLzxxvnkk09KgWGbNm0yYcKEVT4fAKC4PPEFAPD/a9q0aR588MFcd9112X///bPllluWAq+Kiop8//vfz+jRo5cKvZJ/vQJ4++23Z8CAAenRo0eaNWuWOXPmpFGjRtl5550zePDgjBkzZqnQK0n222+/vPTSSznjjDOy4447pn79+pk9e3Y23XTT7LbbbvnpT3+aJ598slrotapuvfXWnHbaaenVq1datGiRuXPnZpNNNknnzp3z05/+NM8999xqhV5JcuONN+b888/Ptttum4033jhVVVXp1atXRowYkWuuuWaF+3br1i1PP/10jj322JSXl+fzzz/PlltumZNPPjl//etfS0/Rbb755svc/8wzz8zTTz+dH/zgB+nQoUOWLFmSefPmZauttsq+++6bCy+8MA8//PBqnQ8AUFye+AIA4Eujf//+ueOOO5b5tBgAwOryxBcAAF8KU6ZMKb1C+cVcYgAAa0LwBQDAOvPggw/mwgsvzJtvvlmaZ2zhwoV58MEHc/DBB2f+/PnZZZdd0qtXr1quFAAoAq86AgCwzvzhD3/IKaeckiTZaKONsvnmm+fTTz/NokWLkiStW7fOfffdl2222aY2ywQACkLwBQDAOjN16tTcfPPNeeqpp/Luu++msrIyDRo0yDbbbJMDDjggP/7xj0u/VgkAsKYEXwAAAAAUkjm+AAAAACgkwRcAAAAAhST4ghoyadKk2i6B9YjxwuowXlhVxgqrw3hhdRgvrA7jhdWxtseL4AsAAACAQhJ8AQAAAFBIgi8AAAAACqlebRewPtpp20Nru4QNzisT/1zbJQAAAADrGU98AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIVU68HXkUcemQEDBtR2GQAAAAAUzEqDrwMPPDBnnnnmUutvueWWtGrVqkaKWltuuummHHTQQWnTpk3KysoyderUpdq89dZbOeaYY9K+fftsvfXW6d27dx5//PFaqBYAAACAtanWn/haGz7//PNlrp83b1722WefnH322cvd98gjj8zChQtz77335qmnnkqvXr1yzDHH5O23366pcgEAAABYB9Za8DVgwIAceeSRGTFiRLbffvu0bds2J510UubNm1dqM2/evAwYMCCtWrVKRUVFrrzyyqWO89lnn+W8887LDjvskBYtWmTvvffOX//619L2MWPGpKysLH/5y1+yzz77pHnz5tW2/7uTTjopp512Wnbfffdlbq+srMw//vGP/OQnP0nXrl3Tvn37nH/++Vm0aFEmTJiwhn8RAAAAAGrTWn3ia+zYsXnzzTfz5z//OTfeeGMeeOCBXHvttaXtgwcPzpNPPpk//OEPuffeezNhwoQ8++yz1Y5x8skn55lnnsn111+fsWPH5uijj85RRx2V1157rVq7888/P+eee25eeOGF9OzZ87+qd4sttsi2226b22+/PXPmzMnixYtz0003pXHjxtltt93+q2MCAAAA8OVQb20ebNNNN81VV12VunXrZtttt82hhx6a0aNH57TTTsucOXNy88035ze/+U323XffJMnw4cOzww47lPZ/++23M2rUqEyYMCGtW7dOkvTv3z9PPvlkbrrppmpPiJ111lnZZ5991qjeOnXq5J577sl3v/vdtG7dOhtttFGaNGmSUaNGZauttlqjYwMAAABQu9Zq8LXtttumbt26peWtttoqL774YpJ/hVqfffZZdt1119L2xo0bp3PnzqXl8ePHp6qqKr169ap23IULF2bPPfestm6nnXZa43qrqqpy+umnZ4sttsjDDz+cBg0a5Oabb873vve9/O1vf0vLli3XuA8AAAAAasdKg69NN900s2fPXmr97Nmzs9lmm1Vbt/HGG1dbrlOnTqqqqla5mCVLlqROnTr529/+ttSxGjRoUG25UaNGq3zc5XnqqafyyCOP5O23305ZWVmSpHv37nniiSdyyy23LPPXLAEAAABYP6w0+KqoqMhjjz2Wqqqq1KlTp7R+/Pjx6dix4yp3tM0222TjjTfOCy+8kHbt2iVJ5s6dmzfeeKO03K1bt1RVVWXGjBlLPeFVE76YeH+jjapPdbbRRhtlyZIlNd4/AAAAADVnpcFXv379cv311+dnP/tZvve976VBgwb5y1/+krvuuiu33XbbKnfUuHHjHHfccTn//PPTrFmzbLXVVvnVr35VLWDq2LFjvvOd7+Skk07KL3/5y+y44475+OOP8/TTT6dt27bp27fvap3cjBkzMmPGjLz11ltJkokTJ2b27Nlp3bp1mjRpkl133TVNmjTJySefnJ/97Gdp2LBhfv/732fKlCnZf//9V6svAAAAAL5cVhp8tWvXLg899FAuvvjifPvb387ChQtTUVGRm266Kfvtt99qdXbRRRdl7ty5+e53v5uGDRumf//+paeuvjB8+PBcccUV+cUvfpHp06enSZMm2XnnnbPHHnus3pklGTlyZIYMGVJa/s53vlPq49hjj03Tpk1z11135aKLLkrfvn2zaNGidOrUKbfccku6d+++2v0BAAAA8OVRZ9asWas+CRdJkp22PbS2S9jgvDLxz7VdwmqbNGlSKioqarsM1hPGC6vDeGFVGSusDuOF1WG8sDqMF1bH2h4vG628CQAAAACsfwRfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEj1aruA9dErE/9c2yUAAAAAsBKe+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSPVqu4D10fd2PK+2SwAAAAriD+MvqO0SAArLE18AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACikGg2+nnnmmRx11FHZfvvtU1ZWlltuuWWpNnPmzMmZZ56ZHXbYIVtttVV69uyZ4cOHr3HfU6dOzcCBA7Pjjjtmq622yo477pgLLrgg8+fPX2b7ysrKUp2VlZVr3D8AAAAAtateTR587ty52WGHHXL00Ufnxz/+8TLbnHPOOXnyySdz7bXXpm3btnn22Wfzk5/8JE2bNs1RRx31X/c9adKkLF68OEOHDk2HDh0yceLEnHrqqfnnP/+ZYcOGLdX+pJNOSteuXfP+++//130CAAAA8OVRo0989enTJ7/4xS9yyCGHZKONlt3VuHHjcuSRR2bPPfdM27Ztc/TRR6dnz5556aWX1qjv3r17Z8SIEdl3333Trl277L///jn99NNz3333LdV2xIgRmT9/fk4++eQ16hMAAACAL49an+OrV69eeeSRR/Lee+8lSZ5//vn8/e9/z7777rvW+/r0009TVlZWbd348eMzbNiwXHvttcsN5wAAAABY/9R60jNkyJB06dIlXbp0SbNmzXLggQfm/PPPzze+8Y212s8777yTa665Jv369Sutmzt3bvr165chQ4akZcuWa7U/AAAAAGpXrQdf1113XcaNG5fbbrstTz75ZC655JIMHjw4jz/++DLbv/vuu2nVqlXpc+WVV660jw8//DCHH3549t5772qvM5511lnp1atXDjnkkLV2PgAAAAB8OdTo5PYrM3/+/Fx44YW56aabcsABByRJunTpktdeey3XXHNNevfuvdQ+LVq0yJgxY0rLTZo0WWEfM2bMSN++fbP99tvnuuuuS506dUrbRo8enWnTpuW2225LklRVVSVJOnXqlFNPPTWDBw9e43MEAAAAoHbUavD1+eef5/PPP0/dunWrra9bt26WLFmyzH3q1auX9u3br9LxP/jggxx88MHZbrvt8rvf/S716lU/3XvuuSefffZZafnll1/OwIED88ADD6RDhw6reTYAAAAAfJnUaPA1Z86cTJ48OUmyZMmSvPfee5kwYUKaNGmS1q1bZ7PNNsvXvva1XHDBBWnUqFFat26dZ555Jn/6059ywQUXrFHf77//fg466KBstdVWufTSS1NZWVna1qxZs9StWzcdO3asts8XbTp16pSmTZuuUf8AAAAA1K4aDb5eeeWVHHzwwaXlSy+9NJdeemmOPvrojBgxIkkycuTIXHDBBenfv38+/vjjtG7dOuecc0769++/Rn3/7W9/yz/+8Y/84x//SJcuXaptGz9+fNq2bbtGxwcAAADgy63OrFmzqmq7iPXN93Y8r7ZLAAAACuIP49fsbZfaMGnSpFRUVNR2GawnjBdWx9oeL7X+q44AAAAAUBMEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQqpX2wWsj/4w/oLaLoH1wKRJk1JRUVHbZbCeMF5YHcYLq8pYYXUYLwAUkSe+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQqpX2wWsjy7d+5LaLgEAAABghQY98fPaLqHWeeILAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKKQaDb6GDh2avffeO61bt06HDh1y5JFH5o033qjWZsCAASkrK6v26d279xr3vWTJkhx11FHp0qVLysvLs+2226Z///6ZPn36MttXVlZm++23T1lZWSorK9e4fwAAAABqV40GX08//XT69euXRx99NPfdd1/q1auXQw89NB9//HG1dnvttVcmTpxY+tx5551rpf8999wzN954Y1544YX84Q9/yJQpU/Ld7353mW1POumkdO3ada30CwAAAEDtq1eTB7/77rurLV933XVp06ZNnnvuuRxwwAGl9fXr1095efla7XujjTbKSSedVFpu06ZNTj311BxzzDFZsGBBGjRoUNo2YsSIzJ8/P6effnr+8pe/rNU6AAAAAKgd63SOrzlz5mTJkiUpKyurtn7s2LHp2LFjevTokVNOOSUzZ85c631//PHHufPOO9OzZ89qodf48eMzbNiwXHvttdloI1OeAQAAABTFOk16zj777HTt2jW77rpraV3v3r1z7bXX5t57783FF1+cl156KX379s3ChQvXSp/nnXdeWrZsmW222Sbvvfdebr/99tK2uXPnpl+/fhkyZEhatmy5VvoDAAAA4MthnQVfP//5z/Pcc8/l5ptvTt26dUvrDzvssHzzm99M586dc8ABB2TUqFGZNGlSHn300WUe5913302rVq1KnyuvvHKF/Z5yyil56qmncs8996Ru3brp379/qqqqkiRnnXVWevXqlUMOOWTtnSgAAAAAXwo1OsfXFwYNGpS77747999/f9q1a7fCti1atEjLli0zefLk5W4fM2ZMablJkyYrPF7Tpk3TtGnTdOzYMZ06dUrnzp0zduzYfPWrX83o0aMzbdq03HbbbUlSCsQ6deqUU089NYMHD16NswQAAADgy6TGg6+zzjor99xzT+6///506tRppe0rKyvz/vvvL3ey+3r16qV9+/b/VS1LlixJknz22WdJknvuuaf030ny8ssvZ+DAgXnggQfSoUOH/6oPAAAAAL4cajT4OuOMM3L77bfnj3/8Y8rKyjJjxowkSaNGjdK4cePMmTMnl112Wfr27Zvy8vK88847ufDCC9O8efMcdNBBa9T3uHHjMn78+PTq1Subb7553n777VxyySVp06ZNevXqlSTp2LFjtX0qKyuT/OuJr6ZNm65R/wAAAADUrhoNvm644YYkWWoOrbPOOiuDBg1K3bp188Ybb+RPf/pTZs+enfLy8uyxxx658cYbs+mmm65R3w0aNMi9996bSy65JPPmzUt5eXl69+6dkSNHVvtVRwAAAACKqc6sWbOqaruI9c2le19S2yUAAAAArNCgJ35e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VORXv/pVvvWtb+WFF17Ipptuusb9//rXv87+++9fWt5ss82WanPXXXelS5cupeUmTZqscb8AAAAA1K4aD77q1auX8vLyZW6rqqrKiBEjcuqpp+aQQw5JkowYMSIVFRUZNWpUjj/++DXuf/PNN19u/1/YYostVtoGAAAAgPVLjc/xNWXKlGy33Xbp1q1bTjjhhEyZMqW0berUqZkxY0b22Wef0rqGDRvmq1/9ap5//vm10v/ZZ5+d9u3bZ++9987IkSOzZMmSpdocd9xx6dixY/bff//ce++9a6VfAAAAAGpXjT7x1bNnz/z2t79NRUVFPvroo1x++eXp06dPnnvuuWyxxRaZMWNGkqR58+bV9mvevHnef//9Ne7/5z//efbYY480atQoo0ePzrnnnpvKysqceeaZSZLGjRvnoosuSq9evVKvXr089NBDOf744zNixIgceeSRa9w/AAAAALWnRoOv/fbbr9pyz549071799x6660ZOHDgf3XMZ599NkcccURp+aqrrsp3vvOdZbb92c9+Vvrvbt26ZcmSJbnyyitLwVfTpk3zf/7P/ym12WmnnfLPf/4zw4YNE3wBAAAArOdqfI6vf9e4ceNst912mTx5cpKU5tWaOXNmWrduXWo3c+bMbLnllss8xk477ZQxY8aUlv/zabEV6dGjRz755JN8+OGHyz1+jx49csstt6zyMQEAAAD4cqrxOb7+3YIFCzJp0qRS4NW2bduUl5fniSeeqNZm7Nix2W233ZZ5jIYNG6Z9+/alz+r88uNrr72WBg0aZPPNN19hGxPdAwAAAKz/avSJr3PPPTff+MY3svXWW5fm+Jo3b16OPvroJEmdOnUyYMCADB06NBUVFenYsWOuuOKKNGrUKIcffvga9f3www/nww8/zC677JKGDRtmzJgxufTSS/P9738/9evXT5Lceuut2XjjjdOtW7dstNFGeeSRR3LDDTfk/PPPX9NTBwAAAKCW1WjwNX369Pzwhz9MZWVlmjVrlp49e+axxx5LmzZtSm1+8pOfZP78+TnzzDMza9as9OjRI3ffffdqPcm1LBtvvHFuuOGGnHPOOVmyZEnatWuXQYMG5cQTT6zW7oorrsi7776bunXrpkOHDvnNb35jfi8AAACAAqjR4GvkyJErbVOnTp0MGjQogwYNWqt99+7dO717915hm2OOOSbHHHPMWu0XAAAAgC+HdTrHFwAAAACsK4IvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKKR6tV3A+qjB986p7RJYD0yaNCkVFRW1XQYAAABssDzxBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQ6tV2Aeujqr/fVtslsB7omKTq7y/WdhlfCnW6HF3bJQAAALAB8sQXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKab0Kvi699NKUlZVV+3Tq1Klam7feeivf/e5306ZNm7Ro0SJ77rlnJk6cWEsVAwAAAFBb6tV2AauroqIiDzzwQGm5bt26pf+eMmVK9t9//xx11FG57777UlZWlv/93/9No0aNlnu8rl275re//W322GOPGq0bAAAAgHVrvQu+6tWrl/Ly8mVuu/jii7PPPvvkl7/8ZWldu3bt1lFlAAAAAHyZrFevOib/eqpru+22S7du3XLCCSdkypQpSZIlS5bkkUceybbbbpvDDjssHTp0yN5775277767dgsGAAAAoFasV8FXz54989vf/jajRo3Kr3/968yYMSN9+vTJP//5z8ycOTNz5szJ0KFDs/fee+eee+7JYYcdlhNPPDGPPvpobZcOAAAAwDq2Xr3quN9++1Vb7tmzZ7p3755bb701hx12WJLkm9/8ZgYOHJgk6datW1599dVcf/312X///ZMkhx9+eMaOHVs6xrx583LEEUdUmyts2rRpNX0qAAAAANSw9Sr4+k+NGzfOdtttl8mTJ6dp06apV69ett1222ptOnXqVO11x1//+tdZsGBBafmggw7K+eefn549e66zugEAAACoeet18LVgwYJMmjQpe+yxRzbZZJPsvPPOmTRpUrU2b731Vlq3bl1abtmyZbXtdevWTYsWLdK+fft1UjMAAAAA68Z6FXyde+65+cY3vpGtt946H330US6//PLMmzcvRx99dJLklFNOyfHHH5+vfvWr2XPPPTNmzJjcfffdueWWW2q5cgAAAADWtfUq+Jo+fXp++MMfprKyMs2aNUvPnj3z2GOPpU2bNkn+9dri1VdfnaFDh+bss89O+/btc+2115bm9wIAAABgw7FeBV8jR45caZtjjz02xx577Cof87XXXluTkgAAAAD4ktqotgsAAAAAgJog+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCqlfbBayP6nQ5urZLYD0wadKkVFRU1HYZAAAAsMHyxBcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCqjNr1qyq2i4CAAAAANY2T3wBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+FpFN9xwQ7p165by8vJ8/etfz7PPPlvbJVHLhg4dmr333jutW7dOhw4dcuSRR+aNN96o1mbAgAEpKyur9undu3ctVUxtuvTSS5caC506dSptr6qqyqWXXprtttsuW221VQ488MC8+eabtVgxtalr165LjZeysrJ85zvfSbLy8USxPfPMMznqqKOy/fbbp6ysLLfccku17atyPZk1a1b69++fNm3apE2bNunfv39mzZq1Ds+CdWVF4+Xzzz/Peeedl69+9atp2bJltt122/zwhz/Mu+++W+0YBx544FLXnBNOOGFdnwo1bGXXllW5r124cGHOPPPMtG/fPi1btsxRRx2VadOmrcvTYB1Z2XhZ1n1MWVlZzjjjjFIb35U2HKvy3bkm718EX6vg7rvvztlnn53TTz89Tz31VHbdddccccQRS90UsGF5+umn069fvzz66KO57777Uq9evRx66KH5+OOPq7Xba6+9MnHixNLnzjvvrKWKqW0VFRXVxsK/B+jDhg3L8OHDM2TIkPztb39L8+bN861vfSuffvppLVZMbXniiSeqjZXRo0enTp06OfTQQ0ttVjSeKLa5c+dmhx12yGWXXZaGDRsutX1Vric//OEPM2HChIwaNSqjRo3KhAkT8qMf/WhdngbryIrGy7x58zJ+/PicccYZGT16dG699dZMmzYthx9+eBYtWlSt7bHHHlvtmnPVVVety9NgHVjZtSVZ+X3toEGDcv/99+d3v/tdHnrooXz66ac58sgjs3jx4nVxCqxDKxsv/z5OJk6cmD/96U9JUu1eJvFdaUOxKt+da/L+pV6NnFXBDB8+PMccc0y+//3vJ0kuv/zy/PWvf83IkSNz3nnn1XJ11Ja777672vJ1112XNm3a5LnnnssBBxxQWl+/fv2Ul5ev6/L4EqpXr94yx0JVVVVGjBiRU089NYccckiSZMSIEamoqMioUaNy/PHHr+tSqWXNmjWrtnzzzTdn0003zbe+9a3SuuWNJ4qvT58+6dOnT5LkpJNOqrZtVa4nEydOzOOPP55HHnkku+66a5LkqquuygEHHJBJkyaloqJi3Z4QNWpF42XzzTfPn//852rrrrrqqvTq1SsTJ05M586dS+u/8pWvuOYU3IrGyhdWdF87e/bs3HzzzRk+fHj23nvvJP+6P+7atWuefPLJ7LvvvjVTOLViZePlP8fJQw89lI4dO+Z//ud/qq33XWnDsLLvzjV9/+KJr5X47LPP8uqrr2afffaptn6fffbJ888/X0tV8WU0Z86cLFmyJGVlZdXWjx07Nh07dkyPHj1yyimnZObMmbVTILVuypQp2W677dKtW7eccMIJmTJlSpJk6tSpmTFjRrXrTMOGDfPVr37VdYZUVVXl5ptvzpFHHlntX1SXN57YsK3K9WTcuHFp3Lhxdtttt1KbXr16pVGjRq45lP5l/T/vZ+666660b98+vXr1yrnnnuuJ5A3Uiu5rX3311Xz++efVrj9bb711tt12W9eWDdycOXNy9913lx4k+Xe+K22Y/vO7c03fv3jiayUqKyuzePHiNG/evNr65s2b58MPP6ylqvgyOvvss9O1a9dS+pwkvXv3zsEHH5y2bdvmnXfeycUXX5y+ffvmySefTP369WuxWta1nj175re//W0qKiry0Ucf5fLLL0+fPn3y3HPPZcaMGUmyzOvM+++/Xxvl8iXyxBNPZOrUqfne975XWrei8bTFFlvUYrXUtlW5nnz44Ydp2rRp6tSpU9pep06dNGvWzL3NBu6zzz7Lueeem2984xtp1apVaf0RRxyR1q1bZ6uttsr//b//NxdccEFef/313HPPPbVYLevayu5rP/zww9StWzdNmzattp/vTYwaNSqfffZZjj766GrrfVfacP3nd+eavn8RfMFa8POf/zzPPfdcHnnkkdStW7e0/rDDDiv9d+fOndO9e/d07do1jz76aPr27VsbpVJL9ttvv2rLPXv2TPfu3XPrrbdml112qaWqWB/8/ve/z84775yuXbuW1q1oPA0cOHBdlwgUwKJFi9K/f//Mnj07t912W7VtP/jBD0r/3blz57Rr1y777rtvXn311XTv3n3dFkqtcV/Lf+v3v/99vvnNby41lYMxtWFa3nfnmuRVx5Vo2rRp6tatu9QjlzNnzsyWW25ZS1XxZTJo0KDcddddue+++9KuXbsVtm3RokVatmyZyZMnr5vi+NJq3Lhxtttuu0yePLk0r4HrDP9p5syZeeihh5b5asC/+/fxxIZtVa4nW265ZSorK1NVVVXaXlVVlY8++sg1ZwO1aNGi9OvXL6+//nruvffelT45utNOO6Vu3bquORu4/7yv3XLLLbN48eJUVlZWa+d+ZsM2YcKEvPLKKyu9l0l8V9oQLO+7c03fvwi+VmKTTTZJ9+7d88QTT1Rb/8QTT1R7t5QN01lnnVX6H26nTp1W2r6ysjLvv/++CRzJggULMmnSpJSXl6dt27YpLy+vdp1ZsGBBxo4d6zqzgbv11ltTv379av8iuiz/Pp7YsK3K9WTXXXfNnDlzMm7cuFKbcePGZe7cua45G6DPP/88xx9/fF5//fXcf//9q3Qdef3117N48WLXnA3cf97Xdu/ePRtvvHG168+0adMyceJE15YN2O9///u0bds2e+2110rb+q5UbCv67lzT9y9edVwFJ598cn70ox+lR48e2W233TJy5Mh88MEHfmltA3fGGWfk9ttvzx//+MeUlZWV3ktu1KhRGjdunDlz5uSyyy5L3759U15ennfeeScXXnhhmjdvnoMOOqiWq2dd+2LOlK233ro0J9O8efNy9NFHp06dOhkwYECGDh2aioqKdOzYMVdccUUaNWqUww8/vLZLp5ZUVVXlD3/4Q7797W+ncePG1bataDxRfHPmzCn9a/iSJUvy3nvvZcKECWnSpElat2690uvJtttum969e+enP/1prr766iTJT3/60+y///5+0bGAVjReWrRoke9///t55ZVXctttt6VOnTql+5nNNtssDRs2zNtvv5077rgjffr0yRZbbJGJEyfm3HPPTbdu3dKrV6/aPDXWshWNlSZNmqz0vnbzzTfPcccdl/POOy/NmzdPkyZNcs4556Rz586rFHqwflnZ/xclybx583LnnXfmlFNOqTYv0xf7+6604VjZd+dV+T60JvcvdWbNmlW1whYkSW644YYMGzYsM2bMyPbbb59LLrkkX/va12q7LGrRf/7a0RfOOuusDBo0KPPnz8+xxx6bCRMmZPbs2SkvL88ee+yRc845J1tvvfW6LZZad8IJJ+TZZ59NZWVlmjVrlp49e+acc87Jdtttl+RfIcdll12Wm266KbNmzUqPHj1yxRVXZIcddqjlyqktTz31VPr27Zu//vWv6dGjR7VtKxtPFNuYMWNy8MEHL7X+6KOPzogRI1bpejJr1qz87Gc/y8MPP5wkOeCAA/KrX/1quf/fxvprRePl7LPPzo477rjM/YYPH55jjz027733Xvr3758333wzc+fOTatWrdKnT5+cffbZadKkSU2Xzzq0orEydOjQVbqvXbhwYc4999yMGjUqCxYsyJ577pkrr7zSvW8Brez/i5Lkj3/8Y37yk5/k73//e1q0aFGtne9KG5aVfXdOVu370H97/yL4AgAAAKCQzPEFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAh/X+3x6KcPP7dOAAAAABJRU5ErkJggg=="
+ "image/svg+xml": "\r\n\r\n\r\n\r\n",
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAABLkAAAICCAYAAAAj5h9BAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA7p0lEQVR4nO3de5hVdd03/vcwo0KgDiKOnAkYQAFFQSV79PGAGKmQecBD2mMmd6gPeecBPOWxkDykpmKPilqpUai3h0wrj6SYlsfUmxvFAyKijkIBIsrM749+7asJBJQZNktfr+va1zVrfb97fT9rvmvP3vs9a69dMX/+/IYAAAAAQIG1KHcBAAAAALCmhFwAAAAAFJ6QCwAAAIDCE3IBAAAAUHhCLgAAAAAKT8gFAAAAQOEJuQAAAAAoPCEXAECZVFdXZ9asWY3WTZgwIaNHjy5TRQAAxSXkAgD4jPvoo4/KXQIAQLMTcgEArKPq6uoyatSodO3aNd27d8/w4cNTX1+fJJk7d24OO+yw9OzZM1tttVWuvPLK0v0mTJiQww8/PKNHj06XLl1y44035i9/+Ut22WWXdOnSJbW1tTnllFNWOOb8+fMzatSo9OzZM926dcuoUaMyZ86cUvsrr7yS4cOHp3Pnzhk5cmROOOGERmeePf744xk2bFi6du2aL3/5y5k2bVoz/XYAABoTcgEArKMuu+yydOzYMS+99FJmzpyZ008/PRUVFamvr89BBx2U/v3754UXXsjtt9+eSZMm5d577y3d96677sqIESPy6quv5oADDsj48ePzne98J7Nnz86TTz6Zfffdd4Vj1tfX55BDDsmzzz6bv/71r2nZsmVOPPHEUvtRRx2VQYMGZdasWRk/fnymTJlSanvjjTdy4IEH5oQTTsgrr7ySc889N4cffnjeeeed5vslAQD8/4RcAADrqKqqqrz55puZPXt21ltvvey4446pqKjIE088kbq6uowbNy7rr79+unfvnm9+85u5+eabS/fdbrvtsvfee6dFixZp1apVqqqqMmvWrNTV1aVNmzbZbrvtVjjmJptskpEjR+YLX/hCNtxwwxx//PF5+OGHkySzZ8/OE088kVNOOSXrr79+vvSlL2X48OGl+/7qV7/KHnvskWHDhqVFixbZdddds8022+R3v/td8/6iAAAi5AIAKJvKysp8+OGHjdZ99NFHqaqqSpKMHTs2PXr0yL777putt946P/7xj5P8I2yaO3duunbtWrpddNFFefvtt0vb6dy5c6PtXnbZZXnppZey3XbbZdddd83dd9+9wpoWL16c4447Lv3790+XLl2y1157ZcGCBVm2bFnefPPNtG3bNl/4whdK/Tt16lT6efbs2bntttsa1fXoo49m3rx5a/aLAgBYDVXlLgAA4POqc+fOee2119KnT5/SuldffTU9e/ZMkmy44Yb5wQ9+kB/84Ad5/vnnM2LEiGy77bbp1KlTunXrlieeeOJjt11RUdFouWfPnrnmmmtSX1+fO+64I9/85jcza9astG7dulG/yy67LDNnzsy9996bmpqaPPPMM9l5553T0NCQmpqavPfee1m8eHEp6PrX63V16tQpo0aNyqWXXrrGvxsAgE/KmVwAAGXy9a9/PRdccEHmzJmT+vr6PPDAA7n77rszcuTIJMndd9+dWbNmpaGhIRtttFEqKytTUVGRQYMGpU2bNrn44ovz/vvvZ9myZXn++edXGnpNmTIl77zzTlq0aJGNN944SdKixfIvBRcuXJhWrVpl4403znvvvZeJEyeW2rp27Zptttkm5513XpYuXZrHHnus0RlhBx54YO6+++7ce++9WbZsWZYsWZJp06Y1CsIAAJqLkAsAoExOOumkbL/99vnKV76S7t275/vf/37+3//7f9lyyy2TJC+99FJGjhyZTp06ZdiwYTnyyCOz8847p7KyMlOmTMmzzz6brbfeOj169MjYsWPzt7/97WPHuvfeezNkyJB06tQp48ePzzXXXJNWrVot12/MmDF5//3307NnzwwdOjRDhw5t1H7VVVfl8ccfT48ePXLuuedm3333zfrrr5/kH2em3XjjjbnwwgvTs2fP9OvXLz/5yU9K3wgJANCcKubPn99Q7iIAACimI444IrW1tTnllFPKXQoA8DnnTC4AAFbbE088kZdffjn19fX5wx/+kLvuuit77bVXucsCAHDheQAAVt+8efNy2GGH5d13303Hjh1z4YUXZuutty53WQAAPq4IAAAAQPH5uCIAAAAAhSfkAgAAAKDwhFwAAAAAFJ6QCwAAAIDCE3LBapo5c2a5S6CMzP/nm/nHMfD5Zv4/38z/55v5/3wz/8Uj5AIAAACg8IRcAAAAABSekAsAAACAwqsqdwFFtE2fr5W7BNbAkzP+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oPCEXAAAAAAUnpALAAAAgMITcgEAAABQeEIuAAAAAApPyAUAAABA4Qm5AAAAACg8IRcAAAAAhSfkAgAAAKDwhFwAAAAAFJ6QCwAAAIDCE3IBAAAAUHhCLgAAAAAKT8gFAAAAQOEJuQAAAAAoPCEXAAAAAIUn5AIAAACg8IRcAAAAABSekAsAAACAwmvWkOvhhx/OQQcdlC222CLV1dW54YYbluuzcOHCnHjiidlyyy2z+eabZ/Dgwbn88svXeOxXX301xx57bLbeeutsvvnm2XrrrXPWWWfl/fffX2H/urq6Up11dXVrPD4AAAAAa09Vc2580aJF2XLLLXPwwQfnO9/5zgr7nHrqqXnggQdy5ZVXplu3bnnkkUfy3e9+N+3atctBBx30qceeOXNmli1blosuuig9e/bMjBkzctxxx+Xdd9/NJZdcslz/o48+OgMGDMjcuXM/9ZgAAAAAlEeznsk1bNiwfP/738/IkSPTosWKh3rssccyatSo7LzzzunWrVsOPvjgDB48OH/5y1/WaOyhQ4dm0qRJ2X333dO9e/fsueeeOf7443P77bcv13fSpEl5//33c8wxx6zRmAAAAACUR9mvyTVkyJDcfffdef3115Mkf/rTn/LXv/41u+++e5OP9fe//z3V1dWN1j399NO55JJLcuWVV35sEAcAAADAuq3sqc7EiRPTv3//9O/fP5tuumn22muvnHnmmfnKV77SpOO89tpr+clPfpIjjzyytG7RokU58sgjM3HixHTs2LFJxwMAAABg7Sl7yPXTn/40jz32WG666aY88MAD+eEPf5jTTz89f/jDH1bYf/bs2enUqVPpduGFF65yjLfeeiv7779/dt1110YfSRw3blyGDBmSkSNHNtn+AAAAALD2NeuF51fl/fffz9lnn53rrrsuw4cPT5L0798/zz77bH7yk59k6NChy92nQ4cOmTZtWmm5bdu2Kx1j3rx5GTFiRLbYYov89Kc/TUVFRantwQcfzJw5c3LTTTclSRoaGpIkvXv3znHHHZfTTz99jfcRAAAAgOZX1pDrww8/zIcffpjKyspG6ysrK1NfX7/C+1RVVaVHjx6rtf0333wz++yzT/r27ZtrrrkmVVWNd/fWW2/N0qVLS8tPPPFEjj322Nx5553p2bPnJ9wbAAAAAMqlWUOuhQsXZtasWUmS+vr6vP7663nm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FwAAAACFJ+QCAAAAoPCEXAAAAAAUnpALAAAAgMITcgEAAABQeEIuAAAAAApPyAUAAABA4Qm5AAAAACg8IRcAAAAAhSfkAgAAAKDwhFwAAAAAFN5aC7kuuuiiVFdX58QTT2y0fsyYMamurm50Gzp0aJOOvWTJknz5y19OdXV1nnzyyUZtDz74YIYNG5bOnTund+/eOeOMM/LRRx816fgAAAAANK+1EnI9/vjjue6669KvX78Vtu+yyy6ZMWNG6fbrX/+6Scc//fTT06lTp+XWP/vssznggAOyyy675KGHHsrkyZPz29/+NmeeeWaTjg8AAABA82r2kGvBggU56qijctlll6W6unqFfTbYYIPU1NSUbm3btm2y8X/zm99k2rRpOeecc5Zru/XWW9OnT5+ccsop6dGjR/7X//pfOeuss3L11Vfn73//e5PVAAAAAEDzavaQ67jjjsvIkSOz8847f2yf6dOnp1evXhk0aFDGjh2bt99+u0nGnjNnTo4//vhcddVVadmy5XLtH3zwwXLrW7VqlSVLluSpp55qkhoAAAAAaH7NGnJdf/31mTVrVk477bSP7TN06NBceeWVue2223LuuefmL3/5S0aMGJEPPvhgjcZetmxZjjrqqBxzzDEZMGDACvvsvvvu+fOf/5wpU6bko48+yhtvvJGJEycmSebNm7dG4wMAAACw9jRbyDVz5sycffbZufrqq7Peeut9bL/99tsvX/3qV9OvX78MHz48U6dOzcyZM3PPPfessP/s2bPTqVOn0u3CCy9cYb8LL7ww66+/fo499tiPHXu33XbLOeeckxNPPDE1NTUZPHhwhg0bliRp0cIXTwIAAAAURVVzbfixxx5LXV1dhgwZUlq3bNmyPPLII5k8eXLeeOONbLDBBsvdr0OHDunYsWNmzZq1wu126NAh06ZNKy1/3PW7HnzwwUyfPj2bbrppo/VDhw7N17/+9Vx11VVJkmOPPTbHHHNM3nzzzVRXV+e1117LWWedle7du3/SXQYAAACgTJot5Nprr72yzTbbNFp3zDHHpGfPnvne976X9ddff4X3q6ury9y5c1NTU7PC9qqqqvTo0WOV419++eVZvHhxafnNN98shVs77LBDo74VFRXp0KFDkmTq1Knp3Llztt5661WOAQAAAMC6odlCrurq6uW+TfELX/hC2rZtmy233DJJsnDh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hFwAAAAAFJ6QCwAAAIDCE3IBAAAAUHhCLgAAAAAKT8gFAAAAQOFVlbuAImp5+KnlLoEymDlzZmpra8tdBgAAALACzuQCAAAAoPCEXAAAAAAUnpALAAAAgMITcgEAAABQeEIuAAAAAApPyAUAAABA4Qm5AAAAACg8IRcAAAAAhSfkAgAAAKDwhFwAAAAAFJ6QCwAAAIDCE3IBAAAAUHhV5S6giBr+elO5S6AMeiVp+Oufy13GOqGi/8HlLgEAAAAacSYXAAAAAIUn5AIAAACg8IRcAAAAABSekAsAAACAwhNyAQAAAFB4Qi4AAAAACk/IBQAAAEDhCbkAAAAAKDwhFwAAAACFJ+QCAAAAoPCEXAAAAAAUnpALAAAAgMITcgEAAABQeEIuAAAAAApPyAUAAABA4Qm5AAAAACg8IRcAAAAAhSfkAgAAAKDwhFwAAAAAFJ6QCwAAAIDCE3IBAAAAUHhCLgAAAAAKr1Ah14QJE1JdXd3o1rt370Z9XnzxxXzjG99I165d06FDh+y8886ZMWNGmSoGAAAAYG2oKncBn1RtbW3uvPPO0nJlZWXp51deeSV77rlnDjrooNx+++2prq7O//zP/6R169Yfu70BAwbkiiuuyE477dSsdQMAAADQfAoXclVVVaWmpmaFbeeee2522223/OAHPyit6969+1qqDAAAAIByKdTHFZN/nK3Vt2/fbLXVVvnWt76VV155JUlSX1+fu+++O3369Ml+++2Xnj17Ztddd80tt9xS3oIBAAAAaHaFCrkGDx6cK664IlOnTs2ll16aefPmZdiwYXn33Xfz9ttvZ+HChbnooouy66675tZbb81+++2Xo446Kvfcc0+5SwcAAACgGRXq44p77LFHo+XBgwdn4MCBufHGG7PffvslSb761a/m2GOPTZJstdVWeeqpp3LVVVdlzz33TJLsv//+mT59emkbixcvzgEHHNDo2l5z5sxp7l0BAAAAoAkVKuT6d23atEnfvn0za9astGvXLlVVVenTp0+jPr179270kcVLL700S5YsKS3vvffeOfPMMzN48OC1VjcAAAAATavQIdeSJUsyc+bM7LTTTll//fWz7bbbZubMmY36vPjii+nSpUtpuWPHjo3aKysr06FDh/To0WOt1AwAAABA0ytUyHXaaaflK1/5Sjp37px33nkn559/fhYvXpyDDz44STJ27NgcccQR2XHHHbPzzjtn2rRpueWWW3LDDTeUuXIAAAAAmlOhQq433ngj3/72t1NXV5dNN900gwcPzu9///t07do1yT8+enjxxRfnoosuyvjx49OjR49ceeWVpetxAQAAAPDZVKiQa/Lkyavsc+ihh+bQQw9d7W0+++yza1ISAAAAAOuAFuUuAAAAAADWlJALAAAAgMITcgEAAABQeEIuAAAAAApPyAUAAABA4Qm5AAAAACg8IRcAAAAAhSfkAgAAAKDwhFwAAAAAFJ6QCwAAAIDCE3IBAAAAUHhCLgAAAAAKT8gFAAAAQOEJuQAAAAAoPCEXAAAAAIUn5AIAAACg8IRcAAAAABSekAsAAACAwhNyAQAAAFB4Qi4AAAAACq+q3AUUUUX/g8tdAmUwc+bM1NbWlrsMAAAAYAWcyQUAAABA4Qm5AAAAACg8IRcAAAAAhSfkAgAAAKDwKubPn99Q7iIAAAAAYE04kwsAAACAwhNyAQAAAFB4Qi4AAAAACk/IBQAAAEDhCbkAAAAAKDwh12q6+uqrs9VWW6Wmpib/+3//7zzyyCPlLok1dNFFF2XXXXdNly5d0rNnz4waNSrPP/98oz5jxoxJdXV1o9vQoUMb9fnggw9y4oknpkePHunYsWMOOuigzJkzZ23uCp/ChAkTlpvb3r17l9obGhoyYcKE9O3bN5tvvnn22muvvPDCC422MX/+/IwePTpdu3ZN165dM3r06MyfP38t7wmfxoABA5ab/+rq6hx44IFJVn18JKt3jLDuePjhh3PQQQdliy22SHV1dW644YZG7U31mH/uuefy1a9+NZtvvnm22GKLTJw4MQ0Nvsi6nFY29x9++GHOOOOM7LjjjunYsWP69OmTb3/725k9e3ajbey1117L/U341re+1aiP54R116oe/031em/27NkZNWpUOnbsmB49euSkk07K0qVLm33/WLlVzf+KXg9UV1fnhBNOKPXxnqCYVuf9nuf/zx4h12q45ZZbMn78+Bx//PF56KGHsv322+eAAw5Y7gUQxfLHP/4xRx55ZO65557cfvvtqaqqyte+9rW89957jfrtsssumTFjRun261//ulH7ySefnDvuuCPXXHNN7rrrrvz973/PqFGjsmzZsrW5O3wKtbW1jeb2X8PrSy65JJdffnkmTpyY++67L+3bt8++++6bv//976U+3/72t/PMM89k6tSpmTp1ap555pn8x3/8Rzl2hU/o/vvvbzT3Dz74YCoqKvK1r32t1Gdlx0eyescI645FixZlyy23zHnnnZdWrVot194Uj/m//e1v2XfffbPZZpvlvvvuy3nnnZef/OQnueyyy9bKPrJiK5v7xYsX5+mnn84JJ5yQBx98MDfeeGPmzJmT/fffPx999FGjvoceemijvwk//vGPG7V7Tlh3rerxn6z5671ly5Zl1KhRWbhwYe66665cc801uf3223Pqqac2+/6xcqua/3+d9xkzZuSXv/xlkjR6TZB4T1BEq/N+z/P/Z0/F/PnzxYursPvuu6dfv3659NJLS+u23XbbjBw5MmeccUYZK6MpLVy4MF27ds0NN9yQ4cOHJ/nHf23efffdTJkyZYX3WbBgQXr16pXLL7+8dAbI66+/ngEDBmTq1KnZfffd11r9fDITJkzI7bffnunTpy/X1tDQkL59++aoo44q/Rfv/fffT21tbc4555wcccQRmTFjRnbYYYfcfffdGTJkSJJk+vTpGT58eB5//PHU1tau1f1hzVxwwQW59NJLM2PGjLRq1Wqlx0eyescI665OnTrlRz/6UQ499NAkTfeYv+aaa3LmmWfmf/7nf0pvpM4///xMnjw5zz//fCoqKsqzw5T8+9yvyH//939nyJAhefjhh9OvX78k/ziTa8stt8z555+/wvt4TiiOFR0DTfF67/e//30OPPDAPPvss+ncuXOSZMqUKRk7dmxmzpyZjTbaqPl3jlVanb8BY8eOzSOPPJI///nPpXXeE3w2/Pv7Pc//n03O5FqFpUuX5qmnnspuu+3WaP1uu+2WP/3pT2WqiuawcOHC1NfXp7q6utH66dOnp1evXhk0aFDGjh2bt99+u9T21FNP5cMPP2x0fHTu3Dl9+vRxfBTAK6+8kr59+2arrbbKt771rbzyyitJkldffTXz5s1rNK+tWrXKjjvuWJrXxx57LG3atMkOO+xQ6jNkyJC0bt3a3BdMQ0NDfv7zn2fUqFGN/sP7ccdHsnrHCMXRVI/5xx57LF/60pcaHUe777575s6dm1dffXUt7Q1r6p//vf/31wM333xzevTokSFDhuS0005r9F9+zwnFt6av9x577LH06dOnFHAl/3j8f/DBB3nqqafW2n6wZhYuXJhbbrkl3/zmN5dr856g+P79/Z7n/8+mqnIXsK6rq6vLsmXL0r59+0br27dvn7feeqtMVdEcxo8fnwEDBmT77bcvrRs6dGj22WefdOvWLa+99lrOPffcjBgxIg888EA22GCDvPXWW6msrEy7du0abcvxse4bPHhwrrjiitTW1uadd97J+eefn2HDhuXRRx/NvHnzkmSFj/u5c+cmSd566620a9eu0X9mKioqsummm5r7grn//vvz6quv5vDDDy+tW9nxsckmm6zWMUJxNNVj/q233krHjh2X28Y/27p3795cu0ATWbp0aU477bR85StfSadOnUrrDzjggHTp0iWbb755/vu//ztnnXVWnnvuudx6661JPCcUXVO83nvrrbeW+xvSrl27VFZWOgYKZOrUqVm6dGkOPvjgRuu9J/hs+Pf3e57/P5uEXJDklFNOyaOPPpq77747lZWVpfX77bdf6ed+/fpl4MCBGTBgQO65556MGDGiHKXSRPbYY49Gy4MHD87AgQNz4403ZrvttitTVZTD9ddfn2233TYDBgworVvZ8XHssceu7RKBteCjjz7K6NGjs2DBgtx0002N2v7P//k/pZ/79euX7t27Z/fdd89TTz2VgQMHrt1CaXJe7/FP119/fb761a9m0003bbTeMVJ8H/d+j88eH1dchX/+B+ZfT0dNkrfffjubbbZZmaqiKZ188sm5+eabc/vtt68yZe/QoUM6duyYWbNmJUk222yzLFu2LHV1dY36OT6Kp02bNunbt29mzZqVmpqaJFnp436zzTZLXV1do29NaWhoyDvvvGPuC+Ttt9/OXXfdtcKPJfyrfz0+kqzWMUJxNNVjfrPNNlvhNv7Zxrrro48+ypFHHpnnnnsut912WzbZZJOV9t9mm21SWVnZ6PWA54TPjk/zem9Fj/9/fiLEMVAMzzzzTJ588slVviZIvCcomo97v+f5/7NJyLUK66+/fgYOHJj777+/0fr777+/0edyKaZx48aV/uD17t17lf3r6uoyd+7c0h/EgQMHZr311mt0fMyZM6d0gUKKY8mSJZk5c2ZqamrSrVu31NTUNJrXJUuWZPr06aV53X777bNw4cI89thjpT6PPfZYFi1aZO4L5MYbb8wGG2zQ6D+0K/Kvx0eS1TpGKI6mesxvv/32mT59epYsWVLqc//996dDhw7p1q3bWtobPqkPP/wwRxxxRJ577rnccccdpcf5yjz33HNZtmxZqa/nhM+WT/N6b/vtt8+MGTMyZ86cUp/7778/G2ywgbP9CuL6669Pt27dsssuu6yyr/cExbGy93ue/z+bfFxxNRxzzDH5j//4jwwaNCg77LBDJk+enDfffNO3ZxXcCSeckClTpuQXv/hFqqurS5/Jbt26ddq0aZOFCxfmvPPOy4gRI1JTU5PXXnstZ599dtq3b5+99947SbLxxhvnsMMOyxlnnJH27dunbdu2OfXUU9OvX7/VeoKkfP55zZXOnTuXrrm0ePHiHHzwwamoqMiYMWNy0UUXpba2Nr169coFF1yQ1q1bZ//990+S9OnTJ0OHDs1//ud/5uKLL06S/Od//mf23HNP36JVEA0NDfnZz36Wr3/962nTpk2jtpUdH0lW6xhh3bJw4cLSf9zr6+vz+uuv55lnnknbtm3TpUuXJnnM77///pk4cWKOPvronHDCCXnxxRdz8cUX56STTvLNSmW0srnv0KFDvvnNb+bJJ5/MTTfdlIqKitLrgY022iitWrXKyy+/nF/96lcZNmxYNtlkk8yYMSOnnXZattpqq9I3bXlOWLet7Bho27Ztk7ze22233bLFFlvkO9/5Ts4999y89957+f73v5/DDz/cNyuW2ar+/ifJ4sWL8+tf/zpjx45d7u+19wTFtar3e031mt/z/7qlYv78+Q2r7sbVV1+dSy65JPPmzcsWW2yRH/7wh/nyl79c7rJYA//+rUn/NG7cuJx88sl5//33c+ihh+aZZ57JggULUlNTk5122imnnnpqo2/O+eCDD3Laaadl6tSpWbJkSXbeeedceOGFjfqw7vnWt76VRx55JHV1ddl0000zePDgnHrqqenbt2+SfwQg5513Xq677rrMnz8/gwYNygUXXJAtt9yytI358+fnpJNOym9/+9skyfDhw/OjH/3oY48t1i0PPfRQRowYkXvvvTeDBg1q1Laq4yNZvWOEdce0adOyzz77LLf+4IMPzqRJk5rsMf/cc8/lhBNOyBNPPJHq6uocccQRGTdunBe5ZbSyuR8/fny23nrrFd7v8ssvz6GHHprXX389o0ePzgsvvJBFixalU6dOGTZsWMaPH5+2bduW+ntOWHet7Bi46KKLmuz13uzZs3PCCSfkoYceSsuWLXPAAQfknHPOyQYbbLBW9pMVW9Xf/yT5xS9+ke9+97v561//mg4dOjTq5z1Bca3q/V7SdK/5Pf+vO4RcAAAAABSea3IBAAAAUHhCLgAAAAAKT8gFAAAAQOEJuQAAAAAoPCEXAAAAAIUn5AIAAACg8IRcAAAAABSekAsAAACAwhNyAQAAAFB4/x9nBGN4jbN+fgAAAABJRU5ErkJggg=="
},
"metadata": {}
}
],
"metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "source": [
+ "# Plot gender of users\r\n",
+ "gender_counts = users['gender'].value_counts()\r\n",
+ "colors1 = ['lightblue', 'pink']\r\n",
+ "pie = go.Pie(labels=gender_counts.index,\r\n",
+ " values=gender_counts.values,\r\n",
+ " marker=dict(colors=colors1),\r\n",
+ " hole=0.5)\r\n",
+ "layout = go.Layout(title='Gender Users', font=dict(size=12), legend=dict(orientation='h'))\r\n",
+ "\r\n",
+ "fig = go.Figure(data=[pie], layout=layout)\r\n",
+ "py.iplot(fig)"
+ ],
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/html": [
+ ""
+ ],
+ "application/vnd.plotly.v1+json": {
+ "config": {
+ "linkText": "Export to plot.ly",
+ "plotlyServerURL": "https://plot.ly",
+ "showLink": false
+ },
+ "data": [
+ {
+ "hole": 0.5,
+ "labels": [
+ "Male",
+ "Female"
+ ],
+ "marker": {
+ "colors": [
+ "lightblue",
+ "pink"
+ ]
+ },
+ "type": "pie",
+ "values": [
+ 4331,
+ 1709
+ ]
+ }
+ ],
+ "layout": {
+ "font": {
+ "size": 12
+ },
+ "legend": {
+ "orientation": "h"
+ },
+ "template": {
+ "data": {
+ "bar": [
+ {
+ "error_x": {
+ "color": "#2a3f5f"
+ },
+ "error_y": {
+ "color": "#2a3f5f"
+ },
+ "marker": {
+ "line": {
+ "color": "#E5ECF6",
+ "width": 0.5
+ },
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "bar"
+ }
+ ],
+ "barpolar": [
+ {
+ "marker": {
+ "line": {
+ "color": "#E5ECF6",
+ "width": 0.5
+ },
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "barpolar"
+ }
+ ],
+ "carpet": [
+ {
+ "aaxis": {
+ "endlinecolor": "#2a3f5f",
+ "gridcolor": "white",
+ "linecolor": "white",
+ "minorgridcolor": "white",
+ "startlinecolor": "#2a3f5f"
+ },
+ "baxis": {
+ "endlinecolor": "#2a3f5f",
+ "gridcolor": "white",
+ "linecolor": "white",
+ "minorgridcolor": "white",
+ "startlinecolor": "#2a3f5f"
+ },
+ "type": "carpet"
+ }
+ ],
+ "choropleth": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "choropleth"
+ }
+ ],
+ "contour": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "contour"
+ }
+ ],
+ "contourcarpet": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "contourcarpet"
+ }
+ ],
+ "heatmap": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "heatmap"
+ }
+ ],
+ "heatmapgl": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "heatmapgl"
+ }
+ ],
+ "histogram": [
+ {
+ "marker": {
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "histogram"
+ }
+ ],
+ "histogram2d": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "histogram2d"
+ }
+ ],
+ "histogram2dcontour": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "histogram2dcontour"
+ }
+ ],
+ "mesh3d": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "mesh3d"
+ }
+ ],
+ "parcoords": [
+ {
+ "line": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "parcoords"
+ }
+ ],
+ "pie": [
+ {
+ "automargin": true,
+ "type": "pie"
+ }
+ ],
+ "scatter": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatter"
+ }
+ ],
+ "scatter3d": [
+ {
+ "line": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatter3d"
+ }
+ ],
+ "scattercarpet": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattercarpet"
+ }
+ ],
+ "scattergeo": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattergeo"
+ }
+ ],
+ "scattergl": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattergl"
+ }
+ ],
+ "scattermapbox": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattermapbox"
+ }
+ ],
+ "scatterpolar": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterpolar"
+ }
+ ],
+ "scatterpolargl": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterpolargl"
+ }
+ ],
+ "scatterternary": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterternary"
+ }
+ ],
+ "surface": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "surface"
+ }
+ ],
+ "table": [
+ {
+ "cells": {
+ "fill": {
+ "color": "#EBF0F8"
+ },
+ "line": {
+ "color": "white"
+ }
+ },
+ "header": {
+ "fill": {
+ "color": "#C8D4E3"
+ },
+ "line": {
+ "color": "white"
+ }
+ },
+ "type": "table"
+ }
+ ]
+ },
+ "layout": {
+ "annotationdefaults": {
+ "arrowcolor": "#2a3f5f",
+ "arrowhead": 0,
+ "arrowwidth": 1
+ },
+ "autotypenumbers": "strict",
+ "coloraxis": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "colorscale": {
+ "diverging": [
+ [
+ 0,
+ "#8e0152"
+ ],
+ [
+ 0.1,
+ "#c51b7d"
+ ],
+ [
+ 0.2,
+ "#de77ae"
+ ],
+ [
+ 0.3,
+ "#f1b6da"
+ ],
+ [
+ 0.4,
+ "#fde0ef"
+ ],
+ [
+ 0.5,
+ "#f7f7f7"
+ ],
+ [
+ 0.6,
+ "#e6f5d0"
+ ],
+ [
+ 0.7,
+ "#b8e186"
+ ],
+ [
+ 0.8,
+ "#7fbc41"
+ ],
+ [
+ 0.9,
+ "#4d9221"
+ ],
+ [
+ 1,
+ "#276419"
+ ]
+ ],
+ "sequential": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "sequentialminus": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ]
+ },
+ "colorway": [
+ "#636efa",
+ "#EF553B",
+ "#00cc96",
+ "#ab63fa",
+ "#FFA15A",
+ "#19d3f3",
+ "#FF6692",
+ "#B6E880",
+ "#FF97FF",
+ "#FECB52"
+ ],
+ "font": {
+ "color": "#2a3f5f"
+ },
+ "geo": {
+ "bgcolor": "white",
+ "lakecolor": "white",
+ "landcolor": "#E5ECF6",
+ "showlakes": true,
+ "showland": true,
+ "subunitcolor": "white"
+ },
+ "hoverlabel": {
+ "align": "left"
+ },
+ "hovermode": "closest",
+ "mapbox": {
+ "style": "light"
+ },
+ "paper_bgcolor": "white",
+ "plot_bgcolor": "#E5ECF6",
+ "polar": {
+ "angularaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "bgcolor": "#E5ECF6",
+ "radialaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ }
+ },
+ "scene": {
+ "xaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ },
+ "yaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ },
+ "zaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ }
+ },
+ "shapedefaults": {
+ "line": {
+ "color": "#2a3f5f"
+ }
+ },
+ "ternary": {
+ "aaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "baxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "bgcolor": "#E5ECF6",
+ "caxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ }
+ },
+ "title": {
+ "x": 0.05
+ },
+ "xaxis": {
+ "automargin": true,
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": "",
+ "title": {
+ "standoff": 15
+ },
+ "zerolinecolor": "white",
+ "zerolinewidth": 2
+ },
+ "yaxis": {
+ "automargin": true,
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": "",
+ "title": {
+ "standoff": 15
+ },
+ "zerolinecolor": "white",
+ "zerolinewidth": 2
+ }
+ }
+ },
+ "title": {
+ "text": "Gender Users"
+ }
+ }
+ }
+ },
+ "metadata": {}
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "source": [
+ "# Merge reviews, movie and user dataset\r\n",
+ "final_df = reviews.merge(movies, on='movieId', how='left').merge(users, on='userId', how='left')\r\n",
+ "print('final_df shape:', final_df.shape)\r\n",
+ "final_df.head()"
+ ],
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "final_df shape: (1000209, 9)\n"
+ ]
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ " userId movieId rating title \\\n",
+ "0 1 1193 5 One Flew Over the Cuckoo's Nest (1975) \n",
+ "1 1 661 3 James and the Giant Peach (1996) \n",
+ "2 1 914 3 My Fair Lady (1964) \n",
+ "3 1 3408 4 Erin Brockovich (2000) \n",
+ "4 1 2355 5 Bug's Life, A (1998) \n",
+ "\n",
+ " genres release_year gender age occupation \n",
+ "0 Drama 1975 Female Under 18 K-12 student \n",
+ "1 Animation|Children's|Musical 1996 Female Under 18 K-12 student \n",
+ "2 Musical|Romance 1964 Female Under 18 K-12 student \n",
+ "3 Drama 2000 Female Under 18 K-12 student \n",
+ "4 Animation|Children's|Comedy 1998 Female Under 18 K-12 student "
+ ],
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " userId | \n",
+ " movieId | \n",
+ " rating | \n",
+ " title | \n",
+ " genres | \n",
+ " release_year | \n",
+ " gender | \n",
+ " age | \n",
+ " occupation | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 1193 | \n",
+ " 5 | \n",
+ " One Flew Over the Cuckoo's Nest (1975) | \n",
+ " Drama | \n",
+ " 1975 | \n",
+ " Female | \n",
+ " Under 18 | \n",
+ " K-12 student | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1 | \n",
+ " 661 | \n",
+ " 3 | \n",
+ " James and the Giant Peach (1996) | \n",
+ " Animation|Children's|Musical | \n",
+ " 1996 | \n",
+ " Female | \n",
+ " Under 18 | \n",
+ " K-12 student | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1 | \n",
+ " 914 | \n",
+ " 3 | \n",
+ " My Fair Lady (1964) | \n",
+ " Musical|Romance | \n",
+ " 1964 | \n",
+ " Female | \n",
+ " Under 18 | \n",
+ " K-12 student | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1 | \n",
+ " 3408 | \n",
+ " 4 | \n",
+ " Erin Brockovich (2000) | \n",
+ " Drama | \n",
+ " 2000 | \n",
+ " Female | \n",
+ " Under 18 | \n",
+ " K-12 student | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 1 | \n",
+ " 2355 | \n",
+ " 5 | \n",
+ " Bug's Life, A (1998) | \n",
+ " Animation|Children's|Comedy | \n",
+ " 1998 | \n",
+ " Female | \n",
+ " Under 18 | \n",
+ " K-12 student | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 10
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "source": [
+ "final_df[final_df['age'] == '18 - 24']['title'].value_counts()[:10].to_frame()"
+ ],
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ " title\n",
+ "American Beauty (1999) 715\n",
+ "Star Wars: Episode VI - Return of the Jedi (1983) 586\n",
+ "Star Wars: Episode V - The Empire Strikes Back ... 579\n",
+ "Matrix, The (1999) 567\n",
+ "Star Wars: Episode IV - A New Hope (1977) 562\n",
+ "Braveheart (1995) 544\n",
+ "Saving Private Ryan (1998) 543\n",
+ "Jurassic Park (1993) 541\n",
+ "Terminator 2: Judgment Day (1991) 529\n",
+ "Sixth Sense, The (1999) 514"
+ ],
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " title | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | American Beauty (1999) | \n",
+ " 715 | \n",
+ "
\n",
+ " \n",
+ " | Star Wars: Episode VI - Return of the Jedi (1983) | \n",
+ " 586 | \n",
+ "
\n",
+ " \n",
+ " | Star Wars: Episode V - The Empire Strikes Back (1980) | \n",
+ " 579 | \n",
+ "
\n",
+ " \n",
+ " | Matrix, The (1999) | \n",
+ " 567 | \n",
+ "
\n",
+ " \n",
+ " | Star Wars: Episode IV - A New Hope (1977) | \n",
+ " 562 | \n",
+ "
\n",
+ " \n",
+ " | Braveheart (1995) | \n",
+ " 544 | \n",
+ "
\n",
+ " \n",
+ " | Saving Private Ryan (1998) | \n",
+ " 543 | \n",
+ "
\n",
+ " \n",
+ " | Jurassic Park (1993) | \n",
+ " 541 | \n",
+ "
\n",
+ " \n",
+ " | Terminator 2: Judgment Day (1991) | \n",
+ " 529 | \n",
+ "
\n",
+ " \n",
+ " | Sixth Sense, The (1999) | \n",
+ " 514 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 39
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "source": [
+ "# Print movie / user sum\r\n",
+ "n_movies = final_df['movieId'].nunique()\r\n",
+ "n_users = final_df['userId'].nunique()\r\n",
+ "\r\n",
+ "print('Number of movies:', n_movies)\r\n",
+ "print('Number of users:', n_users) "
+ ],
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Number of movies: 3706\n",
+ "Number of users: 6040\n"
+ ]
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "source": [
+ "# implement SVD with Python SurPRISE, a Python Recommendation Framework\r\n",
+ "\r\n",
+ "from surprise import Reader, Dataset, SVD, SVDpp\r\n",
+ "from surprise import accuracy\r\n",
+ "\r\n",
+ "reader = Reader(rating_scale=(1, 5))\r\n",
+ "dataset = Dataset.load_from_df(final_df[['userId', 'movieId', 'rating']], reader=reader)\r\n",
+ "\r\n",
+ "svd = SVD(n_factors=50)\r\n",
+ "svd_plusplus = SVDpp(n_factors=50)\r\n",
+ "\r\n",
+ "# train with SVD\r\n",
+ "trainset = dataset.build_full_trainset()\r\n",
+ "svd.fit(trainset)\r\n",
+ "# train with SVD++, ATTENTION this take a LONG TIME\r\n",
+ "# svd_plusplus.fit(trainset)\r\n"
+ ],
+ "outputs": [
+ {
+ "output_type": "error",
+ "ename": "ModuleNotFoundError",
+ "evalue": "No module named 'surprise'",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# implement SVD with Python SurPRISE, a Python Recommendation Framework\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0msurprise\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mReader\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mDataset\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mSVD\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mSVDpp\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msurprise\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0maccuracy\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'surprise'"
+ ]
+ }
+ ],
+ "metadata": {}
}
],
"metadata": {