diff --git a/DL/recommender_system/.gitignore b/DL/recommender_system/.gitignore new file mode 100644 index 0000000..5084e53 --- /dev/null +++ b/DL/recommender_system/.gitignore @@ -0,0 +1,3 @@ +*.csv +.ipynb_checkpoints +*.pth diff --git a/DL/recommender_system/nn.ipynb b/DL/recommender_system/nn.ipynb new file mode 100644 index 0000000..0c8f839 --- /dev/null +++ b/DL/recommender_system/nn.ipynb @@ -0,0 +1,1954 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "29b5381a-72b4-4f81-9208-2075f7acad85", + "metadata": {}, + "source": [ + "# Recommender System using Neural Network" + ] + }, + { + "cell_type": "markdown", + "id": "cac03d32", + "metadata": {}, + "source": [ + "Configure the project. Indeed you create a dataset in csv format." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6f480cda-8380-4355-998a-5c59d6203b05", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Archive: ./dataset/archive.zip\n", + " inflating: anime.csv \n", + " inflating: animelist.csv \n", + " inflating: anime_with_synopsis.csv \n", + " inflating: rating_complete.csv \n" + ] + } + ], + "source": [ + "! rm -rf *.csv\n", + "! unzip ./dataset/archive.zip\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "db1f7e48", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total 2.7G\n", + "-rw-r--r-- 1 andre andre 5.5M Jul 13 2021 anime.csv\n", + "-rw-r--r-- 1 andre andre 6.9M Jul 13 2021 anime_with_synopsis.csv\n", + "-rw-r--r-- 1 andre andre 1.9G Jul 13 2021 animelist.csv\n", + "-rw-r--r-- 1 andre andre 781M Jul 13 2021 rating_complete.csv\n", + "drwxr-xr-x 6 andre andre 4.0K Sep 14 12:48 ..\n", + "drwxr-xr-x 2 andre andre 4.0K Sep 25 18:58 dataset\n", + "-rw-r--r-- 1 andre andre 198K Sep 26 15:26 best_anime_model.pth\n", + "-rw-r--r-- 1 andre andre 11K Sep 27 00:50 nn.py\n", + "-rw-r--r-- 1 andre andre 195K Sep 27 01:09 best_model.pth\n", + "drwxr-xr-x 3 andre andre 4.0K Sep 27 01:11 .\n", + "-rw-r--r-- 1 andre andre 193K Sep 27 01:11 nn.ipynb\n" + ] + } + ], + "source": [ + "! ls -ltrha" + ] + }, + { + "cell_type": "markdown", + "id": "52ec2f48", + "metadata": {}, + "source": [ + "Import needed libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "dd17f780", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.model_selection import train_test_split\n", + "from torch.utils.data import TensorDataset, DataLoader\n", + "import matplotlib.pyplot as plt\n", + "from tqdm import tqdm\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "aec5c99e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using device: cpu\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/andre/miniconda3/envs/venv/lib/python3.12/site-packages/torch/cuda/__init__.py:128: UserWarning: CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up environment, e.g. changing env variable CUDA_VISIBLE_DEVICES after program start. Setting the available devices to be zero. (Triggered internally at ../c10/cuda/CUDAFunctions.cpp:108.)\n", + " return torch._C._cuda_getDeviceCount() > 0\n" + ] + } + ], + "source": [ + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "print(f'Using device: {device}')" + ] + }, + { + "cell_type": "markdown", + "id": "57b33a77", + "metadata": {}, + "source": [ + "Read data from csv files using pandas and store in data frame structure. Also shuffle data to have uniform distribution. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a102a751", + "metadata": {}, + "outputs": [], + "source": [ + "anime_df = pd.read_csv(\"anime.csv\")\n", + "anime_df = anime_df.sample(frac=1.0, random_state=42).reset_index(drop=True)\n", + "\n", + "anime_synopsis_df = pd.read_csv(\"anime_with_synopsis.csv\")\n", + "anime_synopsis_df = anime_synopsis_df.sample(frac=1.0, random_state=42).reset_index(drop=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "639afef8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MAL_IDNameScoreGenresEnglish nameJapanese nameTypeEpisodesAiredPremiered...Score-10Score-9Score-8Score-7Score-6Score-5Score-4Score-3Score-2Score-1
040176Miru Tights: Cosplay Satsuei Tights6.53Ecchi, SchoolUnknownみるタイツ コスプレ撮影 タイツSpecial1Aug 23, 2019Unknown...875.0350.0762.01526.01542.0924.0384.0245.0162.0148.0
113969Thermae Romae x Yoyogi Animation Gakuin Collab...6.29Comedy, Historical, SeinenUnknownテルマエ・ロマエx代々木アニメーション学院企業コラボレーションSpecial1Jul 9, 2012Unknown...35.047.0114.0253.0240.0162.063.029.010.010.0
213459Ribbon-chanUnknownComedyUnknownリボンちゃんTV24Apr 4, 2012 to Mar 27, 2013Spring 2012...7.0UnknownUnknown2.02.04.01.0Unknown2.07.0
315617Jinrui wa Suitai Shimashita Specials7.23Comedy, Fantasy, SeinenHumanity Has Declined Specials人類は衰退しましたSpecial6Sep 19, 2012 to Feb 20, 2013Unknown...451.0885.02432.03038.01388.0588.0130.038.022.019.0
419157Youkai Watch6.54Comedy, Demons, Kids, SupernaturalYo-kai Watch妖怪ウォッチTV214Jan 8, 2014 to Mar 30, 2018Winter 2014...517.0532.01141.01912.01636.01196.0500.0228.0138.0125.0
..................................................................
1755732238Watashi wa, Kairaku Izonshou6.2HentaiUnknown私は、快楽依存症OVA2Feb 26, 2016 to May 20, 2016Unknown...117.096.0197.0329.0363.0216.0110.049.052.052.0
1755833552Mameshiba Bangai-hen5.75Music, ComedyUnknown豆しば番外編Special52008 to Jun 20, 2019Unknown...8.02.06.08.024.047.011.06.02.012.0
175598476Otome Youkai Zakuro7.47Demons, Historical, Military, Romance, Seinen,...Zakuroおとめ妖怪 ざくろTV13Oct 5, 2010 to Dec 28, 2010Fall 2010...3237.05815.012079.012757.05674.02383.0688.0234.099.081.0
17560953Jyu Oh Sei7.26Action, Sci-Fi, Adventure, Mystery, Drama, ShoujoJyu-Oh-Sei:Planet of the Beast King獣王星TV11Apr 14, 2006 to Jun 23, 2006Spring 2006...2193.03886.07188.08062.04360.02140.0934.0302.0172.0148.0
1756139769Kimi ni Sekai6.7Sci-Fi, Music, FantasyUnknown君に世界Music1Apr 20, 2019Unknown...48.042.072.0181.0134.064.017.013.07.04.0
\n", + "

17562 rows × 35 columns

\n", + "
" + ], + "text/plain": [ + " MAL_ID Name Score \\\n", + "0 40176 Miru Tights: Cosplay Satsuei Tights 6.53 \n", + "1 13969 Thermae Romae x Yoyogi Animation Gakuin Collab... 6.29 \n", + "2 13459 Ribbon-chan Unknown \n", + "3 15617 Jinrui wa Suitai Shimashita Specials 7.23 \n", + "4 19157 Youkai Watch 6.54 \n", + "... ... ... ... \n", + "17557 32238 Watashi wa, Kairaku Izonshou 6.2 \n", + "17558 33552 Mameshiba Bangai-hen 5.75 \n", + "17559 8476 Otome Youkai Zakuro 7.47 \n", + "17560 953 Jyu Oh Sei 7.26 \n", + "17561 39769 Kimi ni Sekai 6.7 \n", + "\n", + " Genres \\\n", + "0 Ecchi, School \n", + "1 Comedy, Historical, Seinen \n", + "2 Comedy \n", + "3 Comedy, Fantasy, Seinen \n", + "4 Comedy, Demons, Kids, Supernatural \n", + "... ... \n", + "17557 Hentai \n", + "17558 Music, Comedy \n", + "17559 Demons, Historical, Military, Romance, Seinen,... \n", + "17560 Action, Sci-Fi, Adventure, Mystery, Drama, Shoujo \n", + "17561 Sci-Fi, Music, Fantasy \n", + "\n", + " English name Japanese name \\\n", + "0 Unknown みるタイツ コスプレ撮影 タイツ \n", + "1 Unknown テルマエ・ロマエx代々木アニメーション学院企業コラボレーション \n", + "2 Unknown リボンちゃん \n", + "3 Humanity Has Declined Specials 人類は衰退しました \n", + "4 Yo-kai Watch 妖怪ウォッチ \n", + "... ... ... \n", + "17557 Unknown 私は、快楽依存症 \n", + "17558 Unknown 豆しば番外編 \n", + "17559 Zakuro おとめ妖怪 ざくろ \n", + "17560 Jyu-Oh-Sei:Planet of the Beast King 獣王星 \n", + "17561 Unknown 君に世界 \n", + "\n", + " Type Episodes Aired Premiered ... \\\n", + "0 Special 1 Aug 23, 2019 Unknown ... \n", + "1 Special 1 Jul 9, 2012 Unknown ... \n", + "2 TV 24 Apr 4, 2012 to Mar 27, 2013 Spring 2012 ... \n", + "3 Special 6 Sep 19, 2012 to Feb 20, 2013 Unknown ... \n", + "4 TV 214 Jan 8, 2014 to Mar 30, 2018 Winter 2014 ... \n", + "... ... ... ... ... ... \n", + "17557 OVA 2 Feb 26, 2016 to May 20, 2016 Unknown ... \n", + "17558 Special 5 2008 to Jun 20, 2019 Unknown ... \n", + "17559 TV 13 Oct 5, 2010 to Dec 28, 2010 Fall 2010 ... \n", + "17560 TV 11 Apr 14, 2006 to Jun 23, 2006 Spring 2006 ... \n", + "17561 Music 1 Apr 20, 2019 Unknown ... \n", + "\n", + " Score-10 Score-9 Score-8 Score-7 Score-6 Score-5 Score-4 Score-3 \\\n", + "0 875.0 350.0 762.0 1526.0 1542.0 924.0 384.0 245.0 \n", + "1 35.0 47.0 114.0 253.0 240.0 162.0 63.0 29.0 \n", + "2 7.0 Unknown Unknown 2.0 2.0 4.0 1.0 Unknown \n", + "3 451.0 885.0 2432.0 3038.0 1388.0 588.0 130.0 38.0 \n", + "4 517.0 532.0 1141.0 1912.0 1636.0 1196.0 500.0 228.0 \n", + "... ... ... ... ... ... ... ... ... \n", + "17557 117.0 96.0 197.0 329.0 363.0 216.0 110.0 49.0 \n", + "17558 8.0 2.0 6.0 8.0 24.0 47.0 11.0 6.0 \n", + "17559 3237.0 5815.0 12079.0 12757.0 5674.0 2383.0 688.0 234.0 \n", + "17560 2193.0 3886.0 7188.0 8062.0 4360.0 2140.0 934.0 302.0 \n", + "17561 48.0 42.0 72.0 181.0 134.0 64.0 17.0 13.0 \n", + "\n", + " Score-2 Score-1 \n", + "0 162.0 148.0 \n", + "1 10.0 10.0 \n", + "2 2.0 7.0 \n", + "3 22.0 19.0 \n", + "4 138.0 125.0 \n", + "... ... ... \n", + "17557 52.0 52.0 \n", + "17558 2.0 12.0 \n", + "17559 99.0 81.0 \n", + "17560 172.0 148.0 \n", + "17561 7.0 4.0 \n", + "\n", + "[17562 rows x 35 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "anime_df" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ac373668", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MAL_IDNameScoreGenressypnopsis
01220Hoshizora Kiseki5.8Romance, Sci-FiKozue is a girl who loves astronomy, particula...
138407Ishii Hiroyuki x Saitou Souma Essay-shuuUnknownSpaceadvertisement for a photo and essay collection...
22705Bakusou Kyoudai Let's & Go6.78Adventure, Cars, Sports, ShounenBased on the manga by Tetsuhiro Koshita, Bakus...
318829Hello Kitty no Shiawase no Aoi HotaruUnknownKidsp to camping with Kitty and her class.
49014Kuttsukiboshi6.12Romance, Supernatural, Drama, Shoujo AiTo Kiiko Kawakami, there was nothing in the wo...
..................
1620938009Re:Stage! Dream Days♪6.69Music, School, Slice of Lifeana Shikimiya has just transferred into Mareho...
1621010348Fireball Charming6.8Sci-Fi3D computer animation about a female robot duc...
16211979Street Fighter Zero The Animation6.55Action, Drama, Martial Arts, Shounen, Super Poweru, the current Street Fighter champion, must o...
1621242826Seijo no Maryoku wa Bannou DesuUnknownRomance, FantasySei, a 20-year-old office worker, is whisked a...
1621320047Sakura Trick7.02Slice of Life, Comedy, Romance, School, Seinen...Having been best friends since middle school, ...
\n", + "

16214 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " MAL_ID Name Score \\\n", + "0 1220 Hoshizora Kiseki 5.8 \n", + "1 38407 Ishii Hiroyuki x Saitou Souma Essay-shuu Unknown \n", + "2 2705 Bakusou Kyoudai Let's & Go 6.78 \n", + "3 18829 Hello Kitty no Shiawase no Aoi Hotaru Unknown \n", + "4 9014 Kuttsukiboshi 6.12 \n", + "... ... ... ... \n", + "16209 38009 Re:Stage! Dream Days♪ 6.69 \n", + "16210 10348 Fireball Charming 6.8 \n", + "16211 979 Street Fighter Zero The Animation 6.55 \n", + "16212 42826 Seijo no Maryoku wa Bannou Desu Unknown \n", + "16213 20047 Sakura Trick 7.02 \n", + "\n", + " Genres \\\n", + "0 Romance, Sci-Fi \n", + "1 Space \n", + "2 Adventure, Cars, Sports, Shounen \n", + "3 Kids \n", + "4 Romance, Supernatural, Drama, Shoujo Ai \n", + "... ... \n", + "16209 Music, School, Slice of Life \n", + "16210 Sci-Fi \n", + "16211 Action, Drama, Martial Arts, Shounen, Super Power \n", + "16212 Romance, Fantasy \n", + "16213 Slice of Life, Comedy, Romance, School, Seinen... \n", + "\n", + " sypnopsis \n", + "0 Kozue is a girl who loves astronomy, particula... \n", + "1 advertisement for a photo and essay collection... \n", + "2 Based on the manga by Tetsuhiro Koshita, Bakus... \n", + "3 p to camping with Kitty and her class. \n", + "4 To Kiiko Kawakami, there was nothing in the wo... \n", + "... ... \n", + "16209 ana Shikimiya has just transferred into Mareho... \n", + "16210 3D computer animation about a female robot duc... \n", + "16211 u, the current Street Fighter champion, must o... \n", + "16212 Sei, a 20-year-old office worker, is whisked a... \n", + "16213 Having been best friends since middle school, ... \n", + "\n", + "[16214 rows x 5 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "anime_synopsis_df" + ] + }, + { + "cell_type": "markdown", + "id": "75a968d7", + "metadata": {}, + "source": [ + "Define the neural network" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "ba2cb244", + "metadata": {}, + "outputs": [], + "source": [ + "class AnimeRecommendationNN(nn.Module):\n", + " def __init__(self, input_size):\n", + " super(AnimeRecommendationNN, self).__init__()\n", + " self.fc1 = nn.Linear(input_size, 256)\n", + " self.fc2 = nn.Linear(256, 128)\n", + " self.fc3 = nn.Linear(128, 64)\n", + " self.fc4 = nn.Linear(64, 32)\n", + " self.fc5 = nn.Linear(32, 1)\n", + " self.relu = nn.LeakyReLU(negative_slope=0.01)\n", + " self.dropout = nn.Dropout(0.3)\n", + " self.batch_norm1 = nn.BatchNorm1d(256)\n", + " self.batch_norm2 = nn.BatchNorm1d(128)\n", + " self.batch_norm3 = nn.BatchNorm1d(64)\n", + " self.batch_norm4 = nn.BatchNorm1d(32)\n", + "\n", + " def forward(self, x):\n", + " x = self.dropout(self.relu(self.batch_norm1(self.fc1(x))))\n", + " x = self.dropout(self.relu(self.batch_norm2(self.fc2(x))))\n", + " x = self.dropout(self.relu(self.batch_norm3(self.fc3(x))))\n", + " x = self.dropout(self.relu(self.batch_norm4(self.fc4(x))))\n", + " x = self.fc5(x)\n", + " return x" + ] + }, + { + "cell_type": "markdown", + "id": "90f1197e", + "metadata": {}, + "source": [ + "Feature engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "45c355f5", + "metadata": {}, + "outputs": [], + "source": [ + "def clean_numeric_column(series):\n", + " series = series.astype(str)\n", + " series = series.replace(['Unknown', ''], np.nan)\n", + " series = pd.to_numeric(series, errors='coerce')\n", + " return series" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "28654be7", + "metadata": {}, + "outputs": [], + "source": [ + "def engineer_features(df):\n", + " df = df.copy()\n", + " \n", + " df['genre_count'] = df['Genres'].str.count(',') + 1\n", + " df['synopsis_length'] = df['sypnopsis'].str.len().fillna(0)\n", + " \n", + " numeric_columns = ['Score', 'Episodes', 'Members', 'Popularity', 'Ranked']\n", + " \n", + " for col in numeric_columns:\n", + " df[col] = clean_numeric_column(df[col])\n", + " # Fill NaN with median without using inplace\n", + " median_value = df[col].median()\n", + " df[col] = df[col].fillna(median_value)\n", + " \n", + " return df[['MAL_ID', 'Score', 'Episodes', 'Members', 'Popularity', 'Ranked', 'genre_count', 'synopsis_length']]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "65ee1094", + "metadata": {}, + "outputs": [], + "source": [ + "anime_features = engineer_features(pd.merge(anime_df, anime_synopsis_df[['MAL_ID', 'sypnopsis']], on='MAL_ID', how='left'))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "a35cb269", + "metadata": {}, + "outputs": [], + "source": [ + "non_numeric_check = anime_features.drop('MAL_ID', axis=1).select_dtypes(exclude=[np.number])\n", + "if not non_numeric_check.empty:\n", + " print(\"Warning: Non-numeric data found in columns:\", non_numeric_check.columns)\n", + " print(\"Sample of non-numeric data:\")\n", + " print(non_numeric_check.head())\n", + " raise ValueError(\"Please check your data preprocessing steps.\")" + ] + }, + { + "cell_type": "markdown", + "id": "56cc96a6", + "metadata": {}, + "source": [ + "Normalize features" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0072397d", + "metadata": {}, + "outputs": [], + "source": [ + "scaler = StandardScaler()\n", + "anime_features_scaled = scaler.fit_transform(anime_features.drop('MAL_ID', axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "c8a66545", + "metadata": {}, + "outputs": [], + "source": [ + "X = anime_features_scaled\n", + "y = anime_features['Score'].values" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "9cc83cb0", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0fdea965", + "metadata": {}, + "outputs": [], + "source": [ + "train_dataset = TensorDataset(torch.FloatTensor(X_train), torch.FloatTensor(y_train))\n", + "val_dataset = TensorDataset(torch.FloatTensor(X_val), torch.FloatTensor(y_val))\n", + "\n", + "batch_size = 512\n", + "train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n", + "val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)" + ] + }, + { + "cell_type": "markdown", + "id": "f6e2b4c3", + "metadata": {}, + "source": [ + "Training" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "bc6fad2c", + "metadata": {}, + "outputs": [], + "source": [ + "input_size = X_train.shape[1]\n", + "model = AnimeRecommendationNN(input_size).to(device)\n", + "optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-5)\n", + "scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'min', patience=5, factor=0.5, min_lr=1e-6)\n", + "criterion = nn.MSELoss()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "3cf30295", + "metadata": {}, + "outputs": [], + "source": [ + "num_epochs = 100\n", + "patience = 15\n", + "best_val_loss = float('inf')\n", + "no_improve = 0\n", + "\n", + "train_losses = []\n", + "val_losses = []" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "de45215b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 2%|▏ | 2/100 [00:00<00:20, 4.73it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [1/100], Train Loss: 35.1908, Val Loss: 34.1363\n", + "Epoch [2/100], Train Loss: 28.4761, Val Loss: 26.1533\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 4%|▍ | 4/100 [00:00<00:14, 6.71it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [3/100], Train Loss: 22.8870, Val Loss: 20.3565\n", + "Epoch [4/100], Train Loss: 18.0055, Val Loss: 15.7408\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 6%|▌ | 6/100 [00:00<00:12, 7.81it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [5/100], Train Loss: 13.4245, Val Loss: 11.4652\n", + "Epoch [6/100], Train Loss: 9.5039, Val Loss: 7.3833\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 8%|▊ | 8/100 [00:01<00:12, 7.19it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [7/100], Train Loss: 6.0797, Val Loss: 4.0210\n", + "Epoch [8/100], Train Loss: 3.4364, Val Loss: 1.7301\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 10%|█ | 10/100 [00:01<00:11, 7.98it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [9/100], Train Loss: 1.8735, Val Loss: 0.3324\n", + "Epoch [10/100], Train Loss: 1.3259, Val Loss: 0.0896\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 12%|█▏ | 12/100 [00:01<00:10, 8.41it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [11/100], Train Loss: 1.1793, Val Loss: 0.0788\n", + "Epoch [12/100], Train Loss: 1.1421, Val Loss: 0.0493\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 14%|█▍ | 14/100 [00:01<00:09, 8.67it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [13/100], Train Loss: 1.0728, Val Loss: 0.0493\n", + "Epoch [14/100], Train Loss: 1.0055, Val Loss: 0.0373\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 15%|█▌ | 15/100 [00:02<00:09, 8.75it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [15/100], Train Loss: 0.9540, Val Loss: 0.0340\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 17%|█▋ | 17/100 [00:02<00:11, 7.42it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [16/100], Train Loss: 0.9143, Val Loss: 0.0470\n", + "Epoch [17/100], Train Loss: 0.8634, Val Loss: 0.0281\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 19%|█▉ | 19/100 [00:02<00:10, 7.40it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [18/100], Train Loss: 0.8607, Val Loss: 0.0362\n", + "Epoch [19/100], Train Loss: 0.8161, Val Loss: 0.0189\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 21%|██ | 21/100 [00:02<00:09, 7.97it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [20/100], Train Loss: 0.7852, Val Loss: 0.0166\n", + "Epoch [21/100], Train Loss: 0.7763, Val Loss: 0.0257\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 23%|██▎ | 23/100 [00:03<00:08, 8.60it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [22/100], Train Loss: 0.7352, Val Loss: 0.0183\n", + "Epoch [23/100], Train Loss: 0.7398, Val Loss: 0.0281\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 25%|██▌ | 25/100 [00:03<00:08, 9.11it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [24/100], Train Loss: 0.7096, Val Loss: 0.0287\n", + "Epoch [25/100], Train Loss: 0.7122, Val Loss: 0.0163\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 27%|██▋ | 27/100 [00:03<00:08, 8.19it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [26/100], Train Loss: 0.6918, Val Loss: 0.0232\n", + "Epoch [27/100], Train Loss: 0.6863, Val Loss: 0.0228\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 29%|██▉ | 29/100 [00:03<00:08, 8.61it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [28/100], Train Loss: 0.6635, Val Loss: 0.0170\n", + "Epoch [29/100], Train Loss: 0.6679, Val Loss: 0.0171\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 30%|███ | 30/100 [00:03<00:08, 8.75it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [30/100], Train Loss: 0.6446, Val Loss: 0.0272\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 32%|███▏ | 32/100 [00:04<00:09, 7.44it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [31/100], Train Loss: 0.6492, Val Loss: 0.0337\n", + "Epoch [32/100], Train Loss: 0.6390, Val Loss: 0.0221\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 34%|███▍ | 34/100 [00:04<00:08, 8.14it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [33/100], Train Loss: 0.6460, Val Loss: 0.0324\n", + "Epoch [34/100], Train Loss: 0.6318, Val Loss: 0.0180\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 36%|███▌ | 36/100 [00:04<00:07, 8.85it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [35/100], Train Loss: 0.6359, Val Loss: 0.0235\n", + "Epoch [36/100], Train Loss: 0.6204, Val Loss: 0.0253\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 38%|███▊ | 38/100 [00:04<00:06, 9.30it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [37/100], Train Loss: 0.6167, Val Loss: 0.0258\n", + "Epoch [38/100], Train Loss: 0.6130, Val Loss: 0.0227\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 40%|████ | 40/100 [00:05<00:06, 9.36it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [39/100], Train Loss: 0.6214, Val Loss: 0.0161\n", + "Epoch [40/100], Train Loss: 0.6209, Val Loss: 0.0237\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 42%|████▏ | 42/100 [00:05<00:07, 8.24it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [41/100], Train Loss: 0.6044, Val Loss: 0.0238\n", + "Epoch [42/100], Train Loss: 0.6016, Val Loss: 0.0171\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 44%|████▍ | 44/100 [00:05<00:06, 8.61it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [43/100], Train Loss: 0.6160, Val Loss: 0.0218\n", + "Epoch [44/100], Train Loss: 0.6252, Val Loss: 0.0178\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 45%|████▌ | 45/100 [00:05<00:06, 8.85it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [45/100], Train Loss: 0.6161, Val Loss: 0.0247\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 47%|████▋ | 47/100 [00:05<00:07, 7.50it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [46/100], Train Loss: 0.5884, Val Loss: 0.0257\n", + "Epoch [47/100], Train Loss: 0.6001, Val Loss: 0.0157\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 49%|████▉ | 49/100 [00:06<00:06, 8.01it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [48/100], Train Loss: 0.6033, Val Loss: 0.0279\n", + "Epoch [49/100], Train Loss: 0.6040, Val Loss: 0.0180\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 51%|█████ | 51/100 [00:06<00:05, 8.17it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [50/100], Train Loss: 0.6089, Val Loss: 0.0159\n", + "Epoch [51/100], Train Loss: 0.5913, Val Loss: 0.0169\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 53%|█████▎ | 53/100 [00:06<00:05, 8.48it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [52/100], Train Loss: 0.6020, Val Loss: 0.0197\n", + "Epoch [53/100], Train Loss: 0.5963, Val Loss: 0.0158\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 55%|█████▌ | 55/100 [00:06<00:05, 8.78it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [54/100], Train Loss: 0.5993, Val Loss: 0.0205\n", + "Epoch [55/100], Train Loss: 0.5912, Val Loss: 0.0193\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 57%|█████▋ | 57/100 [00:07<00:04, 9.02it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [56/100], Train Loss: 0.5841, Val Loss: 0.0203\n", + "Epoch [57/100], Train Loss: 0.5937, Val Loss: 0.0202\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 59%|█████▉ | 59/100 [00:07<00:04, 9.17it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [58/100], Train Loss: 0.6112, Val Loss: 0.0150\n", + "Epoch [59/100], Train Loss: 0.5767, Val Loss: 0.0172\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 60%|██████ | 60/100 [00:07<00:05, 7.97it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [60/100], Train Loss: 0.5896, Val Loss: 0.0179\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 62%|██████▏ | 62/100 [00:07<00:05, 7.05it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [61/100], Train Loss: 0.5894, Val Loss: 0.0130\n", + "Epoch [62/100], Train Loss: 0.5865, Val Loss: 0.0131\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 64%|██████▍ | 64/100 [00:08<00:04, 8.05it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [63/100], Train Loss: 0.5908, Val Loss: 0.0180\n", + "Epoch [64/100], Train Loss: 0.5949, Val Loss: 0.0164\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 66%|██████▌ | 66/100 [00:08<00:03, 8.66it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [65/100], Train Loss: 0.5909, Val Loss: 0.0197\n", + "Epoch [66/100], Train Loss: 0.5723, Val Loss: 0.0174\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 68%|██████▊ | 68/100 [00:08<00:03, 8.79it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [67/100], Train Loss: 0.5814, Val Loss: 0.0222\n", + "Epoch [68/100], Train Loss: 0.5995, Val Loss: 0.0202\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 70%|███████ | 70/100 [00:08<00:03, 8.57it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [69/100], Train Loss: 0.5859, Val Loss: 0.0246\n", + "Epoch [70/100], Train Loss: 0.5812, Val Loss: 0.0132\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 72%|███████▏ | 72/100 [00:08<00:03, 8.19it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [71/100], Train Loss: 0.5821, Val Loss: 0.0183\n", + "Epoch [72/100], Train Loss: 0.5841, Val Loss: 0.0206\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 74%|███████▍ | 74/100 [00:09<00:02, 8.78it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [73/100], Train Loss: 0.5871, Val Loss: 0.0192\n", + "Epoch [74/100], Train Loss: 0.5782, Val Loss: 0.0155\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epochs: 75%|███████▌ | 75/100 [00:09<00:03, 8.00it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [75/100], Train Loss: 0.5961, Val Loss: 0.0175\n", + "Epoch [76/100], Train Loss: 0.5817, Val Loss: 0.0208\n", + "Early stopping triggered after 76 epochs\n", + "Training completed.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "/tmp/ipykernel_307086/1420535760.py:64: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model.load_state_dict(torch.load('best_model.pth'))\n" + ] + }, + { + "data": { + "text/plain": [ + "AnimeRecommendationNN(\n", + " (fc1): Linear(in_features=7, out_features=256, bias=True)\n", + " (fc2): Linear(in_features=256, out_features=128, bias=True)\n", + " (fc3): Linear(in_features=128, out_features=64, bias=True)\n", + " (fc4): Linear(in_features=64, out_features=32, bias=True)\n", + " (fc5): Linear(in_features=32, out_features=1, bias=True)\n", + " (relu): LeakyReLU(negative_slope=0.01)\n", + " (dropout): Dropout(p=0.3, inplace=False)\n", + " (batch_norm1): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", + " (batch_norm2): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", + " (batch_norm3): BatchNorm1d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", + " (batch_norm4): BatchNorm1d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", + ")" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "for epoch in tqdm(range(num_epochs), desc=\"Epochs\"):\n", + " model.train()\n", + " train_loss = 0\n", + " total_train_loss = 0\n", + " train_batch_count = 0\n", + "\n", + " for batch_X, batch_y in train_loader:\n", + " batch_X, batch_y = batch_X.to(device), batch_y.to(device)\n", + "\n", + " optimizer.zero_grad()\n", + " outputs = model(batch_X)\n", + " loss = criterion(outputs.squeeze(), batch_y)\n", + " loss.backward()\n", + " \n", + " torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n", + " \n", + " optimizer.step()\n", + "\n", + " total_train_loss += loss.item()\n", + " train_batch_count += 1\n", + " train_loss += loss.item()\n", + "\n", + " train_loss /= len(train_loader)\n", + " train_losses.append(train_loss)\n", + "\n", + " avg_train_loss = total_train_loss / train_batch_count\n", + "\n", + " # Validation phase\n", + " model.eval()\n", + " total_val_loss = 0\n", + " val_batch_count = 0\n", + "\n", + " with torch.no_grad():\n", + " for batch_X, batch_y in val_loader:\n", + " batch_X, batch_y = batch_X.to(device), batch_y.to(device)\n", + " outputs = model(batch_X)\n", + " val_loss = criterion(outputs.squeeze(), batch_y)\n", + " total_val_loss += val_loss.item()\n", + " val_batch_count += 1\n", + "\n", + " avg_val_loss = total_val_loss / val_batch_count\n", + " val_losses.append(avg_val_loss) # Changed from val_loss to avg_val_loss\n", + "\n", + " tqdm.write(f'Epoch [{epoch+1}/{num_epochs}], Train Loss: {avg_train_loss:.4f}, Val Loss: {avg_val_loss:.4f}')\n", + " \n", + " # Learning rate scheduling\n", + " scheduler.step(avg_val_loss)\n", + " \n", + " # Early stopping\n", + " if avg_val_loss < best_val_loss:\n", + " best_val_loss = avg_val_loss\n", + " no_improve = 0\n", + " torch.save(model.state_dict(), 'best_model.pth')\n", + " else:\n", + " no_improve += 1\n", + " if no_improve == patience:\n", + " print(f\"Early stopping triggered after {epoch+1} epochs\")\n", + " break\n", + "\n", + "print(\"Training completed.\")\n", + "\n", + "# Load the best model for inference\n", + "model.load_state_dict(torch.load('best_model.pth'))\n", + "model.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "0aaef025", + "metadata": {}, + "outputs": [], + "source": [ + "def predict_anime_score(anime_features_dict):\n", + " feature_order = anime_features.columns.tolist()\n", + " feature_order.remove('MAL_ID') # Remove MAL_ID as it's not used for prediction \n", + " features_list = [anime_features_dict.get(feature, 0) for feature in feature_order]\n", + " \n", + " model.eval()\n", + " with torch.no_grad():\n", + " features = torch.FloatTensor(scaler.transform([features_list])).to(device)\n", + " prediction = model(features)\n", + " return prediction.item()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "338fa304", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Predicted score for the new anime: 1.48\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/andre/miniconda3/envs/venv/lib/python3.12/site-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "new_anime_features = {\n", + " 'Score': 0,\n", + " 'Episodes': 12,\n", + " 'Members': 1000000,\n", + " 'Popularity': 1000,\n", + " 'Ranked': 500,\n", + " 'genre_count': 3,\n", + " 'synopsis_length': 150\n", + "}\n", + "\n", + "predicted_score = predict_anime_score(new_anime_features)\n", + "print(f\"Predicted score for the new anime: {predicted_score:.2f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "224e985a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation MSE: 0.0130\n", + "Validation RMSE: 0.1140\n" + ] + } + ], + "source": [ + "model.eval()\n", + "val_predictions = []\n", + "val_true_scores = []\n", + "\n", + "with torch.no_grad():\n", + " for batch_X, batch_y in val_loader:\n", + " batch_X, batch_y = batch_X.to(device), batch_y.to(device)\n", + " outputs = model(batch_X)\n", + " val_predictions.extend(outputs.squeeze().cpu().numpy())\n", + " val_true_scores.extend(batch_y.cpu().numpy())\n", + "\n", + "val_predictions = np.array(val_predictions)\n", + "val_true_scores = np.array(val_true_scores)\n", + "\n", + "# Calculate MSE and RMSE\n", + "mse = np.mean((val_predictions - val_true_scores) ** 2)\n", + "rmse = np.sqrt(mse)\n", + "\n", + "print(f\"Validation MSE: {mse:.4f}\")\n", + "print(f\"Validation RMSE: {rmse:.4f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "36e94621", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAIjCAYAAADFthA8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACpuklEQVR4nOzdd3hUZfrG8e+ZPukJKSQhtNCbUhQVBJWm2DtW7Lr2wu7q6orYsHdXUX9iZe19VQS7iIKiKAhC6CSQQkgmddo5vz8iAyG0hIQEcn+ui2uZ95w555nAYu6873lew7IsCxERERERkVbC1twFiIiIiIiI7EkKQSIiIiIi0qooBImIiIiISKuiECQiIiIiIq2KQpCIiIiIiLQqCkEiIiIiItKqKASJiIiIiEirohAkIiIiIiKtikKQiIiIiIi0KgpBIiK7oGPHjpx33nmR11999RWGYfDVV181W01b27pGqb/DDjuMww47rNnubxgGt912W7PdX0SktVAIEpEW74UXXsAwjMgvj8dDt27duPLKK8nPz2/u8url448/bjXf5C5atCjy51VSUtLg69x999289957jVZXYwqHw2RkZGAYBp988klzl9MkPvzwQ4YPH05qaipRUVF07tyZ0047jU8//bS5SxMRaTCFIBHZa9x+++28/PLLPPHEExxyyCE89dRTHHzwwVRWVu7xWoYNG0ZVVRXDhg2r1/s+/vhjJk2a1ERVtSyvvPIKbdu2BeCtt95q8HVacgj64osvWLduHR07duTVV1/d7etVVVVxyy23NEJljeOBBx7guOOOwzAMbrrpJh5++GFOPvlkli5dymuvvdbc5YmINJijuQsQEdlVRx11FIMGDQLgoosuok2bNjz00EO8//77nHHGGdt8T0VFBdHR0Y1ei81mw+PxNPp19xWWZTFt2jTOPPNMVqxYwauvvspFF13U3GU1uldeeYUBAwYwfvx4/vWvf+3237eW9HcqFApxxx13MGrUKD777LM6xwsKCvZYLaZpEggEWtTXR0T2bpoJEpG91hFHHAHAihUrADjvvPOIiYlh2bJljB07ltjYWM466yyg5puoRx55hN69e+PxeEhLS+PSSy9l48aNta5pWRZ33nkn7dq1IyoqisMPP5yFCxfWuff2ngn68ccfGTt2LImJiURHR9OvXz8effTRSH1PPvkkQK3lfZs0do1bCwaDJCUlcf7559c55vP58Hg8TJgwITL2+OOP07t3b6KiokhMTGTQoEFMmzZtp/cBmDVrFitXrmTcuHGMGzeOb775hrVr19Y5zzRNHn30Ufr27YvH4yElJYUjjzySn376KfJ1qqio4MUXX4x8vTY993TeeefRsWPHOte87bbban1dAaZOncoRRxxBamoqbrebXr168dRTT+3SZ9meqqoq3n33XcaNG8dpp51GVVUV77//fp3zNv29zM3N5YQTTiAmJoaUlBQmTJhAOByude7WzwRt+ixLlizh7LPPJj4+npSUFP79739jWRZr1qzh+OOPJy4ujrZt2/Lggw/Wub/f72fixIl06dIFt9tNVlYW//jHP/D7/Tv8fEVFRfh8PoYMGbLN46mpqbVeV1dXc9ttt9GtWzc8Hg/p6emcdNJJLFu2LHJORUUFN9xwA1lZWbjdbrp3784DDzyAZVl1vg5XXnklr776Kr1798btdkeW3+Xm5nLBBReQlpaG2+2md+/ePP/883Xq252/vyKy79NMkIjstTZ9c9WmTZvIWCgUYsyYMQwdOpQHHniAqKgoAC699FJeeOEFzj//fK6++mpWrFjBE088wS+//MKsWbNwOp0A3Hrrrdx5552MHTuWsWPHMm/ePEaPHk0gENhpPTNmzOCYY44hPT2da665hrZt27Jo0SI++ugjrrnmGi699FLy8vKYMWMGL7/8cp33N3WNTqeTE088kXfeeYcpU6bgcrkix9577z38fj/jxo0D4Nlnn+Xqq6/mlFNO4ZprrqG6uprffvuNH3/8kTPPPHOnX4tXX32V7OxsDjjgAPr06UNUVBT//e9/+fvf/17rvAsvvJAXXniBo446iosuuohQKMS3337LDz/8wKBBg3j55Ze56KKLOPDAA7nkkksAyM7O3un9t/bUU0/Ru3dvjjvuOBwOBx9++CGXX345pmlyxRVX1Pt6AB988AHl5eWMGzeOtm3bcthhh/Hqq69u8+sTDocZM2YMgwcP5oEHHmDmzJk8+OCDZGdn87e//W2n9zr99NPp2bMn99xzD//73/+48847SUpKYsqUKRxxxBHce++9vPrqq0yYMIEDDjggskzTNE2OO+44vvvuOy655BJ69uzJ77//zsMPP8ySJUt2uMwwNTUVr9fLhx9+yFVXXUVSUtJ2zw2HwxxzzDF8/vnnjBs3jmuuuYaysjJmzJjBggULyM7OxrIsjjvuOL788ksuvPBC9t9/f6ZPn87f//53cnNzefjhh2td84svvuCNN97gyiuvJDk5mY4dO5Kfn89BBx0UCUkpKSl88sknXHjhhfh8Pq699lpg9//+ikgrYImItHBTp061AGvmzJlWYWGhtWbNGuu1116z2rRpY3m9Xmvt2rWWZVnW+PHjLcC68cYba73/22+/tQDr1VdfrTX+6aef1hovKCiwXC6XdfTRR1umaUbO+9e//mUB1vjx4yNjX375pQVYX375pWVZlhUKhaxOnTpZHTp0sDZu3FjrPlte64orrrC29U9vU9S4LdOnT7cA68MPP6w1PnbsWKtz586R18cff7zVu3fvHV5rewKBgNWmTRvr5ptvjoydeeaZ1n777VfrvC+++MICrKuvvrrONbb8bNHR0dv8XOPHj7c6dOhQZ3zixIl1vsaVlZV1zhszZkytz2xZljV8+HBr+PDh2/hUdR1zzDHWkCFDIq+feeYZy+FwWAUFBXXqBKzbb7+91nj//v2tgQMH1hoDrIkTJ9b5LJdccklkLBQKWe3atbMMw7DuueeeyPjGjRstr9db62v18ssvWzabzfr2229r3efpp5+2AGvWrFk7/Iy33nqrBVjR0dHWUUcdZd11113Wzz//XOe8559/3gKshx56qM6xTX+W7733ngVYd955Z63jp5xyimUYhpWTk1Pr62Cz2ayFCxfWOvfCCy+00tPTraKiolrj48aNs+Lj4yN/zrvz91dEWgcthxORvcbIkSNJSUkhKyuLcePGERMTw7vvvktmZmat87b+yfqbb75JfHw8o0aNoqioKPJr4MCBxMTE8OWXXwIwc+ZMAoEAV111Va3lVJt+urwjv/zyCytWrODaa68lISGh1rGtl2Zty56oEWqWECYnJ/P6669HxjZu3MiMGTM4/fTTI2MJCQmsXbuWuXPn7tJ1t/TJJ5+wYcOGWs9pnXHGGcyfP7/Wsr23334bwzCYOHFinWvsytesPrxeb+T3paWlFBUVMXz4cJYvX05paWm9r7dhwwamT59e6zOefPLJGIbBG2+8sc33XHbZZbVeH3rooSxfvnyX7rfl81R2u51BgwZhWRYXXnhhZDwhIYHu3bvXuuabb75Jz5496dGjR62/V5uWkm76e7U9kyZNYtq0afTv35/p06dz8803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P/54jj32WA4//HBuvvlmVq5cyX777cdnn33G+++/z7XXXrtLrc/vuecevvzySwYPHszFF19Mr169KC4uZt68ecycOZPi4mKgYX9/RaSVaY6WdCIi9bGpRfbcuXN3eN748eOt6Ojo7R5/5plnrIEDB1per9eKjY21+vbta/3jH/+w8vLyIueEw2Fr0qRJVnp6uuX1eq3DDjvMWrBggdWhQ4cdtsje5LvvvrNGjRplxcbGWtHR0Va/fv2sxx9/PHI8FApZV111lZWSkmIZhlGnlXNj1rgjpmlaWVlZ22xZbFmWNWXKFGvYsGFWmzZtLLfbbWVnZ1t///vfrdLS0u1e88EHH7QA6/PPP9/uOS+88IIFWO+//37k63H//fdbPXr0sFwul5WSkmIdddRRtdowL1682Bo2bJjl9XrrtAH/7LPPrD59+lgul8vq3r279corr2yzRfYHH3xg9evXz/J4PFbHjh2te++9N9LWecWKFZHzdtYi++eff7YA69///vd2z1m5cqUFWNddd51lWdv/e7mtOtlOi+zCwsJa523vmsOHD6/TGjoQCFj33nuv1bt3b8vtdluJiYnWwIEDrUmTJu3wzzMYDFrPPvusdcIJJ1gdOnSw3G63FRUVZfXv39+6//77Lb/fX+v8yspK6+abb7Y6depkOZ1Oq23bttYpp5xiLVu2LHJOWVmZdd1111kZGRmW0+m0unbtat1///21WqJv+jpcccUV26wrPz/fuuKKK6ysrKzIfUaMGGE988wzkXMa8vdXRFoXw7K22qZZRERERERkH6ZngkREREREpFVRCBIRERERkVZFIUhERERERFoVhSAREREREWlVFIJERERERKRVUQgSEREREZFWZa/eLNU0TfLy8oiNjcUwjOYuR0REREREmollWZSVlZGRkYHNtuO5nr06BOXl5W13x24REREREWl91qxZQ7t27XZ4zl4dgmJjY4GaDxoXF9fM1YiIiIiISHPx+XxkZWVFMsKO7NUhaNMSuLi4OIUgERERERHZpcdk1BhBRERERERaFYUgERERERFpVRSCRERERESkVVEIEhERERGRVkUhSEREREREWhWFIBERERERaVUUgkREREREpFVRCBIRERERkVZFIUhERERERFoVhSAREREREWlVFIJERERERKRVUQgSEREREZFWRSFIRERERERaFYUgERERERFpVRSCRERERESkVVEIEhERERGRVkUhSERERERE6i83FxYvbu4qGkQhSEREREREdp3fD/feC927w7nngmk2d0X1phAkIiIiIiK75uOPoW9fuPFGqKiAuXPhpZeau6p6czR3ASIiIiIi0sLl5MB118FHH20es9ngssvguOOar64GUggSEREREZHte+01GD8eAoHNY4ceCo8/Dvvt13x17QYthxMRERERke076KCaWR+AjAyYNg2+/nqvDUCgmSAREREREdlSZSVERW1+3bEj3Hor+Hxw880QE9NspTUWhSAREREREYGNG2vCzgcfwMKFtcPOTTc1X11NQMvhRERERERas3AYnn0WunWDJ56A1avhrruau6om1awhqKysjGuvvZYOHTrg9Xo55JBDmDt3bnOWJCIiIiLSesyeDYMHwyWXQFFRzVhUFCQnN29dTaxZQ9BFF13EjBkzePnll/n9998ZPXo0I0eOJDc3tznLEhERERHZt61fX9Px7ZBD4OefN4+fcQb8+SfccEPz1bYHGJZlWc1x46qqKmJjY3n//fc5+uijI+MDBw7kqKOO4s4776zzHr/fj9/vj7z2+XxkZWVRWlpKXFzcHqlbRERERGSvFQjAY4/B7bdDWdnm8X79alpeDxvWfLXtJp/PR3x8/C5lg2abCQqFQoTDYTweT61xr9fLd999t833TJ48mfj4+MivrKysPVGqiIiIiMi+YcMGmDRpcwBKSKh5Dujnn/fqAFRfzRaCYmNjOfjgg7njjjvIy8sjHA7zyiuvMHv2bNatW7fN99x0002UlpZGfq1Zs2YPVy0iIiIishdLT4d//xsMo+Y5oKVL4YorwNG6mkY36zNBL7/8MpZlkZmZidvt5rHHHuOMM87AZtt2WW63m7i4uFq/RERERERkGyora7q8lZTUHr/22pqZnylT9vkGCNvTrCEoOzubr7/+mvLyctasWcOcOXMIBoN07ty5OcsSEREREdl7WRa89Rb07Am33AK33Vb7uMsF/fs3S2ktRYvYJyg6Opr09HQ2btzI9OnTOf7445u7JBERERGRvc/ChTByJJx6as1+PwDPPLO5/bUAzRyCpk+fzqeffsqKFSuYMWMGhx9+OD169OD8889vzrJERERERPYuJSU1y9z22w+++GLz+JgxMG9eq132tj3N+gRUaWkpN910E2vXriUpKYmT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pnHnnXfSrVs35s2bp4XhTejtt9/mm2++0S/eJnj00UeZPn06119/PUVFRaSmpnLttddyxx13mF1azCgtLWXatGl89913JCUlMWbMGGbPnk1cXJzZpTUp7RMkIiIiIiIxRWuCREREREQkpigEiYiIiIhITFEIEhERERGRmKIQJCIiIiIiMUUhSEREREREYopCkIiIiIiIxBSFIBERERERiSkKQSIiIiIiElMUgkREpEWxWCwsW7bM7DJERKQFUwgSEZEGffDBB9hsNkaNGnXEr+3atSvz5s07+kUdhuLiYq677jo6d+6M0+nkmGOOYcSIEaxdu9aUekREpPmxm12AiIg0T4sWLWLSpEksWrSIgoICUlNTzS7psIwZM4ZAIMBTTz1FRkYGhYWFvPPOO+zZs6fRPjMQCOBwOBrt/UVE5OjSTJCIiBykoqKCF198keuuu45Ro0bx5JNPHnTO66+/zoABA3C5XLRv357zzjsPgKFDh/L1119z4403YrFYsFgsAMycOZPjjz8+6j3mzZtH165d675ft24dw4cPp3379vh8Pk455RQ++eSTw667pKSE999/n3vuuYdTTz2VLl268Ktf/Ypp06bx29/+Nuq8a6+9lo4dO+JyuejTpw/Lly+vO/7KK6+QnZ2N0+mka9euPPDAA1Gf07VrV2bNmsUVV1xBYmIi11xzDQBr1qzh5JNPxu12k56ezuTJk6msrKx73YIFC8jKysLlctGxY0cuuOCCw742ERE5ehSCRETkIC+99BK9evWiZ8+eXH755fz973/HMIy64//3f//Heeedx1lnncWGDRt45513+NWvfgXAP//5Tzp16sSdd97Jrl272LVr12F/bnl5OePGjWPNmjV8+OGHZGVlcdZZZ1FeXn5Yr/d4PHg8HpYtW0ZNTU2D54TDYUaOHMnatWtZsmQJmzdvZu7cudhsNgA+/vhjLrroIi655BI+++wzZs6cyfTp0w8Kgvfffz/HHXccGzZsYPr06ezYsYMzzzyTMWPG8Omnn/Liiy+yZs0abrjhBgDWr1/P5MmTufPOO9myZQv/+te/GDJkyGHfGxEROYoMERGRAwwaNMiYN2+eYRiGUVtba7Rv395477336o4PHDjQGDt27CFf36VLF+Ohhx6KGpsxY4Zx3HHHRY099NBDRpcuXQ75PqFQyPB6vcbrr79eNwYYS5cuPeRrXn75ZaNt27aGy+UyBg0aZEybNs3YtGlT3fHc3FzDarUaW7ZsafD1l112mTF8+PCosVtvvdXo3bt31PWde+65UedcffXVxjXXXBM19v777xtWq9Worq42XnnlFSMxMdEoKys7ZO0iItI0NBMkIiJRtmzZwkcffcSll14KgN1u5+KLL2bRokV152zcuJHTTz/9qH92YWEh//M//0NWVhY+n4/ExEQqKir45ptvDvs9xowZQ0FBAa+99hpnnnkmK1eupF+/fnUzORs3bqRTp0706NGjwdd/8cUXDB48OGps8ODBbNu2jVAoVDfWv3//qHM2bdrEk08+WTcb5fF4GDFiBOFwmC+//JLhw4fTpUsXMjIy+N3vfsezzz5LVVXVYV+XiIgcPWqMICIiURYtWkQwGIxqhGAYBk6nk/nz5+Pz+XC73Uf8vlarNeqROoDa2tqo78eNG8eePXt4+OGH6dKlC06nk4EDBxIIBI7os1wuF8OHD2f48OFMnz6dCRMmMGPGDK688sqfVXtDEhISor6vqKjg2muvZfLkyQed27lzZxwOB5988gkrV67kzTff5I477mDmzJmsW7eONm3aHJWaRETk8GgmSERE6gSDQZ5++mkeeOABNm7cWPe1adMmUlNTef755wHIycnhnXfeOeT7OByOqFkTgA4dOrB79+6oILRx48aoc9auXcvkyZM566yz6hoTfP/997/4unr37l3XoCAnJ4fvvvuOrVu3Nnjusccee1A77bVr19KjR4+6dUMN6devH5s3byYzM/Ogr32d4+x2O8OGDePee+/l008/5auvvuLdd9/9xdcnIiJHRjNBIiJSZ/ny5fzwww9cffXV+Hy+qGNjxoxh0aJF/P73v2fGjBmcfvrpdO/enUsuuYRgMMgbb7zBbbfdBkS6p61evZpLLrkEp9NJ+/btGTp0KMXFxdx7771ccMEF/Otf/2LFihUkJibWfUZWVhbPPPMM/fv3p6ysjFtvvfWIZm727NnDhRdeyFVXXUVOTg5er5f169dz7733Mnr0aABOOeUUhgwZwpgxY3jwwQfJzMzkv//9LxaLhTPPPJObb76ZAQMGMGvWLC6++GI++OAD5s+fz4IFC370s2+77TZ+/etfc8MNNzBhwgQSEhLYvHkzb731FvPnz2f58uXs3LmTIUOG0LZtW9544w3C4TA9e/Y87OsTEZGjxOQ1SSIi0oycffbZxllnndXgsf/85z8GUNdk4JVXXjGOP/54w+FwGO3btzfOP//8unM/+OADIycnx3A6ncb+/6lZuHChkZ6ebiQkJBhXXHGFMXv27KjGCJ988onRv39/w+VyGVlZWcY//vGPg5os8CONEfx+vzF16lSjX79+hs/nM+Lj442ePXsaf/7zn42qqqq68/bs2WOMHz/eaNeuneFyuYw+ffoYy5cvrzv+8ssvG7179zbi4uKMzp07G/fdd1/U5zTU+MEwDOOjjz4yhg8fbng8HiMhIcHIyckxZs+ebRhGpEnCKaecYrRt29Zwu91GTk6O8eKLLzZ4HSIi0rgshnHAA9oiIiIiIiKtmNYEiYiIiIhITFEIEhERERGRmKIQJCIiIiIiMUUhSEREREREYopCkIiIiIiIxBSFIBERERERiSkKQSIiIiIiElMUgkREREREJKYoBImIiIiISExRCBIRERERkZiiECQiIiIiIjHl/wFttAD0tUCgeQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0kAAAIjCAYAAADWYVDIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB1TklEQVR4nO3deXwU9f3H8ffsJtncCYScEO77VAEpWhEB5bAoStVarOBRq4K3/SlVEakVq7ZaUVGrBa2iFitUrYqAgEdFAUVQEAG5BEK4cpJzd35/7O5kNwkQQpLZJK/n47GP3Z2d3f3s7OR4z/cYwzRNUwAAAAAASZLD7gIAAAAAIJQQkgAAAAAgACEJAAAAAAIQkgAAAAAgACEJAAAAAAIQkgAAAAAgACEJAAAAAAIQkgAAAAAgACEJAAAAAAIQkgAgBEyaNEnt27ev1XOnT58uwzDqtqAQs337dhmGoblz5zb4exuGoenTp1v3586dK8MwtH379uM+t3379po0aVKd1nMy+woAoGYISQBwDIZh1OiyfPlyu0tt9m6++WYZhqEtW7YcdZ177rlHhmFo3bp1DVjZiduzZ4+mT5+utWvX2l2KxR9UH3vsMbtLAYB6F2Z3AQAQyv75z38G3X/55Ze1ePHiKst79OhxUu/z97//XR6Pp1bPvffee3X33Xef1Ps3BRMmTNCsWbM0b948TZs2rdp1XnvtNfXp00d9+/at9fv85je/0a9+9Su5XK5av8bx7NmzRw888IDat2+vU045Jeixk9lXAAA1Q0gCgGO44oorgu6vXLlSixcvrrK8siNHjig6OrrG7xMeHl6r+iQpLCxMYWH8Oh80aJA6d+6s1157rdqQ9Pnnn2vbtm16+OGHT+p9nE6nnE7nSb3GyTiZfQUAUDN0twOAkzR06FD17t1ba9as0ZAhQxQdHa0//OEPkqT//Oc/Ov/885WRkSGXy6VOnTrpj3/8o9xud9BrVB5nEti16fnnn1enTp3kcrk0cOBArVq1Kui51Y1JMgxDU6ZM0cKFC9W7d2+5XC716tVLH3zwQZX6ly9frgEDBigyMlKdOnXSc889V+NxTp988okuueQStW3bVi6XS5mZmbrttttUVFRU5fPFxsZq9+7dGjdunGJjY5WcnKw777yzyrbIycnRpEmTlJCQoMTERE2cOFE5OTnHrUXytiZ9//33+uqrr6o8Nm/ePBmGocsvv1ylpaWaNm2a+vfvr4SEBMXExOiss87SsmXLjvse1Y1JMk1TDz74oNq0aaPo6Gidc845+u6776o899ChQ7rzzjvVp08fxcbGKj4+XqNHj9Y333xjrbN8+XINHDhQknTVVVdZXTr947GqG5NUWFioO+64Q5mZmXK5XOrWrZsee+wxmaYZtN6J7Be1lZ2drWuuuUapqamKjIxUv3799NJLL1VZ7/XXX1f//v0VFxen+Ph49enTR3/729+sx8vKyvTAAw+oS5cuioyMVFJSkn7+859r8eLFdVYrABwNhx4BoA4cPHhQo0eP1q9+9StdccUVSk1NleT9hzo2Nla33367YmNj9dFHH2natGnKy8vTo48+etzXnTdvnvLz8/W73/1OhmHokUce0cUXX6wff/zxuC0Kn376qd566y3deOONiouL05NPPqnx48dr586dSkpKkiR9/fXXGjVqlNLT0/XAAw/I7XZrxowZSk5OrtHnnj9/vo4cOaIbbrhBSUlJ+vLLLzVr1iz99NNPmj9/ftC6brdbI0eO1KBBg/TYY49pyZIl+stf/qJOnTrphhtukOQNGxdeeKE+/fRTXX/99erRo4cWLFigiRMn1qieCRMm6IEHHtC8efN02mmnBb33v/71L5111llq27atDhw4oBdeeEGXX365fvvb3yo/P18vvviiRo4cqS+//LJKF7fjmTZtmh588EGNGTNGY8aM0VdffaXzzjtPpaWlQev9+OOPWrhwoS655BJ16NBB+/bt03PPPaezzz5bGzZsUEZGhnr06KEZM2Zo2rRpuu6663TWWWdJks4444xq39s0TV1wwQVatmyZrrnmGp1yyilatGiRfv/732v37t16/PHHg9avyX5RW0VFRRo6dKi2bNmiKVOmqEOHDpo/f74mTZqknJwc3XLLLZKkxYsX6/LLL9fw4cP15z//WZK0ceNGffbZZ9Y606dP18yZM3Xttdfq9NNPV15enlavXq2vvvpK55577knVCQDHZQIAamzy5Mlm5V+dZ599tinJfPbZZ6usf+TIkSrLfve735nR0dFmcXGxtWzixIlmu3btrPvbtm0zJZlJSUnmoUOHrOX/+c9/TEnmO++8Yy27//77q9QkyYyIiDC3bNliLfvmm29MSeasWbOsZWPHjjWjo6PN3bt3W8s2b95shoWFVXnN6lT3+WbOnGkahmHu2LEj6PNJMmfMmBG07qmnnmr279/fur9w4UJTkvnII49Yy8rLy82zzjrLlGTOmTPnuDUNHDjQbNOmjel2u61lH3zwgSnJfO6556zXLCkpCXre4cOHzdTUVPPqq68OWi7JvP/++637c+bMMSWZ27ZtM03TNLOzs82IiAjz/PPPNz0ej7XeH/7wB1OSOXHiRGtZcXFxUF2m6f2uXS5X0LZZtWrVUT9v5X3Fv80efPDBoPV++ctfmoZhBO0DNd0vquPfJx999NGjrvPEE0+YksxXXnnFWlZaWmoOHjzYjI2NNfPy8kzTNM1bbrnFjI+PN8vLy4/6Wv369TPPP//8Y9YEAPWF7nYAUAdcLpeuuuqqKsujoqKs2/n5+Tpw4IDOOussHTlyRN9///1xX/eyyy5TixYtrPv+VoUff/zxuM8dMWKEOnXqZN3v27ev4uPjree63W4tWbJE48aNU0ZGhrVe586dNXr06OO+vhT8+QoLC3XgwAGdccYZMk1TX3/9dZX1r7/++qD7Z511VtBnee+99xQWFma1LEneMUA33XRTjeqRvOPIfvrpJ3388cfWsnnz5ikiIkKXXHKJ9ZoRERGSJI/Ho0OHDqm8vFwDBgyotqvesSxZskSlpaW66aabgroo3nrrrVXWdblccji8f3rdbrcOHjyo2NhYdevW7YTf1++9996T0+nUzTffHLT8jjvukGmaev/994OWH2+/OBnvvfee0tLSdPnll1vLwsPDdfPNN6ugoEArVqyQJCUmJqqwsPCYXecSExP13XffafPmzSddFwCcKEISANSB1q1bW/90B/ruu+900UUXKSEhQfHx8UpOTrYmfcjNzT3u67Zt2zbovj8wHT58+ISf63++/7nZ2dkqKipS586dq6xX3bLq7Ny5U5MmTVLLli2tcUZnn322pKqfLzIysko3vsB6JGnHjh1KT09XbGxs0HrdunWrUT2S9Ktf/UpOp1Pz5s2TJBUXF2vBggUaPXp0UOB86aWX1LdvX2u8S3Jysv773//W6HsJtGPHDklSly5dgpYnJycHvZ/kDWSPP/64unTpIpfLpVatWik5OVnr1q074fcNfP+MjAzFxcUFLffPuOivz+94+8XJ2LFjh7p06WIFwaPVcuONN6pr164aPXq02rRpo6uvvrrKuKgZM2YoJydHXbt2VZ8+ffT73/8+5KduB9B0EJIAoA4Etqj45eTk6Oyzz9Y333yjGTNm6J133tHixYutMRg1mcb5aLOomZUG5Nf1c2vC7Xbr3HPP1X//+1/dddddWrhwoRYvXmxNMFD58zXUjHApKSk699xz9e9//1tlZWV65513lJ+frwkTJljrvPLKK5o0aZI6deqkF198UR988IEWL16sYcOG1ev02g899JBuv/12DRkyRK+88ooWLVqkxYsXq1evXg02rXd97xc1kZKSorVr1+rtt9+2xlONHj06aOzZkCFDtHXrVv3jH/9Q79699cILL+i0007TCy+80GB1Ami+mLgBAOrJ8uXLdfDgQb311lsaMmSItXzbtm02VlUhJSVFkZGR1Z589VgnZPVbv369fvjhB7300ku68sorreUnM/tYu3bttHTpUhUUFAS1Jm3atOmEXmfChAn64IMP9P7772vevHmKj4/X2LFjrcfffPNNdezYUW+99VZQF7n777+/VjVL0ubNm9WxY0dr+f79+6u0zrz55ps655xz9OKLLwYtz8nJUatWraz7NZlZMPD9lyxZovz8/KDWJH93Tn99DaFdu3Zat26dPB5PUGtSdbVERERo7NixGjt2rDwej2688UY999xzuu+++6yWzJYtW+qqq67SVVddpYKCAg0ZMkTTp0/Xtdde22CfCUDzREsSANQT/xH7wCP0paWleuaZZ+wqKYjT6dSIESO0cOFC7dmzx1q+ZcuWKuNYjvZ8KfjzmaYZNI3ziRozZozKy8s1e/Zsa5nb7dasWbNO6HXGjRun6OhoPfPMM3r//fd18cUXKzIy8pi1f/HFF/r8889PuOYRI0YoPDxcs2bNCnq9J554osq6TqezSovN/PnztXv37qBlMTExklSjqc/HjBkjt9utp556Kmj5448/LsMwajy+rC6MGTNGWVlZeuONN6xl5eXlmjVrlmJjY62umAcPHgx6nsPhsE7wW1JSUu06sbGx6ty5s/U4ANQnWpIAoJ6cccYZatGihSZOnKibb75ZhmHon//8Z4N2azqe6dOn68MPP9SZZ56pG264wfpnu3fv3lq7du0xn9u9e3d16tRJd955p3bv3q34+Hj9+9//PqmxLWPHjtWZZ56pu+++W9u3b1fPnj311ltvnfB4ndjYWI0bN84alxTY1U6SfvGLX+itt97SRRddpPPPP1/btm3Ts88+q549e6qgoOCE3st/vqeZM2fqF7/4hcaMGaOvv/5a77//flDrkP99Z8yYoauuukpnnHGG1q9fr1dffTWoBUqSOnXqpMTERD377LOKi4tTTEyMBg0apA4dOlR5/7Fjx+qcc87RPffco+3bt6tfv3768MMP9Z///Ee33npr0CQNdWHp0qUqLi6usnzcuHG67rrr9Nxzz2nSpElas2aN2rdvrzfffFOfffaZnnjiCaul69prr9WhQ4c0bNgwtWnTRjt27NCsWbN0yimnWOOXevbsqaFDh6p///5q2bKlVq9erTfffFNTpkyp088DANUhJAFAPUlKStK7776rO+64Q/fee69atGihK664QsOHD9fIkSPtLk+S1L9/f73//vu68847dd999ykzM1MzZszQxo0bjzv7Xnh4uN555x3dfPPNmjlzpiIjI3XRRRdpypQp6tevX63qcTgcevvtt3XrrbfqlVdekWEYuuCCC/SXv/xFp5566gm91oQJEzRv3jylp6dr2LBhQY9NmjRJWVlZeu6557Ro0SL17NlTr7zyiubPn6/ly5efcN0PPvigIiMj9eyzz2rZsmUaNGiQPvzwQ51//vlB6/3hD39QYWGh5s2bpzfeeEOnnXaa/vvf/+ruu+8OWi88PFwvvfSSpk6dquuvv17l5eWaM2dOtSHJv82mTZumN954Q3PmzFH79u316KOP6o477jjhz3I8H3zwQbUnn23fvr169+6t5cuX6+6779ZLL72kvLw8devWTXPmzNGkSZOsda+44go9//zzeuaZZ5STk6O0tDRddtllmj59utVN7+abb9bbb7+tDz/8UCUlJWrXrp0efPBB/f73v6/zzwQAlRlmKB3SBACEhHHjxjH9MgCg2WJMEgA0c0VFRUH3N2/erPfee09Dhw61pyAAAGxGSxIANHPp6emaNGmSOnbsqB07dmj27NkqKSnR119/XeXcPwAANAeMSQKAZm7UqFF67bXXlJWVJZfLpcGDB+uhhx4iIAEAmi1akgAAAAAgAGOSAAAAACAAIQkAAAAAAjT5MUkej0d79uxRXFycDMOwuxwAAAAANjFNU/n5+crIyLDOy1adJh+S9uzZo8zMTLvLAAAAABAidu3apTZt2hz18SYfkuLi4iR5N0R8fLzN1QAAAACwS15enjIzM62McDRNPiT5u9jFx8cTkgAAAAAcdxgOEzcAAAAAQABCEgAAAAAEICQBAAAAQIAmPyYJAAAAocU0TZWXl8vtdttdCpoYp9OpsLCwkz71DyEJAAAADaa0tFR79+7VkSNH7C4FTVR0dLTS09MVERFR69cgJAEAAKBBeDwebdu2TU6nUxkZGYqIiDjpI/6An2maKi0t1f79+7Vt2zZ16dLlmCeMPRZCEgAAABpEaWmpPB6PMjMzFR0dbXc5aIKioqIUHh6uHTt2qLS0VJGRkbV6HSZuAAAAQIOq7dF9oCbqYv9iDwUAAACAAIQkAAAAAAhASAIAAABs0L59ez3xxBM1Xn/58uUyDEM5OTn1VhO8CEkAAADAMRiGcczL9OnTa/W6q1at0nXXXVfj9c844wzt3btXCQkJtXq/miKMMbsdAAAAcEx79+61br/xxhuaNm2aNm3aZC2LjY21bpumKbfbrbCw4/+bnZycfEJ1REREKC0t7YSeg9qhJQkAAAC2MU1TR0rLbbmYplmjGtPS0qxLQkKCDMOw7n///feKi4vT+++/r/79+8vlcunTTz/V1q1bdeGFFyo1NVWxsbEaOHCglixZEvS6lbvbGYahF154QRdddJGio6PVpUsXvf3229bjlVt45s6dq8TERC1atEg9evRQbGysRo0aFRTqysvLdfPNNysxMVFJSUm66667NHHiRI0bN67W39nhw4d15ZVXqkWLFoqOjtbo0aO1efNm6/EdO3Zo7NixatGihWJiYtSrVy+999571nMnTJig5ORkRUVFqUuXLpozZ06ta6kvtCQBAADANkVlbvWctsiW994wY6SiI+rm3+G7775bjz32mDp27KgWLVpo165dGjNmjP70pz/J5XLp5Zdf1tixY7Vp0ya1bdv2qK/zwAMP6JFHHtGjjz6qWbNmacKECdqxY4datmxZ7fpHjhzRY489pn/+859yOBy64oordOedd+rVV1+VJP35z3/Wq6++qjlz5qhHjx7629/+poULF+qcc86p9WedNGmSNm/erLffflvx8fG66667NGbMGG3YsEHh4eGaPHmySktL9fHHHysmJkYbNmywWtvuu+8+bdiwQe+//75atWqlLVu2qKioqNa11BdCEgAAAHCSZsyYoXPPPde637JlS/Xr18+6/8c//lELFizQ22+/rSlTphz1dSZNmqTLL79ckvTQQw/pySef1JdffqlRo0ZVu35ZWZmeffZZderUSZI0ZcoUzZgxw3p81qxZmjp1qi666CJJ0lNPPWW16tSGPxx99tlnOuOMMyRJr776qjIzM7Vw4UJdcskl2rlzp8aPH68+ffpIkjp27Gg9f+fOnTr11FM1YMAASd7WtFBka0iaPXu2Zs+ere3bt0uSevXqpWnTpmn06NGSpKFDh2rFihVBz/nd736nZ599tqFLPWmmaerzHw9qT06xftE3XZHhTrtLAgAAsF1UuFMbZoy07b3riv+ffr+CggJNnz5d//3vf7V3716Vl5erqKhIO3fuPObr9O3b17odExOj+Ph4ZWdnH3X96OhoKyBJUnp6urV+bm6u9u3bp9NPP9163Ol0qn///vJ4PCf0+fw2btyosLAwDRo0yFqWlJSkbt26aePGjZKkm2++WTfccIM+/PBDjRgxQuPHj7c+1w033KDx48frq6++0nnnnadx48ZZYSuU2DomqU2bNnr44Ye1Zs0arV69WsOGDdOFF16o7777zlrnt7/9rfbu3WtdHnnkERsrPjm/fWm17pz/jXbnhF6TIgAAgB0Mw1B0RJgtF8Mw6uxzxMTEBN2/8847tWDBAj300EP65JNPtHbtWvXp00elpaXHfJ3w8PAq2+dYgaa69Ws61qq+XHvttfrxxx/1m9/8RuvXr9eAAQM0a9YsSdLo0aO1Y8cO3XbbbdqzZ4+GDx+uO++809Z6q2NrSBo7dqzGjBmjLl26qGvXrvrTn/6k2NhYrVy50lonOjo6aLBcfHy8jRXXnmEYykiMkiTtISQBAAA0aZ999pkmTZqkiy66SH369FFaWprVe6qhJCQkKDU1VatWrbKWud1uffXVV7V+zR49eqi8vFxffPGFtezgwYPatGmTevbsaS3LzMzU9ddfr7feekt33HGH/v73v1uPJScna+LEiXrllVf0xBNP6Pnnn691PfUlZMYkud1uzZ8/X4WFhRo8eLC1/NVXX9Urr7yitLQ0jR07Vvfdd5+io6OP+jolJSUqKSmx7ufl5dVr3SciIzFKm7MLCEkAAABNXJcuXfTWW29p7NixMgxD9913X627uJ2Mm266STNnzlTnzp3VvXt3zZo1S4cPH65RK9r69esVFxdn3TcMQ/369dOFF16o3/72t3ruuecUFxenu+++W61bt9aFF14oSbr11ls1evRode3aVYcPH9ayZcvUo0cPSdK0adPUv39/9erVSyUlJXr33Xetx0KJ7SFp/fr1Gjx4sIqLixUbG6sFCxZYKfTXv/612rVrp4yMDK1bt0533XWXNm3apLfeeuuorzdz5kw98MADDVX+CfG3JO3OKba5EgAAANSnv/71r7r66qt1xhlnqFWrVrrrrrtsOXh/1113KSsrS1deeaWcTqeuu+46jRw5Uk7n8cdjDRkyJOi+0+lUeXm55syZo1tuuUW/+MUvVFpaqiFDhui9996zuv653W5NnjxZP/30k+Lj4zVq1Cg9/vjjkrznepo6daq2b9+uqKgonXXWWXr99dfr/oOfJMO0udNiaWmpdu7cqdzcXL355pt64YUXtGLFiqDmOr+PPvpIw4cP15YtW4IGqAWqriUpMzNTubm5tnfVe+qjzXrswx/0y/5t9Ngl/Y7/BAAAgCakuLhY27ZtU4cOHRQZGWl3Oc2Sx+NRjx49dOmll+qPf/yj3eXUi2PtZ3l5eUpISDhuNrC9JSkiIkKdO3eWJPXv31+rVq3S3/72Nz333HNV1vXPonGskORyueRyueqv4JPAmCQAAAA0pB07dujDDz/U2WefrZKSEj311FPatm2bfv3rX9tdWkizdeKG6ng8nqCWoEBr166V5J3asDEiJAEAAKAhORwOzZ07VwMHDtSZZ56p9evXa8mSJSE5DiiU2NqSNHXqVI0ePVpt27ZVfn6+5s2bp+XLl2vRokXaunWr5s2bpzFjxigpKUnr1q3TbbfdpiFDhgTNH9+YtPaHpNxieTymHI66m3YSAAAAqCwzM1OfffaZ3WU0OraGpOzsbF155ZXau3evEhIS1LdvXy1atEjnnnuudu3apSVLluiJJ55QYWGhMjMzNX78eN177712lnxSUuMjZRhSablHBwtLlRwXmt0CAQAAgObM1pD04osvHvWxzMxMrVixogGrqX8RYQ6lxLm0L69Ee3KKCEkAAABACAq5MUlNHeOSAAAAgNBGSGpgFedKIiQBAAAAoYiQ1FBMU/rXRE3dfZNaKVd7OKEsAAAAEJJsP09Ss2EY0s7P1aZwn1KNQ3S3AwAAAEIULUkNKS5NkpRqHNaeXEISAABAczJ06FDdeuut1v327dvriSeeOOZzDMPQwoULT/q96+p1mgtCUkOK9YakFCOHliQAAIBGYuzYsRo1alS1j33yyScyDEPr1q074dddtWqVrrvuupMtL8j06dN1yimnVFm+d+9ejR49uk7fq7K5c+cqMTGxXt+joRCSGlJcqiQpRTk6UFCq4jK3zQUBAADgeK655hotXrxYP/30U5XH5syZowEDBqhv374n/LrJycmKjo6uixKPKy0tTS4Xp5+pKUJSQ/K1JGU4cyVJe3OZvAEAADRzpimVFtpzMc0alfiLX/xCycnJmjt3btDygoICzZ8/X9dcc40OHjyoyy+/XK1bt1Z0dLT69Omj11577ZivW7m73ebNmzVkyBBFRkaqZ8+eWrx4cZXn3HXXXeratauio6PVsWNH3XfffSorK5Pkbcl54IEH9M0338gwDBmGYdVcubvd+vXrNWzYMEVFRSkpKUnXXXedCgoKrMcnTZqkcePG6bHHHlN6erqSkpI0efJk671qY+fOnbrwwgsVGxur+Ph4XXrppdq3b5/1+DfffKNzzjlHcXFxio+PV//+/bV69WpJ0o4dOzR27Fi1aNFCMTEx6tWrl957771a13I8TNzQkHxjkjIjcqVS77mSOrSKsbkoAAAAG5UdkR7KsOe9/7BHijj+/2JhYWG68sorNXfuXN1zzz0yDEOSNH/+fLndbl1++eUqKChQ//79dddddyk+Pl7//e9/9Zvf/EadOnXS6aefftz38Hg8uvjii5WamqovvvhCubm5QeOX/OLi4jR37lxlZGRo/fr1+u1vf6u4uDj93//9ny677DJ9++23+uCDD7RkyRJJUkJCQpXXKCws1MiRIzV48GCtWrVK2dnZuvbaazVlypSgILhs2TKlp6dr2bJl2rJliy677DKdcsop+u1vf3vcz1Pd5/MHpBUrVqi8vFyTJ0/WZZddpuXLl0uSJkyYoFNPPVWzZ8+W0+nU2rVrFR4eLkmaPHmySktL9fHHHysmJkYbNmxQbGzsCddRU4SkhuQLSWkOb0sS50oCAABoHK6++mo9+uijWrFihYYOHSrJ29Vu/PjxSkhIUEJCgu68805r/ZtuukmLFi3Sv/71rxqFpCVLluj777/XokWLlJHhDY0PPfRQlXFE9957r3W7ffv2uvPOO/X666/r//7v/xQVFaXY2FiFhYUpLS3tqO81b948FRcX6+WXX1ZMjDckPvXUUxo7dqz+/Oc/KzXVO0SkRYsWeuqpp+R0OtW9e3edf/75Wrp0aa1C0tKlS7V+/Xpt27ZNmZmZkqSXX35ZvXr10qpVqzRw4EDt3LlTv//979W9e3dJUpcuXazn79y5U+PHj1efPn0kSR07djzhGk4EIakh+brbJZmHJYnJGwAAAMKjvS06dr13DXXv3l1nnHGG/vGPf2jo0KHasmWLPvnkE82YMUOS5Ha79dBDD+lf//qXdu/erdLSUpWUlNR4zNHGjRuVmZlpBSRJGjx4cJX13njjDT355JPaunWrCgoKVF5ervj4+Bp/Dv979evXzwpIknTmmWfK4/Fo06ZNVkjq1auXnE6ntU56errWr19/Qu8V+J6ZmZlWQJKknj17KjExURs3btTAgQN1++2369prr9U///lPjRgxQpdccok6deokSbr55pt1ww036MMPP9SIESM0fvz4Wo0DqynGJDUk38QNceUHZchDSAIAADAMb5c3Oy6+bnM1dc011+jf//638vPzNWfOHHXq1Elnn322JOnRRx/V3/72N911111atmyZ1q5dq5EjR6q0tLTONtXnn3+uCRMmaMyYMXr33Xf19ddf65577qnT9wjk7+rmZxiGPB5PvbyX5J2Z77vvvtP555+vjz76SD179tSCBQskSddee61+/PFH/eY3v9H69es1YMAAzZo1q95qISQ1pFhvSHKabrVQgfbkMHEDAABAY3HppZfK4XBo3rx5evnll3X11Vdb45M+++wzXXjhhbriiivUr18/dezYUT/88EONX7tHjx7atWuX9u7day1buXJl0Dr/+9//1K5dO91zzz0aMGCAunTpoh07dgStExERIbf72DMo9+jRQ998840KCwutZZ999pkcDoe6detW45pPhP/z7dq1y1q2YcMG5eTkqGfPntayrl276rbbbtOHH36oiy++WHPmzLEey8zM1PXXX6+33npLd9xxh/7+97/XS60SIalhOcOl6FaSfCeUpSUJAACg0YiNjdVll12mqVOnau/evZo0aZL1WJcuXbR48WL973//08aNG/W73/0uaOa24xkxYoS6du2qiRMn6ptvvtEnn3yie+65J2idLl26aOfOnXr99de1detWPfnkk1ZLi1/79u21bds2rV27VgcOHFBJSUmV95owYYIiIyM1ceJEffvtt1q2bJluuukm/eY3v7G62tWW2+3W2rVrgy4bN27UiBEj1KdPH02YMEFfffWVvvzyS1155ZU6++yzNWDAABUVFWnKlClavny5duzYoc8+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vvzyS7tLalI+/vhjjR07VhkZGTIMQwsXLgx63DRNTZs2Tenp6YqKitKIESO0efNme4ptImbOnKmBAwcqLi5OKSkpGjdunDZt2hS0TnFxsSZPnqykpCTFxsZq/Pjx2rdvn00VNw2zZ89W3759rRMKDh48WO+//771ONu8YTz88MMyDEO33nqrtYxtX/emT58uwzCCLt27d7ceZ5vXn927d+uKK65QUlKSoqKi1KdPH61evdp6nL+rda99+/ZV9nfDMDR58mRJ7O8NiZDUQN544w3dfvvtuv/++/XVV1+pX79+GjlypLKzs+0urckoLCxUv3799PTTT1f7+COPPKInn3xSzz77rL744gvFxMRo5MiRKi4ubuBKm44VK1Zo8uTJWrlypRYvXqyysjKdd955KiwstNa57bbb9M4772j+/PlasWKF9uzZo4svvtjGqhu/Nm3a6OGHH9aaNWu0evVqDRs2TBdeeKG+++47SWzzhrBq1So999xz6tu3b9Bytn396NWrl/bu3WtdPv30U+sxtnn9OHz4sM4880yFh4fr/fff14YNG/SXv/xFLVq0sNbh72rdW7VqVdC+vnjxYknSJZdcIon9vUGZaBCnn366OXnyZOu+2+02MzIyzJkzZ9pYVdMlyVywYIF13+PxmGlpaeajjz5qLcvJyTFdLpf52muv2VBh05SdnW1KMlesWGGapncbh4eHm/Pnz7fW2bhxoynJ/Pzzz+0qs0lq0aKF+cILL7DNG0B+fr7ZpUsXc/HixebZZ59t3nLLLaZpsr/Xl/vvv9/s169ftY+xzevPXXfdZf785z8/6uP8XW0Yt9xyi9mpUyfT4/GwvzcwWpIaQGlpqdasWaMRI0ZYyxwOh0aMGKHPP//cxsqaj23btikrKyvoO0hISNCgQYP4DupQbm6uJKlly5aSpDVr1qisrCxou3fv3l1t27Zlu9cRt9ut119/XYWFhRo8eDDbvAFMnjxZ559/ftA2ltjf69PmzZuVkZGhjh07asKECdq5c6cktnl9evvttzVgwABdcsklSklJ0amnnqq///3v1uP8Xa1/paWleuWVV3T11VfLMAz29wZGSGoABw4ckNvtVmpqatDy1NRUZWVl2VRV8+LfznwH9cfj8ejWW2/VmWeeqd69e0vybveIiAglJiYGrct2P3nr169XbGysXC6Xrr/+ei1YsEA9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AAB7MCYJANCorFy5ssr9Hj16SJJ69Oihb775RoWFhdbjn332mRwOh7p166a4uDi1b99eS5cuPakakpOTNXHiRL3yyit64okn9Pzzz5/U6wEAQgstSQCAkFJSUqKsrKygZWFhYdbkCPPnz9eAAQP085//XK+++qq+/PJLvfjii5KkCRMm6P7779fEiRM1ffp07d+/XzfddJN+85vfKDU1VZI0ffp0XX/99UpJSdHo0aOVn5+vzz77TDfddFON6ps2bZr69++vXr16qaSkRO+++64V0gAATQMhCQAQUj744AOlp6cHLevWrZu+//57Sd6Z515//XXdeOONSk9P12uvvaaePXtKkqKjo7Vo0SLdcsstGjhwoKKjozV+/Hj99a9/tV5r4sSJKi4u1uOPP64777xTrVq10i9/+csa1xcREaGpU6dq+/btioqK0llnnaXXX3+9Dj45ACBUMLsdAKDRMAxDCxYs0Lhx4+wuBQDQhDEmCQAAAAACEJIAAAAAIABjkgAAjQY9xAEADYGWJAAAAAAIQEgCAAAAgACEJAAAAAAIQEgCAAAAgACEJAAAAAAIQEgCAAAAgACEJAAAAAAIQEgCAAAAgAD/D1odPqCzFSOvAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10, 6))\n", + "plt.scatter(val_true_scores, val_predictions, alpha=0.5)\n", + "plt.plot([val_true_scores.min(), val_true_scores.max()], [val_true_scores.min(), val_true_scores.max()], 'r--', lw=2)\n", + "plt.xlabel(\"Actual Scores\")\n", + "plt.ylabel(\"Predicted Scores\")\n", + "plt.title(\"Predicted vs Actual Anime Scores\")\n", + "plt.show()\n", + "\n", + "plt.figure(figsize=(10, 6))\n", + "plt.plot(train_losses, label='Training Loss')\n", + "plt.plot(val_losses, label='Validation Loss')\n", + "plt.xlabel(\"Epochs\")\n", + "plt.ylabel(\"Loss\")\n", + "plt.title(\"Training and Validation Loss\")\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "da17265a", + "metadata": {}, + "source": [ + "get result" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "21bdb5a9", + "metadata": {}, + "outputs": [], + "source": [ + "def get_recommendations(input_anime, top_n=10):\n", + " model.eval()\n", + " with torch.no_grad():\n", + " input_with_id = pd.merge(input_anime, anime_df[['MAL_ID', 'Name']], left_on='Title', right_on='Name', how='left')\n", + " input_features = pd.merge(input_with_id, anime_features, on='MAL_ID', how='left')\n", + " feature_columns = ['Score', 'Episodes', 'Members', 'Popularity', 'Ranked', 'genre_count', 'synopsis_length']\n", + " input_features = input_features[feature_columns]\n", + "\n", + " for col in feature_columns:\n", + " if input_features[col].isnull().any():\n", + " input_features[col].fillna(input_features[col].median(), inplace=True)\n", + " \n", + " input_scaled = scaler.transform(input_features)\n", + " input_tensor = torch.FloatTensor(input_scaled).to(device)\n", + " predicted_ratings = model(input_tensor).cpu().numpy().flatten()\n", + "\n", + " input_anime['Predicted_Rating'] = predicted_ratings\n", + " recommendations = input_anime.sort_values('Predicted_Rating', ascending=False).head(top_n)\n", + " return recommendations" + ] + }, + { + "cell_type": "markdown", + "id": "31322025", + "metadata": {}, + "source": [ + "User input" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "27c34fa3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Title Rating\n", + "0 Boku dake ga Inai Machi 10.0\n", + "1 Violet Evergarden 9.5\n", + "2 Goblin Slayer 6.0\n", + "3 Berserk 8.0\n", + "4 Shingeki no Kyojin 7.0\n", + "5 Tokyo Ghoul 6.5\n", + "6 Orange 6.0\n", + "7 Death Parade 8.0\n", + "8 Death Note 7.5\n", + "9 Bungou Stray Dogs 7.5\n", + "10 Tenki no Ko 8.0\n", + "11 Kimi no Na wa. 8.0\n", + "12 Kimi no Suizou wo Tabetai 8.5\n", + "13 Mononoke Hime 7.5\n", + "14 Sen to Chihiro no Kamikakushi 7.5\n", + "15 Koe no Katachi 8.5\n", + "16 Ao Haru Ride 5.5\n", + "17 Toki wo Kakeru Shoujo 7.0\n", + "18 Another 7.5\n", + "19 Kimetsu no Yaiba 7.0\n", + "20 Shigatsu wa Kimi no Uso 8.0\n", + "21 Byousoku 5 Centimeter 6.0\n", + "22 Kokoro ga Sakebitagatterunda. 7.5\n", + "23 Schick x Evangelion 5.0\n" + ] + } + ], + "source": [ + "userInput = [\n", + " {'Title': 'Boku dake ga Inai Machi', 'Rating': 10.0},\n", + " {'Title': 'Violet Evergarden', 'Rating': 9.5},\n", + " {'Title': 'Goblin Slayer', 'Rating': 6.0},\n", + " {'Title': 'Berserk', 'Rating': 8.0},\n", + " {'Title': 'Shingeki no Kyojin', 'Rating': 7.0},\n", + " {'Title': 'Tokyo Ghoul', 'Rating': 6.5},\n", + " {'Title': 'Orange', 'Rating': 6.0},\n", + " {'Title': 'Death Parade', 'Rating': 8.0},\n", + " {'Title': 'Death Note', 'Rating': 7.5},\n", + " {'Title': 'Bungou Stray Dogs', 'Rating': 7.5},\n", + " {'Title': 'Tenki no Ko', 'Rating': 8.0},\n", + " {'Title': 'Kimi no Na wa.', 'Rating': 8.0},\n", + " {'Title': 'Kimi no Suizou wo Tabetai', 'Rating': 8.5},\n", + " {'Title': 'Mononoke Hime', 'Rating': 7.5},\n", + " {'Title': 'Sen to Chihiro no Kamikakushi', 'Rating': 7.5},\n", + " {'Title': 'Koe no Katachi', 'Rating': 8.5},\n", + " {'Title': 'Ao Haru Ride', 'Rating': 5.5},\n", + " {'Title': 'Toki wo Kakeru Shoujo', 'Rating': 7.0},\n", + " {'Title': 'Another', 'Rating': 7.5},\n", + " {'Title': 'Kimetsu no Yaiba', 'Rating': 7.0},\n", + " {'Title': 'Shigatsu wa Kimi no Uso', 'Rating': 8.0},\n", + " {'Title': 'Byousoku 5 Centimeter', 'Rating': 6.0},\n", + " {'Title': 'Kokoro ga Sakebitagatterunda.', 'Rating': 7.5},\n", + " {'Title': 'Schick x Evangelion', 'Rating': 5.0}\n", + "]\n", + "\n", + "inputAnime = pd.DataFrame(userInput)\n", + "print(inputAnime)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "e457680c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Top 10 Recommended Anime:\n", + " Title Predicted_Rating\n", + "15 Koe no Katachi 8.676968\n", + "11 Kimi no Na wa. 8.668777\n", + "8 Death Note 8.655032\n", + "4 Shingeki no Kyojin 8.560674\n", + "14 Sen to Chihiro no Kamikakushi 8.536744\n", + "20 Shigatsu wa Kimi no Uso 8.446907\n", + "13 Mononoke Hime 8.424243\n", + "1 Violet Evergarden 8.375561\n", + "19 Kimetsu no Yaiba 8.362001\n", + "12 Kimi no Suizou wo Tabetai 8.318801\n" + ] + } + ], + "source": [ + "recommendations = get_recommendations(inputAnime)\n", + "print(\"\\nTop 10 Recommended Anime:\")\n", + "print(recommendations[['Title', 'Predicted_Rating']])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}