Systemy-rekomedacyjne-praca.../P0. Data preparation.ipynb
2020-06-05 16:01:34 +02:00

683 lines
71 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Building train and test sets"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# if you don't have some library installed try using pip or pip3 to install it - you can do it from the notebook\n",
"# example: !pip install tqdm\n",
"# also on labs it's better to use python3 kernel - ipython3 notebook\n",
"\n",
"import pandas as pd\n",
"import numpy as np\n",
"import scipy.sparse as sparse\n",
"import time\n",
"import random\n",
"import evaluation_measures as ev\n",
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# df = pd.DataFrame(np.loadtxt( './Datasets/ml-1m.dat',delimiter='::'))\n",
"df=pd.read_csv('./Datasets/ml-100k/u.data',delimiter='\\t', header=None)\n",
"df.columns=['user', 'item', 'rating', 'timestamp']\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"train, test = train_test_split(df, test_size=0.2, random_state=30)\n",
"\n",
"train.to_csv('./Datasets/ml-100k/train.csv', sep='\\t', header=None, index=False)\n",
"test.to_csv('./Datasets/ml-100k/test.csv', sep='\\t', header=None, index=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interactions properties"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### How data looks like?"
]
},
{
"cell_type": "code",
"execution_count": 18,
"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>user</th>\n",
" <th>item</th>\n",
" <th>rating</th>\n",
" <th>timestamp</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>196</td>\n",
" <td>242</td>\n",
" <td>3</td>\n",
" <td>881250949</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>186</td>\n",
" <td>302</td>\n",
" <td>3</td>\n",
" <td>891717742</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>22</td>\n",
" <td>377</td>\n",
" <td>1</td>\n",
" <td>878887116</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>244</td>\n",
" <td>51</td>\n",
" <td>2</td>\n",
" <td>880606923</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>166</td>\n",
" <td>346</td>\n",
" <td>1</td>\n",
" <td>886397596</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" user item rating timestamp\n",
"0 196 242 3 881250949\n",
"1 186 302 3 891717742\n",
"2 22 377 1 878887116\n",
"3 244 51 2 880606923\n",
"4 166 346 1 886397596"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[:5]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sample properties"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"We have 943 users, 1682 items and 100000 ratings.\n",
"\n",
"Average number of ratings per user is 106.04. \n",
"\n",
"Average number of ratings per item is 59.453.\n",
"\n",
"Data sparsity (% of missing entries) is 6.3047%.\n"
]
}
],
"source": [
"users, items, ratings=len(set(df['user'])), len(set(df['item'])), len(df)\n",
"\n",
"print('We have {} users, {} items and {} ratings.\\n'.format(users, items, ratings))\n",
"\n",
"print('Average number of ratings per user is {}. \\n'.format(round(ratings/users,2)))\n",
"print('Average number of ratings per item is {}.\\n'.format(round(ratings/items,4)))\n",
"print('Data sparsity (% of missing entries) is {}%.'.format(round(100*ratings/(users*items),4)))"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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LrlE559/vr7//e8rOoI6jBtvvFGjR49uzX7eeed1yXoPOeQQjR07VmamRYsW6Qtf+IKWLFmigQMH6r777tMWW2yhNWvWaN9999XYsWM3mz2Qe+65pxYuXCgpaq4GDx6so446qnU+24a07bbbatq0abrxxhsrzr/ssss0ZMgQvfLKK63TTj31VN10000aMmSIfvGLX+iCCy7QVVdd1SV5AAAA0Hmd2VP6b5KWuPuylglmNsDMesf3Pyhpd0mPdy5izzd8+PDW+wMHDmx9/J73vEdDhgzR8uXLqz6/b9++WrdundauXau+fftq6dKlWr58uT7xiU+0+5xbbrlFe+21lz72sY/pm9/8Zuueo5Y9bi323XdfNTc3S5KOPPJINTQ0aJ999tGMGTNal9l66601adIk7b///hoxYoRWrVql++67T7Nnz9Z3vvMd1dfXa+nSpTrppJN03XXXpbLceuutOvDAAzV8+HAdc8wxWrNmTdX3u/XWW7c2VK+99lrr/X79+mmLLbaQJL3xxht65513qq4nb8q3g47ccccd2m233fSBD3yg6nJdvW2U733M47axww476IADDlDfvn1T85YtW6Z58+bpq1/9amK6mbU2qS+//PJm8yUGAADA5qKWS8JcI+mvkvY0s2Vm9pV41jglD92VpIMlLTKzhyVdJ+lr7v5CVwbuiZqamipOb25u1kMPPaSPfOQjrdN+/vOfa+jQoTr55JP14osvSpK+973vacKECbr00kt12mmnadKkSTr//PPbfb3XX39d48eP15w5c3TPPffomWeeScw//fTTKz7vyiuvVFNTkxobGzVt2jQ9//zzkqLGcMSIEXr44Yd18MEHa+bMmfroRz+qsWPH6qKLLtLChQu12267VVznc889pwsuuEC33367FixYoFKppP/8z/+UFB3SOXv27IrPu+GGG7TXXntp1KhRuvLKK1unP/300xo6dKh23nlnffe73+1RDUZ720El1157rY477rjEtCy2jfbkadtoz+mnn66f/OQn6tUr+c/ar371Kx1xxBHaaaed9Otf/1oTJ07cqPUCAACge3XYlLr7ce4+0N37uvtO7n5FPP0kd/9lm2Wvd/d93H1/dx/u7nO6K3hPMmHChNS0NWvW6Oijj9all16q9743Ou321FNP1dKlS7Vw4UINHDhQ3/72tyVJ9fX1uv/++3XnnXfq8ccf16BBg+TuOvbYY3X88cdr1apViXUvWbJEu+66q3bffXeZmY4//vjE/Ep7rCRp2rRprXu8nn76aT36aDR+Vb9+/Vr3pjU0NLTuPavF/fffr8WLF+uggw5SfX29Zs2apSeffFJSdEjn2LFjKz7vqKOO0pIlS3TjjTfq7LPPbp2+8847a9GiRXrsscc0a9as1HvPs0rbQSVvvvmmZs+erWOOOaZ1WlbbRnvytG1UMnfuXO2www5qaGhIzfvpT3+qm2++WcuWLdOXv/xlnXnmmTWvFwAAAN2vswMdoQYzZ85MPH7rrbd09NFH64tf/KI+97nPtU7fcccd1bt3b/Xq1Uvjx4/XAw88kHieu+uCCy7Q2WefrXPPPVfnnnuujj/+eE2bNi31mu2dT9inTx/97W9/a338+uuvS5Luuusu3X777frrX/+qhx9+WMOGDWud17dv39b19e7dW+vXr6/5vbu7Dj30UC1cuFALFy7U4sWLdcUVV9T8/IMPPlhLly7Vc889l5g+aNAg7bPPPrrnnntqXldobbeD9vzxj3/U8OHDteOOO7ZOy2rbKD8kOu/bRrn58+dr9uzZqqur07hx4/TnP/9Zxx9/vFavXq2HH3649WiEY489Vvfdd98mvQYAAAC6B01pxtxdX/nKVzRkyJDUHpvy0VlvuOEG7btv8nKvs2bN0qhRo9S/f3+tXbtWvXr1Uq9evbR27drEcnvttZeeeOIJLV26VJJ0zTUbjrKuq6trvb9gwQI98cQTkqJz7fr376+tttpKS5Ys0f3339/he3nPe96jV199teoyI0aM0Pz581tHPF27dq3+9a9/VX3OY4891jpy7IIFC/Tmm29qu+2207Jly7Ru3TpJ0osvvqj58+drzz337DBnT3PNNdekDt3NattYsGCBpPxuG+358Y9/rGXLlqm5uVnXXnutPvWpT+k3v/mN+vfvr5dffrl1vbfddpuGDBmySa8BAACA7rHJo+8WTd3EeVXnN08dVdN65s+fr1//+tfab7/9VF9fL0n60Y9+pCOOOEL/8R//oYULF8rMVFdXp+nTp7c+b+3atZo1a5ZuvfVWSdKZZ56po48+Wv369Us0FpL0rne9SzNmzNCoUaO0/fbb62Mf+5geeeQRSdLRRx+tE044QfX19TrggAO0xx57SJIOP/xw/fKXv9TQoUO15557asSIER2+l3Hjxmn8+PGaNm1au4cEDxgwQFdddZWOO+44vfHGG5KkCy64QHvssYfOOecclUql1GGa119/va6++mr17dtXW265pX7/+9/LzPSPf/xD3/72t2VmcnedddZZ2m+//Wope4+xdu1a3XbbbYnfvaTMto2rr74619vGM888o1KppFdeeUW9evXSpZdeqsWLF7ceAt9Wnz59NHPmTB199NHq1auX+vfvnzhHGQAAAOFZyGsZtiiVSr6p1y3MSmea0hUrVgQdkOeuu+7SxRdfrLlz5+YiT1Hlse5ttw0AAACgO5hZk7uXKs3j8N0MbG68TcUAACAASURBVMyoq1nIW56ioO4AAABAGntKa9SZPaUth5vmRd7yFAV1BwAAQFGxpxQAAAAAkEs0pQAAAACAYGhKM9B2JNXQ8panKKg7AAAAkMY5pTXqqkvCAAAAAEDRcE5pYGYWOkJC3vIUBXUHAAAA0mhKAQAAAADB0JQCAAAAAIKhKc3A6NGjQ0dIyFueoqDuAAAAQBpNaQbmzJkTOkJC3vIUBXUHAAAA0mhKMzBmzJjQERLylqcoqDsAAACQRlOagblz54aOkJC3PEVB3QEAAIA0mlKkmJlOOOGE1sfr16/XgAEDNvqcyJEjR6rl+rNHHHGEXnrppS7NKUlPPfWUPv3pT2vIkCHae++91dzcLEk66aSTtOuuu6q+vl719fVauHBhl782AAAAgM7rEzoA8ufd7363HnnkEa1bt05bbrmlbrvtNg0ePLhT67z55pu7KF3Sl770JU2aNEmHHnqo1qxZo169NnzPctFFF+nzn/98t7wuAAAAgK7BntIMuHvoCAm15PnMZz6jefPmSZKuueYaHXfcca3zXnvtNZ188sk64IADNGzYMN10002SpHXr1mncuHEaOnSojj32WK1bt671OXV1dXruueckSUceeaQaGhq0zz77aMaMGa3LbL311po0aZL2339/jRgxQqtWraqacfHixVq/fr0OPfTQ1udvtdVWNVYhe3nbDgAAAIA8oCnNQHnjlQe15Bk3bpyuvfZavf7661q0aJE+8pGPtM774Q9/qE996lN68MEHdeedd+o73/mOXnvtNV1++eXaaquttGjRIk2aNElNTU0V133llVeqqalJjY2NmjZtmp5//nlJUbM7YsQIPfzwwzr44IM1c+ZMSdLs2bN1zjnnpNbz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\n",
"text/plain": [
"<Figure size 1152x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"items_per_user=df.groupby(['user']).count()['rating']\n",
"\n",
"plt.figure(figsize=(16,8))\n",
"plt.hist(items_per_user, bins=100)\n",
"\n",
"# Let's add median\n",
"t=items_per_user.median()\n",
"plt.axvline(t, color='k', linestyle='dashed', linewidth=1)\n",
"plt.text(t*1.1, plt.ylim()[1]*0.9, 'Median: {:.0f}'.format(t))\n",
"\n",
"# Let's add also some percentiles\n",
"t=items_per_user.quantile(0.25)\n",
"plt.axvline(t, color='k', linestyle='dashed', linewidth=1)\n",
"plt.text(t*1.1, plt.ylim()[1]*0.95, '25% quantile: {:.0f}'.format(t))\n",
"\n",
"t=items_per_user.quantile(0.75)\n",
"plt.axvline(t, color='k', linestyle='dashed', linewidth=1)\n",
"plt.text(t*1.05, plt.ylim()[1]*0.95, '75% quantile: {:.0f}'.format(t))\n",
"\n",
"plt.title('Number of ratings per user', fontsize=30)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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1ZIWS3pa0p3xrM8AACQmE7Pv7rbbbt6zZ8+0u7HJlixZos6dO2/1MfOIPAEAAADpa2hoeMfdi34xz8RIac+ePVVfX592NwAAAAAAW4CZvdnaOmbfTcC4ceM+EzHziDwBAAAA2ZaJw3dramo8zyOlZqbQeUwjZh6RJwAAACB9Ztbg7jXF1jFSCgAAAABIDUUpAAAAACA1FKUJSOPQ4zwf7hwSeQIAAACyjaIUAAAAAJAaJjpKABMdZRd5AgAAANLHREcAAAAAgEyiKAUAAAAApIaiNAFjx479TMTMI/IEAAAAZBvnlAIAAAAAtijOKd3CunXr9pmImUfkCQAAAMg2itIENDU1af78+fra176mAw44QH369NE111yzdv24cePUvXt3VVVVqaqqSvfdd58k6YknnlDfvn116KGHas6cOZKkZcuWaeDAgWVnjG1qatpi7+cPf/iDXnzxxbXPL774Yj344IOSpAEDBmzWtT9nzpypqqoq9enTR1/96lc3u6/ltJanV155Ze3nUVVVpR133FFXX321pC3zeW1JW+rzev/99zVkyBAdfPDB6tOnj2699da16yZNmqTevXurd+/emjRp0ua9AQAAAHymtUu7A1uLdu3a6aqrrlK/fv20fPlyVVdX6+ijj9YXvvAFSdIPf/hD/fjHP17vNVdddZXuuecezZs3TzfeeKOuuuoqXXrppfr5z38uM0vjbUiKipzBgwev7fsll1ySyHaXLVums88+W9OnT9dee+2lt99+O5Htbor9999fjY2NkqRPPvlE3bt31wknnLB2PZ+XdMMNN+gLX/iCpkyZoiVLlmj//ffXt7/9ba1YsULjx49XfX29zEzV1dUaOnSodtlll0TiAgAA4LOFkdIE9OvXT127dlW/fv0kSTvssIMOOOAALVy4sOTr2rdvr1WrVmnlypVq37695s6dq4ULF5YcQZw+fbo+//nPa/vtt9cPfvADDR48WFI0unfllVeubXfggQdq3rx5kqTjjz9e1dXV6tOnj+rq6ta26dixoy666CIdfPDB6t+/vxYvXqy//OUvmjx5sn7yk5+oqqpKc+fO1YgRI3T33Xdv0Jf7779fhx9+uPr166eTTz5ZK1asKPl+//d//1cnnnii9tprL0nS7rvvXrJ9Epo/k1Ieeugh9erVS3vvvXfJdpvzeX35y1/O3edlZlq+fLncXStWrFCnTp3Url07zZgxQ0cffbQ6deqkXXbZRUcffbSmT59eclsAAABAayhKE9DQ0LDe83nz5um5557TF7/4xbXLrr/+evXt21dnnnmm3nvvPUnSz372M9XW1urqq6/W6NGjddFFF+nSSy9tNc5HH32kkSNHasqUKVq+fLneeuutivp3yy23qKGhQfX19br22mu1dOlSSdKHH36o/v37a/bs2TryyCM1YcIEfelLX9LQoUP1q1/9So2NjerVq1fRbb7zzju67LLL9OCDD2rWrFmqqanRf/7nf0qKDh+dPHnyBq959dVX9d5772nAgAGqrq7WbbfdVlH/N0fLz6aYO++8U6eccsp6y5L+vB577LHcfV6jR4/WSy+9pG7duumggw7SNddcozZt2mjhwoXac88917br0aNH2R9gAAAAgNZQlCagtrZ27eMVK1Zo2LBhuvrqq7XjjjtKkr73ve9p7ty5amxsVNeuXfWjH/1IklRVVaWnnnpKjzzyiF5//XV169ZN7q5vfetbOvXUU7V48eL14rz88svaZ5991Lt3b40aNUqnnnpqRf279tpr146uzZ8/X6+99pokqUOHDmtH7qqrq9eO1FXiqaee0osvvqgjjjhCVVVVmjRpkt58801J0eGjQ4cO3eA1a9asUUNDg6ZNm6YZM2bo0ksv1auvvlpxzE1R+NkUs3r1ak2ePFknn3zy2mVb4vMys9x9XjNmzFBVVZUWLVqkxsZGjR49Wh988EHR82fTPHwZAAAA+UZRmoAJEyZIkv7xj39o2LBh+va3v60TTzxx7fouXbqobdu2atOmjUaOHKlnnnlmvde7uy677DKNGTNG48eP1/jx43Xqqafq2muv3SBW85f/5pjN2rVrp08//XTt848++khSNLHQgw8+qCeffFKzZ8/WIYccsnZd+/bt126vbdu2WrNmTcXv2d119NFHq7GxUY2NjXrxxRd18803l3xNjx49NGjQIG2//fbabbfddOSRR2r27NkVx9wULfPU0p/+9Cf169dPXbp0WbtsS3xeLeXh87r11lt14oknysy07777ap999tHLL7+sHj16aP78+WvbLViwgFmOAQAAsMkoShPi7jrrrLN0wAEH6Pzzz19vXeEMsPfee68OPPDA9dZPmjRJxx57rHbZZRetXLlSbdq0UZs2bbRy5cr12n3+85/XG2+8oblz50qS7rjjjrXrevbsqVmzZkmSZs2apTfeeENSNIPqLrvsou22204vv/yynnrqqbLvZYcddtDy5ctLtunfv7+eeOKJtbPQrly5suyo53HHHafHHntMa9as0cqVK/X000/rgAMOKNufLemOO+7Y4NBdPq/IXnvtpYceekiStHjxYr3yyiv6p3/6Jw0cOFD333+/3nvvPb333nu6//77NXDgwLL9BAAAAIph9t0K9bxwWsn1TzzxhH7729/qoIMOUlVVlSTpl7/8pY455hj99Kc/VWNjo8xMPXv21E033bT2dStXrtSkSZN0//33S5LOP/98DRs2TB06dFiviJGkbbbZRnV1dTr22GMlSXvvvbdeeOEFSdKwYcN02223qaqqSoceeqj2228/SdKgQYP0X//1X+rbt6/2339/9e/fv+x7HT58uEaOHKlrr7226IQ5ktS5c2dNnDhRp5xyij7++GNJ0mWXXab99ttPF198sWpqajY4JPSAAw7QoEGD1LdvX7Vp00b/9m//tkHBF9LKlSv1wAMPrPd5SNoin9duu+2mL3/5y7n6vMaMGaMRI0booIMOkrvriiuu0G677bZ23aGHHiopOie1U6dOZfsJAAAAFGNpXl+xWU1NjW/OtS9DKFWUrlm+VAtuOD1gb6RFixbp1Vdf1ZVXXqmpU6cGjZ0nixYtysyhpTNnzuTzAgAAwGeSmTW4e02xdRy+m4DVi+cEj1nJrLIgTwAAAEDWMVJaoVIjpW9eMbjojKRbkpkFj5lH5AkAAABIHyOlAAAAAIBMoigFAAAAAKSGojQBnQaODh6z5YyxKI48AQAAANlGUZqAHaoGBY9ZW1sbPGYekScAAAAg2yhKE/DmFYODxzSz4DHziDwBAAAA2UZRCgAAAABIDUUpAAAAACA1FKUJ2LbXocFjDh4c/pDhPCJPAAAAQLZRlCZg95PGBo85ZcqU4DHziDwBAAAA2UZRmoC37x4fPOaQIUOCx8wj8gQAAABkG0VpAlbNfTZ4zKlTpwaPmUfkCQAAAMg2itKtiJnptNNOW/t8zZo16ty580afVzlgwADV19dLko455hgtW7Ys0X42Njbq8MMPV58+fdS3b1/97ne/W7vuK1/5iqqqqlRVVaVu3brp+OOPTzQ2AAAAgGxpl3YHkJztt99eL7zwglatWqVtt91WDzzwgLp3775Z27zvvvsS6t062223nW677Tb17t1bixYtUnV1tQYOHKidd95Zjz322Np2w4YN03HHHZd4fAAAAADZwUhpAva+IPwhou5edPk3vvENTZs2TZJ0xx136JRTTlm77sMPP9SZZ56pQw89VIcccoj++Mc/SpJWrVql4cOHq2/fvvrWt76lVatWrX1Nz5499c4770iSjj/+eFVXV6tPnz6qq6tb26Zjx4666KKLdPDBB6t///5avHhxyb7vt99+6t27tySpW7du2n333bVkyZL12ixfvlwPP/zwZo+UtpYnAAAAANlQcVFqZm3N7Dkzmxo/38fMnjaz15qZYQcAACAASURBVMzsd2bWIV7+ufj5nHh9zy3T9exY3jg9eMzCorDQ8OHDdeedd+qjjz7S888/ry9+8Ytr1/3iF7/QUUcdpWeffVaPPPKIfvKTn+jDDz/UjTfeqO22207PP/+8LrroIjU0NBTd9i233KKGhgbV19fr2muv1dKlSyVFxW7//v01e/ZsHXnkkZowYYIkafLkybr44otLvo9nnnlGq1evVq9evdZbfu+99+rrX/+6dtxxx4pzUkxreQIAAACQDRszUnqupJcKnl8h6dfu3lvSe5LOipefJek9d99X0q/jdlu1d2dcHzzmqFGjii7v27ev5s2bpzvuuEPHHHPMeuvuv/9+XX755aqqqtKAAQP00Ucf6e9//7seffRRnXrqqWtf37dv36Lbvvbaa9eOhs6fP1+vvfaaJKlDhw5rz1utrq7WvHnzJElDhw7VJZdc0up7aGpq0mmnnaZbb71Vbdqsvyu2HOXdVK3lCQAAAEA2VHROqZn1kHSspF9IOt/MTNJRkv41bjJJ0jhJN0o6Ln4sSXdLut7MzDmOMpihQ4fqxz/+sWbOnLl2NFOKDmW95557tP/++2/wmugjbd3MmTP14IMP6sknn9R22223tqiVpPbt2699fdu2bbVmzZqyffzggw907LHH6rLLLlP//v3XW7d06VI988wzuvfee8tuBwAAAEC+VTpSerWkn0r6NH6+q6Rl7t5cfSyQ1DyjTndJ8yUpXv9+3B6BnHnmmbr44ot10EEHrbd84MCBuu6669aeZ/ncc89Jko488kjdfvvtkqQXXnhBzz///AbbfP/997XLLrtou+2208svv6ynnnpqk/u3evVqnXDCCTr99NN18sknb7D+//7v/zR48GBt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\n",
"text/plain": [
"<Figure size 1152x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"items_per_user=df.groupby(['item']).count()['rating']\n",
"\n",
"plt.figure(figsize=(16,8))\n",
"plt.hist(items_per_user, bins=100)\n",
"\n",
"# Let's add median\n",
"t=items_per_user.median()\n",
"plt.axvline(t, color='k', linestyle='dashed', linewidth=1)\n",
"plt.text(t*1.1, plt.ylim()[1]*0.9, 'Median: {:.0f}'.format(t))\n",
"\n",
"# Let's add also some percentiles\n",
"t=items_per_user.quantile(0.25)\n",
"plt.axvline(t, color='k', linestyle='dashed', linewidth=1)\n",
"plt.text(t*1.1, plt.ylim()[1]*0.95, '25% quantile: {:.0f}'.format(t))\n",
"\n",
"t=items_per_user.quantile(0.75)\n",
"plt.axvline(t, color='k', linestyle='dashed', linewidth=1)\n",
"plt.text(t*1.05, plt.ylim()[1]*0.95, '75% quantile: {:.0f}'.format(t))\n",
"\n",
"plt.title('Number of ratings per item', fontsize=30)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"rating\n",
"1 0.06110\n",
"2 0.11370\n",
"3 0.27145\n",
"4 0.34174\n",
"5 0.21201\n",
"Name: user, dtype: float64"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.groupby(['rating']).count()['user']/len(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Item attributes"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"genres = pd.read_csv('./Datasets/ml-100k/u.genre', sep='|', header=None,\n",
" encoding='latin-1')\n",
"genres=dict(zip(genres[1], genres[0]))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{0: 'unknown',\n",
" 1: 'Action',\n",
" 2: 'Adventure',\n",
" 3: 'Animation',\n",
" 4: \"Children's\",\n",
" 5: 'Comedy',\n",
" 6: 'Crime',\n",
" 7: 'Documentary',\n",
" 8: 'Drama',\n",
" 9: 'Fantasy',\n",
" 10: 'Film-Noir',\n",
" 11: 'Horror',\n",
" 12: 'Musical',\n",
" 13: 'Mystery',\n",
" 14: 'Romance',\n",
" 15: 'Sci-Fi',\n",
" 16: 'Thriller',\n",
" 17: 'War',\n",
" 18: 'Western'}"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"genres"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"movies = pd.read_csv('./Datasets/ml-100k/u.item', sep='|', encoding='latin-1', header=None)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"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>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" <th>7</th>\n",
" <th>8</th>\n",
" <th>9</th>\n",
" <th>...</th>\n",
" <th>14</th>\n",
" <th>15</th>\n",
" <th>16</th>\n",
" <th>17</th>\n",
" <th>18</th>\n",
" <th>19</th>\n",
" <th>20</th>\n",
" <th>21</th>\n",
" <th>22</th>\n",
" <th>23</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Toy Story (1995)</td>\n",
" <td>01-Jan-1995</td>\n",
" <td>NaN</td>\n",
" <td>http://us.imdb.com/M/title-exact?Toy%20Story%2...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>GoldenEye (1995)</td>\n",
" <td>01-Jan-1995</td>\n",
" <td>NaN</td>\n",
" <td>http://us.imdb.com/M/title-exact?GoldenEye%20(...</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>Four Rooms (1995)</td>\n",
" <td>01-Jan-1995</td>\n",
" <td>NaN</td>\n",
" <td>http://us.imdb.com/M/title-exact?Four%20Rooms%...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>3 rows × 24 columns</p>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 \\\n",
"0 1 Toy Story (1995) 01-Jan-1995 NaN \n",
"1 2 GoldenEye (1995) 01-Jan-1995 NaN \n",
"2 3 Four Rooms (1995) 01-Jan-1995 NaN \n",
"\n",
" 4 5 6 7 8 9 ... \\\n",
"0 http://us.imdb.com/M/title-exact?Toy%20Story%2... 0 0 0 1 1 ... \n",
"1 http://us.imdb.com/M/title-exact?GoldenEye%20(... 0 1 1 0 0 ... \n",
"2 http://us.imdb.com/M/title-exact?Four%20Rooms%... 0 0 0 0 0 ... \n",
"\n",
" 14 15 16 17 18 19 20 21 22 23 \n",
"0 0 0 0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 1 0 0 \n",
"2 0 0 0 0 0 0 0 1 0 0 \n",
"\n",
"[3 rows x 24 columns]"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"movies[:3]"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"for i in range(19):\n",
" movies[i+5]=movies[i+5].apply(lambda x: genres[i] if x==1 else '')"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"movies['genre']=movies.iloc[:, 5:].apply(lambda x: ', '.join(x[x!='']), axis = 1)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"movies=movies[[0,1,'genre']]\n",
"movies.columns=['id', 'title', 'genres']"
]
},
{
"cell_type": "code",
"execution_count": 30,
"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>id</th>\n",
" <th>title</th>\n",
" <th>genres</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Toy Story (1995)</td>\n",
" <td>Animation, Children's, Comedy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>GoldenEye (1995)</td>\n",
" <td>Action, Adventure, Thriller</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>Four Rooms (1995)</td>\n",
" <td>Thriller</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>Get Shorty (1995)</td>\n",
" <td>Action, Comedy, Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>Copycat (1995)</td>\n",
" <td>Crime, Drama, Thriller</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id title genres\n",
"0 1 Toy Story (1995) Animation, Children's, Comedy\n",
"1 2 GoldenEye (1995) Action, Adventure, Thriller\n",
"2 3 Four Rooms (1995) Thriller\n",
"3 4 Get Shorty (1995) Action, Comedy, Drama\n",
"4 5 Copycat (1995) Crime, Drama, Thriller"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"movies.to_csv('./Datasets/ml-100k/movies.csv', index=False)\n",
"movies[:5]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Toy example"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"if not os.path.exists('./Datasets/toy-example/'):\n",
" os.mkdir('./Datasets/toy-example/')"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"toy_train=pd.DataFrame([[0,0,3,0], [0,10,4,0], [0,40,5,0], [0,70,4,0],\n",
" [10,10,1,0], [10,20,2,0], [10,30,3,0],\n",
" [20,30,5,0], [20,50,3,0], [20,60,4,0]])\n",
"toy_test=pd.DataFrame([[0,60,3,0],\n",
" [10,40,5,0],\n",
" [20,0,5,0], [20,20,4,0], [20,70,2,0]])\n",
"\n",
"toy_train.to_csv('./Datasets/toy-example/train.csv', sep='\\t', header=None, index=False)\n",
"toy_test.to_csv('./Datasets/toy-example/test.csv', sep='\\t', header=None, index=False)"
]
}
],
"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.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}