{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/home/vincent/Project/jupyter/DataScience/Week9/Lecture/ml-100k\n" ] } ], "source": [ "cd ml-100k/" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
user_iditem_idratingtimestamp
01962423881250949
11863023891717742
2223771878887116
3244512880606923
41663461886397596
\n", "
" ], "text/plain": [ " user_id item_id 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": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "names = ['user_id', 'item_id', 'rating', 'timestamp']\n", "df = pd.read_csv('u.data', sep='\\t', names=names)\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "943 users\n", "1682 items\n" ] } ], "source": [ "n_users = df.user_id.unique().shape[0]\n", "n_items = df.item_id.unique().shape[0]\n", "print(str(n_users) + ' users')\n", "print(str(n_items) + ' items')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1. 1. 1. ... 0. 0. 0.]\n", " [1. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " ...\n", " [1. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 1. 0. ... 0. 0. 0.]]\n" ] } ], "source": [ "ratingsNum = np.zeros((n_users, n_items))\n", "for row in df.itertuples():\n", " ratingsNum[row[1]-1, row[2]-1] = 1\n", "print(ratingsNum)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "itemRateNumCurrent = ratingsNum.sum(axis=0)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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rxAiIiKyqVkTt+Pj43HixAl719KidIsMRFdd7eRtLipJRETkepoVkl5++WXMmzcP//vf/1BQUIDS0lKrBzVOkH/tPdyqqs0yV0JERETXatI6SXXuuusuAMCYMWOsvuVWd7sSs5l/9BvD78oikgxJRERErqdZIWnTpk32rqNF8lPVhqTLDElEREQup1khafDgwfauo0Wqux1JlYkhiYiIyNU0a05SncrKShw6dAj79u2zejTW8uXL0bNnTwQGBiIwMBADBgzA999/L+0XQmDRokXQ6/Xw8/PDkCFDkJOTY3UMo9GIWbNmISwsDBqNBmPGjEF+fv6tfCynqQtJl6stMldCRERE12pWSDp//jxGjRqFgIAA9OjRAwkJCVaPxmrbti1eeeUV7Nq1C7t27cKdd96J++67TwpCixcvxpIlS7Bs2TLs3LkTOp0OI0aMQFlZmXSMlJQUrF27FmvWrMG2bdtQXl6OUaNGucW8KM2Vy23Flfx2GxERkatpVkhKSUlBcXExduzYAT8/P6xfvx6ffPIJYmNj8e233zb6OKNHj8Y999yDzp07o3Pnznj55ZfRqlUr7NixA0IILF26FM899xzGjRuHuLg4fPLJJ6isrMTnn38OADAYDFixYgVef/11DB8+HAkJCVi9ejX279+PjRs3Xvd9jUajS3wjr7s+EACw/fhFCCFkqYGIiIhsa1ZI+umnn/DGG2/gtttug5eXF6Kjo/HQQw9h8eLFSEtLa1YhZrMZa9asQUVFBQYMGIDc3FwUFhYiOTlZaqNWqzF48GBkZmYCALKyslBdXW3VRq/XIy4uTmpjS1paGrRarfSIiopqVs23amiXcPgpvXH4XBney+C6U0RERK6kWSGpoqIC4eHhAICQkBCcP38eQO0ik029ue3+/fvRqlUrqNVqzJgxA2vXrkX37t1RWFgIAIiIiLBqHxERIe0rLCyESqVqcHuUq9vYsmDBAhgMBumRl5fXpJrtJchfhYm31Qa0V9cfwr78ElnqICIiooaaFZK6dOmCw4cPAwB69+6N999/H2fOnMF7772HyMjIJh9r79692LFjBx5//HFMnToVBw4ckPZfvQ4TUL8W043crI1arZYmi9c95DI3ubP08+OrmxYwiYiIyHGaPSepoKAAQO2Nb9evX4927drhrbfeQmpqapOOpVKp0KlTJ/Tt2xdpaWno1asX3nzzTeh0OgBoMCJUVFQkjS7pdDqYTCYUFxdft42rC/BV4r2H+gAAzpRU4fv9BTJXREREREAzQ9KUKVMwbdo0AEBCQgJOnjyJnTt3Ii8vDxMnTrylgoQQMBqNiImJgU6nQ3p6urTPZDIhIyMDSUlJAIDExEQolUqrNgUFBcjOzpbauIORPXTSz0s3HpWxEiIiIqrTrMUkr+Xv748+ffo0+XV//etfcffddyMqKgplZWVYs2YNNm/ejPXr10OhUCAlJQWpqamIjY1FbGwsUlNT4e/vj8mTJwMAtFotpk+fjrlz5yI0NBQhISGYN28e4uPjMXz4cHt8NKdQKBT4euZAjH3nZxwpKsPpi5VoF+ovd1lEREQtWqND0tNPP93ogy5ZsqRR7c6dO4eHH34YBQUF0Gq16NmzJ9avX48RI0YAAObPn4+qqio88cQTKC4uRr9+/bBhwwYEBARIx3jjjTfg4+ODCRMmoKqqCsOGDcOqVavg7e3d6HpdQe+oIPRsq8W+fAOyzxoYkoiIiGSmEI1coGfo0KGNO6BCgZ9++umWinK20tJSaLVaGAwGWSdxP/rpLqQfOIeX74/DlH7RstVBRETkDhz997vRI0m8qa3jhfirAADFFVyBm4iISG63dO82sq+wgNqQdLCw7CYtiYiIyNGaNXF76NChN1yHyN0ut7mKwZ3D8c6m4/gh+/oLYRIREZFzNCsk9e7d2+p5dXU19u7di+zsbEydOtUedbVIXSNrJ6TXWAR2nLiI/h1CZa6IiIio5WpWSHrjjTdsbl+0aBHKy8tvqaCWLNBXKf2cfcbAkERERCQju85Jeuihh/Dxxx/b85AtzmODOwAAlqQfkbkSIiKils2uIWn79u3w9fW15yFbnISo2pv1VprMyLtUKXM1RERELVezLreNGzfO6rkQAgUFBdi1axeef/55uxTWUt0Vp0ObID+cKalCzlkDokK4qCQREZEcmjWSpNVqrR4hISEYMmQI1q1bh4ULF9q7xhanbi7S4ULO7yIiIpJLs0aSVq5cae866CpddK0AAIfPlcpcCRERUct1Sze43bVrFw4ePAiFQoFu3bohMTHRXnW1aF10tUurr9tfiBqzBT7eXPOTiIjI2ZoVkvLz8zFp0iT8/PPPCAoKAgCUlJQgKSkJX3zxBaKiouxZY4vTQ19//5mfj1/E4M6tZayGiIioZWrWEMUf//hHVFdX4+DBg7h06RIuXbqEgwcPQgiB6dOn27vGFieslRodwjQAgEMFvORGREQkh2aFpK1bt2L58uXo0qWLtK1Lly54++23sXXrVrsV15Ldn9AGAHD4HO/jRkREJIdmhaR27dqhurq6wfaamhq0adPmlosioLOu9hYlOWc4kkRERCSHZoWkxYsXY9asWdi1axeEEABqJ3HPmTMH//jHP+xaYEvV9UpIOnyuDCfOcykAIiIiZ1OIupTTBMHBwaisrERNTQ18fGrnftf9rNForNpeunTJPpU6UGlpKbRaLQwGAwIDA2/+AiewWAQ6/HUdAGD2nZ3wdHKXm7yCiIioZXH03+9mfbtt6dKldi6DruXlpcCf7+iAD7acwLJNxzBneGd4eynkLouIiKjFaFZImjp1qr3rIBsm9I3CB1tOwCKAzYeLMKxbhNwlERERtRjNXkzSbDbj66+/lhaT7N69O8aMGQNvb2971teidQpvhQl92+Lfu/Lx3NpsDOwUBl8l+5eIiMgZmhWSjh07hnvuuQdnzpxBly5dIITAkSNHEBUVhe+++w4dO3a0d50tVueI2gnchaWXseynY5g3knOTiIiInKFZ326bPXs2OnbsiLy8POzevRt79uzB6dOnERMTg9mzZ9u7xhZtfGIUukXWTkbLOHJe5mqIiIhajmaFpIyMDCxevBghISHSttDQULzyyivIyMiwW3EEaP2VeOvB3gCA4+fLYawxy1sQERFRC9GskKRWq1FW1nAl6PLycqhUqlsuiqzFhGkQHqBGpcmMf+3Mk7scIiKiFqFZIWnUqFH485//jF9++QVCCAghsGPHDsyYMQNjxoyxd40tno+3F+7sGg4A+Ns3ObhQbpS5IiIiIs/XrJD01ltvoWPHjhgwYAB8fX3h6+uLpKQkdOrUCW+++aa9ayQA02+PkX7+MitfxkqIiIhahmatuF3n2LFjOHDgAACge/fu6NSpk90KcyZXXHHblr//7wBWbMsFAPy/J29HfFutzBURERHJx9F/v5s1kgQAK1aswNixYzF+/HiMHz8eY8eOxUcffWTP2ugajw+pX1rh3c3HZKyEiIjI8zUrJD3//POYM2cORo8ejf/85z/4z3/+g9GjR+Opp57C//3f/9m7RroirJUaqffHAwCyzxpkroaIiMizNetyW1hYGN5++21MmjTJavsXX3yB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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "itemRateNumCurrent.sort()\n", "\n", "itemRateNumCurrent\n", "import matplotlib.pyplot as plt\n", "plt.plot(itemRateNumCurrent[::-1])\n", "plt.xlabel('sorted items') # adds label to x axis\n", "plt.ylabel('popularity') # adds label to y axis\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[5. 3. 4. ... 0. 0. 0.]\n", " [4. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " ...\n", " [5. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 5. 0. ... 0. 0. 0.]]\n" ] } ], "source": [ "ratings = np.zeros((n_users, n_items))\n", "for row in df.itertuples():\n", " ratings[row[1]-1, row[2]-1] = row[3]\n", "print(ratings)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3.87831858 3.20610687 3.03333333 ... 2. 3. 3. ]\n", "[452. 131. 90. ... 1. 1. 1.]\n" ] } ], "source": [ "itemRateNum = ratingsNum.sum(axis=0)\n", "itemRateSum = ratings.sum(axis=0)\n", "itemRateAvg = itemRateSum/itemRateNum\n", "print(itemRateAvg)\n", "print(itemRateNum)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
movie idmovie titlerelease datevideo release dateIMDb URLunknownActionAdventureAnimationChildren's...FantasyFilm-NoirHorrorMusicalMysteryRomanceSci-FiThrillerWarWestern
01Toy Story (1995)01-Jan-1995NaNhttp://us.imdb.com/M/title-exact?Toy%20Story%2...00011...0000000000
12GoldenEye (1995)01-Jan-1995NaNhttp://us.imdb.com/M/title-exact?GoldenEye%20(...01100...0000000100
23Four Rooms (1995)01-Jan-1995NaNhttp://us.imdb.com/M/title-exact?Four%20Rooms%...00000...0000000100
34Get Shorty (1995)01-Jan-1995NaNhttp://us.imdb.com/M/title-exact?Get%20Shorty%...01000...0000000000
45Copycat (1995)01-Jan-1995NaNhttp://us.imdb.com/M/title-exact?Copycat%20(1995)00000...0000000100
\n", "

5 rows × 24 columns

\n", "
" ], "text/plain": [ " movie id movie title release date video release date \\\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", "3 4 Get Shorty (1995) 01-Jan-1995 NaN \n", "4 5 Copycat (1995) 01-Jan-1995 NaN \n", "\n", " IMDb URL unknown Action \\\n", "0 http://us.imdb.com/M/title-exact?Toy%20Story%2... 0 0 \n", "1 http://us.imdb.com/M/title-exact?GoldenEye%20(... 0 1 \n", "2 http://us.imdb.com/M/title-exact?Four%20Rooms%... 0 0 \n", "3 http://us.imdb.com/M/title-exact?Get%20Shorty%... 0 1 \n", "4 http://us.imdb.com/M/title-exact?Copycat%20(1995) 0 0 \n", "\n", " Adventure Animation Children's ... Fantasy Film-Noir Horror Musical \\\n", "0 0 1 1 ... 0 0 0 0 \n", "1 1 0 0 ... 0 0 0 0 \n", "2 0 0 0 ... 0 0 0 0 \n", "3 0 0 0 ... 0 0 0 0 \n", "4 0 0 0 ... 0 0 0 0 \n", "\n", " Mystery Romance Sci-Fi Thriller War Western \n", "0 0 0 0 0 0 0 \n", "1 0 0 0 1 0 0 \n", "2 0 0 0 1 0 0 \n", "3 0 0 0 0 0 0 \n", "4 0 0 0 1 0 0 \n", "\n", "[5 rows x 24 columns]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "i_cols = ['movie id', 'movie title' ,'release date','video release date', 'IMDb URL', 'unknown', 'Action', 'Adventure',\n", " 'Animation', 'Children\\'s', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy',\n", " 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western']\n", "items = pd.read_csv('u.item', sep='|', names=i_cols, encoding='latin-1')\n", "\n", "items.head()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "movie ID\t movie title\n", "1535 Aiqing wansui (1994)\n", "1652 Entertaining Angels: The Dorothy Day Story (1996)\n", "1200 Marlene Dietrich: Shadow and Light (1996) \n", "1598 Someone Else's America (1995)\n", "1121 They Made Me a Criminal (1939)\n", "Name: movie title, dtype: object\n" ] } ], "source": [ "#Implementation of MovieAvg to recommend the top_n = 5 movies to the activeUser = 0\n", "#change top_n to a larger number to recommend more movie\n", "\n", "top_n = 5\n", "activeUser = 0\n", "mask_activeUser = ratings[activeUser, :] > 0\n", "itemRateAvgCurrent = itemRateAvg.copy()\n", "itemRateAvgCurrent[mask_activeUser] = 0\n", "itemSortInd = itemRateAvgCurrent.argsort()\n", "print('movie ID' + '\\t movie title')\n", "print(items['movie title'][itemSortInd[range(len(itemSortInd)-1,len(itemSortInd)-top_n-1, -1)]])" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "movie ID\t movie title\n", "49 Star Wars (1977)\n", "99 Fargo (1996)\n", "285 English Patient, The (1996)\n", "0 Toy Story (1995)\n", "120 Independence Day (ID4) (1996)\n", "173 Raiders of the Lost Ark (1981)\n", "126 Godfather, The (1972)\n", "55 Pulp Fiction (1994)\n", "6 Twelve Monkeys (1995)\n", "97 Silence of the Lambs, The (1991)\n", "Name: movie title, dtype: object\n" ] } ], "source": [ "#Implementation of TopPop to recommend the top_n = 5 movies to the activeUser = 0\n", "\n", "top_n = 10\n", "activeUser = 2\n", "mask_activeUser = ratings[activeUser, :] > 0\n", "itemRateNumCurrent = itemRateNum.copy()\n", "#print(itemRateNumCurrent)\n", "itemRateNumCurrent[mask_activeUser] = 0\n", "itemSortInd = itemRateNumCurrent.argsort()\n", "print('movie ID' + '\\t movie title')\n", "print(items['movie title'][itemSortInd[range(len(itemSortInd)-1,len(itemSortInd)-top_n-1, -1)]])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "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.9.6" } }, "nbformat": 4, "nbformat_minor": 4 }