<jupyter_start><jupyter_text>RECOMMENDER SYSTEM  NEURAL COLLABORATIVE FILTER  IMPORT LIBRARIES<jupyter_code>import numpy as np
import pandas as pd
import json
from keras.models import Model
from keras.layers import Input, Dense, Embedding, concatenate, Flatten, Activation, Add, Dropout, Multiply
from keras.optimizers import Adam<jupyter_output><empty_output><jupyter_text>LOADING AND PROCESSING DATA<jupyter_code>meta = pd.read_csv('the-movies-dataset/movies_metadata.csv')
meta.head(5)
"""meta = meta[['id', 'original_title', 'original_language', 'genres']]
meta = meta.rename(columns={'id':'movieId'})
meta = meta[meta['original_language'] == 'en']
meta.head()"""
meta.columns
def parse_genres(genres_str):
    genres = json.loads(genres_str.replace('\'', '"'))
    
    genres_list = []
    for g in genres:
        genres_list.append(g['name'])

    return genres_list

meta['genres'] = meta['genres'].apply(parse_genres)

meta.head()
rating_df = pd.read_csv('the-movies-dataset/ratings_small.csv')
rating_df.head()
# sort data frame by timestemp for splitting
rating_df = rating_df.sort_values('timestamp')
rating_df.head()<jupyter_output><empty_output><jupyter_text>ENCODING<jupyter_code>from sklearn.preprocessing import LabelEncoder
user_encoder = LabelEncoder()
movie_encoder = LabelEncoder()

user_ids = user_encoder.fit_transform(rating_df.userId)
movie_ids = movie_encoder.fit_transform(rating_df.movieId)<jupyter_output><empty_output><jupyter_text>SPLITING DATASET<jupyter_code># train / val split
num_train = int(len(user_ids) * 0.8)
train_user_ids = user_ids[:num_train]
train_movie_ids = movie_ids[:num_train]
train_ratings = rating_df.rating.values[:num_train]
val_user_ids = user_ids[num_train:]
val_movie_ids = movie_ids[num_train:]
val_ratings = rating_df.rating.values[num_train:]
num_users= user_ids.max()+1
num_movies = movie_ids.max() + 1<jupyter_output><empty_output><jupyter_text>RATE NORMALISATION<jupyter_code>train_ratings /= 5
val_ratings /= 5<jupyter_output><empty_output><jupyter_text>BUILDING MODEL<jupyter_code>def get_ncf_model():
    user_inp = Input((1,))
    user_hidden = Embedding(input_dim=num_users, output_dim=64)(user_inp)
    user_hidden = Flatten()(user_hidden)
    
    item_inp = Input((1,))
    item_hidden = Embedding(input_dim=num_movies, output_dim=64)(item_inp)
    item_hidden = Flatten()(item_hidden)
    
    # element-wise multiplication
    mf_output = Multiply()([user_hidden, item_hidden])
    
    hidden = concatenate([user_hidden, item_hidden])
    hidden = Dense(128, activation='relu')(hidden)
    hidden = Dropout(0.2)(hidden)
    mlp_output = Dense(64, activation='relu')(hidden)    

    
    output = concatenate([mf_output, mlp_output])
    output = Dense(1, activation='sigmoid')(output)
    
    model = Model(inputs=[user_inp, item_inp], outputs=output)
    model.compile(loss='mse', optimizer='adam')
    return model

model = get_ncf_model()
model.summary()
from keras.callbacks import EarlyStopping
# early stopping wait for 1 epoch
callbacks = [EarlyStopping(patience=1)]

# train for 50 epochs
model.fit([train_user_ids, train_movie_ids], train_ratings,\
          validation_data=([val_user_ids, val_movie_ids], val_ratings), epochs=50, batch_size=128, callbacks=callbacks)
def dcg_at_k(r, k):
    '''
    Compute DCG
    args:
        r: np.array, to be evaluated
        k: int, number of entries to be considered
    
    returns:
        dcg: float, computed dcg
        
    '''
    r = r[:k]
    dcg = np.sum(r / np.log2(np.arange(2, len(r) + 2)))
    return dcg
def ndcg_at_k(r, k, method=0):
    '''
    Compute NDCG
    args:
        r: np.array, to be evaluated
        k: int, number of entries to be considered
    
    returns:
        dcg: float, computed ndcg
        
    '''
    dcg_max = dcg_at_k(sorted(r, reverse=True), k)

    return dcg_at_k(r, k) / dcg_max
# compute average ndcg for all users
def evaluate_prediction(predictions):
    '''
    Return the average ndcg for each users
    args:
        predictions: np.array user-item predictions
    returns:
        ndcg: float, computed NDCG
    '''
    ndcgs = []
    for target_user in np.unique(val_user_ids):
        # get movie ids and ratings associated with the target user.
        target_val_movie_ids = val_movie_ids[val_user_ids == target_user] 
        target_val_ratings = val_ratings[val_user_ids == target_user] 
        
        # compute ndcg for this user
        ndcg = ndcg_at_k(target_val_ratings[np.argsort(-predictions[val_user_ids == target_user])], k=30)
        ndcgs.append(ndcg)
    ndcg = np.mean(ndcgs)
    return ndcg
# prediction & evalutation
predictions = model.predict([val_user_ids, val_movie_ids])
evaluate_prediction(predictions[:,0])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11667017027538365, 'fraction_numerical': 0.007778011351692243, 'mean_word_length': 4.538998835855646, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '455039', 'license': 'CC0-1.0', 'n_tokens_mistral': 1734, 'n_tokens_neox': 1687, 'n_words': 326, 'path': 'Neural collaborative filter -Recommender system.ipynb', 'repo_name': 'Apekshagaonkar/Neural-Collaborative-Filtering-Movie-Recommendation-System', 'size': '4757'}