workshops_recommender_systems/.ipynb_checkpoints/P4. Matrix Factorization-checkpoint.ipynb

1468 lines
75 KiB
Plaintext
Raw Permalink Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Self made SVD"
]
},
{
"cell_type": "code",
"execution_count": 6,
"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",
"execution_count": 7,
"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",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Epoch 39 RMSE: 0.7481223595239049. Training epoch 40...: 100%|██████████| 40/40 [02:09<00:00, 3.25s/it]\n"
]
}
],
"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",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f40f450bf98>"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"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",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f40f148f710>"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"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",
"execution_count": 11,
"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",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"943it [00:00, 4506.01it/s]\n"
]
},
{
"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",
" <td>0.915304</td>\n",
" <td>0.719016</td>\n",
" <td>0.100848</td>\n",
" <td>0.042228</td>\n",
" <td>0.051191</td>\n",
" <td>0.067885</td>\n",
" <td>0.092275</td>\n",
" <td>0.07073</td>\n",
" <td>0.104366</td>\n",
" <td>0.049606</td>\n",
" <td>0.192999</td>\n",
" <td>0.517831</td>\n",
" <td>0.465536</td>\n",
" <td>0.867869</td>\n",
" <td>0.150072</td>\n",
" <td>3.847796</td>\n",
" <td>0.972676</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" RMSE MAE precision recall F_1 F_05 \\\n",
"0 0.915304 0.719016 0.100848 0.042228 0.051191 0.067885 \n",
"\n",
" precision_super recall_super NDCG mAP MRR LAUC \\\n",
"0 0.092275 0.07073 0.104366 0.049606 0.192999 0.517831 \n",
"\n",
" HR Reco in test Test coverage Shannon Gini \n",
"0 0.465536 0.867869 0.150072 3.847796 0.972676 "
]
},
"execution_count": 12,
"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",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"943it [00:00, 4962.65it/s]\n",
"943it [00:00, 4020.02it/s]\n",
"943it [00:00, 3974.62it/s]\n",
"943it [00:00, 4763.58it/s]\n",
"943it [00:00, 4203.99it/s]\n",
"943it [00:00, 4230.96it/s]\n",
"943it [00:00, 3909.05it/s]\n",
"943it [00:00, 4215.47it/s]\n",
"943it [00:00, 4293.30it/s]\n",
"943it [00:00, 4389.83it/s]\n",
"943it [00:00, 4410.76it/s]\n"
]
},
{
"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>Ready_LightFMpureMF</td>\n",
" <td>7.953192</td>\n",
" <td>7.462008</td>\n",
" <td>0.334464</td>\n",
" <td>0.219997</td>\n",
" <td>0.217225</td>\n",
" <td>0.254981</td>\n",
" <td>0.233798</td>\n",
" <td>0.266952</td>\n",
" <td>0.398778</td>\n",
" <td>0.263058</td>\n",
" <td>0.629129</td>\n",
" <td>0.607709</td>\n",
" <td>0.913043</td>\n",
" <td>1.000000</td>\n",
" <td>0.275613</td>\n",
" <td>5.085818</td>\n",
" <td>0.913665</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_LightFM</td>\n",
" <td>162.707436</td>\n",
" <td>160.855483</td>\n",
" <td>0.340827</td>\n",
" <td>0.217682</td>\n",
" <td>0.217990</td>\n",
" <td>0.258010</td>\n",
" <td>0.243884</td>\n",
" <td>0.260663</td>\n",
" <td>0.403850</td>\n",
" <td>0.268266</td>\n",
" <td>0.637590</td>\n",
" <td>0.606568</td>\n",
" <td>0.898197</td>\n",
" <td>1.000000</td>\n",
" <td>0.351371</td>\n",
" <td>5.366291</td>\n",
" <td>0.885046</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_P3</td>\n",
" <td>3.702446</td>\n",
" <td>3.527273</td>\n",
" <td>0.282185</td>\n",
" <td>0.192092</td>\n",
" <td>0.186749</td>\n",
" <td>0.216980</td>\n",
" <td>0.204185</td>\n",
" <td>0.240096</td>\n",
" <td>0.339114</td>\n",
" <td>0.204905</td>\n",
" <td>0.572157</td>\n",
" <td>0.593544</td>\n",
" <td>0.875928</td>\n",
" <td>1.000000</td>\n",
" <td>0.077201</td>\n",
" <td>3.875892</td>\n",
" <td>0.974947</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_ImplicitALS</td>\n",
" <td>3.266101</td>\n",
" <td>3.065824</td>\n",
" <td>0.255037</td>\n",
" <td>0.188653</td>\n",
" <td>0.176852</td>\n",
" <td>0.201189</td>\n",
" <td>0.166631</td>\n",
" <td>0.214925</td>\n",
" <td>0.305908</td>\n",
" <td>0.172546</td>\n",
" <td>0.523871</td>\n",
" <td>0.591709</td>\n",
" <td>0.889714</td>\n",
" <td>1.000000</td>\n",
" <td>0.502886</td>\n",
" <td>5.722957</td>\n",
" <td>0.827507</td>\n",
" </tr>\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_LightFMcontent</td>\n",
" <td>182.471340</td>\n",
" <td>180.405210</td>\n",
" <td>0.160339</td>\n",
" <td>0.101224</td>\n",
" <td>0.102198</td>\n",
" <td>0.121074</td>\n",
" <td>0.102682</td>\n",
" <td>0.112455</td>\n",
" <td>0.180079</td>\n",
" <td>0.087429</td>\n",
" <td>0.337825</td>\n",
" <td>0.547572</td>\n",
" <td>0.704136</td>\n",
" <td>0.974973</td>\n",
" <td>0.264791</td>\n",
" <td>4.909893</td>\n",
" <td>0.926201</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_SVD</td>\n",
" <td>0.915304</td>\n",
" <td>0.719016</td>\n",
" <td>0.100848</td>\n",
" <td>0.042228</td>\n",
" <td>0.051191</td>\n",
" <td>0.067885</td>\n",
" <td>0.092275</td>\n",
" <td>0.070730</td>\n",
" <td>0.104366</td>\n",
" <td>0.049606</td>\n",
" <td>0.192999</td>\n",
" <td>0.517831</td>\n",
" <td>0.465536</td>\n",
" <td>0.867869</td>\n",
" <td>0.150072</td>\n",
" <td>3.847796</td>\n",
" <td>0.972676</td>\n",
" </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",
" <td>1.514355</td>\n",
" <td>1.216383</td>\n",
" <td>0.049735</td>\n",
" <td>0.022300</td>\n",
" <td>0.025782</td>\n",
" <td>0.033598</td>\n",
" <td>0.028219</td>\n",
" <td>0.021751</td>\n",
" <td>0.054383</td>\n",
" <td>0.021119</td>\n",
" <td>0.133978</td>\n",
" <td>0.507680</td>\n",
" <td>0.339343</td>\n",
" <td>0.986957</td>\n",
" <td>0.177489</td>\n",
" <td>5.088670</td>\n",
" <td>0.907676</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",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Model RMSE MAE precision recall \\\n",
"0 Ready_LightFMpureMF 7.953192 7.462008 0.334464 0.219997 \n",
"0 Ready_LightFM 162.707436 160.855483 0.340827 0.217682 \n",
"0 Self_P3 3.702446 3.527273 0.282185 0.192092 \n",
"0 Ready_ImplicitALS 3.266101 3.065824 0.255037 0.188653 \n",
"0 Self_TopPop 2.508258 2.217909 0.188865 0.116919 \n",
"0 Ready_LightFMcontent 182.471340 180.405210 0.160339 0.101224 \n",
"0 Self_SVD 0.915304 0.719016 0.100848 0.042228 \n",
"0 Ready_Baseline 0.949459 0.752487 0.091410 0.037652 \n",
"0 Self_GlobalAvg 1.125760 0.943534 0.061188 0.025968 \n",
"0 Ready_Random 1.514355 1.216383 0.049735 0.022300 \n",
"0 Self_BaselineUI 0.967585 0.762740 0.000954 0.000170 \n",
"\n",
" F_1 F_05 precision_super recall_super NDCG mAP \\\n",
"0 0.217225 0.254981 0.233798 0.266952 0.398778 0.263058 \n",
"0 0.217990 0.258010 0.243884 0.260663 0.403850 0.268266 \n",
"0 0.186749 0.216980 0.204185 0.240096 0.339114 0.204905 \n",
"0 0.176852 0.201189 0.166631 0.214925 0.305908 0.172546 \n",
"0 0.118732 0.141584 0.130472 0.137473 0.214651 0.111707 \n",
"0 0.102198 0.121074 0.102682 0.112455 0.180079 0.087429 \n",
"0 0.051191 0.067885 0.092275 0.070730 0.104366 0.049606 \n",
"0 0.046030 0.061286 0.079614 0.056463 0.095957 0.043178 \n",
"0 0.031383 0.041343 0.040558 0.032107 0.067695 0.027470 \n",
"0 0.025782 0.033598 0.028219 0.021751 0.054383 0.021119 \n",
"0 0.000278 0.000463 0.000644 0.000189 0.000752 0.000168 \n",
"\n",
" MRR LAUC HR Reco in test Test coverage Shannon \\\n",
"0 0.629129 0.607709 0.913043 1.000000 0.275613 5.085818 \n",
"0 0.637590 0.606568 0.898197 1.000000 0.351371 5.366291 \n",
"0 0.572157 0.593544 0.875928 1.000000 0.077201 3.875892 \n",
"0 0.523871 0.591709 0.889714 1.000000 0.502886 5.722957 \n",
"0 0.400939 0.555546 0.765642 1.000000 0.038961 3.159079 \n",
"0 0.337825 0.547572 0.704136 0.974973 0.264791 4.909893 \n",
"0 0.192999 0.517831 0.465536 0.867869 0.150072 3.847796 \n",
"0 0.198193 0.515501 0.437964 1.000000 0.033911 2.836513 \n",
"0 0.171187 0.509546 0.384942 1.000000 0.025974 2.711772 \n",
"0 0.133978 0.507680 0.339343 0.986957 0.177489 5.088670 \n",
"0 0.001677 0.496424 0.009544 0.600530 0.005051 1.803126 \n",
"\n",
" Gini \n",
"0 0.913665 \n",
"0 0.885046 \n",
"0 0.974947 \n",
"0 0.827507 \n",
"0 0.987317 \n",
"0 0.926201 \n",
"0 0.972676 \n",
"0 0.991139 \n",
"0 0.992003 \n",
"0 0.907676 \n",
"0 0.996380 "
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import evaluation_measures as ev\n",
"\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",
"execution_count": 14,
"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 ]])"
]
},
"execution_count": 14,
"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",
"execution_count": 15,
"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",
" <td>44</td>\n",
" <td>1.000000</td>\n",
" <td>45</td>\n",
" <td>45</td>\n",
" <td>Eat Drink Man Woman (1994)</td>\n",
" <td>Comedy, Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>855</td>\n",
" <td>0.966812</td>\n",
" <td>856</td>\n",
" <td>856</td>\n",
" <td>Night on Earth (1991)</td>\n",
" <td>Comedy, Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1403</td>\n",
" <td>0.966571</td>\n",
" <td>1404</td>\n",
" <td>1404</td>\n",
" <td>Withnail and I (1987)</td>\n",
" <td>Comedy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>112</td>\n",
" <td>0.966115</td>\n",
" <td>113</td>\n",
" <td>113</td>\n",
" <td>Horseman on the Roof, The (Hussard sur le toit...</td>\n",
" <td>Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>955</td>\n",
" <td>0.965365</td>\n",
" <td>956</td>\n",
" <td>956</td>\n",
" <td>Nobody's Fool (1994)</td>\n",
" <td>Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>1222</td>\n",
" <td>0.965232</td>\n",
" <td>1223</td>\n",
" <td>1223</td>\n",
" <td>King of the Hill (1993)</td>\n",
" <td>Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>60</td>\n",
" <td>0.964481</td>\n",
" <td>61</td>\n",
" <td>61</td>\n",
" <td>Three Colors: White (1994)</td>\n",
" <td>Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>535</td>\n",
" <td>0.963322</td>\n",
" <td>536</td>\n",
" <td>536</td>\n",
" <td>Ponette (1996)</td>\n",
" <td>Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>1102</td>\n",
" <td>0.962597</td>\n",
" <td>1103</td>\n",
" <td>1103</td>\n",
" <td>Trust (1990)</td>\n",
" <td>Comedy, Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>713</td>\n",
" <td>0.962459</td>\n",
" <td>714</td>\n",
" <td>714</td>\n",
" <td>Carrington (1995)</td>\n",
" <td>Drama, Romance</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" code score item_id id \\\n",
"0 44 1.000000 45 45 \n",
"1 855 0.966812 856 856 \n",
"2 1403 0.966571 1404 1404 \n",
"3 112 0.966115 113 113 \n",
"4 955 0.965365 956 956 \n",
"5 1222 0.965232 1223 1223 \n",
"6 60 0.964481 61 61 \n",
"7 535 0.963322 536 536 \n",
"8 1102 0.962597 1103 1103 \n",
"9 713 0.962459 714 714 \n",
"\n",
" title genres \n",
"0 Eat Drink Man Woman (1994) Comedy, Drama \n",
"1 Night on Earth (1991) Comedy, Drama \n",
"2 Withnail and I (1987) Comedy \n",
"3 Horseman on the Roof, The (Hussard sur le toit... Drama \n",
"4 Nobody's Fool (1994) Drama \n",
"5 King of the Hill (1993) Drama \n",
"6 Three Colors: White (1994) Drama \n",
"7 Ponette (1996) Drama \n",
"8 Trust (1990) Comedy, Drama \n",
"9 Carrington (1995) Drama, Romance "
]
},
"execution_count": 15,
"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",
"execution_count": 16,
"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",
"execution_count": 17,
"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",
"execution_count": 18,
"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",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"943it [00:00, 4110.82it/s]\n",
"943it [00:00, 4014.43it/s]\n",
"943it [00:00, 3946.85it/s]\n",
"943it [00:00, 4832.12it/s]\n",
"943it [00:00, 4090.40it/s]\n",
"943it [00:00, 4152.16it/s]\n",
"943it [00:00, 4456.22it/s]\n",
"943it [00:00, 3943.66it/s]\n",
"943it [00:00, 4298.65it/s]\n",
"943it [00:00, 4243.05it/s]\n",
"943it [00:00, 4391.40it/s]\n",
"943it [00:00, 4528.23it/s]\n",
"943it [00:00, 4419.43it/s]\n"
]
},
{
"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>Ready_LightFMpureMF</td>\n",
" <td>7.953192</td>\n",
" <td>7.462008</td>\n",
" <td>0.334464</td>\n",
" <td>0.219997</td>\n",
" <td>0.217225</td>\n",
" <td>0.254981</td>\n",
" <td>0.233798</td>\n",
" <td>0.266952</td>\n",
" <td>0.398778</td>\n",
" <td>0.263058</td>\n",
" <td>0.629129</td>\n",
" <td>0.607709</td>\n",
" <td>0.913043</td>\n",
" <td>1.000000</td>\n",
" <td>0.275613</td>\n",
" <td>5.085818</td>\n",
" <td>0.913665</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_LightFM</td>\n",
" <td>162.707436</td>\n",
" <td>160.855483</td>\n",
" <td>0.340827</td>\n",
" <td>0.217682</td>\n",
" <td>0.217990</td>\n",
" <td>0.258010</td>\n",
" <td>0.243884</td>\n",
" <td>0.260663</td>\n",
" <td>0.403850</td>\n",
" <td>0.268266</td>\n",
" <td>0.637590</td>\n",
" <td>0.606568</td>\n",
" <td>0.898197</td>\n",
" <td>1.000000</td>\n",
" <td>0.351371</td>\n",
" <td>5.366291</td>\n",
" <td>0.885046</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_P3</td>\n",
" <td>3.702446</td>\n",
" <td>3.527273</td>\n",
" <td>0.282185</td>\n",
" <td>0.192092</td>\n",
" <td>0.186749</td>\n",
" <td>0.216980</td>\n",
" <td>0.204185</td>\n",
" <td>0.240096</td>\n",
" <td>0.339114</td>\n",
" <td>0.204905</td>\n",
" <td>0.572157</td>\n",
" <td>0.593544</td>\n",
" <td>0.875928</td>\n",
" <td>1.000000</td>\n",
" <td>0.077201</td>\n",
" <td>3.875892</td>\n",
" <td>0.974947</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_ImplicitALS</td>\n",
" <td>3.266101</td>\n",
" <td>3.065824</td>\n",
" <td>0.255037</td>\n",
" <td>0.188653</td>\n",
" <td>0.176852</td>\n",
" <td>0.201189</td>\n",
" <td>0.166631</td>\n",
" <td>0.214925</td>\n",
" <td>0.305908</td>\n",
" <td>0.172546</td>\n",
" <td>0.523871</td>\n",
" <td>0.591709</td>\n",
" <td>0.889714</td>\n",
" <td>1.000000</td>\n",
" <td>0.502886</td>\n",
" <td>5.722957</td>\n",
" <td>0.827507</td>\n",
" </tr>\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_LightFMcontent</td>\n",
" <td>182.471340</td>\n",
" <td>180.405210</td>\n",
" <td>0.160339</td>\n",
" <td>0.101224</td>\n",
" <td>0.102198</td>\n",
" <td>0.121074</td>\n",
" <td>0.102682</td>\n",
" <td>0.112455</td>\n",
" <td>0.180079</td>\n",
" <td>0.087429</td>\n",
" <td>0.337825</td>\n",
" <td>0.547572</td>\n",
" <td>0.704136</td>\n",
" <td>0.974973</td>\n",
" <td>0.264791</td>\n",
" <td>4.909893</td>\n",
" <td>0.926201</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Ready_SVD</td>\n",
" <td>0.951475</td>\n",
" <td>0.750225</td>\n",
" <td>0.099470</td>\n",
" <td>0.051407</td>\n",
" <td>0.056004</td>\n",
" <td>0.070229</td>\n",
" <td>0.088197</td>\n",
" <td>0.083166</td>\n",
" <td>0.115422</td>\n",
" <td>0.053515</td>\n",
" <td>0.253329</td>\n",
" <td>0.522434</td>\n",
" <td>0.522800</td>\n",
" <td>0.996713</td>\n",
" <td>0.216450</td>\n",
" <td>4.424505</td>\n",
" <td>0.952962</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Self_SVD</td>\n",
" <td>0.915304</td>\n",
" <td>0.719016</td>\n",
" <td>0.100848</td>\n",
" <td>0.042228</td>\n",
" <td>0.051191</td>\n",
" <td>0.067885</td>\n",
" <td>0.092275</td>\n",
" <td>0.070730</td>\n",
" <td>0.104366</td>\n",
" <td>0.049606</td>\n",
" <td>0.192999</td>\n",
" <td>0.517831</td>\n",
" <td>0.465536</td>\n",
" <td>0.867869</td>\n",
" <td>0.150072</td>\n",
" <td>3.847796</td>\n",
" <td>0.972676</td>\n",
" </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>Ready_SVDBiased</td>\n",
" <td>0.937841</td>\n",
" <td>0.739906</td>\n",
" <td>0.079427</td>\n",
" <td>0.032570</td>\n",
" <td>0.039804</td>\n",
" <td>0.053022</td>\n",
" <td>0.071030</td>\n",
" <td>0.050639</td>\n",
" <td>0.088490</td>\n",
" <td>0.039308</td>\n",
" <td>0.201565</td>\n",
" <td>0.512929</td>\n",
" <td>0.425239</td>\n",
" <td>0.997031</td>\n",
" <td>0.170996</td>\n",
" <td>4.167051</td>\n",
" <td>0.963929</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",
" <td>1.514355</td>\n",
" <td>1.216383</td>\n",
" <td>0.049735</td>\n",
" <td>0.022300</td>\n",
" <td>0.025782</td>\n",
" <td>0.033598</td>\n",
" <td>0.028219</td>\n",
" <td>0.021751</td>\n",
" <td>0.054383</td>\n",
" <td>0.021119</td>\n",
" <td>0.133978</td>\n",
" <td>0.507680</td>\n",
" <td>0.339343</td>\n",
" <td>0.986957</td>\n",
" <td>0.177489</td>\n",
" <td>5.088670</td>\n",
" <td>0.907676</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",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Model RMSE MAE precision recall \\\n",
"0 Ready_LightFMpureMF 7.953192 7.462008 0.334464 0.219997 \n",
"0 Ready_LightFM 162.707436 160.855483 0.340827 0.217682 \n",
"0 Self_P3 3.702446 3.527273 0.282185 0.192092 \n",
"0 Ready_ImplicitALS 3.266101 3.065824 0.255037 0.188653 \n",
"0 Self_TopPop 2.508258 2.217909 0.188865 0.116919 \n",
"0 Ready_LightFMcontent 182.471340 180.405210 0.160339 0.101224 \n",
"0 Ready_SVD 0.951475 0.750225 0.099470 0.051407 \n",
"0 Self_SVD 0.915304 0.719016 0.100848 0.042228 \n",
"0 Ready_Baseline 0.949459 0.752487 0.091410 0.037652 \n",
"0 Ready_SVDBiased 0.937841 0.739906 0.079427 0.032570 \n",
"0 Self_GlobalAvg 1.125760 0.943534 0.061188 0.025968 \n",
"0 Ready_Random 1.514355 1.216383 0.049735 0.022300 \n",
"0 Self_BaselineUI 0.967585 0.762740 0.000954 0.000170 \n",
"\n",
" F_1 F_05 precision_super recall_super NDCG mAP \\\n",
"0 0.217225 0.254981 0.233798 0.266952 0.398778 0.263058 \n",
"0 0.217990 0.258010 0.243884 0.260663 0.403850 0.268266 \n",
"0 0.186749 0.216980 0.204185 0.240096 0.339114 0.204905 \n",
"0 0.176852 0.201189 0.166631 0.214925 0.305908 0.172546 \n",
"0 0.118732 0.141584 0.130472 0.137473 0.214651 0.111707 \n",
"0 0.102198 0.121074 0.102682 0.112455 0.180079 0.087429 \n",
"0 0.056004 0.070229 0.088197 0.083166 0.115422 0.053515 \n",
"0 0.051191 0.067885 0.092275 0.070730 0.104366 0.049606 \n",
"0 0.046030 0.061286 0.079614 0.056463 0.095957 0.043178 \n",
"0 0.039804 0.053022 0.071030 0.050639 0.088490 0.039308 \n",
"0 0.031383 0.041343 0.040558 0.032107 0.067695 0.027470 \n",
"0 0.025782 0.033598 0.028219 0.021751 0.054383 0.021119 \n",
"0 0.000278 0.000463 0.000644 0.000189 0.000752 0.000168 \n",
"\n",
" MRR LAUC HR Reco in test Test coverage Shannon \\\n",
"0 0.629129 0.607709 0.913043 1.000000 0.275613 5.085818 \n",
"0 0.637590 0.606568 0.898197 1.000000 0.351371 5.366291 \n",
"0 0.572157 0.593544 0.875928 1.000000 0.077201 3.875892 \n",
"0 0.523871 0.591709 0.889714 1.000000 0.502886 5.722957 \n",
"0 0.400939 0.555546 0.765642 1.000000 0.038961 3.159079 \n",
"0 0.337825 0.547572 0.704136 0.974973 0.264791 4.909893 \n",
"0 0.253329 0.522434 0.522800 0.996713 0.216450 4.424505 \n",
"0 0.192999 0.517831 0.465536 0.867869 0.150072 3.847796 \n",
"0 0.198193 0.515501 0.437964 1.000000 0.033911 2.836513 \n",
"0 0.201565 0.512929 0.425239 0.997031 0.170996 4.167051 \n",
"0 0.171187 0.509546 0.384942 1.000000 0.025974 2.711772 \n",
"0 0.133978 0.507680 0.339343 0.986957 0.177489 5.088670 \n",
"0 0.001677 0.496424 0.009544 0.600530 0.005051 1.803126 \n",
"\n",
" Gini \n",
"0 0.913665 \n",
"0 0.885046 \n",
"0 0.974947 \n",
"0 0.827507 \n",
"0 0.987317 \n",
"0 0.926201 \n",
"0 0.952962 \n",
"0 0.972676 \n",
"0 0.991139 \n",
"0 0.963929 \n",
"0 0.992003 \n",
"0 0.907676 \n",
"0 0.996380 "
]
},
"execution_count": 19,
"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.8.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}