workshops_recommender_systems/P4. Matrix Factorization.ipynb

1392 lines
72 KiB
Plaintext
Raw Normal View History

2020-05-21 13:42:50 +02:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Self made SVD"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import helpers\n",
"import pandas as pd\n",
"import numpy as np\n",
"import scipy.sparse as sparse\n",
"from collections import defaultdict\n",
"from itertools import chain\n",
"import random\n",
"\n",
"train_read=pd.read_csv('./Datasets/ml-100k/train.csv', sep='\\t', header=None)\n",
"test_read=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\\t', header=None)\n",
"train_ui, test_ui, user_code_id, user_id_code, item_code_id, item_id_code = helpers.data_to_csr(train_read, test_read)"
]
},
{
"cell_type": "code",
2020-05-21 16:20:12 +02:00
"execution_count": 2,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [],
"source": [
"# Done similarly to https://github.com/albertauyeung/matrix-factorization-in-python\n",
"from tqdm import tqdm\n",
"\n",
"class SVD():\n",
" \n",
" def __init__(self, train_ui, learning_rate, regularization, nb_factors, iterations):\n",
" self.train_ui=train_ui\n",
" self.uir=list(zip(*[train_ui.nonzero()[0],train_ui.nonzero()[1], train_ui.data]))\n",
" \n",
" self.learning_rate=learning_rate\n",
" self.regularization=regularization\n",
" self.iterations=iterations\n",
" self.nb_users, self.nb_items=train_ui.shape\n",
" self.nb_ratings=train_ui.nnz\n",
" self.nb_factors=nb_factors\n",
" \n",
" self.Pu=np.random.normal(loc=0, scale=1./self.nb_factors, size=(self.nb_users, self.nb_factors))\n",
" self.Qi=np.random.normal(loc=0, scale=1./self.nb_factors, size=(self.nb_items, self.nb_factors))\n",
"\n",
" def train(self, test_ui=None):\n",
" if test_ui!=None:\n",
" self.test_uir=list(zip(*[test_ui.nonzero()[0],test_ui.nonzero()[1], test_ui.data]))\n",
" \n",
" self.learning_process=[]\n",
" pbar = tqdm(range(self.iterations))\n",
" for i in pbar:\n",
" pbar.set_description(f'Epoch {i} RMSE: {self.learning_process[-1][1] if i>0 else 0}. Training epoch {i+1}...')\n",
" np.random.shuffle(self.uir)\n",
" self.sgd(self.uir)\n",
" if test_ui==None:\n",
" self.learning_process.append([i+1, self.RMSE_total(self.uir)])\n",
" else:\n",
" self.learning_process.append([i+1, self.RMSE_total(self.uir), self.RMSE_total(self.test_uir)])\n",
" \n",
" def sgd(self, uir):\n",
" \n",
" for u, i, score in uir:\n",
" # Computer prediction and error\n",
" prediction = self.get_rating(u,i)\n",
" e = (score - prediction)\n",
" \n",
" # Update user and item latent feature matrices\n",
" Pu_update=self.learning_rate * (e * self.Qi[i] - self.regularization * self.Pu[u])\n",
" Qi_update=self.learning_rate * (e * self.Pu[u] - self.regularization * self.Qi[i])\n",
" \n",
" self.Pu[u] += Pu_update\n",
" self.Qi[i] += Qi_update\n",
" \n",
" def get_rating(self, u, i):\n",
" prediction = self.Pu[u].dot(self.Qi[i].T)\n",
" return prediction\n",
" \n",
" def RMSE_total(self, uir):\n",
" RMSE=0\n",
" for u,i, score in uir:\n",
" prediction = self.get_rating(u,i)\n",
" RMSE+=(score - prediction)**2\n",
" return np.sqrt(RMSE/len(uir))\n",
" \n",
" def estimations(self):\n",
" self.estimations=\\\n",
" np.dot(self.Pu,self.Qi.T)\n",
"\n",
" def recommend(self, user_code_id, item_code_id, topK=10):\n",
" \n",
" top_k = defaultdict(list)\n",
" for nb_user, user in enumerate(self.estimations):\n",
" \n",
" user_rated=self.train_ui.indices[self.train_ui.indptr[nb_user]:self.train_ui.indptr[nb_user+1]]\n",
" for item, score in enumerate(user):\n",
" if item not in user_rated and not np.isnan(score):\n",
" top_k[user_code_id[nb_user]].append((item_code_id[item], score))\n",
" result=[]\n",
" # Let's choose k best items in the format: (user, item1, score1, item2, score2, ...)\n",
" for uid, item_scores in top_k.items():\n",
" item_scores.sort(key=lambda x: x[1], reverse=True)\n",
" result.append([uid]+list(chain(*item_scores[:topK])))\n",
" return result\n",
" \n",
" def estimate(self, user_code_id, item_code_id, test_ui):\n",
" result=[]\n",
" for user, item in zip(*test_ui.nonzero()):\n",
" result.append([user_code_id[user], item_code_id[item], \n",
" self.estimations[user,item] if not np.isnan(self.estimations[user,item]) else 1])\n",
" return result"
]
},
{
"cell_type": "code",
2020-05-21 16:20:12 +02:00
"execution_count": 3,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
2020-05-21 22:53:34 +02:00
"Epoch 39 RMSE: 0.7476169311403564. Training epoch 40...: 100%|██████████| 40/40 [01:47<00:00, 2.68s/it]\n"
2020-05-21 13:42:50 +02:00
]
}
],
"source": [
"model=SVD(train_ui, learning_rate=0.005, regularization=0.02, nb_factors=100, iterations=40)\n",
"model.train(test_ui)"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 4,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2020-05-21 22:53:34 +02:00
"<matplotlib.legend.Legend at 0x7f963dab39b0>"
2020-05-21 13:42:50 +02:00
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 4,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
2020-05-21 22:53:34 +02:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAcHElEQVR4nO3de3RV9Z338feXJBCQlJDLKEPAYHWWVtCoMeiIDsqqg4wXpg+PpX1mWsfOylOVQVvLU2Qcrc64RktbK73o0NbLdPqIdrxbq9MKjpcqNGBAKBRQtARpCWBCqIAEvvPHPoechJPkJDnJPtn781prr7Nv55wve5HP/p3fvpm7IyIig9+QsAsQEZHsUKCLiESEAl1EJCIU6CIiEaFAFxGJiPywvrisrMwrKyvD+noRkUFp5cqVO929PN2y0AK9srKSurq6sL5eRGRQMrP3OlumLhcRkYhQoIuIRIQCXUQkIkLrQxeRwefgwYM0NDSwf//+sEuJvMLCQioqKigoKMj4PQp0EclYQ0MDRUVFVFZWYmZhlxNZ7s6uXbtoaGhgwoQJGb9PXS4ikrH9+/dTWlqqMO9nZkZpaWmPfwkp0EWkRxTmA6M323nQBfqWLXDDDXDwYNiViIjklkEX6GvXwj33wOLFYVciIpJbBl2gX3opTJ0KX/saNDeHXY2IDKSmpia+//3v9/h9M2bMoKmpqcfvu+qqq5gwYQJVVVWcfvrpvPjii0eWTZ06lfHjx5P6kKCZM2cycuRIAA4fPszcuXOZOHEikyZN4uyzz2bLli1AcKX8pEmTqKqqoqqqirlz5/a4tnQG3VkuZvCNb0B1Ndx5J/zrv4ZdkYgMlGSgX3vtte3mt7a2kp/feZw999xzvf7OhQsXMmvWLJYtW0ZtbS2bNm06sqy4uJjXXnuNKVOm0NTUxPbt248se+SRR3j//fdZs2YNQ4YMoaGhgWOOOebI8mXLllFWVtbrutIZdIEOcNZZ8Dd/A3ffDddcA+PHh12RSPzccAPU12f3M6uq4Nvf7nz5/Pnzefvtt6mqqqKgoIDCwkJGjx7Nhg0b2LhxIzNnzmTr1q3s37+f66+/ntraWqDt3lF79+7lkksuYcqUKfzqV79i7NixPPXUUwwfPrzb2s4991y2bdvWbt7s2bNZsmQJU6ZM4fHHH+dTn/oU69atA2D79u2MGTOGIUOCjpCKiopebpXMDboul6Q77gheb7453DpEZODceeedfPzjH6e+vp6FCxeyatUq7rnnHjZu3AjA/fffz8qVK6mrq2PRokXs2rXrqM/YtGkT1113HevWraO4uJjHHnsso+9+/vnnmTlzZrt506ZN4+WXX+bQoUMsWbKET3/600eWXXnllTzzzDNUVVVx44038uabb7Z774UXXniky+Xuu+/u6aZIa1C20CFolX/pS0G3yw03wJlnhl2RSLx01ZIeKDU1Ne0uvFm0aBFPPPEEAFu3bmXTpk2Ulpa2e0+yTxzgrLPO4t133+3yO+bNm8eCBQtoaGjg9ddfb7csLy+PKVOmsGTJEvbt20fqLcErKir47W9/y9KlS1m6dCnTpk3jpz/9KdOmTQP6p8tl0LbQAebPh7IyuPFGSDkuISIxkdon/dJLL/HLX/6S119/ndWrV3PGGWekvTBn2LBhR8bz8vJobW3t8jsWLlzIxo0bueuuu7j66quPWj579mzmzp3LlVdemfa7LrnkEhYuXMiCBQt48skne/LP67FBHeijRgVnu7z0EvzsZ2FXIyL9raioiJaWlrTLmpubGT16NCNGjGDDhg288cYbWf3uOXPmcPjwYV544YV2888//3xuuukmPvOZz7Sbv2rVKt5//30gOONlzZo1HH/88VmtqaNBHegAtbXwZ38G8+ZBNztaERnkSktLOe+885g4cSLz5s1rt2z69Om0trZyyimnMH/+fM4555ysfreZcfPNN/P1r3/9qPlf+cpXjuo+2bFjB5dddhkTJ07ktNNOIz8/nzlz5hxZntqH/rnPfS47NXpIfRXV1dWerScWPfUUzJwJ994LX/xiVj5SRNJYv349p5xySthlxEa67W1mK929Ot36g76FDnD55XDBBXDrrbBnT9jViIiEo9tAN7NCM1thZqvNbJ2Z3ZZmnavMrNHM6hPD3/dPuZ3VGFxstGMHdPg1JCLSreuuu+5I90dyeOCBB8Iuq8cyOW3xAHCRu+81swLgVTP7ubt3POLwiLvPSfP+AXH22fDZz8I3vxl0uwzAOfwiseTukbvj4ve+972wSzhKb7rDu22he2BvYrIgMeTkSYJ33BGcvqiLjUT6R2FhIbt27epV2Ejmkg+4KCws7NH7MrqwyMzygJXAicD33H15mtX+l5ldAGwEvuTuW9N8Ti1QCzC+H67Xr6yEq6+GH/4QHngg6IoRkeypqKigoaGBxsbGsEuJvOQj6Hoio0B390NAlZkVA0+Y2UR3X5uyyjPAw+5+wMz+L/AQcFGaz1kMLIbgLJceVZqhE08M7pW+Z09wnrqIZE9BQUGPHokmA6tHZ7m4exOwDJjeYf4udz+QmPwhcFZ2yuu55FW+aW7hICISaZmc5VKeaJljZsOBTwIbOqwzJmXycmB9NovsCQW6iMRVJl0uY4CHEv3oQ4BH3f1ZM7sdqHP3p4G5ZnY50ArsBq7qr4K7o0AXkbjqNtDdfQ1wRpr5t6SM3wTclN3SekeBLiJxFYkrRVMp0EUkriIX6MXFwemKCnQRiZvIBXpeXhDqu3eHXYmIyMCKXKBD0O2iFrqIxI0CXUQkIhToIiIRoUAXEYkIBbqISERENtBbWuCjj8KuRERk4EQy0EtKgleduigicRLJQNfVoiISR5EOdLXQRSROIh3oaqGLSJwo0EVEIkKBLiISEZEM9BEjYNgwBbqIxEskA91MFxeJSPxEMtAhOBddgS4icRLZQFcLXUTiJtKBrvPQRSROIh3oaqGLSJxEPtDdw65ERGRgRDrQDx6EvXvDrkREZGBEOtBB3S4iEh/dBrqZFZrZCjNbbWbrzOy2NOsMM7NHzGyzmS03s8r+KLYnFOgiEjeZtNAPABe5++lAFTDdzM7psM4XgA/c/UTgbuCu7JbZcwp0EYmbbgPdA8me6ILE0PFQ4xXAQ4nx/wSmmZllrcpeSD7kQoEuInGRUR+6meWZWT2wA/iFuy/vsMpYYCuAu7cCzUBpms+pNbM6M6trbGzsW+XdUAtdROImo0B390PuXgVUADVmNrE3X+bui9292t2ry8vLe/MRGdNj6EQkbnp0lou7NwHLgOkdFm0DxgGYWT4wCgi1bZyfD6NGqYUuIvGRyVku5WZWnBgfDnwS2NBhtaeBzyfGZwFL3cO/pEdXi4pInORnsM4Y4CEzyyPYATzq7s+a2e1Anbs/DfwI+LGZbQZ2A7P7reIeUKCLSJx0G+juvgY4I838W1LG9wP/O7ul9Z0CXUTiJLJXioICXUTiJdKBrodciEicRDrQS0uhuRlaW8OuRESk/0U+0EHnootIPCjQRUQiIhaBrn50EYkDBbqISEQo0EVEIkKBLiISEZEO9JEjg5t0KdBFJA4iHehmulpUROIj0oEOCnQRiY9YBLrOQxeROIhFoKuFLiJxoEAXEYmI2AR6+M9PEhHpX7EI9AMH4MMPw65ERKR/RT7QS0qCV3W7iEjURT7QdbWoiMSFAl1EJCIU6CIiERGbQNfFRSISdZEPdB0UFZG4iHygDx0KRUUKdBGJvm4D3czGmdkyM/uNma0zs+vTrDPVzJrNrD4x3NI/5faOrhYVkTjIz2CdVuBGd19lZkXASjP7hbv/psN6r7j7pdkvse9KShToIhJ93bbQ3X27u69KjLcA64Gx/V1YNqmFLiJx0KM+dDOrBM4AlqdZfK6ZrTazn5vZqZ28v9bM6sysrrGxscfF9pYCXUTiIONAN7ORwGPADe6+p8PiVcDx7n468B3gyXSf4e6L3b3a3avLy8t7W3OPKdBFJA4yCnQzKyAI85+4++Mdl7v7Hnffmxh/Digws7KsVtoHpaXQ1ASHDoVdiYhI/8nkLBcDfgSsd/d
2020-05-21 13:42:50 +02:00
"text/plain": [
2020-05-21 22:53:34 +02:00
"<Figure size 432x288 with 1 Axes>"
2020-05-21 13:42:50 +02:00
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"df=pd.DataFrame(model.learning_process).iloc[:,:2]\n",
"df.columns=['epoch', 'train_RMSE']\n",
"plt.plot('epoch', 'train_RMSE', data=df, color='blue')\n",
"plt.legend()"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 5,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2020-05-21 22:53:34 +02:00
"<matplotlib.legend.Legend at 0x7f963ce5ddd8>"
2020-05-21 13:42:50 +02:00
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 5,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
2020-05-21 22:53:34 +02:00
"image/png": "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
2020-05-21 13:42:50 +02:00
"text/plain": [
2020-05-21 22:53:34 +02:00
"<Figure size 432x288 with 1 Axes>"
2020-05-21 13:42:50 +02:00
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"df=pd.DataFrame(model.learning_process[10:], columns=['epoch', 'train_RMSE', 'test_RMSE'])\n",
"plt.plot('epoch', 'train_RMSE', data=df, color='blue')\n",
"plt.plot('epoch', 'test_RMSE', data=df, color='yellow', linestyle='dashed')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Saving and evaluating recommendations"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 6,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [],
"source": [
"model.estimations()\n",
"\n",
"top_n=pd.DataFrame(model.recommend(user_code_id, item_code_id, topK=10))\n",
"\n",
"top_n.to_csv('Recommendations generated/ml-100k/Self_SVD_reco.csv', index=False, header=False)\n",
"\n",
"estimations=pd.DataFrame(model.estimate(user_code_id, item_code_id, test_ui))\n",
"estimations.to_csv('Recommendations generated/ml-100k/Self_SVD_estimations.csv', index=False, header=False)"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 7,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
2020-05-21 22:53:34 +02:00
"943it [00:00, 5237.55it/s]\n"
2020-05-21 13:42:50 +02:00
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>RMSE</th>\n",
" <th>MAE</th>\n",
" <th>precision</th>\n",
" <th>recall</th>\n",
" <th>F_1</th>\n",
" <th>F_05</th>\n",
" <th>precision_super</th>\n",
" <th>recall_super</th>\n",
" <th>NDCG</th>\n",
" <th>mAP</th>\n",
" <th>MRR</th>\n",
" <th>LAUC</th>\n",
" <th>HR</th>\n",
" <th>Reco in test</th>\n",
" <th>Test coverage</th>\n",
" <th>Shannon</th>\n",
" <th>Gini</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
2020-05-21 22:53:34 +02:00
" <td>0.913861</td>\n",
" <td>0.717063</td>\n",
" <td>0.10403</td>\n",
" <td>0.044109</td>\n",
" <td>0.053339</td>\n",
" <td>0.07051</td>\n",
" <td>0.094313</td>\n",
" <td>0.075814</td>\n",
" <td>0.107692</td>\n",
" <td>0.051047</td>\n",
" <td>0.201273</td>\n",
" <td>0.518782</td>\n",
" <td>0.481442</td>\n",
" <td>0.87211</td>\n",
2020-05-21 16:20:12 +02:00
" <td>0.146465</td>\n",
2020-05-21 22:53:34 +02:00
" <td>3.881417</td>\n",
" <td>0.972029</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
2020-05-21 22:53:34 +02:00
" RMSE MAE precision recall F_1 F_05 \\\n",
"0 0.913861 0.717063 0.10403 0.044109 0.053339 0.07051 \n",
2020-05-21 13:42:50 +02:00
"\n",
2020-05-21 16:20:12 +02:00
" precision_super recall_super NDCG mAP MRR LAUC \\\n",
2020-05-21 22:53:34 +02:00
"0 0.094313 0.075814 0.107692 0.051047 0.201273 0.518782 \n",
2020-05-21 13:42:50 +02:00
"\n",
2020-05-21 16:20:12 +02:00
" HR Reco in test Test coverage Shannon Gini \n",
2020-05-21 22:53:34 +02:00
"0 0.481442 0.87211 0.146465 3.881417 0.972029 "
2020-05-21 13:42:50 +02:00
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 7,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import evaluation_measures as ev\n",
"\n",
"estimations_df=pd.read_csv('Recommendations generated/ml-100k/Self_SVD_estimations.csv', header=None)\n",
"reco=np.loadtxt('Recommendations generated/ml-100k/Self_SVD_reco.csv', delimiter=',')\n",
"\n",
"ev.evaluate(test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\\t', header=None),\n",
" estimations_df=estimations_df, \n",
" reco=reco,\n",
" super_reactions=[4,5])"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 8,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
2020-05-21 22:53:34 +02:00
"943it [00:00, 6996.89it/s]\n",
"943it [00:00, 5574.45it/s]\n",
"943it [00:00, 5909.51it/s]\n",
"943it [00:00, 6568.51it/s]\n",
"943it [00:00, 5488.25it/s]\n",
"943it [00:00, 5363.29it/s]\n",
"943it [00:00, 6280.36it/s]\n",
"943it [00:00, 5709.71it/s]\n",
"943it [00:00, 6279.20it/s]\n",
"943it [00:00, 5819.38it/s]\n"
2020-05-21 13:42:50 +02:00
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Model</th>\n",
" <th>RMSE</th>\n",
" <th>MAE</th>\n",
" <th>precision</th>\n",
" <th>recall</th>\n",
" <th>F_1</th>\n",
" <th>F_05</th>\n",
" <th>precision_super</th>\n",
" <th>recall_super</th>\n",
" <th>NDCG</th>\n",
" <th>mAP</th>\n",
" <th>MRR</th>\n",
" <th>LAUC</th>\n",
" <th>HR</th>\n",
" <th>Reco in test</th>\n",
" <th>Test coverage</th>\n",
" <th>Shannon</th>\n",
" <th>Gini</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_TopPop</td>\n",
" <td>2.508258</td>\n",
" <td>2.217909</td>\n",
" <td>0.188865</td>\n",
" <td>0.116919</td>\n",
" <td>0.118732</td>\n",
" <td>0.141584</td>\n",
" <td>0.130472</td>\n",
" <td>0.137473</td>\n",
" <td>0.214651</td>\n",
" <td>0.111707</td>\n",
" <td>0.400939</td>\n",
" <td>0.555546</td>\n",
" <td>0.765642</td>\n",
" <td>1.000000</td>\n",
" <td>0.038961</td>\n",
" <td>3.159079</td>\n",
" <td>0.987317</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_SVD</td>\n",
2020-05-21 22:53:34 +02:00
" <td>0.913861</td>\n",
" <td>0.717063</td>\n",
" <td>0.104030</td>\n",
" <td>0.044109</td>\n",
" <td>0.053339</td>\n",
" <td>0.070510</td>\n",
" <td>0.094313</td>\n",
" <td>0.075814</td>\n",
" <td>0.107692</td>\n",
" <td>0.051047</td>\n",
" <td>0.201273</td>\n",
" <td>0.518782</td>\n",
" <td>0.481442</td>\n",
" <td>0.872110</td>\n",
2020-05-21 16:20:12 +02:00
" <td>0.146465</td>\n",
2020-05-21 22:53:34 +02:00
" <td>3.881417</td>\n",
" <td>0.972029</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_Baseline</td>\n",
" <td>0.949459</td>\n",
" <td>0.752487</td>\n",
" <td>0.091410</td>\n",
" <td>0.037652</td>\n",
" <td>0.046030</td>\n",
" <td>0.061286</td>\n",
" <td>0.079614</td>\n",
" <td>0.056463</td>\n",
" <td>0.095957</td>\n",
" <td>0.043178</td>\n",
" <td>0.198193</td>\n",
" <td>0.515501</td>\n",
" <td>0.437964</td>\n",
" <td>1.000000</td>\n",
" <td>0.033911</td>\n",
" <td>2.836513</td>\n",
" <td>0.991139</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_GlobalAvg</td>\n",
" <td>1.125760</td>\n",
" <td>0.943534</td>\n",
" <td>0.061188</td>\n",
" <td>0.025968</td>\n",
" <td>0.031383</td>\n",
" <td>0.041343</td>\n",
" <td>0.040558</td>\n",
" <td>0.032107</td>\n",
" <td>0.067695</td>\n",
" <td>0.027470</td>\n",
" <td>0.171187</td>\n",
" <td>0.509546</td>\n",
" <td>0.384942</td>\n",
" <td>1.000000</td>\n",
" <td>0.025974</td>\n",
" <td>2.711772</td>\n",
" <td>0.992003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_Random</td>\n",
2020-05-21 22:53:34 +02:00
" <td>1.517787</td>\n",
" <td>1.217953</td>\n",
" <td>0.047826</td>\n",
" <td>0.017861</td>\n",
" <td>0.022711</td>\n",
" <td>0.031080</td>\n",
" <td>0.028219</td>\n",
" <td>0.016982</td>\n",
" <td>0.051154</td>\n",
" <td>0.019551</td>\n",
" <td>0.125693</td>\n",
" <td>0.505448</td>\n",
" <td>0.318134</td>\n",
" <td>0.986426</td>\n",
" <td>0.186869</td>\n",
" <td>5.091730</td>\n",
" <td>0.908288</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_I-KNN</td>\n",
" <td>1.030386</td>\n",
" <td>0.813067</td>\n",
" <td>0.026087</td>\n",
" <td>0.006908</td>\n",
" <td>0.010593</td>\n",
" <td>0.016046</td>\n",
" <td>0.021137</td>\n",
" <td>0.009522</td>\n",
" <td>0.024214</td>\n",
" <td>0.008958</td>\n",
" <td>0.048068</td>\n",
" <td>0.499885</td>\n",
" <td>0.154825</td>\n",
" <td>0.402333</td>\n",
" <td>0.434343</td>\n",
" <td>5.133650</td>\n",
" <td>0.877999</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_I-KNNBaseline</td>\n",
" <td>0.935327</td>\n",
" <td>0.737424</td>\n",
" <td>0.002545</td>\n",
" <td>0.000755</td>\n",
" <td>0.001105</td>\n",
" <td>0.001602</td>\n",
" <td>0.002253</td>\n",
" <td>0.000930</td>\n",
" <td>0.003444</td>\n",
" <td>0.001362</td>\n",
" <td>0.011760</td>\n",
" <td>0.496724</td>\n",
" <td>0.021209</td>\n",
" <td>0.482821</td>\n",
" <td>0.059885</td>\n",
" <td>2.232578</td>\n",
" <td>0.994487</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_U-KNN</td>\n",
" <td>1.023495</td>\n",
" <td>0.807913</td>\n",
" <td>0.000742</td>\n",
" <td>0.000205</td>\n",
" <td>0.000305</td>\n",
" <td>0.000449</td>\n",
" <td>0.000536</td>\n",
" <td>0.000198</td>\n",
" <td>0.000845</td>\n",
" <td>0.000274</td>\n",
" <td>0.002744</td>\n",
" <td>0.496441</td>\n",
" <td>0.007423</td>\n",
" <td>0.602121</td>\n",
" <td>0.010823</td>\n",
" <td>2.089186</td>\n",
" <td>0.995706</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_BaselineUI</td>\n",
" <td>0.967585</td>\n",
" <td>0.762740</td>\n",
" <td>0.000954</td>\n",
" <td>0.000170</td>\n",
" <td>0.000278</td>\n",
" <td>0.000463</td>\n",
" <td>0.000644</td>\n",
" <td>0.000189</td>\n",
" <td>0.000752</td>\n",
" <td>0.000168</td>\n",
" <td>0.001677</td>\n",
" <td>0.496424</td>\n",
" <td>0.009544</td>\n",
" <td>0.600530</td>\n",
" <td>0.005051</td>\n",
" <td>1.803126</td>\n",
" <td>0.996380</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_IKNN</td>\n",
" <td>1.018363</td>\n",
" <td>0.808793</td>\n",
" <td>0.000318</td>\n",
" <td>0.000108</td>\n",
" <td>0.000140</td>\n",
" <td>0.000189</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000214</td>\n",
" <td>0.000037</td>\n",
" <td>0.000368</td>\n",
" <td>0.496391</td>\n",
" <td>0.003181</td>\n",
" <td>0.392153</td>\n",
" <td>0.115440</td>\n",
" <td>4.174741</td>\n",
" <td>0.965327</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Model RMSE MAE precision recall F_1 \\\n",
"0 Self_TopPop 2.508258 2.217909 0.188865 0.116919 0.118732 \n",
2020-05-21 22:53:34 +02:00
"0 Self_SVD 0.913861 0.717063 0.104030 0.044109 0.053339 \n",
2020-05-21 13:42:50 +02:00
"0 Ready_Baseline 0.949459 0.752487 0.091410 0.037652 0.046030 \n",
"0 Self_GlobalAvg 1.125760 0.943534 0.061188 0.025968 0.031383 \n",
2020-05-21 22:53:34 +02:00
"0 Ready_Random 1.517787 1.217953 0.047826 0.017861 0.022711 \n",
2020-05-21 13:42:50 +02:00
"0 Ready_I-KNN 1.030386 0.813067 0.026087 0.006908 0.010593 \n",
"0 Ready_I-KNNBaseline 0.935327 0.737424 0.002545 0.000755 0.001105 \n",
"0 Ready_U-KNN 1.023495 0.807913 0.000742 0.000205 0.000305 \n",
"0 Self_BaselineUI 0.967585 0.762740 0.000954 0.000170 0.000278 \n",
"0 Self_IKNN 1.018363 0.808793 0.000318 0.000108 0.000140 \n",
"\n",
" F_05 precision_super recall_super NDCG mAP MRR \\\n",
"0 0.141584 0.130472 0.137473 0.214651 0.111707 0.400939 \n",
2020-05-21 22:53:34 +02:00
"0 0.070510 0.094313 0.075814 0.107692 0.051047 0.201273 \n",
2020-05-21 13:42:50 +02:00
"0 0.061286 0.079614 0.056463 0.095957 0.043178 0.198193 \n",
"0 0.041343 0.040558 0.032107 0.067695 0.027470 0.171187 \n",
2020-05-21 22:53:34 +02:00
"0 0.031080 0.028219 0.016982 0.051154 0.019551 0.125693 \n",
2020-05-21 13:42:50 +02:00
"0 0.016046 0.021137 0.009522 0.024214 0.008958 0.048068 \n",
"0 0.001602 0.002253 0.000930 0.003444 0.001362 0.011760 \n",
"0 0.000449 0.000536 0.000198 0.000845 0.000274 0.002744 \n",
"0 0.000463 0.000644 0.000189 0.000752 0.000168 0.001677 \n",
"0 0.000189 0.000000 0.000000 0.000214 0.000037 0.000368 \n",
"\n",
" LAUC HR Reco in test Test coverage Shannon Gini \n",
"0 0.555546 0.765642 1.000000 0.038961 3.159079 0.987317 \n",
2020-05-21 22:53:34 +02:00
"0 0.518782 0.481442 0.872110 0.146465 3.881417 0.972029 \n",
2020-05-21 13:42:50 +02:00
"0 0.515501 0.437964 1.000000 0.033911 2.836513 0.991139 \n",
"0 0.509546 0.384942 1.000000 0.025974 2.711772 0.992003 \n",
2020-05-21 22:53:34 +02:00
"0 0.505448 0.318134 0.986426 0.186869 5.091730 0.908288 \n",
2020-05-21 13:42:50 +02:00
"0 0.499885 0.154825 0.402333 0.434343 5.133650 0.877999 \n",
"0 0.496724 0.021209 0.482821 0.059885 2.232578 0.994487 \n",
"0 0.496441 0.007423 0.602121 0.010823 2.089186 0.995706 \n",
"0 0.496424 0.009544 0.600530 0.005051 1.803126 0.996380 \n",
"0 0.496391 0.003181 0.392153 0.115440 4.174741 0.965327 "
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 8,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import imp\n",
"imp.reload(ev)\n",
"\n",
"import evaluation_measures as ev\n",
"dir_path=\"Recommendations generated/ml-100k/\"\n",
"super_reactions=[4,5]\n",
"test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\\t', header=None)\n",
"\n",
"ev.evaluate_all(test, dir_path, super_reactions)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Embeddings"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 9,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 2],\n",
" [3, 4]])"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"array([[0.4472136 , 0.89442719],\n",
" [0.6 , 0.8 ]])"
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 9,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x=np.array([[1,2],[3,4]])\n",
"display(x)\n",
"x/np.linalg.norm(x, axis=1)[:,None]"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 10,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>code</th>\n",
" <th>score</th>\n",
" <th>item_id</th>\n",
" <th>id</th>\n",
" <th>title</th>\n",
" <th>genres</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1051</td>\n",
2020-05-21 13:42:50 +02:00
" <td>1.000000</td>\n",
2020-05-21 22:53:34 +02:00
" <td>1052</td>\n",
" <td>1052</td>\n",
" <td>Dracula: Dead and Loving It (1995)</td>\n",
" <td>Comedy, Horror</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1177</td>\n",
" <td>0.951303</td>\n",
" <td>1178</td>\n",
" <td>1178</td>\n",
" <td>Major Payne (1994)</td>\n",
" <td>Comedy</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1290</td>\n",
" <td>0.950489</td>\n",
" <td>1291</td>\n",
" <td>1291</td>\n",
" <td>Celtic Pride (1996)</td>\n",
" <td>Comedy</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1375</td>\n",
" <td>0.949864</td>\n",
" <td>1376</td>\n",
" <td>1376</td>\n",
" <td>Meet Wally Sparks (1997)</td>\n",
" <td>Comedy</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1489</td>\n",
" <td>0.947375</td>\n",
" <td>1490</td>\n",
" <td>1490</td>\n",
" <td>Fausto (1993)</td>\n",
" <td>Comedy</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1495</td>\n",
" <td>0.947368</td>\n",
" <td>1496</td>\n",
" <td>1496</td>\n",
" <td>Carpool (1996)</td>\n",
" <td>Comedy, Crime</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1497</td>\n",
" <td>0.947347</td>\n",
" <td>1498</td>\n",
" <td>1498</td>\n",
" <td>Farmer &amp; Chase (1995)</td>\n",
" <td>Comedy</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1490</td>\n",
" <td>0.946829</td>\n",
" <td>1491</td>\n",
" <td>1491</td>\n",
" <td>Tough and Deadly (1995)</td>\n",
" <td>Action, Drama, Thriller</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1320</td>\n",
" <td>0.946152</td>\n",
" <td>1321</td>\n",
" <td>1321</td>\n",
" <td>Open Season (1996)</td>\n",
" <td>Comedy</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
2020-05-21 22:53:34 +02:00
" <td>1487</td>\n",
" <td>0.945425</td>\n",
" <td>1488</td>\n",
" <td>1488</td>\n",
" <td>Germinal (1993)</td>\n",
" <td>Drama</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
2020-05-21 22:53:34 +02:00
" code score item_id id title \\\n",
"0 1051 1.000000 1052 1052 Dracula: Dead and Loving It (1995) \n",
"1 1177 0.951303 1178 1178 Major Payne (1994) \n",
"2 1290 0.950489 1291 1291 Celtic Pride (1996) \n",
"3 1375 0.949864 1376 1376 Meet Wally Sparks (1997) \n",
"4 1489 0.947375 1490 1490 Fausto (1993) \n",
"5 1495 0.947368 1496 1496 Carpool (1996) \n",
"6 1497 0.947347 1498 1498 Farmer & Chase (1995) \n",
"7 1490 0.946829 1491 1491 Tough and Deadly (1995) \n",
"8 1320 0.946152 1321 1321 Open Season (1996) \n",
"9 1487 0.945425 1488 1488 Germinal (1993) \n",
2020-05-21 13:42:50 +02:00
"\n",
2020-05-21 22:53:34 +02:00
" genres \n",
"0 Comedy, Horror \n",
"1 Comedy \n",
"2 Comedy \n",
"3 Comedy \n",
"4 Comedy \n",
"5 Comedy, Crime \n",
"6 Comedy \n",
"7 Action, Drama, Thriller \n",
"8 Comedy \n",
"9 Drama "
2020-05-21 13:42:50 +02:00
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 10,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"item=random.choice(list(set(train_ui.indices)))\n",
"\n",
"embeddings_norm=model.Qi/np.linalg.norm(model.Qi, axis=1)[:,None] # we do not mean-center here\n",
"# omitting normalization also makes sense, but items with a greater magnitude will be recommended more often\n",
"\n",
"similarity_scores=np.dot(embeddings_norm,embeddings_norm[item].T)\n",
"top_similar_items=pd.DataFrame(enumerate(similarity_scores), columns=['code', 'score'])\\\n",
".sort_values(by=['score'], ascending=[False])[:10]\n",
"\n",
"top_similar_items['item_id']=top_similar_items['code'].apply(lambda x: item_code_id[x])\n",
"\n",
"items=pd.read_csv('./Datasets/ml-100k/movies.csv')\n",
"\n",
"result=pd.merge(top_similar_items, items, left_on='item_id', right_on='id')\n",
"\n",
"result"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# project task 5: implement SVD on top baseline (as it is in Surprise library)"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 11,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [],
"source": [
"# making changes to our implementation by considering additional parameters in the gradient descent procedure \n",
"# seems to be the fastest option\n",
"# please save the output in 'Recommendations generated/ml-100k/Self_SVDBaseline_reco.csv' and\n",
"# 'Recommendations generated/ml-100k/Self_SVDBaseline_estimations.csv'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ready-made SVD - Surprise implementation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SVD"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 12,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generating predictions...\n",
"Generating top N recommendations...\n",
"Generating predictions...\n"
]
}
],
"source": [
"import helpers\n",
"import surprise as sp\n",
"import imp\n",
"imp.reload(helpers)\n",
"\n",
"algo = sp.SVD(biased=False) # to use unbiased version\n",
"\n",
"helpers.ready_made(algo, reco_path='Recommendations generated/ml-100k/Ready_SVD_reco.csv',\n",
" estimations_path='Recommendations generated/ml-100k/Ready_SVD_estimations.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SVD biased - on top baseline"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 13,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generating predictions...\n",
"Generating top N recommendations...\n",
"Generating predictions...\n"
]
}
],
"source": [
"import helpers\n",
"import surprise as sp\n",
"import imp\n",
"imp.reload(helpers)\n",
"\n",
"algo = sp.SVD() # default is biased=True\n",
"\n",
"helpers.ready_made(algo, reco_path='Recommendations generated/ml-100k/Ready_SVDBiased_reco.csv',\n",
" estimations_path='Recommendations generated/ml-100k/Ready_SVDBiased_estimations.csv')"
]
},
{
"cell_type": "code",
2020-05-21 22:53:34 +02:00
"execution_count": 14,
2020-05-21 13:42:50 +02:00
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
2020-05-21 22:53:34 +02:00
"943it [00:00, 5528.02it/s]\n",
"943it [00:00, 6531.06it/s]\n",
"943it [00:00, 5593.54it/s]\n",
"943it [00:00, 5845.59it/s]\n",
"943it [00:00, 5997.91it/s]\n",
"943it [00:00, 6080.78it/s]\n",
"943it [00:00, 6121.00it/s]\n",
"943it [00:00, 5934.94it/s]\n",
"943it [00:00, 5026.29it/s]\n",
"943it [00:00, 5850.46it/s]\n",
"943it [00:00, 5530.89it/s]\n",
"943it [00:00, 6004.16it/s]\n"
2020-05-21 13:42:50 +02:00
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Model</th>\n",
" <th>RMSE</th>\n",
" <th>MAE</th>\n",
" <th>precision</th>\n",
" <th>recall</th>\n",
" <th>F_1</th>\n",
" <th>F_05</th>\n",
" <th>precision_super</th>\n",
" <th>recall_super</th>\n",
" <th>NDCG</th>\n",
" <th>mAP</th>\n",
" <th>MRR</th>\n",
" <th>LAUC</th>\n",
" <th>HR</th>\n",
" <th>Reco in test</th>\n",
" <th>Test coverage</th>\n",
" <th>Shannon</th>\n",
" <th>Gini</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_TopPop</td>\n",
" <td>2.508258</td>\n",
" <td>2.217909</td>\n",
" <td>0.188865</td>\n",
" <td>0.116919</td>\n",
" <td>0.118732</td>\n",
" <td>0.141584</td>\n",
" <td>0.130472</td>\n",
" <td>0.137473</td>\n",
" <td>0.214651</td>\n",
" <td>0.111707</td>\n",
" <td>0.400939</td>\n",
" <td>0.555546</td>\n",
" <td>0.765642</td>\n",
" <td>1.000000</td>\n",
" <td>0.038961</td>\n",
" <td>3.159079</td>\n",
" <td>0.987317</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_SVD</td>\n",
2020-05-21 22:53:34 +02:00
" <td>0.949892</td>\n",
" <td>0.749292</td>\n",
" <td>0.104666</td>\n",
" <td>0.048611</td>\n",
" <td>0.055656</td>\n",
" <td>0.071900</td>\n",
" <td>0.092811</td>\n",
" <td>0.078241</td>\n",
" <td>0.117730</td>\n",
" <td>0.057464</td>\n",
" <td>0.244097</td>\n",
" <td>0.521054</td>\n",
" <td>0.501591</td>\n",
2020-05-21 16:20:12 +02:00
" <td>0.998091</td>\n",
2020-05-21 22:53:34 +02:00
" <td>0.217172</td>\n",
" <td>4.458001</td>\n",
" <td>0.951551</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_SVD</td>\n",
2020-05-21 22:53:34 +02:00
" <td>0.913861</td>\n",
" <td>0.717063</td>\n",
" <td>0.104030</td>\n",
" <td>0.044109</td>\n",
" <td>0.053339</td>\n",
" <td>0.070510</td>\n",
" <td>0.094313</td>\n",
" <td>0.075814</td>\n",
" <td>0.107692</td>\n",
" <td>0.051047</td>\n",
" <td>0.201273</td>\n",
" <td>0.518782</td>\n",
" <td>0.481442</td>\n",
" <td>0.872110</td>\n",
2020-05-21 16:20:12 +02:00
" <td>0.146465</td>\n",
2020-05-21 22:53:34 +02:00
" <td>3.881417</td>\n",
" <td>0.972029</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_Baseline</td>\n",
" <td>0.949459</td>\n",
" <td>0.752487</td>\n",
" <td>0.091410</td>\n",
" <td>0.037652</td>\n",
" <td>0.046030</td>\n",
" <td>0.061286</td>\n",
" <td>0.079614</td>\n",
" <td>0.056463</td>\n",
" <td>0.095957</td>\n",
" <td>0.043178</td>\n",
" <td>0.198193</td>\n",
" <td>0.515501</td>\n",
" <td>0.437964</td>\n",
" <td>1.000000</td>\n",
" <td>0.033911</td>\n",
" <td>2.836513</td>\n",
" <td>0.991139</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
2020-05-21 16:20:12 +02:00
" <td>Ready_SVDBiased</td>\n",
2020-05-21 22:53:34 +02:00
" <td>0.942994</td>\n",
" <td>0.743492</td>\n",
" <td>0.083351</td>\n",
" <td>0.034097</td>\n",
" <td>0.041677</td>\n",
" <td>0.055673</td>\n",
" <td>0.073283</td>\n",
" <td>0.052910</td>\n",
" <td>0.091866</td>\n",
" <td>0.042598</td>\n",
" <td>0.198210</td>\n",
" <td>0.513705</td>\n",
2020-05-21 16:20:12 +02:00
" <td>0.423118</td>\n",
2020-05-21 22:53:34 +02:00
" <td>0.997561</td>\n",
" <td>0.168831</td>\n",
" <td>4.195234</td>\n",
" <td>0.963319</td>\n",
2020-05-21 16:20:12 +02:00
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
2020-05-21 13:42:50 +02:00
" <td>Self_GlobalAvg</td>\n",
" <td>1.125760</td>\n",
" <td>0.943534</td>\n",
" <td>0.061188</td>\n",
" <td>0.025968</td>\n",
" <td>0.031383</td>\n",
" <td>0.041343</td>\n",
" <td>0.040558</td>\n",
" <td>0.032107</td>\n",
" <td>0.067695</td>\n",
" <td>0.027470</td>\n",
" <td>0.171187</td>\n",
" <td>0.509546</td>\n",
" <td>0.384942</td>\n",
" <td>1.000000</td>\n",
" <td>0.025974</td>\n",
" <td>2.711772</td>\n",
" <td>0.992003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_Random</td>\n",
2020-05-21 22:53:34 +02:00
" <td>1.517787</td>\n",
" <td>1.217953</td>\n",
" <td>0.047826</td>\n",
" <td>0.017861</td>\n",
" <td>0.022711</td>\n",
" <td>0.031080</td>\n",
" <td>0.028219</td>\n",
" <td>0.016982</td>\n",
" <td>0.051154</td>\n",
" <td>0.019551</td>\n",
" <td>0.125693</td>\n",
" <td>0.505448</td>\n",
" <td>0.318134</td>\n",
" <td>0.986426</td>\n",
" <td>0.186869</td>\n",
" <td>5.091730</td>\n",
" <td>0.908288</td>\n",
2020-05-21 13:42:50 +02:00
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_I-KNN</td>\n",
" <td>1.030386</td>\n",
" <td>0.813067</td>\n",
" <td>0.026087</td>\n",
" <td>0.006908</td>\n",
" <td>0.010593</td>\n",
" <td>0.016046</td>\n",
" <td>0.021137</td>\n",
" <td>0.009522</td>\n",
" <td>0.024214</td>\n",
" <td>0.008958</td>\n",
" <td>0.048068</td>\n",
" <td>0.499885</td>\n",
" <td>0.154825</td>\n",
" <td>0.402333</td>\n",
" <td>0.434343</td>\n",
" <td>5.133650</td>\n",
" <td>0.877999</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_I-KNNBaseline</td>\n",
" <td>0.935327</td>\n",
" <td>0.737424</td>\n",
" <td>0.002545</td>\n",
" <td>0.000755</td>\n",
" <td>0.001105</td>\n",
" <td>0.001602</td>\n",
" <td>0.002253</td>\n",
" <td>0.000930</td>\n",
" <td>0.003444</td>\n",
" <td>0.001362</td>\n",
" <td>0.011760</td>\n",
" <td>0.496724</td>\n",
" <td>0.021209</td>\n",
" <td>0.482821</td>\n",
" <td>0.059885</td>\n",
" <td>2.232578</td>\n",
" <td>0.994487</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_U-KNN</td>\n",
" <td>1.023495</td>\n",
" <td>0.807913</td>\n",
" <td>0.000742</td>\n",
" <td>0.000205</td>\n",
" <td>0.000305</td>\n",
" <td>0.000449</td>\n",
" <td>0.000536</td>\n",
" <td>0.000198</td>\n",
" <td>0.000845</td>\n",
" <td>0.000274</td>\n",
" <td>0.002744</td>\n",
" <td>0.496441</td>\n",
" <td>0.007423</td>\n",
" <td>0.602121</td>\n",
" <td>0.010823</td>\n",
" <td>2.089186</td>\n",
" <td>0.995706</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_BaselineUI</td>\n",
" <td>0.967585</td>\n",
" <td>0.762740</td>\n",
" <td>0.000954</td>\n",
" <td>0.000170</td>\n",
" <td>0.000278</td>\n",
" <td>0.000463</td>\n",
" <td>0.000644</td>\n",
" <td>0.000189</td>\n",
" <td>0.000752</td>\n",
" <td>0.000168</td>\n",
" <td>0.001677</td>\n",
" <td>0.496424</td>\n",
" <td>0.009544</td>\n",
" <td>0.600530</td>\n",
" <td>0.005051</td>\n",
" <td>1.803126</td>\n",
" <td>0.996380</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_IKNN</td>\n",
" <td>1.018363</td>\n",
" <td>0.808793</td>\n",
" <td>0.000318</td>\n",
" <td>0.000108</td>\n",
" <td>0.000140</td>\n",
" <td>0.000189</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000214</td>\n",
" <td>0.000037</td>\n",
" <td>0.000368</td>\n",
" <td>0.496391</td>\n",
" <td>0.003181</td>\n",
" <td>0.392153</td>\n",
" <td>0.115440</td>\n",
" <td>4.174741</td>\n",
" <td>0.965327</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Model RMSE MAE precision recall F_1 \\\n",
"0 Self_TopPop 2.508258 2.217909 0.188865 0.116919 0.118732 \n",
2020-05-21 22:53:34 +02:00
"0 Ready_SVD 0.949892 0.749292 0.104666 0.048611 0.055656 \n",
"0 Self_SVD 0.913861 0.717063 0.104030 0.044109 0.053339 \n",
2020-05-21 13:42:50 +02:00
"0 Ready_Baseline 0.949459 0.752487 0.091410 0.037652 0.046030 \n",
2020-05-21 22:53:34 +02:00
"0 Ready_SVDBiased 0.942994 0.743492 0.083351 0.034097 0.041677 \n",
2020-05-21 13:42:50 +02:00
"0 Self_GlobalAvg 1.125760 0.943534 0.061188 0.025968 0.031383 \n",
2020-05-21 22:53:34 +02:00
"0 Ready_Random 1.517787 1.217953 0.047826 0.017861 0.022711 \n",
2020-05-21 13:42:50 +02:00
"0 Ready_I-KNN 1.030386 0.813067 0.026087 0.006908 0.010593 \n",
"0 Ready_I-KNNBaseline 0.935327 0.737424 0.002545 0.000755 0.001105 \n",
"0 Ready_U-KNN 1.023495 0.807913 0.000742 0.000205 0.000305 \n",
"0 Self_BaselineUI 0.967585 0.762740 0.000954 0.000170 0.000278 \n",
"0 Self_IKNN 1.018363 0.808793 0.000318 0.000108 0.000140 \n",
"\n",
" F_05 precision_super recall_super NDCG mAP MRR \\\n",
"0 0.141584 0.130472 0.137473 0.214651 0.111707 0.400939 \n",
2020-05-21 22:53:34 +02:00
"0 0.071900 0.092811 0.078241 0.117730 0.057464 0.244097 \n",
"0 0.070510 0.094313 0.075814 0.107692 0.051047 0.201273 \n",
2020-05-21 13:42:50 +02:00
"0 0.061286 0.079614 0.056463 0.095957 0.043178 0.198193 \n",
2020-05-21 22:53:34 +02:00
"0 0.055673 0.073283 0.052910 0.091866 0.042598 0.198210 \n",
2020-05-21 13:42:50 +02:00
"0 0.041343 0.040558 0.032107 0.067695 0.027470 0.171187 \n",
2020-05-21 22:53:34 +02:00
"0 0.031080 0.028219 0.016982 0.051154 0.019551 0.125693 \n",
2020-05-21 13:42:50 +02:00
"0 0.016046 0.021137 0.009522 0.024214 0.008958 0.048068 \n",
"0 0.001602 0.002253 0.000930 0.003444 0.001362 0.011760 \n",
"0 0.000449 0.000536 0.000198 0.000845 0.000274 0.002744 \n",
"0 0.000463 0.000644 0.000189 0.000752 0.000168 0.001677 \n",
"0 0.000189 0.000000 0.000000 0.000214 0.000037 0.000368 \n",
"\n",
" LAUC HR Reco in test Test coverage Shannon Gini \n",
"0 0.555546 0.765642 1.000000 0.038961 3.159079 0.987317 \n",
2020-05-21 22:53:34 +02:00
"0 0.521054 0.501591 0.998091 0.217172 4.458001 0.951551 \n",
"0 0.518782 0.481442 0.872110 0.146465 3.881417 0.972029 \n",
2020-05-21 13:42:50 +02:00
"0 0.515501 0.437964 1.000000 0.033911 2.836513 0.991139 \n",
2020-05-21 22:53:34 +02:00
"0 0.513705 0.423118 0.997561 0.168831 4.195234 0.963319 \n",
2020-05-21 13:42:50 +02:00
"0 0.509546 0.384942 1.000000 0.025974 2.711772 0.992003 \n",
2020-05-21 22:53:34 +02:00
"0 0.505448 0.318134 0.986426 0.186869 5.091730 0.908288 \n",
2020-05-21 13:42:50 +02:00
"0 0.499885 0.154825 0.402333 0.434343 5.133650 0.877999 \n",
"0 0.496724 0.021209 0.482821 0.059885 2.232578 0.994487 \n",
"0 0.496441 0.007423 0.602121 0.010823 2.089186 0.995706 \n",
"0 0.496424 0.009544 0.600530 0.005051 1.803126 0.996380 \n",
"0 0.496391 0.003181 0.392153 0.115440 4.174741 0.965327 "
]
},
2020-05-21 22:53:34 +02:00
"execution_count": 14,
2020-05-21 13:42:50 +02:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import imp\n",
"imp.reload(ev)\n",
"\n",
"import evaluation_measures as ev\n",
"dir_path=\"Recommendations generated/ml-100k/\"\n",
"super_reactions=[4,5]\n",
"test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\\t', header=None)\n",
"\n",
"ev.evaluate_all(test, dir_path, super_reactions)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}