Last active
January 9, 2019 20:11
-
-
Save xiaohk/e8fbdd059f16c5869ed814dcd1c79dbd to your computer and use it in GitHub Desktop.
Explore Surprise.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Surprise Exploration\n", | |
"\n", | |
"In this notebook, we can explore how a simple and general recommender system works using Surprise." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 1. Collaborative Filtering Algorithm\n", | |
"\n", | |
"There are two types of methods in Collaborative Filtering (CF): user-user and item-item. User-user refers to recommend users items based on other users having the same interests/tastes. Item-item means recommending items that are similar to what the user has liked/purchased." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from surprise import SVD, KNNBaseline, Dataset, NMF\n", | |
"import pandas as pd\n", | |
"import matplotlib.pyplot as plt\n", | |
"import numpy as np\n", | |
"%matplotlib inline" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Train a model to predict rating using user-item-rating tuple." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<surprise.prediction_algorithms.matrix_factorization.SVD at 0x118912828>" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"data = Dataset.load_builtin('ml-100k')\n", | |
"trainset = data.build_full_trainset()\n", | |
"\n", | |
"model = SVD()\n", | |
"model.fit(trainset)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Recommend unwatched movies to a user using item-item CF." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Get the (user, unwatched movie, unknow rating) tuple\n", | |
"testset = trainset.build_anti_testset(fill=0)\n", | |
"predictions = model.test(testset)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[('196', '302', 0.0),\n", | |
" ('196', '377', 0.0),\n", | |
" ('196', '51', 0.0),\n", | |
" ('196', '346', 0.0),\n", | |
" ('196', '474', 0.0),\n", | |
" ('196', '265', 0.0),\n", | |
" ('196', '465', 0.0),\n", | |
" ('196', '451', 0.0),\n", | |
" ('196', '86', 0.0),\n", | |
" ('196', '1014', 0.0)]" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"testset[:10]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[Prediction(uid='196', iid='302', r_ui=0.0, est=4.207584627777337, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='377', r_ui=0.0, est=2.638978793859669, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='51', r_ui=0.0, est=3.331218337187397, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='346', r_ui=0.0, est=3.8273963198197007, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='474', r_ui=0.0, est=4.161019254432978, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='265', r_ui=0.0, est=4.009726137469156, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='465', r_ui=0.0, est=3.6400440236616673, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='451', r_ui=0.0, est=3.3328102289555726, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='86', r_ui=0.0, est=3.8069009649047696, details={'was_impossible': False}),\n", | |
" Prediction(uid='196', iid='1014', r_ui=0.0, est=3.2353053587607623, details={'was_impossible': False})]" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"predictions[:10]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"[('302', 4.207584627777337), ('377', 2.638978793859669), ('51', 3.331218337187397), ('346', 3.8273963198197007), ('474', 4.161019254432978), ('265', 4.009726137469156), ('465', 3.6400440236616673), ('451', 3.3328102289555726), ('86', 3.8069009649047696), ('1014', 3.2353053587607623)]\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"1643" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Estimate ratings for all unrated movies of user 196\n", | |
"prediction_u196 = list(map(lambda p: (p.iid, p.est),\n", | |
" filter(lambda p: True if p.uid == '196' else False,\n", | |
" predictions)))\n", | |
"print(prediction_u196[:10])\n", | |
"len(prediction_u196)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[('483', 4.5772300515540145),\n", | |
" ('197', 4.565017976782498),\n", | |
" ('603', 4.556527569574576),\n", | |
" ('56', 4.528959173948327),\n", | |
" ('511', 4.504870863481298),\n", | |
" ('480', 4.4791866908164115),\n", | |
" ('408', 4.473526579614248),\n", | |
" ('272', 4.459467523992605),\n", | |
" ('178', 4.459254102576342),\n", | |
" ('223', 4.45621533788619)]" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Sort all those 1643 ratings and recommend the top 10 to him/her\n", | |
"prediction_top10_u196 = sorted(prediction_u196, key=lambda t: t[1], reverse=True)[:10]\n", | |
"prediction_top10_u196" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Get the names of these 10 movies\n", | |
"with open(\"/Users/JayWong/.surprise_data/ml-100k/ml-100k/u.item\", 'r', encoding='ISO-8859-1') as fp:\n", | |
" mapping_info = fp.readlines()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"```\n", | |
"u.item -- Information about the items (movies); this is a tab separated\n", | |
" list of\n", | |
" movie id | movie title | release date | video release date |\n", | |
" IMDb URL | unknown | Action | Adventure | Animation |\n", | |
" Children's | Comedy | Crime | Documentary | Drama | Fantasy |\n", | |
" Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi |\n", | |
" Thriller | War | Western |\n", | |
" The last 19 fields are the genres, a 1 indicates the movie\n", | |
" is of that genre, a 0 indicates it is not; movies can be in\n", | |
" several genres at once.\n", | |
" The movie ids are the ones used in the u.data data set.\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"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", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>4</td>\n", | |
" <td>Get Shorty (1995)</td>\n", | |
" <td>01-Jan-1995</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Get%20Shorty%...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>5</td>\n", | |
" <td>Copycat (1995)</td>\n", | |
" <td>01-Jan-1995</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Copycat%20(1995)</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>5 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", | |
"3 4 Get Shorty (1995) 01-Jan-1995 NaN \n", | |
"4 5 Copycat (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", | |
"3 http://us.imdb.com/M/title-exact?Get%20Shorty%... 0 1 0 0 0 ... \n", | |
"4 http://us.imdb.com/M/title-exact?Copycat%20(1995) 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", | |
"3 0 0 0 0 0 0 0 0 0 0 \n", | |
"4 0 0 0 0 0 0 0 1 0 0 \n", | |
"\n", | |
"[5 rows x 24 columns]" | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"df = pd.read_csv(\"/Users/JayWong/.surprise_data/ml-100k/ml-100k/u.item\", sep='|',\n", | |
" encoding='ISO-8859-1', header=None)\n", | |
"df.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Finally, we get the top 10 movies that we can recommend to user 196." | |
] | |
}, | |
{ | |
"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>482</th>\n", | |
" <td>483</td>\n", | |
" <td>Casablanca (1942)</td>\n", | |
" <td>01-Jan-1942</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Casablanca%20...</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>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>196</th>\n", | |
" <td>197</td>\n", | |
" <td>Graduate, The (1967)</td>\n", | |
" <td>01-Jan-1967</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Graduate,%20T...</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>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>602</th>\n", | |
" <td>603</td>\n", | |
" <td>Rear Window (1954)</td>\n", | |
" <td>01-Jan-1954</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Rear%20Window...</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>1</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>55</th>\n", | |
" <td>56</td>\n", | |
" <td>Pulp Fiction (1994)</td>\n", | |
" <td>01-Jan-1994</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Pulp%20Fictio...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>510</th>\n", | |
" <td>511</td>\n", | |
" <td>Lawrence of Arabia (1962)</td>\n", | |
" <td>01-Jan-1962</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Lawrence%20of...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</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>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>479</th>\n", | |
" <td>480</td>\n", | |
" <td>North by Northwest (1959)</td>\n", | |
" <td>01-Jan-1959</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?North%20by%20...</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", | |
" <tr>\n", | |
" <th>407</th>\n", | |
" <td>408</td>\n", | |
" <td>Close Shave, A (1995)</td>\n", | |
" <td>28-Apr-1996</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Close%20Shave...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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>271</th>\n", | |
" <td>272</td>\n", | |
" <td>Good Will Hunting (1997)</td>\n", | |
" <td>01-Jan-1997</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?imdb-title-11...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>177</th>\n", | |
" <td>178</td>\n", | |
" <td>12 Angry Men (1957)</td>\n", | |
" <td>01-Jan-1957</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?12%20Angry%20...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>222</th>\n", | |
" <td>223</td>\n", | |
" <td>Sling Blade (1996)</td>\n", | |
" <td>22-Nov-1996</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Sling%20Blade...</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>10 rows × 24 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" 0 1 2 3 \\\n", | |
"482 483 Casablanca (1942) 01-Jan-1942 NaN \n", | |
"196 197 Graduate, The (1967) 01-Jan-1967 NaN \n", | |
"602 603 Rear Window (1954) 01-Jan-1954 NaN \n", | |
"55 56 Pulp Fiction (1994) 01-Jan-1994 NaN \n", | |
"510 511 Lawrence of Arabia (1962) 01-Jan-1962 NaN \n", | |
"479 480 North by Northwest (1959) 01-Jan-1959 NaN \n", | |
"407 408 Close Shave, A (1995) 28-Apr-1996 NaN \n", | |
"271 272 Good Will Hunting (1997) 01-Jan-1997 NaN \n", | |
"177 178 12 Angry Men (1957) 01-Jan-1957 NaN \n", | |
"222 223 Sling Blade (1996) 22-Nov-1996 NaN \n", | |
"\n", | |
" 4 5 6 7 8 9 \\\n", | |
"482 http://us.imdb.com/M/title-exact?Casablanca%20... 0 0 0 0 0 \n", | |
"196 http://us.imdb.com/M/title-exact?Graduate,%20T... 0 0 0 0 0 \n", | |
"602 http://us.imdb.com/M/title-exact?Rear%20Window... 0 0 0 0 0 \n", | |
"55 http://us.imdb.com/M/title-exact?Pulp%20Fictio... 0 0 0 0 0 \n", | |
"510 http://us.imdb.com/M/title-exact?Lawrence%20of... 0 0 1 0 0 \n", | |
"479 http://us.imdb.com/M/title-exact?North%20by%20... 0 0 0 0 0 \n", | |
"407 http://us.imdb.com/M/title-exact?Close%20Shave... 0 0 0 1 0 \n", | |
"271 http://us.imdb.com/M/title-exact?imdb-title-11... 0 0 0 0 0 \n", | |
"177 http://us.imdb.com/M/title-exact?12%20Angry%20... 0 0 0 0 0 \n", | |
"222 http://us.imdb.com/M/title-exact?Sling%20Blade... 0 0 0 0 0 \n", | |
"\n", | |
" ... 14 15 16 17 18 19 20 21 22 23 \n", | |
"482 ... 0 0 0 0 0 1 0 0 1 0 \n", | |
"196 ... 0 0 0 0 0 1 0 0 0 0 \n", | |
"602 ... 0 0 0 0 1 0 0 1 0 0 \n", | |
"55 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"510 ... 0 0 0 0 0 0 0 0 1 0 \n", | |
"479 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"407 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"271 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"177 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"222 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"\n", | |
"[10 rows x 24 columns]" | |
] | |
}, | |
"execution_count": 10, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"df.iloc[list(map(lambda x: int(x[0]) - 1, prediction_top10_u196))]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 2. Finding Similar Movies/Users\n", | |
"\n", | |
"Some algorithms in Surprise uses similarity measure, so we can find KNN item/user after training such algorithms." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Estimating biases using als...\n", | |
"Computing the pearson_baseline similarity matrix...\n", | |
"Done computing similarity matrix.\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"<surprise.prediction_algorithms.knns.KNNBaseline at 0x1469ff358>" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"sim_options = {'name': 'pearson_baseline', 'user_based': False}\n", | |
"model = KNNBaseline(sim_options=sim_options)\n", | |
"model.fit(trainset)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets try to find the 10 nearest neighbor of the film \"Titanic\"." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def get_n_neighbor_index(base_index, n=10):\n", | |
" base_inner_id = model.trainset.to_inner_iid(str(base_index + 1))\n", | |
" base_neighbors_inner_id = model.get_neighbors(base_inner_id, k=10)\n", | |
" base_neighbors_index = [int(model.trainset.to_raw_iid(i)) - 1 for i in base_neighbors_inner_id]\n", | |
" return base_neighbors_index" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"[312]\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>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>312</th>\n", | |
" <td>313</td>\n", | |
" <td>Titanic (1997)</td>\n", | |
" <td>01-Jan-1997</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?imdb-title-12...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>1 rows × 24 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" 0 1 2 3 \\\n", | |
"312 313 Titanic (1997) 01-Jan-1997 NaN \n", | |
"\n", | |
" 4 5 6 7 8 9 \\\n", | |
"312 http://us.imdb.com/M/title-exact?imdb-title-12... 0 1 0 0 0 \n", | |
"\n", | |
" ... 14 15 16 17 18 19 20 21 22 23 \n", | |
"312 ... 0 0 0 0 0 1 0 0 0 0 \n", | |
"\n", | |
"[1 rows x 24 columns]" | |
] | |
}, | |
"execution_count": 13, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# To get item neighbors, we need to transfer movie name -> raw ID -> inner ID.\n", | |
"possible_index = [i for i in range(len(df[1])) if \"titanic\" in df[1][i].lower()]\n", | |
"print(possible_index)\n", | |
"df.iloc[possible_index]" | |
] | |
}, | |
{ | |
"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>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>299</th>\n", | |
" <td>300</td>\n", | |
" <td>Air Force One (1997)</td>\n", | |
" <td>01-Jan-1997</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Air+Force+One...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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", | |
" <tr>\n", | |
" <th>21</th>\n", | |
" <td>22</td>\n", | |
" <td>Braveheart (1995)</td>\n", | |
" <td>16-Feb-1996</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Braveheart%20...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>422</th>\n", | |
" <td>423</td>\n", | |
" <td>E.T. the Extra-Terrestrial (1982)</td>\n", | |
" <td>01-Jan-1982</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?E%2ET%2E%20th...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>...</td>\n", | |
" <td>1</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", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>209</th>\n", | |
" <td>210</td>\n", | |
" <td>Indiana Jones and the Last Crusade (1989)</td>\n", | |
" <td>01-Jan-1989</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Indiana%20Jon...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>271</th>\n", | |
" <td>272</td>\n", | |
" <td>Good Will Hunting (1997)</td>\n", | |
" <td>01-Jan-1997</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?imdb-title-11...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>173</th>\n", | |
" <td>174</td>\n", | |
" <td>Raiders of the Lost Ark (1981)</td>\n", | |
" <td>01-Jan-1981</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Raiders%20of%...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>309</th>\n", | |
" <td>310</td>\n", | |
" <td>Rainmaker, The (1997)</td>\n", | |
" <td>01-Jan-1997</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Rainmaker,+Th...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>81</th>\n", | |
" <td>82</td>\n", | |
" <td>Jurassic Park (1993)</td>\n", | |
" <td>01-Jan-1993</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Jurassic%20Pa...</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>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>143</th>\n", | |
" <td>144</td>\n", | |
" <td>Die Hard (1988)</td>\n", | |
" <td>01-Jan-1988</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Die%20Hard%20...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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", | |
" <tr>\n", | |
" <th>214</th>\n", | |
" <td>215</td>\n", | |
" <td>Field of Dreams (1989)</td>\n", | |
" <td>01-Jan-1989</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Field%20of%20...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>10 rows × 24 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" 0 1 2 3 \\\n", | |
"299 300 Air Force One (1997) 01-Jan-1997 NaN \n", | |
"21 22 Braveheart (1995) 16-Feb-1996 NaN \n", | |
"422 423 E.T. the Extra-Terrestrial (1982) 01-Jan-1982 NaN \n", | |
"209 210 Indiana Jones and the Last Crusade (1989) 01-Jan-1989 NaN \n", | |
"271 272 Good Will Hunting (1997) 01-Jan-1997 NaN \n", | |
"173 174 Raiders of the Lost Ark (1981) 01-Jan-1981 NaN \n", | |
"309 310 Rainmaker, The (1997) 01-Jan-1997 NaN \n", | |
"81 82 Jurassic Park (1993) 01-Jan-1993 NaN \n", | |
"143 144 Die Hard (1988) 01-Jan-1988 NaN \n", | |
"214 215 Field of Dreams (1989) 01-Jan-1989 NaN \n", | |
"\n", | |
" 4 5 6 7 8 9 \\\n", | |
"299 http://us.imdb.com/M/title-exact?Air+Force+One... 0 1 0 0 0 \n", | |
"21 http://us.imdb.com/M/title-exact?Braveheart%20... 0 1 0 0 0 \n", | |
"422 http://us.imdb.com/M/title-exact?E%2ET%2E%20th... 0 0 0 0 1 \n", | |
"209 http://us.imdb.com/M/title-exact?Indiana%20Jon... 0 1 1 0 0 \n", | |
"271 http://us.imdb.com/M/title-exact?imdb-title-11... 0 0 0 0 0 \n", | |
"173 http://us.imdb.com/M/title-exact?Raiders%20of%... 0 1 1 0 0 \n", | |
"309 http://us.imdb.com/M/title-exact?Rainmaker,+Th... 0 0 0 0 0 \n", | |
"81 http://us.imdb.com/M/title-exact?Jurassic%20Pa... 0 1 1 0 0 \n", | |
"143 http://us.imdb.com/M/title-exact?Die%20Hard%20... 0 1 0 0 0 \n", | |
"214 http://us.imdb.com/M/title-exact?Field%20of%20... 0 0 0 0 0 \n", | |
"\n", | |
" ... 14 15 16 17 18 19 20 21 22 23 \n", | |
"299 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"21 ... 0 0 0 0 0 0 0 0 1 0 \n", | |
"422 ... 1 0 0 0 0 0 1 0 0 0 \n", | |
"209 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"271 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"173 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"309 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"81 ... 0 0 0 0 0 0 1 0 0 0 \n", | |
"143 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"214 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
"[10 rows x 24 columns]" | |
] | |
}, | |
"execution_count": 14, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"df.iloc[get_n_neighbor_index(possible_index[0])]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"It finds many big-name and classic films which are \"similar\" to \"Titanic\".\n", | |
"\n", | |
"We also can find 10 neighbors of \"Akira\", the Japanese animation." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"[205]\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>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>205</th>\n", | |
" <td>206</td>\n", | |
" <td>Akira (1988)</td>\n", | |
" <td>01-Jan-1988</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Akira%20(1988)</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>1</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>1</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>1 rows × 24 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" 0 1 2 3 \\\n", | |
"205 206 Akira (1988) 01-Jan-1988 NaN \n", | |
"\n", | |
" 4 5 6 7 8 9 ... \\\n", | |
"205 http://us.imdb.com/M/title-exact?Akira%20(1988) 0 0 1 1 0 ... \n", | |
"\n", | |
" 14 15 16 17 18 19 20 21 22 23 \n", | |
"205 0 0 0 0 0 0 1 1 0 0 \n", | |
"\n", | |
"[1 rows x 24 columns]" | |
] | |
}, | |
"execution_count": 15, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"possible_index = [i for i in range(len(df[1])) if \"akira\" in df[1][i].lower()]\n", | |
"print(possible_index)\n", | |
"df.iloc[possible_index]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"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>197</th>\n", | |
" <td>198</td>\n", | |
" <td>Nikita (La Femme Nikita) (1990)</td>\n", | |
" <td>01-Jan-1990</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Nikita%20(1990)</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", | |
" <tr>\n", | |
" <th>67</th>\n", | |
" <td>68</td>\n", | |
" <td>Crow, The (1994)</td>\n", | |
" <td>01-Jan-1994</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Crow,%20The%2...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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>1</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>167</th>\n", | |
" <td>168</td>\n", | |
" <td>Monty Python and the Holy Grail (1974)</td>\n", | |
" <td>01-Jan-1974</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Monty%20Pytho...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>86</th>\n", | |
" <td>87</td>\n", | |
" <td>Searching for Bobby Fischer (1993)</td>\n", | |
" <td>01-Jan-1993</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Searching%20f...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>44</th>\n", | |
" <td>45</td>\n", | |
" <td>Eat Drink Man Woman (1994)</td>\n", | |
" <td>01-Jan-1994</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Yinshi%20Nan%...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>483</th>\n", | |
" <td>484</td>\n", | |
" <td>Maltese Falcon, The (1941)</td>\n", | |
" <td>01-Jan-1941</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Maltese%20Fal...</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>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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>635</th>\n", | |
" <td>636</td>\n", | |
" <td>Escape from New York (1981)</td>\n", | |
" <td>01-Jan-1981</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Escape%20from...</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>1</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>30</th>\n", | |
" <td>31</td>\n", | |
" <td>Crimson Tide (1995)</td>\n", | |
" <td>01-Jan-1995</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Crimson%20Tid...</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>1</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>272</th>\n", | |
" <td>273</td>\n", | |
" <td>Heat (1995)</td>\n", | |
" <td>01-Jan-1995</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Heat%20(1995)</td>\n", | |
" <td>0</td>\n", | |
" <td>1</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", | |
" <tr>\n", | |
" <th>922</th>\n", | |
" <td>923</td>\n", | |
" <td>Raise the Red Lantern (1991)</td>\n", | |
" <td>01-Jan-1991</td>\n", | |
" <td>NaN</td>\n", | |
" <td>http://us.imdb.com/M/title-exact?Da%20Hong%20D...</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>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>10 rows × 24 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" 0 1 2 3 \\\n", | |
"197 198 Nikita (La Femme Nikita) (1990) 01-Jan-1990 NaN \n", | |
"67 68 Crow, The (1994) 01-Jan-1994 NaN \n", | |
"167 168 Monty Python and the Holy Grail (1974) 01-Jan-1974 NaN \n", | |
"86 87 Searching for Bobby Fischer (1993) 01-Jan-1993 NaN \n", | |
"44 45 Eat Drink Man Woman (1994) 01-Jan-1994 NaN \n", | |
"483 484 Maltese Falcon, The (1941) 01-Jan-1941 NaN \n", | |
"635 636 Escape from New York (1981) 01-Jan-1981 NaN \n", | |
"30 31 Crimson Tide (1995) 01-Jan-1995 NaN \n", | |
"272 273 Heat (1995) 01-Jan-1995 NaN \n", | |
"922 923 Raise the Red Lantern (1991) 01-Jan-1991 NaN \n", | |
"\n", | |
" 4 5 6 7 8 9 \\\n", | |
"197 http://us.imdb.com/M/title-exact?Nikita%20(1990) 0 0 0 0 0 \n", | |
"67 http://us.imdb.com/M/title-exact?Crow,%20The%2... 0 1 0 0 0 \n", | |
"167 http://us.imdb.com/M/title-exact?Monty%20Pytho... 0 0 0 0 0 \n", | |
"86 http://us.imdb.com/M/title-exact?Searching%20f... 0 0 0 0 0 \n", | |
"44 http://us.imdb.com/M/title-exact?Yinshi%20Nan%... 0 0 0 0 0 \n", | |
"483 http://us.imdb.com/M/title-exact?Maltese%20Fal... 0 0 0 0 0 \n", | |
"635 http://us.imdb.com/M/title-exact?Escape%20from... 0 1 1 0 0 \n", | |
"30 http://us.imdb.com/M/title-exact?Crimson%20Tid... 0 0 0 0 0 \n", | |
"272 http://us.imdb.com/M/title-exact?Heat%20(1995) 0 1 0 0 0 \n", | |
"922 http://us.imdb.com/M/title-exact?Da%20Hong%20D... 0 0 0 0 0 \n", | |
"\n", | |
" ... 14 15 16 17 18 19 20 21 22 23 \n", | |
"197 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"67 ... 0 0 0 0 0 1 0 1 0 0 \n", | |
"167 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"86 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"44 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"483 ... 0 1 0 0 1 0 0 0 0 0 \n", | |
"635 ... 0 0 0 0 0 0 1 1 0 0 \n", | |
"30 ... 0 0 0 0 0 0 0 1 1 0 \n", | |
"272 ... 0 0 0 0 0 0 0 1 0 0 \n", | |
"922 ... 0 0 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
"[10 rows x 24 columns]" | |
] | |
}, | |
"execution_count": 16, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"df.iloc[get_n_neighbor_index(possible_index[0])]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"It finds many Asian and foreign films based on \"Akira\"." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 3. CF Factorization\n", | |
"\n", | |
"<a href=\"https://en.wikipedia.org/wiki/Matrix_factorization_(recommender_systems)\">Matrix factorization</a> is a class of Collaborative Filtering algorithms. It decompose the rating matrix $\\mathbb{R}^{u\\times i}$ into two latent space matrices $\\mathbb{R}^{u\\times f}$ and $\\mathbb{R}^{f\\times i}$. I think we might be interested in visualizing the latent space factor vectors. Different matrix factorization methods should yield different decompositions." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### 3.1. SVD Decomposition" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<surprise.prediction_algorithms.matrix_factorization.SVD at 0x10caa1828>" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"data = Dataset.load_builtin('ml-100k')\n", | |
"trainset = data.build_full_trainset()\n", | |
"\n", | |
"svd_model = SVD()\n", | |
"svd_model.fit(trainset)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"$\\mathbb{R}^{u\\times f}$" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(943, 100)\n", | |
"[[ 0.09827454 -0.03976238 0.01818848 ... 0.06603582 -0.13693396\n", | |
" 0.09220304]\n", | |
" [ 0.2430969 -0.21293087 -0.05987946 ... -0.04940762 0.12689275\n", | |
" -0.09852063]\n", | |
" [ 0.00588489 0.2621444 0.00371794 ... 0.06920038 0.2109561\n", | |
" 0.01523976]\n", | |
" ...\n", | |
" [-0.27229863 -0.14024293 -0.01151298 ... -0.27645588 0.22114294\n", | |
" 0.19151027]\n", | |
" [-0.04344653 0.13792765 0.07480039 ... 0.22425652 0.05482876\n", | |
" -0.13347536]\n", | |
" [ 0.20231929 0.06558981 0.03920855 ... 0.12901358 -0.05891041\n", | |
" 0.04709826]]\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"needs_background": "light" | |
}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"print(svd_model.pu.shape)\n", | |
"print(svd_model.pu)\n", | |
"\n", | |
"plt.imshow(svd_model.pu, cmap='hot', interpolation='nearest')\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"$\\mathbb{R}^{i\\times f}$" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(1682, 100)\n", | |
"[[-0.17629553 0.11007775 0.0442902 ... -0.13306982 0.05124126\n", | |
" -0.0556131 ]\n", | |
" [ 0.10553786 0.39702341 -0.23784865 ... -0.0640464 -0.05775928\n", | |
" -0.05337625]\n", | |
" [ 0.01858199 -0.09989119 0.02385218 ... 0.00385601 0.02945917\n", | |
" 0.02013456]\n", | |
" ...\n", | |
" [ 0.02073325 -0.04456793 0.10833881 ... -0.12161109 -0.04055527\n", | |
" -0.12866432]\n", | |
" [-0.05337481 0.11682032 0.00655933 ... -0.04635817 -0.0631682\n", | |
" 0.07114037]\n", | |
" [-0.05437292 -0.04211752 -0.02952294 ... -0.04904702 -0.00770515\n", | |
" 0.13037699]]\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"needs_background": "light" | |
}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"print(svd_model.qi.shape)\n", | |
"print(svd_model.qi)\n", | |
"\n", | |
"plt.imshow(svd_model.qi, cmap='hot', interpolation='nearest')\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### 3.2. NMF Decomposition" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<surprise.prediction_algorithms.matrix_factorization.NMF at 0x11e4e6668>" | |
] | |
}, | |
"execution_count": 13, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"data = Dataset.load_builtin('ml-100k')\n", | |
"trainset = data.build_full_trainset()\n", | |
"\n", | |
"nmf_model = NMF()\n", | |
"nmf_model.fit(trainset)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(943, 15)\n", | |
"[[0.74925821 0.33733162 0.25183698 ... 0.76754821 0.46347268 0.19515171]\n", | |
" [0.49229828 1.11158307 1.10293635 ... 0.2992807 0.23762653 0.51594267]\n", | |
" [0.15197183 0.96215718 0.21495458 ... 1.02602312 0.56869154 0.62312887]\n", | |
" ...\n", | |
" [0.28880653 0.18415247 0.12133848 ... 0.73764731 0.33596941 0.31132305]\n", | |
" [0.46113588 0.97649045 0.28678778 ... 0.59274594 0.62109594 0.84487729]\n", | |
" [0.61008222 0.13789916 0.84593444 ... 0.80971322 0.04439998 0.24758137]]\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"needs_background": "light" | |
}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"print(nmf_model.pu.shape)\n", | |
"print(nmf_model.pu)\n", | |
"\n", | |
"plt.imshow(nmf_model.pu, cmap='hot', interpolation='nearest')\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(943, 15)\n", | |
"[[0.32517699 0.51912292 0.68280434 ... 0.10826895 0.66647537 0.59907808]\n", | |
" [0.23358898 0.72173147 0.3044164 ... 0.60960966 0.66931133 0.89965064]\n", | |
" [0.42947581 0.29734101 0.1327856 ... 0.00710044 0.10511228 0.49251732]\n", | |
" ...\n", | |
" [0.52350583 0.52568898 0.24850974 ... 0.62218505 0.16235292 0.33266798]\n", | |
" [0.51743654 0.46797779 0.70373928 ... 0.46614849 0.14673009 0.77151883]\n", | |
" [0.26756476 0.47281063 0.7335038 ... 0.71571561 0.15375436 0.76875341]]\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"needs_background": "light" | |
}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"print(nmf_model.pu.shape)\n", | |
"print(nmf_model.qi)\n", | |
"\n", | |
"plt.imshow(nmf_model.pu, cmap='hot', interpolation='nearest')\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 4. Comments" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"1. Those latent spaces are naturally different from each other. I think it does not make a lot of sense to compare them using visualization.\n", | |
"2. We want to read some literature to see if the latent space of matrix decomposition has meanings to users/researchers.\n", | |
"3. Despite Collaborative Filtering methods, another method is content-based recommender system. It concatenates the meta data for each item into a document, then uses document embedding to find similar items. That is probably more closed to Florian's work. We can refer to other packages to explore content-based methods. [List of Recommender Systems](https://github.com/grahamjenson/list_of_recommender_systems)" | |
] | |
} | |
], | |
"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.1" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment