{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Hyperparameter Optimization\n",
"\n",
"In this tutorial, we first demonstrate how `P3alphaRecommender`'s performance can be optimized\n",
"by [optuna](https://github.com/optuna/optuna)-backed `tune` function.\n",
"\n",
"Then, by further splitting the ground-truth interaction into tran, validation and test ones,\n",
"we compare several recommenders' performance optimized on the validation set and measured on the test set."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import clear_output, display\n",
"import numpy as np\n",
"import scipy.sparse as sps\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"from irspack.dataset import MovieLens1MDataManager\n",
"from irspack import (\n",
" P3alphaRecommender, rowwise_train_test_split, Evaluator,\n",
" df_to_sparse\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Read the ML1M dataset again.\n",
"\n",
"We again prepare the sparse matrix `X`."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"loader = MovieLens1MDataManager()\n",
"\n",
"df = loader.read_interaction()\n",
"\n",
"movies = loader.read_item_info()\n",
"movies.head()\n",
"\n",
"\n",
"X, unique_user_ids, unique_movie_ids = df_to_sparse(\n",
" df, 'userId', 'movieId'\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Split scheme 2. Hold-out for partial users.\n",
"\n",
"To perform the hyperparameter optimization, we have to repeatedly measure the accuracy metrics on the validation set. As mentioned in the previous tutorial, doing this for all users is time-comsuming (often heavier than the recommender's learning process), so we truncate this subset as follows:\n",
"\n",
"1. First split **users** into \"train\", \"validation\" (and \"test\") ones.\n",
"1. For train users, feed all their interactions into the recommender. For validation (test) users, hold-out part of their interaction for the validation (\"prediction\" part), and feed the rest (\"learning\" part) into the recommender.\n",
"1. After the fit, ask the recommender to output the score only for validation (test) users, and see how it ranks these held-out interactions for the validation (test) users.\n",
"\n",
"\n",
"\n",
"Although we have prepared another function to do this procedure, let us first do this manually."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Split users into train and validation users.\n",
"\n",
"X_train_user, X_valid_user = train_test_split(X, test_size=.4, random_state=0)\n",
"\n",
"# Split the validation users' interaction into learning 50% and predcition 50%.\n",
"\n",
"X_valid_learn, X_valid_predict = rowwise_train_test_split(\n",
" X_valid_user, test_ratio=.5, random_state=0\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define the evaluator and optimize the validation metric\n",
"\n",
"As illustrated above, we will use \n",
"\n",
" * Train users' all interactions (``X_train_user``)\n",
" * Validation users' 50% interaction (``X_valid_learn``)\n",
" \n",
"as the recommender's training resource, and validation users' rest interaction (``X_valid_predict``) as the held-out ground truth:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"X_train_val_learn = sps.vstack([X_train_user, X_valid_learn])\n",
"evaluator = Evaluator(X_valid_predict, offset=X_train_user.shape[0], target_metric='ndcg', cutoff=20)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The ``offset`` parameter specifies where the validation user block begins (where the train user block ends).\n",
"\n",
"Now to start the optimization."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"best_params, validation_results = P3alphaRecommender.tune(X_train_val_learn, evaluator, random_seed=0, n_trials=20)\n",
"clear_output() # output is a bit lengthy"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The best `ndcg@20` value is\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.5159628863136182"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"validation_results['ndcg@20'].max()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"which has been obtained by using these hyper parameters:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'top_k': 217, 'normalize_weight': True}"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"best_params"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Meanwhile, the default argument of ``P3alphaRecommdner`` (which has been used so far)\n",
"attains `ndcg@20` = 0.4084. So this is indeed a significant improvement:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.4084060191998281"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rec_default = P3alphaRecommender(X_train_val_learn).learn()\n",
"evaluator.get_score(rec_default)['ndcg']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Check the recommender's output again\n",
"\n",
"Let us check how our recommender has evolved from the first tutorial. We consider the same setting (a new user has watched \"Toy Story\"), but fit the \n",
"recommender using the obtained parameters."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"rec_tuned = P3alphaRecommender(X, **best_params).learn()\n",
"\n",
"from irspack import ItemIDMapper\n",
"id_mapper = ItemIDMapper(unique_movie_ids)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" title | \n",
" genres | \n",
" release_year | \n",
"
\n",
" \n",
" | movieId | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | 1265 | \n",
" Groundhog Day (1993) | \n",
" Comedy|Romance | \n",
" 1993 | \n",
"
\n",
" \n",
" | 2396 | \n",
" Shakespeare in Love (1998) | \n",
" Comedy|Romance | \n",
" 1998 | \n",
"
\n",
" \n",
" | 3114 | \n",
" Toy Story 2 (1999) | \n",
" Animation|Children's|Comedy | \n",
" 1999 | \n",
"
\n",
" \n",
" | 1270 | \n",
" Back to the Future (1985) | \n",
" Comedy|Sci-Fi | \n",
" 1985 | \n",
"
\n",
" \n",
" | 2028 | \n",
" Saving Private Ryan (1998) | \n",
" Action|Drama|War | \n",
" 1998 | \n",
"
\n",
" \n",
" | 34 | \n",
" Babe (1995) | \n",
" Children's|Comedy|Drama | \n",
" 1995 | \n",
"
\n",
" \n",
" | 2571 | \n",
" Matrix, The (1999) | \n",
" Action|Sci-Fi|Thriller | \n",
" 1999 | \n",
"
\n",
" \n",
" | 356 | \n",
" Forrest Gump (1994) | \n",
" Comedy|Romance|War | \n",
" 1994 | \n",
"
\n",
" \n",
" | 2355 | \n",
" Bug's Life, A (1998) | \n",
" Animation|Children's|Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
" | 1197 | \n",
" Princess Bride, The (1987) | \n",
" Action|Adventure|Comedy|Romance | \n",
" 1987 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" title genres \\\n",
"movieId \n",
"1265 Groundhog Day (1993) Comedy|Romance \n",
"2396 Shakespeare in Love (1998) Comedy|Romance \n",
"3114 Toy Story 2 (1999) Animation|Children's|Comedy \n",
"1270 Back to the Future (1985) Comedy|Sci-Fi \n",
"2028 Saving Private Ryan (1998) Action|Drama|War \n",
"34 Babe (1995) Children's|Comedy|Drama \n",
"2571 Matrix, The (1999) Action|Sci-Fi|Thriller \n",
"356 Forrest Gump (1994) Comedy|Romance|War \n",
"2355 Bug's Life, A (1998) Animation|Children's|Comedy \n",
"1197 Princess Bride, The (1987) Action|Adventure|Comedy|Romance \n",
"\n",
" release_year \n",
"movieId \n",
"1265 1993 \n",
"2396 1998 \n",
"3114 1999 \n",
"1270 1985 \n",
"2028 1998 \n",
"34 1995 \n",
"2571 1999 \n",
"356 1994 \n",
"2355 1998 \n",
"1197 1987 "
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"toystory_id = 1\n",
"recommended_id_and_score = id_mapper.recommend_for_new_user(\n",
" rec_tuned, user_profile=[toystory_id], cutoff=10\n",
")\n",
"\n",
"# Top-10 recommendations\n",
"movies.reindex([movie_id for movie_id, score in recommended_id_and_score])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note how drastically the recommended contents have changed (increased significance of genre \"Children's\" and disapperance of \"Star Wars\" series, etc...).\n",
"\n",
"## A train/validation/test split example\n",
"\n",
"To rigorously compare the performance of various recommender algorithms,\n",
"we should measure the final score against the **test** dataset, not the validation set,\n",
"and it is straightforward now.\n",
"\n",
"To begin with, we have prepared a function called ``split_dataframe_partial_user_holdout`` which\n",
"splits the users in the original dataframe into train/validation/test users,\n",
"holding out partial interaction for validation/test user:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'train': ,\n",
" 'val': ,\n",
" 'test': }"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from irspack.split import split_dataframe_partial_user_holdout\n",
"\n",
"dataset, item_ids = split_dataframe_partial_user_holdout(\n",
" df, 'userId', 'movieId', val_user_ratio=.3, test_user_ratio=.3,\n",
" heldout_ratio_val=.5, heldout_ratio_test=.5\n",
")\n",
"\n",
"dataset"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see, the returned ``dataset`` is a dictionary which stores train/validation/test-users' interactions as an instance of ``UserTrainTestInteractionPair``."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"train_users = dataset['train']\n",
"val_users = dataset['val']\n",
"test_users = dataset['test']\n",
"\n",
"# Concatenate train/validation users into one.\n",
"train_and_val_users = train_users.concat(val_users)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<1812x3706 sparse matrix of type ''\n",
"\twith 152333 stored elements in Compressed Sparse Row format>"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"val_users.X_train"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<1812x3706 sparse matrix of type ''\n",
"\twith 151435 stored elements in Compressed Sparse Row format>"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"val_users.X_test"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<1812x3706 sparse matrix of type ''\n",
"\twith 303768 stored elements in Compressed Sparse Row format>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"val_users.X_all # which equals val_users.X_train + val_users.X_test"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<2416x3706 sparse matrix of type ''\n",
"\twith 0 stored elements in Compressed Sparse Row format>"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# For train users, there is no \"test\" interaction held out.\n",
"train_users.X_test"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For each recommender algorithm (here ``P3alpha``, ``RP3beta``, ``IALS`` and ``DenseSLIM``), we perform:\n",
"\n",
"1. Hyperparameter optimization. During this phase, we will be using train users' all interaction and validation\n",
" users' train interaction as the source of learning, and validation users' test interaction as the held-out ground truth.\n",
"2. Evaluation. During this phase, we will include train/validation users' all interactions\n",
" as well as test users' train interaction as the source of learning,\n",
" and fit the model using the parameters obtained in the optimization phase.\n",
" Then we measure the recommender's performance against **test** users' test interaction."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"from typing import Type\n",
"from irspack import DenseSLIMRecommender, RP3betaRecommender, IALSRecommender, BaseRecommender"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"val_evaluator = Evaluator(\n",
" val_users.X_test,\n",
" offset=train_users.n_users,\n",
" cutoff=20, target_metric=\"ndcg\"\n",
")\n",
"test_evaluator = Evaluator(\n",
" test_users.X_test,\n",
" offset=train_and_val_users.n_users\n",
")\n",
"test_results = []\n",
"recommender_name_vs_best_parameter = {}\n",
"recommender_class: Type[BaseRecommender]\n",
"for recommender_class in [IALSRecommender, DenseSLIMRecommender, P3alphaRecommender, RP3betaRecommender]:\n",
" print(f'Start tuning {recommender_class.__name__}.')\n",
" best_params, validation_results_df = recommender_class.tune(\n",
" sps.vstack([train_users.X_all, val_users.X_train]),\n",
" val_evaluator, n_trials=40, random_seed=0\n",
" )\n",
" recommender = recommender_class(\n",
" sps.vstack([train_and_val_users.X_all, test_users.X_train]),\n",
" **best_params\n",
" ).learn()\n",
" recommender_name_vs_best_parameter[recommender_class.__name__] = best_params\n",
"\n",
" test_score = dict(\n",
" algorithm=recommender_class.__name__, \n",
" **test_evaluator.get_scores(recommender, cutoffs=[20])\n",
" )\n",
" test_results.append(test_score)\n",
" clear_output()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see below, iALS and DenseSLIM outperforms others\n",
"in terms of accuracy measures (recall, ndcg, map).\n",
"\n",
"iALS performed well regarding the diversity scores (entropy, gini-index, appeared_item), too."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" algorithm | \n",
" hit@20 | \n",
" recall@20 | \n",
" ndcg@20 | \n",
" map@20 | \n",
" precision@20 | \n",
" gini_index@20 | \n",
" entropy@20 | \n",
" appeared_item@20 | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" IALSRecommender | \n",
" 0.996137 | \n",
" 0.208540 | \n",
" 0.576164 | \n",
" 0.135950 | \n",
" 0.528201 | \n",
" 0.915915 | \n",
" 5.989211 | \n",
" 1108.0 | \n",
"
\n",
" \n",
" | 1 | \n",
" DenseSLIMRecommender | \n",
" 0.995033 | \n",
" 0.207463 | \n",
" 0.572965 | \n",
" 0.135436 | \n",
" 0.525055 | \n",
" 0.926926 | \n",
" 5.859120 | \n",
" 1018.0 | \n",
"
\n",
" \n",
" | 2 | \n",
" P3alphaRecommender | \n",
" 0.993377 | \n",
" 0.182982 | \n",
" 0.526259 | \n",
" 0.114564 | \n",
" 0.477152 | \n",
" 0.962736 | \n",
" 5.174319 | \n",
" 690.0 | \n",
"
\n",
" \n",
" | 3 | \n",
" RP3betaRecommender | \n",
" 0.995033 | \n",
" 0.188152 | \n",
" 0.537070 | \n",
" 0.119353 | \n",
" 0.486010 | \n",
" 0.957136 | \n",
" 5.297020 | \n",
" 846.0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" algorithm hit@20 recall@20 ndcg@20 map@20 \\\n",
"0 IALSRecommender 0.996137 0.208540 0.576164 0.135950 \n",
"1 DenseSLIMRecommender 0.995033 0.207463 0.572965 0.135436 \n",
"2 P3alphaRecommender 0.993377 0.182982 0.526259 0.114564 \n",
"3 RP3betaRecommender 0.995033 0.188152 0.537070 0.119353 \n",
"\n",
" precision@20 gini_index@20 entropy@20 appeared_item@20 \n",
"0 0.528201 0.915915 5.989211 1108.0 \n",
"1 0.525055 0.926926 5.859120 1018.0 \n",
"2 0.477152 0.962736 5.174319 690.0 \n",
"3 0.486010 0.957136 5.297020 846.0 "
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"pd.DataFrame(test_results)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's ask each recommender, \"What would you recommend to a user who has just seen \"Toy Story\"?\n",
"\n",
"IALS, DenseSLIM, RP3beta rank \"Toy Story2\" at the top of recommendation list, which seems appropriate."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
" \n",
"
\n",
" 100.00% [9/9 00:00<00:00]\n",
"
\n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"IALSRecommender's result:\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" title | \n",
" genres | \n",
" release_year | \n",
"
\n",
" \n",
" | movieId | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | 3114 | \n",
" Toy Story 2 (1999) | \n",
" Animation|Children's|Comedy | \n",
" 1999 | \n",
"
\n",
" \n",
" | 34 | \n",
" Babe (1995) | \n",
" Children's|Comedy|Drama | \n",
" 1995 | \n",
"
\n",
" \n",
" | 2355 | \n",
" Bug's Life, A (1998) | \n",
" Animation|Children's|Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
" | 1265 | \n",
" Groundhog Day (1993) | \n",
" Comedy|Romance | \n",
" 1993 | \n",
"
\n",
" \n",
" | 588 | \n",
" Aladdin (1992) | \n",
" Animation|Children's|Comedy|Musical | \n",
" 1992 | \n",
"
\n",
" \n",
" | 2396 | \n",
" Shakespeare in Love (1998) | \n",
" Comedy|Romance | \n",
" 1998 | \n",
"
\n",
" \n",
" | 2321 | \n",
" Pleasantville (1998) | \n",
" Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
" | 356 | \n",
" Forrest Gump (1994) | \n",
" Comedy|Romance|War | \n",
" 1994 | \n",
"
\n",
" \n",
" | 1148 | \n",
" Wrong Trousers, The (1993) | \n",
" Animation|Comedy | \n",
" 1993 | \n",
"
\n",
" \n",
" | 595 | \n",
" Beauty and the Beast (1991) | \n",
" Animation|Children's|Musical | \n",
" 1991 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" title genres \\\n",
"movieId \n",
"3114 Toy Story 2 (1999) Animation|Children's|Comedy \n",
"34 Babe (1995) Children's|Comedy|Drama \n",
"2355 Bug's Life, A (1998) Animation|Children's|Comedy \n",
"1265 Groundhog Day (1993) Comedy|Romance \n",
"588 Aladdin (1992) Animation|Children's|Comedy|Musical \n",
"2396 Shakespeare in Love (1998) Comedy|Romance \n",
"2321 Pleasantville (1998) Comedy \n",
"356 Forrest Gump (1994) Comedy|Romance|War \n",
"1148 Wrong Trousers, The (1993) Animation|Comedy \n",
"595 Beauty and the Beast (1991) Animation|Children's|Musical \n",
"\n",
" release_year \n",
"movieId \n",
"3114 1999 \n",
"34 1995 \n",
"2355 1998 \n",
"1265 1993 \n",
"588 1992 \n",
"2396 1998 \n",
"2321 1998 \n",
"356 1994 \n",
"1148 1993 \n",
"595 1991 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"DenseSLIMRecommender's result:\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" title | \n",
" genres | \n",
" release_year | \n",
"
\n",
" \n",
" | movieId | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | 3114 | \n",
" Toy Story 2 (1999) | \n",
" Animation|Children's|Comedy | \n",
" 1999 | \n",
"
\n",
" \n",
" | 2355 | \n",
" Bug's Life, A (1998) | \n",
" Animation|Children's|Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
" | 34 | \n",
" Babe (1995) | \n",
" Children's|Comedy|Drama | \n",
" 1995 | \n",
"
\n",
" \n",
" | 588 | \n",
" Aladdin (1992) | \n",
" Animation|Children's|Comedy|Musical | \n",
" 1992 | \n",
"
\n",
" \n",
" | 1265 | \n",
" Groundhog Day (1993) | \n",
" Comedy|Romance | \n",
" 1993 | \n",
"
\n",
" \n",
" | 2396 | \n",
" Shakespeare in Love (1998) | \n",
" Comedy|Romance | \n",
" 1998 | \n",
"
\n",
" \n",
" | 356 | \n",
" Forrest Gump (1994) | \n",
" Comedy|Romance|War | \n",
" 1994 | \n",
"
\n",
" \n",
" | 1148 | \n",
" Wrong Trousers, The (1993) | \n",
" Animation|Comedy | \n",
" 1993 | \n",
"
\n",
" \n",
" | 1641 | \n",
" Full Monty, The (1997) | \n",
" Comedy | \n",
" 1997 | \n",
"
\n",
" \n",
" | 1923 | \n",
" There's Something About Mary (1998) | \n",
" Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" title \\\n",
"movieId \n",
"3114 Toy Story 2 (1999) \n",
"2355 Bug's Life, A (1998) \n",
"34 Babe (1995) \n",
"588 Aladdin (1992) \n",
"1265 Groundhog Day (1993) \n",
"2396 Shakespeare in Love (1998) \n",
"356 Forrest Gump (1994) \n",
"1148 Wrong Trousers, The (1993) \n",
"1641 Full Monty, The (1997) \n",
"1923 There's Something About Mary (1998) \n",
"\n",
" genres release_year \n",
"movieId \n",
"3114 Animation|Children's|Comedy 1999 \n",
"2355 Animation|Children's|Comedy 1998 \n",
"34 Children's|Comedy|Drama 1995 \n",
"588 Animation|Children's|Comedy|Musical 1992 \n",
"1265 Comedy|Romance 1993 \n",
"2396 Comedy|Romance 1998 \n",
"356 Comedy|Romance|War 1994 \n",
"1148 Animation|Comedy 1993 \n",
"1641 Comedy 1997 \n",
"1923 Comedy 1998 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"RP3betaRecommender's result:\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" title | \n",
" genres | \n",
" release_year | \n",
"
\n",
" \n",
" | movieId | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | 3114 | \n",
" Toy Story 2 (1999) | \n",
" Animation|Children's|Comedy | \n",
" 1999 | \n",
"
\n",
" \n",
" | 1265 | \n",
" Groundhog Day (1993) | \n",
" Comedy|Romance | \n",
" 1993 | \n",
"
\n",
" \n",
" | 2396 | \n",
" Shakespeare in Love (1998) | \n",
" Comedy|Romance | \n",
" 1998 | \n",
"
\n",
" \n",
" | 34 | \n",
" Babe (1995) | \n",
" Children's|Comedy|Drama | \n",
" 1995 | \n",
"
\n",
" \n",
" | 2355 | \n",
" Bug's Life, A (1998) | \n",
" Animation|Children's|Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
" | 1270 | \n",
" Back to the Future (1985) | \n",
" Comedy|Sci-Fi | \n",
" 1985 | \n",
"
\n",
" \n",
" | 260 | \n",
" Star Wars: Episode IV - A New Hope (1977) | \n",
" Action|Adventure|Fantasy|Sci-Fi | \n",
" 1977 | \n",
"
\n",
" \n",
" | 2028 | \n",
" Saving Private Ryan (1998) | \n",
" Action|Drama|War | \n",
" 1998 | \n",
"
\n",
" \n",
" | 356 | \n",
" Forrest Gump (1994) | \n",
" Comedy|Romance|War | \n",
" 1994 | \n",
"
\n",
" \n",
" | 1210 | \n",
" Star Wars: Episode VI - Return of the Jedi (1983) | \n",
" Action|Adventure|Romance|Sci-Fi|War | \n",
" 1983 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" title \\\n",
"movieId \n",
"3114 Toy Story 2 (1999) \n",
"1265 Groundhog Day (1993) \n",
"2396 Shakespeare in Love (1998) \n",
"34 Babe (1995) \n",
"2355 Bug's Life, A (1998) \n",
"1270 Back to the Future (1985) \n",
"260 Star Wars: Episode IV - A New Hope (1977) \n",
"2028 Saving Private Ryan (1998) \n",
"356 Forrest Gump (1994) \n",
"1210 Star Wars: Episode VI - Return of the Jedi (1983) \n",
"\n",
" genres release_year \n",
"movieId \n",
"3114 Animation|Children's|Comedy 1999 \n",
"1265 Comedy|Romance 1993 \n",
"2396 Comedy|Romance 1998 \n",
"34 Children's|Comedy|Drama 1995 \n",
"2355 Animation|Children's|Comedy 1998 \n",
"1270 Comedy|Sci-Fi 1985 \n",
"260 Action|Adventure|Fantasy|Sci-Fi 1977 \n",
"2028 Action|Drama|War 1998 \n",
"356 Comedy|Romance|War 1994 \n",
"1210 Action|Adventure|Romance|Sci-Fi|War 1983 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"P3alphaRecommender's result:\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" title | \n",
" genres | \n",
" release_year | \n",
"
\n",
" \n",
" | movieId | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | 1265 | \n",
" Groundhog Day (1993) | \n",
" Comedy|Romance | \n",
" 1993 | \n",
"
\n",
" \n",
" | 2396 | \n",
" Shakespeare in Love (1998) | \n",
" Comedy|Romance | \n",
" 1998 | \n",
"
\n",
" \n",
" | 3114 | \n",
" Toy Story 2 (1999) | \n",
" Animation|Children's|Comedy | \n",
" 1999 | \n",
"
\n",
" \n",
" | 1270 | \n",
" Back to the Future (1985) | \n",
" Comedy|Sci-Fi | \n",
" 1985 | \n",
"
\n",
" \n",
" | 2028 | \n",
" Saving Private Ryan (1998) | \n",
" Action|Drama|War | \n",
" 1998 | \n",
"
\n",
" \n",
" | 34 | \n",
" Babe (1995) | \n",
" Children's|Comedy|Drama | \n",
" 1995 | \n",
"
\n",
" \n",
" | 356 | \n",
" Forrest Gump (1994) | \n",
" Comedy|Romance|War | \n",
" 1994 | \n",
"
\n",
" \n",
" | 2355 | \n",
" Bug's Life, A (1998) | \n",
" Animation|Children's|Comedy | \n",
" 1998 | \n",
"
\n",
" \n",
" | 1197 | \n",
" Princess Bride, The (1987) | \n",
" Action|Adventure|Comedy|Romance | \n",
" 1987 | \n",
"
\n",
" \n",
" | 588 | \n",
" Aladdin (1992) | \n",
" Animation|Children's|Comedy|Musical | \n",
" 1992 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" title genres \\\n",
"movieId \n",
"1265 Groundhog Day (1993) Comedy|Romance \n",
"2396 Shakespeare in Love (1998) Comedy|Romance \n",
"3114 Toy Story 2 (1999) Animation|Children's|Comedy \n",
"1270 Back to the Future (1985) Comedy|Sci-Fi \n",
"2028 Saving Private Ryan (1998) Action|Drama|War \n",
"34 Babe (1995) Children's|Comedy|Drama \n",
"356 Forrest Gump (1994) Comedy|Romance|War \n",
"2355 Bug's Life, A (1998) Animation|Children's|Comedy \n",
"1197 Princess Bride, The (1987) Action|Adventure|Comedy|Romance \n",
"588 Aladdin (1992) Animation|Children's|Comedy|Musical \n",
"\n",
" release_year \n",
"movieId \n",
"1265 1993 \n",
"2396 1998 \n",
"3114 1999 \n",
"1270 1985 \n",
"2028 1998 \n",
"34 1995 \n",
"356 1994 \n",
"2355 1998 \n",
"1197 1987 \n",
"588 1992 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"for recommender_class in [IALSRecommender, DenseSLIMRecommender, RP3betaRecommender, P3alphaRecommender]:\n",
" rec_tuned = recommender_class(X, **recommender_name_vs_best_parameter[recommender_class.__name__]).learn()\n",
"\n",
" toystory_id = 1\n",
" recommended_id_and_score = id_mapper.recommend_for_new_user(\n",
" rec_tuned, user_profile=[toystory_id], cutoff=10\n",
" )\n",
" print(f\"{recommender_class.__name__}'s result:\")\n",
" # Top-10 recommendations\n",
" display(movies.reindex([movie_id for movie_id, score in recommended_id_and_score]))"
]
}
],
"metadata": {
"interpreter": {
"hash": "2c8d963a96d0919c97b2debbb8f097e0c884c04e5d1a6aef0590fcc7fac9e98a"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}