diff --git "a/recommendation_module_project/model_(2).ipynb" "b/recommendation_module_project/model_(2).ipynb" new file mode 100644--- /dev/null +++ "b/recommendation_module_project/model_(2).ipynb" @@ -0,0 +1,936 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "id": "uq9k8YYUKjnp" + }, + "outputs": [], + "source": [ + "import os\n", + "import urllib.request\n", + "import zipfile\n", + "import json\n", + "import pandas as pd\n", + "import time\n", + "import torch\n", + "import numpy as np\n", + "import pandas as pd\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torch.optim as optim\n", + "from torch.utils.data import DataLoader, TensorDataset\n", + "from sklearn.model_selection import train_test_split\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.preprocessing import LabelEncoder" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "y1pGv3um_VAV", + "outputId": "64ee7998-f542-4477-a6c3-7444a04a42c8" + }, + "outputs": [], + "source": [ + "# from google.colab import drive\n", + "# drive.mount('/content/drive')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "id": "MrmOyqSn_Y7C" + }, + "outputs": [], + "source": [ + "# prompt: copy a file from another directory to current directory in python code and create folders if needed\n", + "\n", + "import shutil\n", + "import os\n", + "\n", + "def copy_file(src, dst):\n", + " \"\"\"\n", + " Copies a file from src to dst, creating any necessary directories.\n", + "\n", + " Args:\n", + " src: The path to the source file.\n", + " dst: The path to the destination file.\n", + " \"\"\"\n", + " # Create the destination directory if it doesn't exist.\n", + " dst_dir = os.path.dirname(dst)\n", + " if not os.path.exists(dst_dir):\n", + " os.makedirs(dst_dir)\n", + "\n", + " # Copy the file.\n", + " shutil.copy2(src, dst)\n", + "\n", + "# copy_file('/content/drive/MyDrive/rec_data/spotify_million_playlist_dataset.zip', os.getcwd() + '/data/raw/spotify_million_playlist_dataset.zip')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "id": "L5h3Tsa0LIoo" + }, + "outputs": [], + "source": [ + "def unzip_archive(filepath, dir_path):\n", + " with zipfile.ZipFile(f\"{filepath}\", 'r') as zip_ref:\n", + " zip_ref.extractall(dir_path)\n", + "\n", + "unzip_archive(os.getcwd() + '/data/raw/spotify_million_playlist_dataset.zip', os.getcwd() + '/data/raw/playlists')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "id": "JcLT9U2Q_LJw" + }, + "outputs": [], + "source": [ + "import shutil\n", + "\n", + "def make_dir(directory):\n", + " if os.path.exists(directory):\n", + " shutil.rmtree(directory)\n", + " os.makedirs(directory)\n", + " else:\n", + " os.makedirs(directory)\n", + "\n", + "directory = os.getcwd() + '/data/raw/data'\n", + "make_dir(directory)\n", + "directory = os.getcwd() + '/data/processed'\n", + "make_dir(directory)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "id": "fC-0iP1L_LJx" + }, + "outputs": [], + "source": [ + "cols = [\n", + " 'name',\n", + " 'pid',\n", + " 'num_followers',\n", + " 'pos',\n", + " 'artist_name',\n", + " 'track_name',\n", + " 'album_name'\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "qyCujIu8cDGg", + "outputId": "f3b21394-acbc-40ab-d70a-b666acd985e7" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mpd.slice.278000-278999.json\t200/1000\t20.0%" + ] + } + ], + "source": [ + "directory = os.getcwd() + '/data/raw/playlists/data'\n", + "df = pd.DataFrame()\n", + "index = 0\n", + "# Loop through all files in the directory\n", + "for filename in os.listdir(directory):\n", + " # Check if the item is a file (not a subdirectory)\n", + " if os.path.isfile(os.path.join(directory, filename)):\n", + " if filename.find('.json') != -1 :\n", + " index += 1\n", + "\n", + " # Print the filename or perform operations on the file\n", + " print(f'\\r{filename}\\t{index}/1000\\t{((index/1000)*100):.1f}%', end='')\n", + "\n", + " # If you need the full file path, you can use:\n", + " full_path = os.path.join(directory, filename)\n", + "\n", + " with open(full_path, 'r') as file:\n", + " json_data = json.load(file)\n", + "\n", + " temp = pd.DataFrame(json_data['playlists'])\n", + " expanded_df = temp.explode('tracks').reset_index(drop=True)\n", + "\n", + " # Normalize the JSON data\n", + " json_normalized = pd.json_normalize(expanded_df['tracks'])\n", + "\n", + " # Concatenate the original DataFrame with the normalized JSON data\n", + " result = pd.concat([expanded_df.drop(columns=['tracks']), json_normalized], axis=1)\n", + "\n", + " result = result[cols]\n", + "\n", + " df = pd.concat([df, result], axis=0, ignore_index=True)\n", + "\n", + " if index % 50 == 0:\n", + " df.to_parquet(f'{os.getcwd()}/data/raw/data/playlists_{index % 1000}.parquet')\n", + " del df\n", + " df = pd.DataFrame()\n", + " if index % 200 == 0:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "id": "unZ418pc_LJy" + }, + "outputs": [], + "source": [ + "import pyarrow.parquet as pq\n", + "\n", + "def read_parquet_folder(folder_path):\n", + " dataframes = []\n", + " for file in os.listdir(folder_path):\n", + " if file.endswith('.parquet'):\n", + " file_path = os.path.join(folder_path, file)\n", + " df = pd.read_parquet(file_path)\n", + " dataframes.append(df)\n", + "\n", + " return pd.concat(dataframes, ignore_index=True)\n", + "\n", + "folder_path = os.getcwd() + '/data/raw/data'\n", + "df = read_parquet_folder(folder_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "id": "es6n8S3a_LJz" + }, + "outputs": [], + "source": [ + "directory = os.getcwd() + '/data/raw/mappings'\n", + "make_dir(directory)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "id": "Rc2JtdBR_LJz" + }, + "outputs": [], + "source": [ + "def create_ids(df, col, name):\n", + " # Create a dictionary mapping unique values to IDs\n", + " value_to_id = {val: i for i, val in enumerate(df[col].unique())}\n", + "\n", + " # Create a new column with the IDs\n", + " df[f'{name}_id'] = df[col].map(value_to_id)\n", + " df[[f'{name}_id', col]].drop_duplicates().to_csv(os.getcwd() + f'/data/processed/{name}.csv')\n", + "\n", + " return df" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "id": "O6aZ566R_LJ0" + }, + "outputs": [], + "source": [ + "# df = create_ids(df, 'artist_name', 'artist')\n", + "df = create_ids(df, 'pid', 'playlist')\n", + "# df = create_ids(df, 'track_name', 'track')\n", + "# df = create_ids(df, 'album_name', 'album')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "id": "pWWICQvh03KH" + }, + "outputs": [], + "source": [ + "df['song_count'] = df.groupby(['pid','artist_name','album_name'])['track_name'].transform('nunique')\n", + "\n", + "df['playlist_songs'] = df.groupby(['pid'])['pos'].transform('max')\n", + "df['playlist_songs'] += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "id": "F-S7j-gI4I6W" + }, + "outputs": [], + "source": [ + "df['artist_album'] = df[['artist_name', 'album_name']].agg('::'.join, axis=1)\n", + "\n", + "# Step 2: Create a dictionary mapping unique combined values to IDs\n", + "value_to_id = {val: i for i, val in enumerate(df['artist_album'].unique())}\n", + "\n", + "# Step 3: Map these IDs back to the DataFrame\n", + "df['artist_album_id'] = df['artist_album'].map(value_to_id)\n", + "\n", + "df[[f'artist_album_id', 'artist_album', 'artist_name', 'album_name', 'track_name']].drop_duplicates().to_csv(os.getcwd() + f'/data/processed/artist_album.csv')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "id": "q6KHerHG6xZF" + }, + "outputs": [], + "source": [ + "# df = df.groupby(['playlist_id','artist_album','artist_album_id','playlist_songs']).agg({\n", + "# 'song_count': 'sum',\n", + "# 'track_name': '|'.join,\n", + "# 'track_name': '|'.join,\n", + "# }).reset_index()\n", + "df['song_count'] = df.groupby(['playlist_id','artist_album_id'])['song_count'].transform('sum')\n", + "\n", + "# Encode the genres data\n", + "encoder = LabelEncoder()\n", + "encoder.fit(df['track_name'])\n", + "df['track_id'] = encoder.transform(df['track_name'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "r0YprWVe_LJ0" + }, + "outputs": [], + "source": [ + "# df['artist_count'] = df.groupby(['playlist_id','artist_id'])['song_id'].transform('nunique')\n", + "# df['album_count'] = df.groupby(['playlist_id','artist_id','album_id'])['song_id'].transform('nunique')\n", + "# df['song_count'] = df.groupby(['artist_id'])['song_id'].transform('count')" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "id": "D0IkRvv6_LJ1" + }, + "outputs": [], + "source": [ + "# df['artist_percent'] = df['artist_count'] / df['playlist_songs']\n", + "df['song_percent'] = df['song_count'] / df['playlist_songs']\n", + "# df['album_percent'] = df['album_count'] / df['playlist_songs']" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "id": "TnFfvqoSxtW3" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "# Assuming you have a DataFrame 'df' with a column 'column_name'\n", + "df['song_percent'] = 1 / (1 + np.exp(-df['song_percent']))" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "XyURi3ZQ_LJ1", + "outputId": "70e3d126-ab5c-490d-a92e-030f32348969" + }, + "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", + "
playlist_idartist_album_idsong_percent
0000.612336
2010.861591
12020.528540
13030.507142
14040.612336
\n", + "
" + ], + "text/plain": [ + " playlist_id artist_album_id song_percent\n", + "0 0 0 0.612336\n", + "2 0 1 0.861591\n", + "12 0 2 0.528540\n", + "13 0 3 0.507142\n", + "14 0 4 0.612336" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "artists = df.loc[:,['playlist_id','artist_album_id','song_percent']].drop_duplicates()\n", + "artists.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "artists.loc[:,['playlist_id','artist_album_id',]].to_csv(os.getcwd() + '/data/processed/playlists.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "qFqdH4JH_LJ2" + }, + "outputs": [], + "source": [ + "X = artists.loc[:,['playlist_id','artist_album_id',]]\n", + "y = artists.loc[:,'song_percent']\n", + "\n", + "# Split our data into training and test sets\n", + "X_train, X_val, y_train, y_val = train_test_split(X,y,random_state=0, test_size=0.2)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "id": "uEYzNHNb_LJ2" + }, + "outputs": [], + "source": [ + "def prep_dataloaders(X_train,y_train,X_val,y_val,batch_size):\n", + " # Convert training and test data to TensorDatasets\n", + " trainset = TensorDataset(torch.from_numpy(np.array(X_train)).long(),\n", + " torch.from_numpy(np.array(y_train)).float())\n", + " valset = TensorDataset(torch.from_numpy(np.array(X_val)).long(),\n", + " torch.from_numpy(np.array(y_val)).float())\n", + "\n", + " # Create Dataloaders for our training and test data to allow us to iterate over minibatches\n", + " trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)\n", + " valloader = torch.utils.data.DataLoader(valset, batch_size=batch_size, shuffle=False)\n", + "\n", + " return trainloader, valloader\n", + "\n", + "batchsize = 64\n", + "trainloader,valloader = prep_dataloaders(X_train,y_train,X_val,y_val,batchsize)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "TBpWfyOc_LJ2" + }, + "outputs": [], + "source": [ + "class NNColabFiltering(nn.Module):\n", + "\n", + " def __init__(self, n_playlists, n_artists, embedding_dim_users, embedding_dim_items, n_activations, rating_range):\n", + " super().__init__()\n", + " self.user_embeddings = nn.Embedding(num_embeddings=n_playlists,embedding_dim=embedding_dim_users)\n", + " self.item_embeddings = nn.Embedding(num_embeddings=n_artists,embedding_dim=embedding_dim_items)\n", + " self.fc1 = nn.Linear(embedding_dim_users+embedding_dim_items,n_activations)\n", + " self.fc2 = nn.Linear(n_activations,1)\n", + " self.rating_range = rating_range\n", + "\n", + " def forward(self, X):\n", + " # Get embeddings for minibatch\n", + " embedded_users = self.user_embeddings(X[:,0])\n", + " embedded_items = self.item_embeddings(X[:,1])\n", + " # Concatenate user and item embeddings\n", + " embeddings = torch.cat([embedded_users,embedded_items],dim=1)\n", + " # Pass embeddings through network\n", + " preds = self.fc1(embeddings)\n", + " preds = F.relu(preds)\n", + " preds = self.fc2(preds)\n", + " # Scale predicted ratings to target-range [low,high]\n", + " preds = torch.sigmoid(preds) * (self.rating_range[1]-self.rating_range[0]) + self.rating_range[0]\n", + " return preds" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "id": "xEa69rXx_LJ3" + }, + "outputs": [], + "source": [ + "def train_model(model, criterion, optimizer, dataloaders, device, num_epochs=5, scheduler=None):\n", + " from torchmetrics import Precision, Recall\n", + " precision = Precision(task=\"multiclass\") \n", + " recall = Recall(task=\"multiclass\")\n", + " \n", + " model = model.to(device) # Send model to GPU if available\n", + " since = time.time()\n", + "\n", + " costpaths = {'train':[],'val':[]}\n", + "\n", + " for epoch in range(num_epochs):\n", + " print('Epoch {}/{}'.format(epoch, num_epochs - 1))\n", + " print('-' * 10)\n", + "\n", + " # Each epoch has a training and validation phase\n", + " for phase in ['train', 'val']:\n", + " if phase == 'train':\n", + " model.train() # Set model to training mode\n", + " else:\n", + " model.eval() # Set model to evaluate mode\n", + "\n", + " running_loss = 0.0\n", + "\n", + " # Get the inputs and labels, and send to GPU if available\n", + " index = 0\n", + " for (inputs,labels) in dataloaders[phase]:\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device)\n", + "\n", + " # Zero the weight gradients\n", + " optimizer.zero_grad()\n", + "\n", + " # Forward pass to get outputs and calculate loss\n", + " # Track gradient only for training data\n", + " with torch.set_grad_enabled(phase == 'train'):\n", + " outputs = model.forward(inputs).view(-1)\n", + " loss = criterion(outputs, labels)\n", + "\n", + " # Backpropagation to get the gradients with respect to each weight\n", + " # Only if in train\n", + " if phase == 'train':\n", + " loss.backward()\n", + " # Update the weights\n", + " optimizer.step()\n", + " \n", + " elif phase == 'val':\n", + " precision.update(torch.argmax(outputs, dim=1), labels)\n", + " recall.update(torch.argmax(outputs, dim=1), labels)\n", + "\n", + " # Convert loss into a scalar and add it to running_loss\n", + " running_loss += np.sqrt(loss.item()) * labels.size(0)\n", + " print(f'\\r{running_loss} {index} {(index / len(dataloaders[phase]))*100:.2f}%', end='')\n", + " index +=1\n", + "\n", + " # Step along learning rate scheduler when in train\n", + " if (phase == 'train') and (scheduler is not None):\n", + " scheduler.step()\n", + "\n", + " # Calculate and display average loss and accuracy for the epoch\n", + " epoch_loss = running_loss / len(dataloaders[phase].dataset)\n", + " costpaths[phase].append(epoch_loss)\n", + " print('\\n{} loss: {:.4f}'.format(phase, epoch_loss))\n", + "\n", + " time_elapsed = time.time() - since\n", + " print('Training complete in {:.0f}m {:.0f}s'.format(\n", + " time_elapsed // 60, time_elapsed % 60))\n", + " \n", + " precision = precision.compute()\n", + " recall = recall.compute()\n", + " \n", + " return costpaths, precision, recall" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Qp7Rymw0gGk0", + "outputId": "03707b9d-a3ad-4f66-a2a3-76b5ab536479" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0/9\n", + "----------\n", + "195501.146801968 122944 100.00%\n", + "train loss: 0.0248\n", + "48852.63561741841 30736 100.00%\n", + "val loss: 0.0248\n", + "Epoch 1/9\n", + "----------\n", + "195288.86805754591 122944 100.00%\n", + "train loss: 0.0248\n", + "48966.005731308476 30736 100.00%\n", + "val loss: 0.0249\n", + "Epoch 2/9\n", + "----------\n", + "195439.2324995683 122944 100.00%\n", + "train loss: 0.0248\n", + "48904.25250419184 30736 100.00%\n", + "val loss: 0.0249\n", + "Epoch 3/9\n", + "----------\n", + "195491.2448816641 122944 100.00%\n", + "train loss: 0.0248\n", + "48849.583460927424 30736 100.00%\n", + "val loss: 0.0248\n", + "Epoch 4/9\n", + "----------\n", + "195327.8279426158 122944 100.00%\n", + "train loss: 0.0248\n", + "49210.33663306126 30736 100.00%\n", + "val loss: 0.0250\n", + "Epoch 5/9\n", + "----------\n", + "195386.44756754907 122944 100.00%\n", + "train loss: 0.0248\n", + "48912.956418048285 30736 100.00%\n", + "val loss: 0.0249\n", + "Epoch 6/9\n", + "----------\n", + "195286.20941203844 122944 100.00%\n", + "train loss: 0.0248\n", + "49132.61363767462 30736 100.00%\n", + "val loss: 0.0250\n", + "Epoch 7/9\n", + "----------\n", + "195173.57979452162 122944 100.00%\n", + "train loss: 0.0248\n", + "49044.77941022041 30736 100.00%\n", + "val loss: 0.0249\n", + "Epoch 8/9\n", + "----------\n", + "195478.6463696328 122944 100.00%\n", + "train loss: 0.0248\n", + "49083.0811937405 30736 100.00%\n", + "val loss: 0.0250\n", + "Epoch 9/9\n", + "----------\n", + "195325.22169511515 122944 100.00%\n", + "train loss: 0.0248\n", + "49103.96672619534 30736 100.00%\n", + "val loss: 0.0250\n", + "Training complete in 309m 10s\n" + ] + } + ], + "source": [ + "# Train the model\n", + "dataloaders = {'train':trainloader, 'val':valloader}\n", + "n_users = X.loc[:,'playlist_id'].max()+1\n", + "n_items = X.loc[:,'artist_album_id'].max()+1\n", + "model = NNColabFiltering(n_users,n_items,embedding_dim_users=50, embedding_dim_items=50, n_activations = 100,rating_range=[0.,1.])\n", + "criterion = nn.MSELoss()\n", + "lr=0.001\n", + "n_epochs=10\n", + "wd=1e-3\n", + "optimizer = optim.Adam(model.parameters(), lr=lr, weight_decay=wd)\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "\n", + "cost_paths = train_model(model,criterion,optimizer,dataloaders, device,n_epochs, scheduler=None)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "`num_classes` is expected to be `int` but ` was passed.`", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[63], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mtorchmetrics\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Precision, Recall\n\u001b[1;32m----> 2\u001b[0m precision \u001b[38;5;241m=\u001b[39m \u001b[43mPrecision\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmulticlass\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# or \"multiclass\" if applicable\u001b[39;00m\n\u001b[0;32m 3\u001b[0m recall \u001b[38;5;241m=\u001b[39m Recall(task\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmulticlass\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 5\u001b[0m final_precision \u001b[38;5;241m=\u001b[39m precision\u001b[38;5;241m.\u001b[39mcompute()\n", + "File \u001b[1;32mc:\\Users\\keese\\anaconda3\\envs\\term_project\\lib\\site-packages\\torchmetrics\\classification\\precision_recall.py:1012\u001b[0m, in \u001b[0;36mPrecision.__new__\u001b[1;34m(cls, task, threshold, num_classes, num_labels, average, multidim_average, top_k, ignore_index, validate_args, **kwargs)\u001b[0m\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m task \u001b[38;5;241m==\u001b[39m ClassificationTask\u001b[38;5;241m.\u001b[39mMULTICLASS:\n\u001b[0;32m 1011\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(num_classes, \u001b[38;5;28mint\u001b[39m):\n\u001b[1;32m-> 1012\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`num_classes` is expected to be `int` but `\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(num_classes)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m was passed.`\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(top_k, \u001b[38;5;28mint\u001b[39m):\n\u001b[0;32m 1014\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`top_k` is expected to be `int` but `\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(top_k)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m was passed.`\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[1;31mValueError\u001b[0m: `num_classes` is expected to be `int` but ` was passed.`" + ] + } + ], + "source": [ + "\n", + "\n", + "print(f\"Precision: {final_precision:.4f}\")\n", + "print(f\"Recall: {final_recall:.4f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def calculate_ndcg(true_relevance, predicted_relevance, k=None):\n", + " if k is None:\n", + " k = len(true_relevance)\n", + " \n", + " dcg = np.sum(predicted_relevance[:k] / np.log2(np.arange(2, k + 2)))\n", + " idcg = np.sum(np.sort(true_relevance)[::-1][:k] / np.log2(np.arange(2, k + 2)))\n", + " \n", + " return dcg / idcg if idcg > 0 else 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 343 + }, + "id": "MiDPM6Zu_LJ4", + "outputId": "06c421bd-e716-47e2-96a2-70b971875638" + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABPQAAAHWCAYAAADw5df1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAADra0lEQVR4nOzdeVyUBf4H8M8czHDftxcqiqAoKopaphWGZlvWpmW1pmu2tmtr61b+rK3svrS0bHOtLHMzU3PdthQFTDskFRAVRQWRS27kPoeZ+f0x8wyMogIO88zxeb9e8/r9duaZeb5QMTPf53tItFqtFkRERERERERERGQVpGIHQERERERERERERF3HhB4REREREREREZEVYUKPiIiIiIiIiIjIijChR0REREREREREZEWY0CMiIiIiIiIiIrIiTOgRERERERERERFZESb0iIiIiIiIiIiIrAgTekRERERERERERFaECT0iIiIiIiIiIiIrwoQeEZGVCQkJwfz588UOg4iIiIh60RdffAGJRILc3FyxQyEiC8SEHhFRLzh06BBWrlyJ6upqsUMhIiIiIiIiGyMXOwAiIlt06NAhvPzyy5g/fz48PT1N+tpnz56FVMrrMURERERERPaK3wiJiESk0WjQ3NzcrecolUo4ODj0UkRERERERERk6ZjQIyIysZUrV+KZZ54BAAwcOBASicQw/0QikWDJkiX46quvMHz4cCiVSsTHxwMAVq1ahUmTJsHHxwdOTk4YO3YsduzYccXrXz5DT5iv8uuvv2LZsmXw8/ODi4sL7r33XpSXl5vlZyYiIiKydzt27IBEIsHBgweveOxf//oXJBIJMjIycOLECcyfPx+DBg2Co6MjAgMD8cc//hGVlZUiRE1E1oott0REJnbffffh3Llz+Prrr/H+++/D19cXAODn5wcA2L9/P7Zt24YlS5bA19cXISEhAIC1a9fi7rvvxsMPP4zW1lZs3boVs2fPxvfff4+ZM2de97xPPvkkvLy88NJLLyE3Nxdr1qzBkiVL8M033/Taz0pEREREOjNnzoSrqyu2bduGKVOmGD32zTffYPjw4RgxYgRWr16NnJwcLFiwAIGBgTh16hQ2bNiAU6dO4bfffoNEIhHpJyAia8KEHhGRiY0cORJjxozB119/jVmzZhkSdoKzZ8/i5MmTiIiIMLr/3LlzcHJyMvzv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RETtzciRI7F69WqzY0qlUqJoiIiIiMhSeJ1HRLaCFXpERBamVCrh7+9vduvcuTMAQ5vE8uXL8cgjj8DZ2RndunXDli1bzO5//PhxDB8+HM7OzvDy8sKf//xnVFVVmZ2zatUq9O3bF0qlEgEBAZg1a5bZ18vKyvCnP/0JLi4u6N69O7Zv3962L5qIiIioA+B1HhHZCib0iIisbP78+RgzZgyOHTuGiRMn4umnn8apU6cAANXV1RgxYgQ6d+6MtLQ0bN68GT/88IPZhdzy5csxc+ZM/PnPf8bx48exfft2REREmD3HP//5T4wfPx6//vorHn30UUycOBGXLl2y6uskIiIi6mh4nUdEViMSEZHFJCYminK5XHR1dTW7vfPOO6IoiiIAccaMGWb3iY2NFZ9//nlRFEVxxYoVYufOncWqqirT17///ntRJpOJGo1GFEVRDAwMFP/3f//3pjEAEP/xj3+Y/ruqqkoEIO7cudNir5OIiIioo+F1HhHZEs7QIyKysAceeADLly83O+bp6Wn633FxcWZfi4uLg1qtBgCcOnUKkZGRcHV1NX39rrvugl6vx5kzZyAIAoqKivDggw/eMoYBAwaY/rerqyvc3d1RWlra2pdEREREROB1HhHZDib0iIgszNXV9YbWCEtxdnZu1nmOjo5m/y0IAvR6fVuERERERNRh8DqPiGwFZ+gREVnZoUOHbvjv3r17AwB69+6NY8eOobq62vT1AwcOQCaToWfPnnBzc0NoaChSUlKsGjMRERER3R6v84jIWlihR0RkYXV1ddBoNGbHHBwc4O3tDQDYvHkzYmJicPfdd+Orr77CkSNHsHLlSgDAxIkTsWDBAiQmJuKNN97AhQsX8MILL+C5556Dn58fAOCNN97AjBkz4Ovri0ceeQSVlZU4cOAAXnjhBeu+UCIiIqIOhtd5RGQrmNAjIrKw5ORkBAQEmB3r2bMnTp8+DcCwmWzDhg3461//ioCAAHz99dfo06cPAMDFxQW7du3C7NmzMXjwYLi4uGDMmDF4//33TY+VmJiI2tpafPDBB3jppZfg7e2NsWPHWu8FEhEREXVQvM4jIlshiKIoSh0EEVFHIQgC/vOf/2D06NFSh0JEREREFsTrPCKyJs7QIyIiIiIiIiIisiNM6BEREREREREREdkRttwSERERERERERHZEVboERERERERERER2REm9IiIiIiIiIiIiOwIE3pERERERERERER2hAk9IiIiIiIiIiIiO8KEHhERERERERERkR1hQo+IiIiIiIiIiMiOMKFHRERERERERERkR5jQIyIiIiIiIiIisiP/H4NUv00KzqzEAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the cost over training and validation sets\n", + "fig,ax = plt.subplots(1,2,figsize=(15,5))\n", + "for i,key in enumerate(cost_paths.keys()):\n", + " ax_sub=ax[i%3]\n", + " ax_sub.plot(cost_paths[key])\n", + " ax_sub.set_title(key)\n", + " ax_sub.set_xlabel('Epoch')\n", + " ax_sub.set_ylabel('Loss')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "id": "NC2SMmwfUepL" + }, + "outputs": [], + "source": [ + "# Save the entire model\n", + "torch.save(model, os.getcwd() + '/recommender.pt')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "model = torch.load('recommender.pt', map_location=device)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "artist_album = pd.read_csv(os.path.join(os.getcwd() + '/data/processed','artist_album.csv'))\n", + "artist_album = artist_album[['artist_album_id','artist_album','artist_name','album_name']].drop_duplicates()\n", + "playlists = pd.read_csv(os.path.join(os.getcwd() + '/data/processed','playlists.csv'))" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "YhpNb8tV8-WC", + "outputId": "4077277b-895e-47bb-f487-26838e0b1266" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Recommendations for playlist 5\n", + "Electric Daisy Carnival Vol. 2 (Mixed by Wolfgang Gartner) \t Alex Gaudino\n", + "In Awe \t Midnite\n", + "Two Strokes Raw \t Alvin Risk\n", + "God City USA \t Canton Jones feat. Tonio\n", + "Lucky Bald \t Digi G'Alessio\n", + "Night Slugs Allstars Volume 2 \t Girl Unit\n", + "Feathers \t Cashmere Cat\n", + "The Fall \t At Dawn We Rage\n", + "Jasmin EP \t Cedaa\n", + "Geordie Racer \t Caspa\n", + "Matt Black \t Swifta Beater\n", + "Throw Away \t Sibot\n", + "Bounce 4 Life \t Monolithium\n", + "Time in Between (Soulection Compilation Vol.2) \t Bosstone\n", + "Split EP \t Arnold\n", + "Gospel \t Summer of Haze\n", + "Red Wine \t araabMUZIK\n", + "Nouvel Humour \t Alesia\n", + "New 8.0 \t Gameface\n", + "Traplife \t Gameface\n", + "Spotlight Compilation, Vol. 3 \t Apex Rise\n", + "Natural Instinct \t High Sunn\n", + "With You Tonight \t Summer Moon\n", + "The Very Best Movie Soundtracks by John Williams \t Philharmonische Orchester des Staatstheaters Cottbus\n", + "Ultra-Lounge / On The Rocks - Part 1 \t Wayne Newton\n", + "You Love You \t Semi Precious Weapons\n", + "Easy Street \t The Collapsable Hearts Club\n", + "Master Of Ceremonies \t Styles P\n", + "The Covers, Vol. 7 \t Alexi Blue\n", + "Chelsea Hotel - This Is the Rhythm of the Night \t Literary Artists\n" + ] + } + ], + "source": [ + "def generate_recommendations(artist_album, playlists, model, playlist_id, device, top_n=10, batch_size=1024):\n", + " model.eval()\n", + "\n", + "\n", + " all_movie_ids = torch.tensor(artist_album['artist_album_id'].values, dtype=torch.long, device=device)\n", + " user_ids = torch.full((len(all_movie_ids),), playlist_id, dtype=torch.long, device=device)\n", + "\n", + " # Initialize tensor to store all predictions\n", + " all_predictions = torch.zeros(len(all_movie_ids), device=device)\n", + "\n", + " # Generate predictions in batches\n", + " with torch.no_grad():\n", + " for i in range(0, len(all_movie_ids), batch_size):\n", + " batch_user_ids = user_ids[i:i+batch_size]\n", + " batch_movie_ids = all_movie_ids[i:i+batch_size]\n", + "\n", + " input_tensor = torch.stack([batch_user_ids, batch_movie_ids], dim=1)\n", + " batch_predictions = model(input_tensor).squeeze()\n", + " all_predictions[i:i+batch_size] = batch_predictions\n", + "\n", + " # Convert to numpy for easier handling\n", + " predictions = all_predictions.cpu().numpy()\n", + "\n", + " albums_listened = set(playlists.loc[playlists['playlist_id'] == playlist_id, 'artist_album_id'].tolist())\n", + "\n", + " unlistened_mask = np.isin(artist_album['artist_album_id'].values, list(albums_listened), invert=True)\n", + "\n", + " # Get top N recommendations\n", + " top_indices = np.argsort(predictions[unlistened_mask])[-top_n:][::-1]\n", + " recs = artist_album['artist_album_id'].values[unlistened_mask][top_indices]\n", + "\n", + " recs_names = artist_album.loc[artist_album['artist_album_id'].isin(recs)]\n", + " album, artist = recs_names['album_name'].values, recs_names['artist_name'].values\n", + "\n", + " return album.tolist(), artist.tolist()\n", + "\n", + "playlist_id = 5 \n", + "albums, artists = generate_recommendations(artist_album, playlists, model, playlist_id, device)\n", + "\n", + "print(\"Recommendations for playlist\", playlist_id)\n", + "for album, artist in zip(albums, artists):\n", + " print(album, '\\t', artist)" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "gpuType": "T4", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}