WSR-432813/P0. Data preparation.ipynb
2021-06-11 01:28:24 +02:00

708 lines
71 KiB
Plaintext
Raw 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": 1,
"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",
"#!pip install pandas\n",
"#!pip install numpy\n",
"#!pip install scipy\n",
"#!pip install time\n",
"#!pip install random\n",
"#!pip install matplotlib\n",
"#!pip install os\n",
"#!pip install sklearn\n",
"#!pip install surprise\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 matplotlib\n",
"import matplotlib.pyplot as plt\n",
"import os\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"import helpers\n",
"\n",
"os.makedirs('./Datasets/', exist_ok = True)\n",
"\n",
"helpers.download_movielens_100k_dataset()\n",
"\n",
"df=pd.read_csv('./Datasets/ml-100k/u.data',delimiter='\\t', header=None)\n",
"df.columns=['user', 'item', 'rating', 'timestamp']\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": 2,
"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": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[:5]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sample properties"
]
},
{
"cell_type": "code",
"execution_count": 3,
"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.0445. \n",
"\n",
"Average number of ratings per item is 59.453.\n",
"\n",
"Data sparsity (% of missing entries) is 93.6953%.\n"
]
}
],
"source": [
"users, items, ratings=df['user'].nunique(), df['item'].nunique(), len(df)\n",
"\n",
"print(f'We have {users} users, {items} items and {ratings} ratings.\\n')\n",
"\n",
"print(f'Average number of ratings per user is {round(ratings/users,4)}. \\n')\n",
"print(f'Average number of ratings per item is {round(ratings/items,4)}.\\n')\n",
"print(f'Data sparsity (% of missing entries) is {round(100*(1-ratings/(users*items)),4)}%.')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6UAAAHvCAYAAACsfXllAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABNeUlEQVR4nO3dfZwVdd3/8fdHbkzD8iYkbtQ1M8UbXOComGVkl8kFSJrdwC9TswusSyvTSsoULCtMuzKzTEhTK7HSNG7M27TUMt1FMENKsVXuRATvEO/Qz++PmV3O7Jw9u7C7852z83o+HvvYc2bmzHnvd2ZhP+f7ne+YuwsAAAAAgBC2Ch0AAAAAAFBcFKUAAAAAgGAoSgEAAAAAwVCUAgAAAACCoSgFAAAAAARDUQoAAAAACIaiFAAyYmbTzczjr9Gh89QaM9vRzL5jZg+a2Ytm9mbcls+FztZdzOzKsnOmLnQeAAC6A0UpgC5X9kd089fBHXjNxLLtp2cQEzXEzAZIapT0DUn1kvpJspCZtoSZjY4/nJhOkQkAQKR36AAACuG7kj4UOgRq2lmS6uLH90r6laTVklzS64EybYnRkqbFj++S1BQqCAAAeUFRCiALh5vZf7n77aGDoGaNjb8/K+nD7r4hZJisuPuJkk4MHAMAgG7F8F0A3am8cPhusBToCXaJv/+rKAUpAABFQVEKoDstk3RD/PhAM/toyDCoaX3j768GTQEAALocRSmA7vZNSW/Gj88zs15buqOyiZDu6uy2ZnZX8zbx863M7KR4+dNm9pKZPWxm3zSz7Vq99p1m9m0ze8jMXjCz583sL2b2iS34mcaa2R/MbLmZvRp/n21mh2zGPt5hZmeZ2d1m9pSZvWZma+LnXzOzfu28vilui6b4+VvM7Itmdo+ZrY5nub1rc3+2sv1va2ZfNrM743yvxm18j5l93cze3sbrWmYrLlv8gQoTaY3ezDwnlr32xHhZycx+bmaPxcc+sV+LvD+e/fdPZrYy/jleMrP/mNm1ZnZUlfecHv8c08oW31nhZ7mr1euqzr4bT5yUmCDMzHY1sx+Y2ZI433Nm9lcz+18z69BlO2Z2jJnNj4//K/E58iuLJy2r1IZt7OcjZvZbM3vczDbE+1phZovM7Hdxpp06kqmN/Sfazcz6m9m3zOwf8e/mC2bWaGZTzWybzdjvmLjtH7VopucNZrY0Xva+dl672edXBzN1eCbmjmxr0e/5/5rZbWa2Kj6f18fH+gEzu9zMPm5mfSu9vmw/h5jZpWa2OD7XXjGzJ83sN2Y2rp3XVjp/9zKzi8zskfj4VT3HAPQQ7s4XX3zx1aVfiiafcUlL4udXli07sY3XTCzbZno7+71rMzJU3FbRJDPN2/STdHvZ89ZfCyTtEL/uEElPV9n2wiqZppdtN1rST6rs5w1J0zrwc54o6YUq+3FJT0k6pMo+muLtmiTtLunhCvtot83b2PcoSSvayfeMoutEq7VXta/Rm5npxPLzUdJUSRur7VfSLzqY5Y+S3taJn+WuVq+7smxdXYX9ji5bP13SGEXX3ba1/1slbV2lbfpI+m2V12+UdEbrNqywn20kzevgz3xaF/xbc5ek4ZKWV3mfRyXt3s7++ku6owOZfy6pT1edXx38WaueC5t53uwRt0dHjk99G+/xVknXduD18yRt18Y+Wp+/xyu67KP1PlLnGF988dWzvpjoCEAWpkuapGgI5nQzu8bdXwsbKeEXimYHvlfRH+RPSdpN0inx9+GSLjKzaZJuUfRz/FzSPZJek/R+SZMVTR53hpnd7O1P6vQlSUcrKsh+LukhSdsqKiqOVTSSZbqZrXX3SyrtwMy+JOmi+OkGSddJ+quktZLeEe9rgqQBkm43swPdfXGVTFtL+r2kfeOf7XpJKxX9oT6gnZ+nUr7hkv6kqECRpAclXSPpSUnvlPQJSYdK2knSPDP7sLvfVbaLayUtjB/fEH//p6Le93IPb262Mp9U1E7PS7pK0W1n3pB0QLys2TaKhg7/WdL9kpZKeklR27xH0qcl7Rjv62pFx7Zc888yMX5PSTq7QvZnOvGz1Ev6qqJb5Vwm6W9x5pKkzykqIo5QNJPxOW3sY6akj8ePX1FU3PxNUZuUJH1W0oWKzrVqviupuZdslaLZkv8pab2iD4HeregDnsM6/NNV93ZF5+5gRYX3jZLWSdorzrxr/J53mFm9u7/QegdmtqOin3WPeNGieJ+PKRrtsZ+iInNwvM/ean8Sqo6eX5kxM5P0O0XtIUXn5XWSHlc0k/UOkoZK+qCic6rSPrZW9EHeqHjRUkm/kfRIvI93Kyow36PoPLjRzI5w9zcr7K7ZoYrOzTckXa7o3+NXFB3Dpzb7BwVQW0JXxXzxxVfP+9KmT7eXlC27uGz5Fyu8JmRPqUv6RoVt+mtTL99GRX+8PS1pWIVtP122r5vaeM/prd7zYUk7V9juaEV/2LmiwmfXCtuUyrZ5sNI28XbjFRXOLum+NrZpapXry11wDmylZI/rRZK2qrDd2WXbPCnpLZ099h3IdmKrn/cRSYPaec37JW1fZf1blexh/EAHzoHRHch6Zdn2dRXWj271szwhac8K2x1Udr6sU4XeUkUfzDTvZ42k/SpsU1fhfDmx1Ta9JD0Xr2uqdI63+h3buxPHsnWP2ikVtukn6c6ybX7cxr5uiNe/KelLbWzTT9EHU837GtMV51cHf9aq50JHt1X0b0fzurmSelXZzz6Sdqqw/Idl+/i+pN4VtumjqBBv3u5zHTh/V0nap7NtxRdffNXeF9eUAsjKdxQVWJJ0lrVznWPGbnH31OzA7r5GUnMvZS9FvRunuvtDFbb9paLhcFJ0C5z2RqJslPRJd3+6wr5ulPSD+Om2kj5f4fXnKOqpeVHSeHd/stKbuPs8STPipweb2XvbyXWDu/+wnW06YryiHldJuk9RoZvqJXH3b0uaHz/dRdJxXfDem8MlTXT3lVU3cr/b3Z+rsv4lRb1nzef4p7ss4eY5zt0fbb3Q3e9X1JMlRT1hB1V47ZfLHp/q7qkeaHdvUvu9g/0V9VxK0h8qneNl+1vj7kva2V9HXevuP6nwHusVfejV3Dv6WTPbvnwbMxuhTb3bP3T3H7WRt3lfzb2cp7eTqUPnV8beXfb4Cnd/o60N3X2xu68tX2ZmAyX9b/z09+7+NXffWOG1r0v6H0U9sFL7bSVJJ3v10RwAeiiKUgCZcPfV2jTUdGdJpwULk1ZxeGzs3rLHq1V92OI98fettWkIYFtucfd/Vll/kaJhbJJ0TPkKM9tBm4ZGznb3Fe2816/KHn+4nW1/3M76jiqfafkCd/cq284oe5z1DM13u/uirtiRu78o6R/x04O7Yp+b6UF3v7vK+j+VPd6nfIWZvUWbzo2VioZ3VuTREOvUBzNlXm7rfbrZD9paEf/70/x7sI2iIbXlmj9E8Gr7iff1rKSb4qeHxUNZ29Jl51cXKr+l0r5tbtW2T2jTbNgXVtswLkybPwzZs50Jmp5Q1HMLoIC4phRAli5Q1Ou3o6SvmNlP3X1d4EyS9Pcq61aXPW6s1NvXxrY7tPOed1Rb6e5Pmdkjiq5je4+Zvd3dm3tnDtWmDxXfMLOj23mvPmWPh1bZ7g1F19R1heaeOJd0Wzvb/lWbrjXMupirVsQlxMXHJyR9RFGv+QBFma3C5kO6JN3mua+d9eUfXrQ+Pw/QpvPkL+2c51I0/H1YpRXu/ryZ3a/oHPgvM7tB0Ycdd8dFSnd4XtH1mtX8SZt6+A5UdJ1vs/fH35+TdFB02WVVW5d9f5eiIbqVdPj8ytA9ij442EbStPhDrqsqjQBpw/vLHg/pwL8/5efaUEVDuivmaufDKwA9GEUpgMzEf6yeL+l8RcP7pkr6WthUkqKJgdpSfl/Matu13vYt7Wz7WDvrm7fZT1HR805tGjJYV7bN51V5eG9bqhXLa939lc3YVzUD4+9PxT2IbXL3N81sqaLCaEcz6+vZTYTVXi+zJMnM9lc08dOeHdzv27Y40ZZrb5KkaufnoLLHj6t97W1ziqIPXt6maFjs0ZJeMrO/KyqKbpd0bweK345a2oGCpvx3blCrdXXx9x20aVKtjqr2O9Wh8ytL7r7OzL4s6VJFfweeLul0M3ta0QdEd0v6o7u3VWjXlT3+7Wa+fU21FYDsMHwXQNZ+rGh4oCSdamat/zjM3Gb8YdxVf0BLySF0bXmp7HH5Nbhvb73hZqh2z8GXq6zbXM33dn2p6labrK/w2iy0+zPHs7Lerk0F6TJFf9B/SdL/UzTk+Jj4q3lIdoj/Xztzfr617PHmnpsp7t6gaObWq7Wpjd8q6XBF10P/RdJSM/vUZietrDO/T1Jt/E51GXe/TNHsundo03mzs6IPD34gabGZ3Wtmla49LlRbAcgGPaUAMuXuL5vZtxX9Ub+Noj9QP9eV72FmtfCB27Yd2Ka8UFjfxuOT3P0XXROpS70oaXslf4ZqyouEqj2rAZyq6A92KZpN9H8qTewiSWZ2VmapulZ5wba552ZF7v4fSSeY2cmKbv/yXknvk/QBRb/7dZJ+ZWa7VZpobDN15vep+fn2kp509906mSUP2v030N3/LOnPZraToiG5hyg6NgfGr3+vpHsq3Kqpue1c0ay7XflhHYCCqoU/3AD0PJcruq+dFM2E+e5qG5dpHtJZ7dN2KbpHZ9515Gdu3saVvE9f+TC3ENcudsSq+Ps725tpOb5vYvPEUGszHLrbUf8Vf98o6bS2CtJYrRY05bPDvqsD23dkG0mSu7/i7ne6+3fc/b8VFfhnKjqvJemcuDDqjD2s/QtBy3/nWs+G2/w7tbOZ9VE+lQ+/7rJ/A919rbvf6O5nuvsoRfd0vSZe3UfpyYya28oU3bMVADqNohRA5uLJTs6Jn/aW9K0OvvS5+Ht7Q35DzHy6uQ6vttLM3qlNkxL9u2ySIyka+tj8B317s+mGcn/83bSpqGvLe7Wpp/T+ahsGMiD+vrbabWHMbLii26FUU96r1O5sOhlapOg+plI0o2x7fx+M3tI3cvf17v59RdfoStFkQQdu6f5ib5c0op1tPlj2+IFW6/4cf3+LpMM6maW7PFf2uM1/A82sl6J7kW6ReDbvE7Tpg7CRZrZN2SZ/Lnuc139/ANQYilIAoczWpttKTFQ0yU17mu9ft5uZVeup+WJngmVkjJlVmwn3i4rujSpJvy9fEd/38eb46fvMLI9/GF5f9vgr7fRindnG6/Ki+XrFnc2s2vWu51RZ16x82GhHhzZ3u3iCq1vjp4Mkfbytbc1stNqYeXczNZU97orLidq8D6aZ9deme+Bu0Kbfn2ZXlz2eFhd2eVN+/85qH2pNVPsfjlQVjwZYXrao/Phcq02jVs40s9ycxwBqF0UpgCDimTKbr78zSV/owMvK/5A8v1KhY2bfUvs9c3nQW9Jv4j+WE8zsKElfiZ9uUHT9bWvf1KaerWvNrPV9F1vvczczu9DMdq62XRear02T/hwq6YJKvW9m9g1JR8VPl0n6dTbxNktzr5pJOq/1Sot8W9EkMe35T9nj9nr2svbDsseXmNl+rTeI7zN5ZbWdmNlwMzvbzAZU2eYd2lT4uqrf97Sj/p+Zpa5Pj4um2do0Qc8VrXu83f3v2vSByPsl/drM2pxB2cx6m9lHzeyULsjdUbdp072LTzGz1FBxMyupnXsNm9mnzOwzrXo/W28zStLw+Onj5TNou/uysvfYU9LceGRHW/vaysz+y8y+WS0XgGJjoiMAwbj7PDP7q6Lhmx35tP0KRbeQ2VHSxyTdbWa/VnQrjF0V9RCUFH2SP7FbQnedGxUVMf80s1mS/qFospYjFf2x3lxwnxn/EZjg7gvM7POSZim6zcIfzexeSX9UVPi8rqid9lY0uUzzcL6LuufHSeV708yOU3SLiW0knSHpg/HxWq5oSOwn4myK8x7fhbek6Uo/lXSSop7rL5pZvaLe66ck7aJoBt7hinqyXpY0ssq+7lb0s/aR9FUzay7Imq8XXOfuQYYwu/sdZnalpBMVXZP4QPz8r4qGHZcUtcPbJF2n6HdQSs/6+3ZFQ/KnxefkXyX9W9EEVjtK2l9Rm+0Yb/9rd3+yk/EXKpqo6NL4vpk3KBru+h5Jn9Wma33/o00fhrV2Urz9/pI+KelIM/utpAZJzyo6jwcrOtZHKPq9u7yTuTvM3Vea2TWSPq2o7R4ws58qOu/6KRpSPUnSOkX3ZG2rN3VPSdMk/djMblP0ocsyRefgzoqK8qO1aaRGpUmovq5oduUPKRoW/biZXa/oPsdrFF3z+k5FI2COiB/foQof6gCARFEKILyvK3mNUpvcfY2ZfVpRQbC1oh64Q1ttNk/RH5d5L0p/pGjCkFMkfaPCepf0LXe/pK0duPvl8b0FZykq8iq1R7m1kjIr+tx9oZl9SFEP1EBFPYOVegfXSfp/rWb4zI345/iCpEsUjTA6TOnrDh+R9BFJP29nX8+Y2YWKzvt+Sl9P/Wd14nrNLjBFUa6PKbq+8nNKzo79pqJe/Oe1qShtPVty8/XOvVS5rcr9Jn7Pznpe0mcU/f4fGX+1tlTSh939hUo7cPcXzOx9kmYqKkq3j7NVy9d6wqTudpqiorle0RDdaa3Wr1J0a6Jq9y5uPj5v1aZ7yFbyuqSz3T1VeLv762Y2VtHtYz6vqGA/TpuGSFfCfUgBtInhuwCCcve/KH19V7Xtb1L06fsvJD2p6NqmNZLuVNSDMMHda+J+d+5+qqRxkuYq+uP2tfj7byQd6u7TO7CPuZJ2V1Q4zFHU4/GyNrXL3xQNtTtK0iB3f6bLf5Dq+f6mqGfmdEUF1xpFf+yujbOdJWkPd78ly1yby90vVVTw/05RD+nrkp5W1At4uqSSuz/WwX19Q1GP1s3xvnIz27C7v+7uH5d0rKJ8axT1oD2paGj1oe7+A0nls+Wua7WPPysqnL6i6AOJJYqupX0z/r5Y0aiHD7j7xK76fXX3hYp6Mc+T9LCiYnm9pAcVffAzzN0fb2cfL7j7REUfnlwUv3atopmX10t6VNEoh9MVnbcduY64y7j7OkUjS6bG2dYrup3PYknfkXRAPBS5mu8o+uDj25JuUXRt78uKfsZnFU02dr6kfdz9/CpZXnP3LygajTFD0t8VnS8bFV128B9JN2lT25+w2T8wgMKw6LIuAACAjomHan40frpTXCyFyNH8R8yf3X10iAwAgM6jpxQAAHRYPNnR+PjpolAFKQCg56AoBQAAkiQz28PMhlRZP1jRJEJ940WXZRIMANCjMdERAABodoikX5jZXxTNFLxU0fWGO0kapWjG5G3jbe9TNCkQAACdQlEKAADK9VZ0O5G2bikiSXdJOtbd36iyDQAAHUJRCgAAms1VdAuUIyQNVXS/0h0VzRC8WtEMq9fGsz4DANAlcjH77jve8Q6vq6sLHaPbrFmzRv379w8do0Xe8hQF7Q4AAICiamxsfMbdK/4xnIue0rq6OjU0NISOAQAAAADoBmb2RFvrmH03A9OnTw8dISFveYqCdgcAAADScjF8t1QqeU/uKTUz5aGdm+UtT1HQ7gAAACgqM2t091KldfSUAgAAAACCoSgFAAAAAARDUZqBvA1NzlueoqDdAQAAgDSKUgAAAABAMEx0lIG8TXCTtzxFQbsDAACgqJjoCAAAAACQS+0WpWZ2hZk9bWYPly37jZktjL+azGxhvLzOzF4uW/ezbswOAAAAAKhxvTuwzZWSLpF0dfMCd/9k82Mz+4Gk58u2X+ru9V2Ur0eYNm1a6AgJectTFLQ7AAAAkNaha0rNrE7SPHffr9Vyk/SkpMPd/dG2tmtPT7+mFAAAAACKrDuvKX2/pNXu/mjZst3N7EEz+7OZvb9KqClm1mBmDWvWrOlkjHwbNGhQ6AgJectTFLQ7AAAAkNbZonSSpNllz1dJ2tXdh0s6XdI1Zva2Si9095nuXnL3Uv/+/TsZI99WrVrV8njZsmX64Ac/qH322Uf77ruvfvSjH7Wsmz59ugYPHqz6+nrV19frpptukiTde++9GjZsmEqlkh59NKr/n3vuOX34wx/Wm2++2ak8nXHjjTdq8eLFLc/POecc3X777ZKk0aNHb/F9Of/whz9o2LBhqq+vV6lU0j333CNJeuKJJzRixAjV19dr33331c9+VluXLLfX7v/6179ajn19fb3e9ra36aKLLpKU3bnRVbrr3FiyZIkOOeQQbb311rrwwgtT69944w0NHz5c48ePb1l2xx13tJw373vf+/TYY49t0XsDAACgm7h7u1+S6iQ93GpZb0mrJQ2p8rq7JJXa2//IkSO9J4uaObJy5UpvbGx0d/cXXnjB99xzT//nP//p7u7Tpk3zCy64IPX6Y445xpctW+Z33323n3766e7ufsYZZ/idd97Z6TydccIJJ/jvfve7ius+8IEP+AMPPLBF+33xxRf9zTffdHf3RYsW+V577eXu7q+++qq/8sorLdvstttuvmLFii16jxA2p903btzoAwYM8KamJnfP7tzoKt11bqxevdrvv/9+/8Y3vlGxPX7wgx/4pEmTfNy4cS3L9txzT1+8eLG7u//kJz/xE044YYveGwAAAFtOUoO3UQ92pqf0vyQtcfflzQvMrL+Z9Yofv0vSnpIe78R79AgjRoxoeTxw4MCW59ttt52GDh2qFStWVH19nz59tGHDBm3YsEF9+vTR0qVLtWzZMo0ePbrN19x8883ae++9NWLECH3xi19s6Tlq7nFrtt9++6mpqUmSdPTRR2vkyJHad999NXPmzJZt+vXrp7POOksHHHCARo0apdWrV+uvf/2r5syZo69+9auqr6/X0qVLdeKJJ+q6665LZbn11lt1yCGHaMSIEfr4xz+u9evXV/15+/Xrp+hyZemll15qedy3b19tvfXWkqRXX301aE/glig/D9pzxx13aI899tBuu+1WdbuuPjfKex/zeG7svPPOOvDAA9WnT5/UuuXLl2v+/Pn6n//5n8RyM9MLL7wgSXr++ecZRg0AAJAzHbklzGxJf5O0l5ktN7PPxqsmKjl0V5IOk/RQfIuY6yR9zt3XdWHemtTY2FhxeVNTkx588EEdfPDBLcsuueQSDRs2TCeddJKeffZZSdLXv/51HX/88fre976nU089VWeddZbOO++8Nt/vlVde0eTJkzV37lw1NjbqqaeeSqw/7bTTKr7uiiuuUGNjoxoaGnTxxRdr7dq1kqLCcNSoUVq0aJEOO+wwzZo1S+9973s1YcIEXXDBBVq4cKH22GOPivt85plndN555+n222/XggULVCqV9H//93+SoiGdc+bMqfi6G264QXvvvbfGjRunK664omX5smXLNGzYMO2yyy4688wza6rAaOs8qOTaa6/VpEmTEsuyODfakqdzoy2nnXaavv/972urrZL/rP385z/X2LFjNWTIEP3yl7/U1KlTN2u/AAAA6F7tFqXuPsndB7p7H3cf4u6Xx8tPdPeftdr2enff193r3X2Eu8/truC1ZMqUKall69ev17HHHquLLrpIb3tbdNnt5z//eS1dulQLFy7UwIEDdcYZZ0iS6uvrdd999+nOO+/U448/roEDB8rd9clPflLHHXecVq9endj3kiVLtPvuu2vPPfeUmem4445LrK/UYyVJF198cUuP17Jly1quUezbt29Lb9rIkSNbes864r777tPixYt16KGHqr6+XldddZWeeOIJSdK3vvUtTZgwoeLrjjnmGC1ZskQ33nijzj777Jblu+yyix566CE99thjuuqqq1I/e55VOg8qee211zRnzhx9/OMfb1mW1bnRljydG5XMmzdPO++8s0aOHJla98Mf/lA33XSTli9frs985jM6/fTTO7xfAAAAdL/OTnSEDpg1a1bi+euvv65jjz1Wn/rUp/TRj360ZfmAAQPUq1cvbbXVVpo8ebLuv//+xOvcXeedd57OPvtsnXvuufr+97+vyZMn6+KLL+5wlt69e+vvf/97y/NXXnlFknTXXXfp9ttv19/+9jctWrRIw4cPb1nXp0+fliG0vXr10saNGzv8fu6uI444QgsXLtTChQu1ePFiXX755R1+/WGHHabHH39czzzzTGL5oEGDtN9+++nuu+/u8L5Ca30etOWPf/yjRowYoQEDBrQsy+rcKB8Snfdzo9y9996rOXPmqK6uThMnTtSf/vQnHXfccVqzZo0WLVrUMhrhk5/8pP76179u0XsAAACge1CUZszd9dnPflZDhw5N9diUz856ww03aL/9krd7vfrqqzV27FjtuOOO2rBhg7baaitttdVW2rBhQ2K7vffeW01NTVq6dKkkafbsTaOs6+rqWh4vWLBA//nPfyRF19rtsMMO2nbbbbVkyRLdd9997f4s2223nV588cWq24waNUr33ntvy4ynL730kv79739Xfc1jjz3WPFGWFixYoFdffVU77bSTli9frpdfflmS9Oyzz+qee+7RXnvt1W7OWjN79uzU0N2szo0FCxZIyu+50Zbvfe97Wr58uZqamnTttdfq8MMP169+9SvtsMMOev7551v2e9ttt2no0KFb9B4AAADoHr1DB6gVdVPnV13fNGNch/Zz77336pe//KX2339/1dfXS5K++93vauzYsfra176mhQsXysxUV1enyy67rOV1GzZs0JVXXqlbb71VknT66adr7Nix6tu3r6655prEe7zlLW/RzJkzNW7cOG277bZ6//vf31IgHHvssfr0pz+tfffdVwcffLDe8573SJLGjBmjn/3sZxo6dKj22msvjRo1qt2fZeLEiS29cW0NCe7fv7+uvPJKTZo0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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": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6UAAAHvCAYAAACsfXllAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABOLUlEQVR4nO3de5wU5ZX/8e8RJF7whiLCoGIQDaI4wqi4JoaYNbAKqNFkdaNidBk2kURzlcSfAlGzuokbrzEMUYFdo3F1NVwMeF+jiZcZBGO8gsFwE/CCgqgEPb8/qgaasae7h6l5qmrm8369+jXdVU/Xefp0Tc+cfqqeMncXAAAAAABp2CbtDgAAAAAAOi6KUgAAAABAaihKAQAAAACpoSgFAAAAAKSGohQAAAAAkBqKUgAAAABAaihKASAAM5toZh7fhqbdn7wxs25mdrmZPWNma83s4ziXa9LuW1sxs6kF+0yftPuD9JjZ0IJ9YWLa/QGApHVOuwMA2hcza3rx4yHu/mSZ55wm6bb44SR3n9gWfUM+mVkPSU9I6pNyV1ol/jJiaPxwqrsvTqsvaH/M7AJJu0pa4+5Xp9oZAGghilIAbe2nkr6YdieQaxdpc0H6uKT/lrRSkkv6e0p92hpDJU2I7z8iaXFaHUG7dIGkfSW9JunqVHsCAC1EUQqgrR1rZv/o7g+k3RHk1vHxz7clfcnd16fZmVDc/WxJZ6fcDWSAuz8iydLuBwC0Fc4pBdBWCguHn6bWC7QHe8c/X+ooBSkAAB0JRSmAtrJE0t3x/cPN7Mtpdga51iX++WGqvQAAAG2CohRAW/p/kj6O719mZp22dkMFM08+0tq2ZvZIY5v48TZmdk68fJWZvWdmz5nZ/zOznZo8dy8zu9TMnjWzd83sHTN71My+uhWv6Xgz+52ZLTWzD+Oft5nZUS3Yxh5mdpGZ/cHMXjezDWa2On78QzPrWub5i+NcLI4fb2dm3zazx8xsZTzL7SMtfW0F29/BzL5jZg/H/fswzvFjZvYjM9ulmedtmq24YPHnC97brZrJ2MzOLnju2fGyGjP7tZktjN/7LbZrkc/Fs/8+ZGbL49fxnpn91cxuN7ORJWJOjF/HhILFDxd5LY80eV7J2XeLzchqZvuY2VVm9mLcvzVm9kcz+6aZVXTKjpmdbGaz4/f/g3gf+W8zO7K5HDaznRPN7A4ze9XM1sfbWmZmC8zsf+I+7V5Jn5rZ/hZ5M7PuZvYTM/tz/Lv5rpk1mNl4M9u+BdsdHuf+FYtmel5vZoviZZ8t89wW718V9qnZ2Xfj98cVnU8qSfsW2beafa/MrIuZnWtmM8xsSfw+rbHoM+6qYvtek+d/Yj81s1PM7Pfx78r78f74MzPr3uS5u5jZD+L36W0zW2dmT5vZv5kZ/6MCHYm7c+PGjVtiN0WTz7ikF+PHUwuWnd3Mc04raDOxzHYfaUEfirZVNMlMY5uukh4oeNz0Nk/SbvHzjpK0qkTbn5fo08SCdkMl3VBiOx9JmlDB6zxb0rsltuOSXpd0VIltLI7bLZa0n6TnimyjbM6b2fYQScvK9O8NReeJlspXqdvQFvbp7ML9UdJ4SRtLbVfSLRX25feSdm7Fa3mkyfOmFqzrU2S7QwvWT5Q0XNF5t81t/z5JnyqRm20l3VHi+Rslfa9pDotsZ3tJsyp8zRck8FnziKTDJC0tEecVSfuV2V53SQ9W0OdfS9o2qf2rwte6xXvdzO9wuVux96pG0qtlnvehpLEl+la4n/ZVNBFZc9taLGnf+HkHSlpYou0dkmxr9w9u3Ljl68ZERwDa2kRJpys6BHOimf3G3Tek26Ut3KJoduDHFf0T9LqiEYfz4p+HSbrazCZImqvodfxa0mOSNkj6nKQxiiaO+56ZzfHykzqdL+kkRQXZryU9K2kHRUXFKYqOYploZm+6+/XFNmBm52vzDJvrJd0p6Y+S3pS0R7ytUZJ6SHrAzA539+dL9OlTkv5X0oD4td0labmif9R7lHk9xfp3mKSHFBUokvSMpN9I+pukvSR9VdLRknaXNMvMvuTRZC6Nbpc0P75/d/zzL4pG3ws919K+FfhnRXl6R9I0SQ2KvhA4NF7WaHtF/5j/n6SnJC2S9J6i3Bwg6UxJ3eJtTVf03hZqfC2nxTEl6eIifX+jFa+lWtIPFE2GM1nSn+I+10j6N0k7SjpO0UzGlzSzjTpJX4nvf6Co2PiTopzUSDpX0s8V7Wul/FTSCfH9FYqKlL9IWqfoS6D9FX3Bc0zFr660XRTtu1WKCu97JL2lqOg5V9I+ccwHzaza3d9tugEz66botfaNFy2It7lQ0dEeBysqMqvibXZW+UmoKt2/WqtW0edHnaJ9cnW8rKl5hQ8sOiLjgfi5rujz7T5FXyRtr+g9OjNe/ysz+9Ddp5bpyxWSTlX0mfbfimYC3kvRZ+TBij5Tp5vZiZLuV5TP38b9WCtpkKLP3h0V7Yv3KfqMBNDepV0Vc+PGrX3dtPlb7hcLll1bsPzbRZ6T5kipS/pxkTbdtXmUb6OiomKVpIFF2p5ZsK17m4k5sUnM5yTtWaTdSYouc+KKCp99irSpKWjzTLE2cbsRigpnl/REM20WN+nXdxLYB7bRliOuV0vapki7iwva/E3Sdq197yvo29lNXu8LknqVec7nJO1aYv2O2nKE8fMV7ANDK+jr1IL2fYqsH9rktbwmqV+RdkcU7C9vqchoqaIvZhq3s1rSwUXa9Cmyv5zdpE0nSWu0eVTsE/t4k9+xz7TivWw6snZekTZdJT1c0Oa6ZrZ1d7z+Y0nnN9Omq6LCrXFbw5PYvyp8rYXv9cRm2jS+N4sr2N5O8e+cKxpdb26f3T/er1zRlwp7lNlPXdKv1OT3XVGRu6CgTb2iL9OOLbK9Y+L3wSU939rccePGLR83jtcHEMLligosSbrIypznGNhcd//E7MDuvlpS4yhlJ0WjG+Pc/dkibf9L0eGBUnQJnHJHoWyU9M/uvqrItu6RdFX8cAdJ3yjy/EsUjdSslTTC3f9WLIi7z1I0ciFJR5rZP5Tp193u/osybSoxQtGIqyQ9oajQ/bhpI3e/VNLs+OHeks5IIHZLuKTT3H15yUbuf3D3NSXWv6do9KxxHz8zsR62zBnu/krThe7+lKLRKEnaTVGR2tR3Cu6Pc/dPjEC7+2KVHx3srmjkUpJ+V2wfL9jeand/scz2KnW7u99QJMY6RV96NY6Onmtmuxa2MbNB2jy6/Qt3v6aZ/jZuq3GU87tl+lTR/pWSMdo8q/VZ7v5/xRq5+0JJX48f7qjiI7CFnlO0/2zx++7u72vzZ5EkDVZUXD9UJOajikZOJam/me3dtA2A9oeiFECbc/eV2nyo6Z6KLvKeFUUPj409XnB/pUoftvhY/PNT2nwIYHPmuvtfSqy/WtFhfpJ0cuEKM9tNmw+NvM3dl5WJ9d8F979Upu11ZdZXqnCm5Z+5u5doW/iPaugZmv/g7guS2JC7r5X05/jhkUlss4Wecfc/lFhf+M//QYUrzGw7bd43lkv6n+Y24tEh1p/4YqbA+83FaWNXNbci/vxp/D3YXtEhtYUav0TwUtuJt/W2pHvjh8eY2adKNE9s/2oDja/5ZXefWaphXDg2FtblPkMmu/vGZtYVfp5+pOgw8+Y8VnA/5H4EICWcUwoglJ8pGvXrJun7ZvZLd38r5T5J0pMl1q0suN9QbLSvmba7lYn5YKmV7v66mb2g6BysA8xsF3dvHJ05Wpu/UPzIzE4qE2vbgvv9S7T7SNE5dUloHIlzReeNlfJHbT7XMHQxV6qI20JcfHxV0omKRs17KOqzFWneO5HetcwTZdYXfnnRdP88VJv3k0fL7OdSdPj7wGIr3P0dM3tK0T7wj2Z2t6IvO/7g7n8vs92t9Y6i8zVLeUjSN+P7hys6z7fR5+KfayQdYVbsLd3Cpwp+flrRIbrFVLx/hWTRjNeN79/KCj5DpOh3VCr9GSJV/nn6UsFnWrm25T5PAbQDFKUAgoj/Wb1S0pWKDu8bL+mH6fZKUjQxUHMKr4tZql3TttuVabuwzPrGNgcrKnr20uZDBvsUtPmGih/e25xS/9y96e4ftGBbpfSMf74ejyA2y90/NrNFigqjbmbWxcNNhFVulFmSZGaHKJr4qV+F2915q3u09cpNklRq/+xVcP/VCmKVa3Oeoi9edlZ0WOxJkt4zsycVjYA9IOnxCorfSi0qMxovbfk716vJuj7xz920eVKtSpX6napo/0rB3tr8xdbntLkor0S5ArHZz0l3/7Cg4E/y8xRAO8DhuwBCuk6bDwMbZ2ZN/zkMrgX/GCf1D7QUTfBRznsF9wvPwd2lacMW6FJi3fsl1rVU47Vd3yvZarN1Bfd3arZV8sq+5nhW1ge0uSBdIulGRTMo/4uiQ45Pjm+Nh2Sn8be1NfvnjgX3W7pvfoK71yuaDXi6Nud4R0nHKjof+lFJi8zsay3uaXGt+X2S8vE7laTWvN5ty6xP4/MUQDvASCmAYNz9fTO7VNE/9dsr+gf135KMkZMLru9QQZvCQmFdM/fPcfdbkulSotZK2lVbvoZSCouEkiOrKRin6DxoKbqsx782d86cmV0UrFfJKizYWrpvFuXuf5U02szGKrq0yD9I+qykzyv63e8j6b/NbN9iE421UGt+nxof7yrpb+6+byv7kgeFr3+6u49OrScAEMvDP28A2pebFF3nUYpmwty/wuc1HtJZamRCiq7RmXWVvObGNq7o2qmNCg8JTOPcxUqsiH/uVW6mZYuO52ucGOrNgIfuVuof458bJV1QYhIXKboGYx4Vzg776QraV9JGkuTuH7j7w+5+ubv/k6IC/0JF+7UkXWJmu1fe1aL6WvkTQQt/55rOhtv4O7WnmZUbCWwP8vAZAqCDoSgFEFQ82ckl8cPOkn5S4VPXxD/LHfKbxsynLXVsqZVmtpc2TyjycpMJQR7V5n/oy82EmZan4p+mzUVdc/5Bm0dKnyrVMCU94p9vlrosjJkdpuhyKKUUHrJYdjadgBYouo6pFM0oW+5/g6FbG8jd17n7fyg6R1eKJgs6fGu3F9tF0qAybb5QcP/pJusaL4eynaJrZOZV4/5Vct9y9zckPR8/HGJmaZwDDQBboCgFkIbbtPmyEqcpmuSmnMZ/ovY1s1IjNd9uTccCGW5mpWax/Laia6NK0v8Wroiv+zgnfvhZM8tiYXpXwf3vlxnFurCZ52VF4/mKe5pZqfNdLymxrlHhYZOVHtrc5uIJru6LH/aS9JXm2prZUDUz824LLS64n8SpRM1eM9TMumvzNXDXa/PvT6PpBfcnmFkn5VPj/lXJvjUt/rmDoknnACBVFKUAgotnymw8/84kfauCpxX+I3llsULHzH6i8iNzWdBZ0m/jf5a3YGYjJX0/frhe0fm3Tf0/bR7Zut3Mml53sek29zWzn5vZnqXaJWi2Nk/6c7SknxUbfTOzH0saGT9cIunWMN1rkcZRNZN0WdOVFrlU0Qyz5fy14H65kb3QflFw/3ozO7hpAzPrI2lqqY2Y2WFmdrGZ9SjRZg9tLnxdpa97Wql/MbNPnJ9uZjsq+hKscXKfm5uOeLv7k9r8hcjnJN1aavTQzDqb2ZfN7LwE+p2kxv1rdzPbp0zbGyS9Ft8fb2Y/KDVCbma7mNm3zSwPn68AcoiJjgCkwt1nmdkfFR2+Wck3+zcruoRMN0mnSvqDmd2q6FIY+ygaca1RdP3B09qk08m5R1ER8xczmyLpz4pGLIYp+me9seC+0N2XNH2yu88zs29ImqLoEg2/N7PHJf1e0T+mf1eUp88omlymJn7q1W3zcj7Rv4/N7AxF1yDdXtL3JH0hfr+WKjok9qtx3xT396wEL0mTpF9KOkfRyPW3zaxa0ej164ourfEvkg5TNJL/vqTBJbb1B0WvdVtJPzCzxoKs8fIXb7l7Kocwu/uDZjZV0tmKzst+On78R0WHhdYoysPOku5U9DsofXIW1V0UHZI/Id4n/yjpZUUTWHWTdIiinHWL29/q7n9rZffnK5qo6Mb4mpt3Kzrc/wBJ52rzub5/1eYvw5o6J25/iKR/ljTMzO6QVC/pbUX7cZWi9/o4Rb93N7Wy30l7UNKo+P7/mtmNis7vbnyP/uzuyyTJ3d+Lc/V/it7T/5A01szuUrQvr4uXf1rRNWeHKjqf/8wgrwRAh0NRCiBNP9Lm87lKcvfVZnamooLgU4pG4I5u0myWon8us16UXqNospHzJP24yHqX9BN3v765Dbj7TWa2SlFh2kPF81HoTUnBij53n29mX1Q0AtVT0chgsdHBtyT9i7s/EqpvLRG/jm9Jul7R0UXH6JPnHb4g6URJvy6zrTfM7OeK9vuu+uT51P+nVpyvmYBaRf06VdH5lf+mLWfH/ljRKP472lyUNp0tufF8504qnqtCv41jttY7kr6u6Pd/WHxrapGkL7n7u8U24O7vmtlnJdUpKkp3jftWqn9NJ0xK282KPlMOUPTlSNP98esqGOmO9+0jFI0kH6ZowrFS147+UOWvhwsAW4XDdwGkxt0f1SfP7yrV/l5F55/eIulvimbkXS3pYUXf4I9y96xeG3AL7j5O0gmSZir653ZD/PO3ko5294kVbGOmpP0UFQ4zFB0C+7425+VPiq4NO1JSr3iCk2Dc/U+Kru/5XUUF12pFI4Vvxn27SFJfd58bsl8t5e43Kir4/0fRCOnfJa1SNAr4XUk17r6wwm39WNLpivb717V5VunUufvf3f0rkk5R1L/VigqRvyk6tPpod79KUuFsuW812cb/KRpt/L6iLyReVDTq9nH883lFxdPn3f20pH5f3X2+osLqMknPKSqW10l6RtEXPwPd/dUy23jX3U9T9OXJ1fFz31Q08/I6Sa8oOsrhu4r220rOIw7G3ddJGiLpcknzFBXrJa8H6u4vKSpgT1R0nunLkt6V9JGi0eYFis65PVtST3ev+PMaAFrColO7AAAAyosP8fxy/HB3d3+rVPs27EfjPzD/5+5D0+gDACAZjJQCAICKxJMdjYgfLkirIAUAtC8UpQAAQGbW18x6l1hfpWgSoS7xoslBOgYAaPeY6AgAAEjSUZJuMbNHFc0UvEjROcq7KzpX8auKZomWpCcUTQoEAECrUZQCAIBGnSUdG9+a84ikU9z9oyA9AgC0exSlAABAimaCrlV0Hc7+iq5X2k3RDMErJT0p6fZ41mcAABKTidl399hjD+/Tp0/a3dhqq1evVvfu3dt9zDwiTwAAAED6Ghoa3nD3ov+YZ2KktE+fPqqvr0+7GwAAAACANmBmrzW3jtl3EzBx4sQOETOPyBMAAACQbZk4fLempsbzPFJqZgqdxzRi5hF5AgAAANJnZg3uXlNsHSOlAAAAAIDUUJQCAAAAAFJDUZqANA49zvPhziGRJwAAACDbKEoBAAAAAKlhoqMEMNFRdpEnAAAAIH1MdAQAAAAAyCSKUgAAAABAaihKEzBhwoQOETOPyBMAAACQbZxTCgAAAABoU5xT2sZ69erVIWLmEXkCAAAAso2iNAErVqzQkiVL9IUvfEEHHXSQBgwYoGuuuWbT+okTJ6qqqkrV1dWqrq7WvffeK0l6/PHHNXDgQNXU1OiVV16RJK1Zs0Zf+tKX9PHHH5eN2VbuuecePf/885seX3LJJXrggQckSUOHDm3VtT8feeQRVVdXa8CAAfr85z/f6r6W01yeXnrppU3vR3V1tXbeeWddffXVktrm/WpLbfV+vfPOOxo5cqQOPfRQDRgwQLfccsumddOmTVO/fv3Ur18/TZs2rXUvAAAAAB1a57Q70F507txZV111lQYNGqS1a9dq8ODBOu6443TQQQdJkr7zne/o+9///hbPueqqq3Tvvfdq8eLF+tWvfqWrrrpKl112mX784x9rm23S+77gnnvu0YgRIzb1/Sc/+Uki212zZo2++c1vas6cOdpnn320atWqRLa7NQ488EDNnz9fkvTRRx+pqqpKJ5988qb1vF/SDTfcoIMOOkgzZ87U6tWrdeCBB+prX/ua1q1bp0mTJqm+vl5mpsGDB2vUqFHabbfdEokLAACAjoWR0gQMGjRIPXv21KBBgyRJO+20k/r3769ly5aVfN62226r9evXa/369dp22221aNEiLVmyREOHDm32OXPmzNFnPvMZbb/99vr2t7+tESNGSIpG937+859vanfwwQdr8eLFkqSTTjpJgwcP1oABA1RXV7epTdeuXXXRRRfp0EMP1ZAhQ7Ry5Ur98Y9/1IwZM/SDH/xA1dXVWrRokc4++2zdeeedn+jLfffdp6OOOkqDBg3SV77yFa1bt67k6/3Nb36jL3/5y9pnn30kSXvuuWfJ9klofE9KefDBB9W3b1/tu+++Jdu15v0aNGhQ7t4vM9PatWvl7lq3bp26deumzp07a+7cuTruuOPUrVs37bbbbjruuOM0Z86cktsCAAAAmkNRmoCGhoYtHi9evFjPPPOMjjzyyE3Lrr/+eg0cOFDnnHOO3n77bUnSj370I5111ln693//d40bN04XXXSRLrvssmbjfPDBBxozZoxmzpyp9957T6+//npF/bv55pvV0NCg+vp6XXvttXrzzTclSe+9956GDBmiBQsW6JhjjtGUKVP0D//wDxo1apR+9rOfaf78+erbt2/Rbb7xxhu67LLL9MADD2jevHmqqanRf/7nf0qKDh+dMWPGJ57z8ssv6+2339bQoUM1ePBgTZ8+vaL+t0bT96aY22+/XaeffvoWy5J+vxoaGnL3fo0bN04vvPCCevXqpUMOOUTXXHONttlmGy1btkx77733pna9e/cu+wUMAAAA0ByK0gTU1tZuur9u3Tqdcsopuvrqq7XzzjtLkr7xjW9o0aJFmj9/vnr27Knvfe97kqTq6mo98cQTevjhh/Xqq6+qZ8+ecnf98z//s8444wytXLlyizgvvvii9ttvP/Xr109jx47VGWecUVH/rr322k2ja0uWLNl0PmSXLl02jdwNHjx400hdJZ544gk9//zzOvroo1VdXa1p06bptddekxQdPjpq1KhPPGfjxo1qaGjQ7NmzNXfuXF166aV6+eWXK465NQrfm2I2bNigGTNm6Ctf+cqmZW3xfplZ7t6vuXPnqrq6WsuXL9f8+fM1btw4vfvuuxXHBAAAACpBUZqAKVOmSJL+/ve/65RTTtHXvvY1ffnLX960vkePHurUqZO22WYbjRkzRk899dQWz3d3XXbZZbr44os1adIk/cd//IfGjBmja6+9tmzMRp07d95isp0PPvhAUjSx0AMPPKA//elPWrBggQ477LBN67bddluZmSSpU6dO2rhxY8Wv2d113HHHaf78+Zo/f76ef/553XTTTSWf07t3bw0bNkw77rij9thjDx1zzDFasGBBxTG3RtM8NfX73/9egwYNUo8ePTYta4v3q6k8vF+33HKLvvzlL8vMtP/++2u//fbTiy++qKqqKi1ZsmRTu6VLl6qqqqrivgAAAACFKEoT4u4699xz1b9/f333u9/dYl3hDLB33323Dj744C3WT58+Xccff7y6deum9evXa5ttttE222yj9evXb9HuM5/5jBYvXqxFixZJkm677bZN6/r06aN58+ZJkubNm6e//vWvkqIZVHfbbTftsMMOevHFF/XEE0+UfS077bST1q5dW7LNkCFD9Pjjj2vhwoWSokNLy416nnjiiXrssce0ceNGrV+/Xk8++aT69+9ftj9t6bbbbvvEobu8X5F99tlHDz74oCRp5cqVeumll/TpT39aw4YN03333ae3335bb7/9tu677z4NGzasbD8BAACAYph9t0J9xs8uuf7xxx/Xf/3Xf+mQQw5RdXW1JOmnP/2pjj/+eP3whz/U/PnzZWbq06ePJk+evOl569ev19SpU3XfffdJkr773e/q+OOPV5cuXfSb3/xmixjbbbed6urqdMIJJ0iKJgpqLEZOOeUUTZ8+XQMGDNCRRx6pAw44QJI0fPhw/epXv1L//v114IEHasiQIWVf62mnnbZp5K/YhDmS1L17d02dOlWnn366PvzwQ0nSZZddpgMOOECXXHKJampqPnFIaP/+/TV8+HANHDhQ22yzjf71X//1EwVfSO+9957uv//+Ld4PSW3yfu2www763Oc+l6v36+KLL9bZZ5+tQw45RO6uK6+8UnvsscemdYcffrik6JzUbt26le0nAAAAUIy5e9p9UE1Njbfm2pchlCpKN659U0tvOCtgb6Tly5fr5Zdf1s9//nPNmjUraOw8Wb58uXr16pV2NyRFh+byfgEAAKAjMrMGd68pto7DdxOwYeXC4DErmVUW5AkAAADIOkZKK1RqpPS1K0codB7NLHjMPCJPAAAAQPoYKQUAAAAAZBJFKQAAAAAgNRSlCeg2bFzwmE1njEVx5AkAAADINorSBOxUPTx4zNra2uAx84g8AQAAANlGUZqA164cETymmQWPmUfkCQAAAMg2ilIAAAAAQGooSgEAAAAAqaEoTcD2fQ8PHnPEiPCHDOcReQIAAACyjaI0AXueOiF4zJkzZwaPmUfkCQAAAMg2itIErLpzUvCYI0eODB4zj8gTAAAAkG0UpQl4f9HTwWPOmjUreMw8Ik8AAABAtlGUtiNmpjPOOGPT440bN6p79+4tPq9y6NChqq+vlyQdf/zxWrNmTZLd1Pz583XUUUdpwIABGjhwoH77299uWve5z31O1dXVqq6uVq9evXTSSSclGhsAAABAtnROuwNIzo477qjnnntO77//vrbffnvdf//9qqqqatU277333oR6t9kOO+yg6dOnq1+/flq+fLkGDx6sYcOGadddd9Uf/vCHTe1OOeUUnXjiiYnHBwAAAJAdjJQmYN8Lwx8i6u5Flx9//PGaPXu2JOm2227T6aefvmnde++9p3POOUdHHHGEDjvsMP3ud7+TJL3//vs67bTT1L9/f5188sl6//33Nz2nT58+euONNyRJJ510kgYPHqwBAwaorq5uU5uuXbvqoosu0qGHHqohQ4Zo5cqVJft+wAEHqF+/fpKkXr16ac8999Tq1au3aPPuu+/qoYceavVIaXN5AgAAAJANFRelZtbJzJ4xs1nx4/3M7EkzW2hmvzWzLvHyT8WPF8br+7RR3zNj7fw5wWMWFoWFTjvtNN1+++364IMP9Oyzz+rII4/ctO7yyy/Xscceq6eeekoPP/ywfvCDH+i9997TjTfeqB122EEvvPCCJk2apIaGhqLbvvnmm9XQ0KD6+npde+21evPNNyVFxe6QIUO0YMECHXPMMZoyZYokacaMGbrkkktKvo6nnnpKGzZsUN++fbdYfs899+iLX/yidt5554pzUkxzeQIAAACQDS0ZKT1f0gsFj6+U9At331/S25LOjZefK+ntePkv4nbt2ltzrw8ec+zYsUWXDxw4UIsXL9Ztt92m448/fot19913n6644gpVV1dr6NCh+uCDD/S3v/1Njz766KZzUQcOHKiBAwcW3fa11167aTR0yZIleuWVVyRJXbp02XTe6uDBg7V48WJJ0qhRo/STn/yk2dewYsUKnXnmmbrlllu0zTZb7opNR3m3VnN5AgAAAJANFZ1Tama9JZ0g6XJJ3zUzk3SspH+Jm0yTNFHSjZJOjO9L0p2Srjczc46jDGbUqFH6/ve/r0ceeWTTaKYUHcp611136cADD2zxNh955BE98MAD+tOf/qQddthhU1ErSdtuu62iXULq1KmTNm7cWHZ77777rk444QRdfvnlGjJkyBbr3njjDT311FO6++67W9xPAAAAAPlS6Ujp1ZJ+KOnj+PHukta4e2P1sVRS44w6VZKWSFK8/p24PQI555xzNGHCBB1yyCFbLB82bJiuu+66TedZPvPMM5KkY445Rr/5zW8kSc8995yeffbZT2zznXfe0W677aYddthBL774op544omt7t+GDRt08skn66yzztKpp576ifV33nmnRowYoe22226rYwAAAADIh7JFqZmNkLTK3YufaLiVzKzW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\n",
"text/plain": [
"<Figure size 1152x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"users_per_item=df.groupby(['item']).count()['rating']\n",
"\n",
"plt.figure(figsize=(16,8))\n",
"plt.hist(users_per_item, bins=100)\n",
"\n",
"# Let's add median\n",
"t=users_per_item.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=users_per_item.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=users_per_item.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": 6,
"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": 6,
"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": 7,
"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": 8,
"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": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"genres"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"movies = pd.read_csv('./Datasets/ml-100k/u.item', sep='|', encoding='latin-1', header=None)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"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": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"movies[:3]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"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": 12,
"metadata": {},
"outputs": [],
"source": [
"movies['genre']=movies.iloc[:, 5:].apply(lambda x: ', '.join(x[x!='']), axis = 1)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"movies=movies[[0,1,'genre']]\n",
"movies.columns=['id', 'title', 'genres']"
]
},
{
"cell_type": "code",
"execution_count": 14,
"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": 14,
"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": 15,
"metadata": {},
"outputs": [],
"source": [
"os.makedirs('./Datasets/toy-example/', exist_ok = True)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"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)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}