{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"-> Links used in study theory\n\n->    https://www.analyticsvidhya.com/blog/2018/06/comprehensive-guide-recommendation-engine-python/\n\n->    https://keras.io/examples/structured_data/collaborative_filtering_movielens/\n\n-> https://github.com/CVxTz/Recommender_keras/blob/master/recommend.py\n\n-> https://www.kaggle.com/rajmehra03/a-detailed-explanation-of-keras-embedding-layer\n\n-> https://www.kaggle.com/rajmehra03/cf-based-recsys-by-low-rank-matrix-factorization\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom zipfile import ZipFile\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom pathlib import Path\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"movielens_dir=\"/kaggle/input/ml-latest-small\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"readme= movielens_dir +\"/README.txt\"\n!cat $readme","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.read_csv(movielens_dir + \"/movies.csv\").head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.read_csv(movielens_dir + \"/tags.csv\").head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.read_csv(movielens_dir + \"/links.csv\").head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# # Download the actual data from http://files.grouplens.org/datasets/movielens/ml-latest-small.zip\"\n# # Use the ratings.csv file\n# movielens_data_file_url = (\n#     \"http://files.grouplens.org/datasets/movielens/ml-latest-small.zip\"\n# )\n# movielens_zipped_file = keras.utils.get_file(\n#     \"ml-latest-small.zip\", movielens_data_file_url, extract=False\n# )\n# keras_datasets_path = Path(movielens_zipped_file).parents[0]\n# movielens_dir = keras_datasets_path / \"ml-latest-small\"\n\n# # Only extract the data the first time the script is run.\n# if not movielens_dir.exists():\n#     with ZipFile(movielens_zipped_file, \"r\") as zip:\n#         # Extract files\n#         print(\"Extracting all the files now...\")\n#         zip.extractall(path=keras_datasets_path)\n#         print(\"Done!\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## The memory-based approch of  collaborative filtering techniques \n\n\nis simple to implement and the resulting recommendations are often easy to explain. \nThey are divided into two:\n\n\n### 1.1: - Item-based collaborative filtering: \nThese systems identify similar items based on users’ previous ratings. For example if users A, B and C gave a 5 star rating to books X and Y then when a user D buys book Y they also get a recommendation to purchase book X because the system identifies book X and Y as similar based on the ratings of users A, B and C.\n\n![image.png](attachment:image.png)\n","attachments":{"image.png":{"image/png":"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QCAQCAQCgc6CQJCzztLT0c5AIBAIBAKBQCAQaBcIBDlrF90UlQwEAoFAIBAIBAKBzoJAkLPO0tPRzkAgEAgEAoFAIBBoFwgEOWsX3dSySv73v/9Nv//+e/rll1/Sf/7zn5Zd1I7P0t5///vf6eeff87t9X+k/4+AMQCbn376Kf3222///4v4FAgEAoFAIHBXI9ApyNkff/yRjRMDVftCZtrSqCMLyqglR/6vd7wtR4f8v/766/Tpp59mo9yWed+NeWnvtWvX0kcffZR+/PHHTNT0pf5uy36VZ+m/thwrtwvTgsHVq1fTgf370/59+9LXX331tzF5u8qvly/8yn1Y7/s4FggEAoFAIPD/EegU5Gzb+++npUuXplmzZjW9Xp09O72+YEHasGFDNvBI1a0mZGHPnj1p3ty56eTJk9kYyZOS9dlnn+Wyz58/33T8VsurvZ4xXr16dRoyaFA6d/Zc7dcd7v9MPg4cSA89+GDGm0r03XffpXfffTctX748XblypU3arJxDhw6lF154IflcS7zbpJA2zOT7779P7733burTp0/q379/mjRpUtr34YeZvLZhMa3K6uzZs2njxo3ptddey8S5VRfHyYFAIBAIdDIEOgU5mzp1aho9enQ2UosXLUper7z8cpo8aVI2Xt7Pnz17y0aDerNjx440Z86cdOHChSYj/uuvv6Zjx45lcvbFF1+0iZE8ceJEemvdurR169b0r3/9Kw9bxAEp6ffEE+nMmTMdfihr7759+9I9//hHOn78eFYLkbOt772XVqxYcVPkbPeuXent9evT9u3bm/qJOvfJJ5+kadOmpW+//bapX+9WgL/88ss81qdNnZr279+f/P/D99+3qULc2rafO3euiZxR0CT3BJxXLF9+y/dea+sT5wcCgUAgcDcj0OHJmXibgQMHpvHjx6d169alo599ll9cYYgNg/vwww+nXbt2pUuXLt1SXyFJlLFDBw9lolBcYIwRIqFMqkYj5aWc35JK7N27N02dMiUrEdooNSJnjcqrltOasqvXVT+3tBxl1Suv3rFq/uVzKaceOct9cPZsNvyUtHqpuXIQhekvvJCWLFmS3dCuR64vX76ciY7Pja4v9apXZu0x57bm/Or1ym+uDog71Wzd2rVZFa5ee6PPra1TS89Hmi0YDh8+3NTuDz74IC+Uxjz7bNMCo1H9WlqO85rD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"}},"execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### 1.2: - User-based collaborative filtering: \nLet us understand this with an example. If person A likes 3 movies, say Interstellar, Inception and Predestination, and person B likes Inception, Predestination and The Prestige, then they have almost similar interests. We can say with some certainty that A should like The Prestige and B should like Interstellar. The collaborative filtering algorithm uses “User Behavior” for recommending items. This is one of the most commonly used algorithms in the industry as it is not dependent on any additional information. \n\n![image.png](attachment:image.png)\n\n\n","attachments":{"image.png":{"image/png":"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"}},"execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# About Movie Lets dataset\nThe MovieLens ratings dataset lists the ratings given by a set of users to a set of movies. \nOur goal is to be able to predict ratings for movies a user has not yet watched. The movies with the highest predicted ratings can then be recommended to the user.\n\nThe steps in the model are as follows:\n\nMap user ID to a \"user vector\" via an embedding matrix\nMap movie ID to a \"movie vector\" via an embedding matrix\nCompute the dot product between the user vector and movie vector, to obtain the a match score between the user and the movie (predicted rating).\nTrain the embeddings via gradient descent using all known user-movie pairs.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Approach\nThe steps in the model are as follows:\n\nMap user ID to a \"user vector\" via an embedding matrix\nMap movie ID to a \"movie vector\" via an embedding matrix\nCompute the dot product between the user vector and movie vector, to obtain the a match score between the user and the movie (predicted rating).\nTrain the embeddings via gradient descent using all known user-movie pairs.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ratings_file = movielens_dir + \"/ratings.csv\"\ndf = pd.read_csv(ratings_file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"global obs_cnt\nobs_cnt = 0\ndef observation(comment):\n    global obs_cnt\n    obs_cnt= obs_cnt+1\n    print(\"\\nObservation-\",obs_cnt,\"->\",comment,\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(df.shape)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Exploring the dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Null checking\nobservation(\"\"\"No null value found\"\"\")\ndf.isna().sum()\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_ids = df[\"userId\"].unique().tolist()\nnum_users=len(user_ids)\nprint(\"no of users:-\",num_users)\nobservation(\"no of unique user id's is 610\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"movie_ids = df[\"movieId\"].unique().tolist()\nnum_movies = len(movie_ids)\nprint(\"no of movie Id:-\",num_movies)\nobservation(\"no of unique movies id is 9724\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"min_rating = np.min(df[\"rating\"])\nmax_rating = np.max(df[\"rating\"])\nprint(\"min Rating:\", min_rating, \"\\nmax Rating:\",max_rating)\nobservation(\"no of min and max rating value given to movie are : 0.5 and 5.0\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Preparing the data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"observation(\"  userId and MovieID columns are of integer type \\n\\t\\t Need to change the datatype into categorical.\")\ndf.dtypes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# covert the datatype of the \ndf.userId = df.userId.astype('category').cat.codes.values\ndf.movieId = df.movieId.astype('category').cat.codes.values\nobservation(\"  userId and MovieID columns datatype changed into categorical.\")\ndf.dtypes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['userId'].value_counts(ascending=True).head(100).values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['userId'].value_counts(ascending=False).head(100).values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['movieId'].value_counts(ascending=True).head(100).values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['movieId'].value_counts(ascending=False).head(100).values","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### BREAKING IT DOWN--\n1) This is the utility matrix; for each of the 671 users arranged rowwise; each column shows the rating of the movie given by a particular user.\n\n2) Note that majority of the matrix is filled with 'Nan' which shows that majority of the movies are unrated by many users.\n\n3) For each movie-user pair if the entry is NOT 'Nan' the vaue indicates the rating given by user to that corressponding movie.\n\n4) For now I am gonna fill the 'Nan' value with value '0'. But note that this just is just indicative, a 0 implies NO RATING and doesn't mean that user has rated 0 to that movie. It doesn't at all represent any rating.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"util_df=pd.pivot_table(data=df,values='rating',index='userId',columns='movieId').fillna(0)\nutil_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics.pairwise import pairwise_distances \nuser_similarity = pairwise_distances(util_df, metric='cosine')\nitem_similarity = pairwise_distances(util_df.T, metric='cosine')\nprint(user_similarity)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Creating Training and Validation Sets","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#user2user_encoded = {x: i for i, x in enumerate(user_ids)}\nuserencoded2user = {i: x for i, x in enumerate(user_ids)}\n#movie2movie_encoded = {x: i for i, x in enumerate(movie_ids)}\nmovie_encoded2movie = {i: x for i, x in enumerate(movie_ids)}\n#user2user_encoded[1]\ndf['userId'] = df['userId'].apply(lambda x: userencoded2user[x])\ndf['movieId'] = df['movieId'].apply(lambda x: movie_encoded2movie[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"split = np.random.rand(len(df)) < 0.8\ntrain = df[split]\nvalid = df[~split]\nprint(train.shape , valid.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":" ### Modeling approach-1  -> simple Matrix Factorization\n\nHere comes the main part!!!\n\n1) Now we move on to the crux of the notebook ie Matrix Factorization. In matrix facorization, we basically break a matrix into usually 2 smaller matrices each with smaller dimensions. these matrices are oftem called 'Embeddings'. We can have variants of Matrix Factorizartion-> 'Low Rank MF' , 'Non-Negaive MF' (NMF) and so on..\n\n2) Here I have used the so called 'Low Rank Matrix Factorization'. I have created embeddings for both user as well as the item; movie in our case. The number of dimensions or the so called 'Latent Factors' in the embeddings is a hyperparameter to deal with in this implementation of Collaborative Filtering.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#preprocess.\nfrom keras.preprocessing.image import ImageDataGenerator\n\n#dl libraraies\nimport keras\nfrom keras import backend as K\nfrom keras.models import Sequential\nfrom keras.layers import Dense , merge\nfrom keras.optimizers import Adam,SGD,Adagrad,Adadelta,RMSprop\nfrom keras.utils import to_categorical\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.callbacks import ReduceLROnPlateau\n\n\nfrom keras.layers.merge import Dot, multiply, concatenate\nfrom keras.models import Model\n\n\n# specifically for deeplearning.\nfrom keras.layers import Dropout, Flatten,Activation,Input,Embedding\nfrom keras.layers import Conv2D, MaxPooling2D, BatchNormalization","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_latent_factors=64  # hyperparamter to deal with. \nnum_users, num_movies # Already calculated above\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_ids[:10], \"\\n\",movie_ids[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_input=Input(shape=(1,),name='user_input',dtype='int64')\nuser_embedding=Embedding(num_users,n_latent_factors,name='user_embedding')(user_input)\n#user_embedding.shape\nuser_vec =Flatten(name='FlattenUsers')(user_embedding)\nuser_vec.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"movie_input=Input(shape=(1,),name='movie_input',dtype='int64')\nmovie_embedding=Embedding(num_movies,n_latent_factors,name='movie_embedding')(movie_input)\nmovie_vec=Flatten(name='FlattenMovies')(movie_embedding)\nmovie_vec","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sim=dot([user_vec,movie_vec],name='Simalarity-Dot-Product',axes=1)\nmodel =keras.models.Model([user_input, movie_input],sim)\nmodel.summary()\n# # A summary of the model is shown below-->","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### BREAKING IT DOWN--\n1) First we need to create embeddings for both the user as well as the item or movie. For this I have used the Embedding layer from keras.\n\n2) Specify the input expected to be embedded (Both in user and item embedding). The use a Embedding layer which expects the no of latent factors in the resulting embedding and also the no of users or items.\n\n3) Then we take the 'Dot-Product' of both the embeddings using the 'merge' layer. Note that 'dot-product' is just a measure of simalrity and we can use any other mode like 'mulitply' or 'cosine simalarity' or 'concatenate' etc...\n\n4) Lastly we make a Keras model from the specified details.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-4),loss='mse')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#[train.userId,train.movieId]\n#train.rating\n#[valid.userId,valid.movieId]\n#valid.rating","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"History = model.fit([train.userId,train.movieId],train.rating,\n                    batch_size=64,epochs =50, \n                    validation_data = ([valid.userId,valid.movieId],valid.rating),verbose = 1\n                   )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"content4\"></a>\n## 4 ) Evaluating the Model Performance","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from pylab import rcParams\nrcParams['figure.figsize'] = 10, 5\nimport matplotlib.pyplot as plt\nplt.plot(History.history['loss'] , 'g')\nplt.plot(History.history['val_loss'] , 'b')\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.grid(True)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"content5\"></a>\n## Modeling Approach 2 ->Using a Deep Neural Network\n\n### Now let us focus on the other main thing!!! Using a NN to matrix factorization ( tuning).\n\n1) Note that this way is not much different from the previous approach.\n\n2) The main difference is that we have used Fully Connected layers as well as the Dropout layers and the BatchNormalization layers.\n\n3) The number of units and the number of layers etc.. are the hyperparametrs here as in a traditional neural network.\n\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating the Embeddings\nn_latent_factors=50\nn_movies=len(df['movieId'].unique())\nn_users=len(df['userId'].unique())\n\n# model configuration part 1\nuser_input=Input(shape=(1,),name='user_input',dtype='int64')\nuser_embedding=Embedding(n_users,n_latent_factors,name='user_embedding')(user_input)\nuser_vec=Flatten(name='FlattenUsers')(user_embedding)\nuser_vec=Dropout(0.40)(user_vec)\n\n# model configuration part 2\nmovie_input=Input(shape=(1,),name='movie_input',dtype='int64')\nmovie_embedding=Embedding(n_movies,n_latent_factors,name='movie_embedding')(movie_input)\nmovie_vec=Flatten(name='FlattenMovies')(movie_embedding)\nmovie_vec=Dropout(0.40)(movie_vec)\n\n# model configuration part 3\nsim=dot([user_vec,movie_vec],name='Simalarity-Dot-Product',axes=1)\nnn_inp=Dense(96,activation='relu')(sim)\nnn_inp=Dropout(0.4)(nn_inp)\n# nn_inp=BatchNormalization()(nn_inp)\nnn_inp=Dense(1,activation='relu')(nn_inp)\n\n# Ensemle Part 1, Part 2, Part 3\nnn_model =keras.models.Model([user_input, movie_input],nn_inp)\nnn_model.summary()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"nn_model.compile(optimizer=Adam(lr=1e-3),loss='mse')\nHistory = nn_model.fit([train.userId,train.movieId],train.rating, batch_size=128,\n                              epochs =40, validation_data = ([valid.userId,valid.movieId],valid.rating),\n                              verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from pylab import rcParams\nrcParams['figure.figsize'] = 10, 5\nimport matplotlib.pyplot as plt\nplt.plot(History.history['loss'] , 'g')\nplt.plot(History.history['val_loss'] , 'b')\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.grid(True)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model experiment 3 : ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_model_3(max_work, max_user):\n    dim_embedddings = 30\n    bias = 1\n    # inputs - part 1\n    w_inputs = Input(shape=(1,), dtype='int32')\n    w = Embedding(max_work+1, dim_embedddings, name=\"work\")(w_inputs)\n    w_bis = Embedding(max_work + 1, bias, name=\"workbias\")(w_inputs)\n\n    # context - part 2\n    u_inputs = Input(shape=(1,), dtype='int32')\n    u = Embedding(max_user+1, dim_embedddings, name=\"user\")(u_inputs)\n    u_bis = Embedding(max_user + 1, bias, name=\"userbias\")(u_inputs)\n    \n    # dot product to find similarity - part 3\n    o = multiply([w, u])\n    #o = dot([w,u],name='Simalarity-Dot-Product',axes=1)\n    o = Dropout(0.5)(o)\n    o = concatenate([o, u_bis, w_bis])\n    o = Flatten()(o)\n    o = Dense(10, activation=\"relu\")(o)\n    o = Dense(1)(o)\n\n    # Ensembling part 1 , part 2, part 3 to make final Model\n    rec_model = Model(inputs=[w_inputs, u_inputs], outputs=o)\n    #rec_model.summary()\n    \n    # compile Model\n    rec_model.compile(loss='mae', optimizer='adam', metrics=[\"mae\"])\n\n    return rec_model\nmodel=get_model_3(num_users,num_movies)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-3),loss='mse')\nHistory = model.fit([train.userId,train.movieId],train.rating, batch_size=128,\n                              epochs =40, validation_data = ([valid.userId,valid.movieId],valid.rating),\n                              verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from pylab import rcParams\nrcParams['figure.figsize'] = 10, 5\nimport matplotlib.pyplot as plt\nplt.plot(History.history['loss'] , 'g')\nplt.plot(History.history['val_loss'] , 'b')\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.grid(True)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import mean_absolute_error, mean_squared_error","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = model.predict([train.movieId, train.userId])\n\ntest_performance = mean_absolute_error(train[\"rating\"], predictions)\ntest_performance1 = mean_squared_error(train[\"rating\"], predictions)\n\n\nprint(\" Test Mae model 1 : %s \" % test_performance)\nprint(\" Test Mae model 1 : %s \" % test_performance1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Pandas sample() is used to generate a sample random row or column from the function caller data frame.\ndf2 = df.sample(frac=1, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = df2[[\"userId\", \"movieId\"]].values\n# Normalize the targets between 0 and 1. Makes it easy to train.\ny = df[\"rating\"].apply(lambda x: (x - min_rating) / (max_rating - min_rating)).values\n# Assuming training on 90% of the data and validating on 10%.\ntrain_indices = int(0.9 * df.shape[0])\nx_train, x_val, y_train, y_val = (\n    x[:train_indices],\n    x[train_indices:],\n    y[:train_indices],\n    y[train_indices:],\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_val.shape, y_val.shape, x_train.shape, y_train.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Create the model\nWe embed both users and movies in to 50-dimensional vectors.\n\nThe model computes a match score between user and movie embeddings via a dot product, and adds a per-movie and per-user bias. The match score is scaled to the [0, 1] interval via a sigmoid (since our ratings are normalized to this range).","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"EMBEDDING_SIZE = 50\n\n\nclass RecommenderNet(keras.Model):\n    def __init__(self, num_users, num_movies, embedding_size, **kwargs):\n        super(RecommenderNet, self).__init__(**kwargs)\n        self.num_users = num_users\n        self.num_movies = num_movies\n        self.embedding_size = embedding_size\n        self.user_embedding = layers.Embedding(\n            num_users,\n            embedding_size,\n            embeddings_initializer=\"he_normal\",\n            embeddings_regularizer=keras.regularizers.l2(1e-6),\n        )\n        self.user_bias = layers.Embedding(num_users, 1)\n        self.movie_embedding = layers.Embedding(\n            num_movies,\n            embedding_size,\n            embeddings_initializer=\"he_normal\",\n            embeddings_regularizer=keras.regularizers.l2(1e-6),\n        )\n        self.movie_bias = layers.Embedding(num_movies, 1)\n\n    def call(self, inputs):\n        user_vector = self.user_embedding(inputs[:, 0])\n        user_bias = self.user_bias(inputs[:, 0])\n        movie_vector = self.movie_embedding(inputs[:, 1])\n        movie_bias = self.movie_bias(inputs[:, 1])\n        dot_user_movie = tf.tensordot(user_vector, movie_vector, 2)\n        # Add all the components (including bias)\n        x = dot_user_movie + user_bias + movie_bias\n        # The sigmoid activation forces the rating to between 0 and 1\n        return tf.nn.sigmoid(x)\n\n\n# model = RecommenderNet(num_users, num_movies, EMBEDDING_SIZE)\n# model.compile(\n#     loss=tf.keras.losses.BinaryCrossentropy(), optimizer=keras.optimizers.Adam(lr=0.001)\n# )\n\n\n# history = model.fit(\n#     x=x_train,\n#     y=y_train,\n#     batch_size=64,\n#     epochs=5,\n#     verbose=1,\n#     validation_data=(x_val, y_val),\n# )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(history.history[\"loss\"])\nplt.plot(history.history[\"val_loss\"])\nplt.title(\"model loss\")\nplt.ylabel(\"loss\")\nplt.xlabel(\"epoch\")\nplt.legend([\"train\", \"test\"], loc=\"upper left\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Show top 10 movie recommendations to a user","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### Step 1: pre processing of new data before making prediction","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"movie_df = pd.read_csv(movielens_dir + \"/movies.csv\")\n\n# # Let us get a user and see the top recommendations.\nuser_id = df.userId.sample(1).iloc[0]\nmovies_watched_by_user = df[df.userId == user_id]\n#movies_watched_by_user\nmovie2movie_encoded = {x: i for i, x in enumerate(movie_ids)}\n\nmovies_not_watched = movie_df[\n    ~movie_df[\"movieId\"].isin(movies_watched_by_user.movieId.values)][\"movieId\"]\n\n# Take the moview from the training input data\nmovies_not_watched = list(\n    set(movies_not_watched).intersection(set(movie2movie_encoded.keys()))\n)\n\nmovies_not_watched = [[movie2movie_encoded.get(x)] for x in movies_not_watched]\n\n\nuser_encoder = user2user_encoded.get(user_id)\n\nuser_movie_array = np.hstack(\n    ([[user_id]] * len(movies_not_watched), movies_not_watched)\n)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Step 2: - making prediction on new data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ratings = model.predict(user_movie_array).flatten()\ntop_ratings_indices = ratings.argsort()[-10:][::-1]\nrecommended_movie_ids = [\n    movie_encoded2movie.get(movies_not_watched[x][0]) for x in top_ratings_indices\n]\n\nprint(\"Showing recommendations for user: {}\".format(user_id))\nprint(\"====\" * 9)\nprint(\"Movies with high ratings from user\")\nprint(\"----\" * 8)\ntop_movies_user = (\n    movies_watched_by_user.sort_values(by=\"rating\", ascending=False)\n    .head(5)\n    .movieId.values\n)\nmovie_df_rows = movie_df[movie_df[\"movieId\"].isin(top_movies_user)]\nfor row in movie_df_rows.itertuples():\n    print(row.title, \":\", row.genres)\n\nprint(\"----\" * 8)\nprint(\"Top 10 movie recommendations\")\nprint(\"----\" * 8)\nrecommended_movies = movie_df[movie_df[\"movieId\"].isin(recommended_movie_ids)]\nfor row in recommended_movies.itertuples():\n    print(row.title, \":\", row.genres)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}