<jupyter_start><jupyter_text>Learning to Rank **Bayesian Personalized Ranking pairwise loss:**  Maximises the prediction difference between a positive example and a randomly chosen negative example. Useful when only positive interactions are present and optimising ROC AUC is desired.**Weighted Approximate-Rank Pairwise loss**:  Maximises the rank of positive examples by repeatedly sampling negative examples until rank violating one is found. Useful when only positive interactions are present and optimising the top of the recommendation list (precision@k) is desired.WARP deals with (user, positive item, negative item) triplets. This procedure yields roughly the following algorithm:- For a given (user, positive item pair), sample a negative item at random from all the remaining items. Compute predictions for both items; if the negative item’s prediction exceeds that of the positive item plus a margin, perform a gradient update to rank the positive item higher and the negative item lower. If there is no rank violation, continue sampling negative items until a violation is found.- If you found a violating negative example at the first try, make a large gradient update: this indicates that a lot of negative items are ranked higher than positives items given the current state of the model, and the model must be updated by a large amount. If it took a lot of sampling to find a violating example, perform a small update: the model is likely close to the optimum and should be updated at a low rate.<jupyter_code>#Get the data

import numpy as np
from lightfm.datasets import fetch_movielens
from lightfm import LightFM<jupyter_output>/Users/amitkaps/miniconda3/lib/python3.5/site-packages/lightfm/_lightfm_fast.py:9: UserWarning: LightFM was compiled without OpenMP support. Only a single thread will be used.
  warnings.warn('LightFM was compiled without OpenMP support. '<jupyter_text>**Movie lens dataset:**![](img/movielens.png)GroupLens Research has collected and made available rating data sets from the MovieLens web site (http://movielens.org). The data sets were collected over various periods of time, depending on the size of the set.http://grouplens.org/datasets/movielens/ **Fetch movielens 100k dataset**The dataset contains 100,000 interactions from 1000 users on 1700 movies, and is exhaustively describedin its README http://files.grouplens.org/datasets/movielens/ml-100k-README.txtThis data set consists of:- 100,000 ratings (1-5) from 943 users on 1682 movies. - Each user has rated at least 20 movies. - Simple demographic info for the users (age, gender, occupation, zip)<jupyter_code>movielens = fetch_movielens() 

#print movie lens 
for key, value in movielens.items():
    print(key, value)
train = movielens['train']
test = movielens['test']
from lightfm import LightFM
from lightfm.evaluation import precision_at_k
from lightfm.evaluation import auc_score<jupyter_output><empty_output><jupyter_text>BPR ModelWe’ll use two metrics of accuracy: precision@k and ROC AUCBoth are ranking metrics: to compute them, we’ll be constructing recommendation lists for all of our users, and checking the ranking of known positive movies. For precision at k we’ll be looking at whether they are within the first k results on the list; for AUC, we’ll be calculating the probability that any known positive is higher on the list than a random negative example.<jupyter_code>model = LightFM(learning_rate=0.05, loss='bpr')
model.fit(train, epochs=10)
train_precision = precision_at_k(model, train, k=10).mean()
test_precision = precision_at_k(model, test, k=10).mean()
train_auc = auc_score(model, train).mean()
test_auc = auc_score(model, test).mean()
print('Precision: train %.2f, test %.2f.' % (train_precision, test_precision))
print('AUC: train %.2f, test %.2f.' % (train_auc, test_auc))<jupyter_output>Precision: train 0.42, test 0.06.
AUC: train 0.84, test 0.82.<jupyter_text>WARP Model<jupyter_code>model = LightFM(learning_rate=0.05, loss='warp')
model.fit_partial(train, epochs=10)
train_precision = precision_at_k(model, train, k=10).mean()
test_precision = precision_at_k(model, test, k=10).mean()
train_auc = auc_score(model, train).mean()
test_auc = auc_score(model, test).mean()
print('Precision: train %.2f, test %.2f.' % (train_precision, test_precision))
print('AUC: train %.2f, test %.2f.' % (train_auc, test_auc))<jupyter_output>Precision: train 0.60, test 0.11.
AUC: train 0.93, test 0.90.<jupyter_text>Discuss the results 1. From the model output, what do you think?2. Which model do you think will run faster?   Prototype Rec Sys<jupyter_code>#Let's quickly prototype a movie recommendation system
import numpy as np
from lightfm import LightFM
from lightfm.datasets import fetch_movielens
from lightfm.evaluation import precision_at_k
data = fetch_movielens(min_rating=5.0)
print(repr(data['train']))
print(repr(data['test']))
model = LightFM(loss='warp')
%time model.fit(data['train'], epochs=30, num_threads=2)
print("Train precision: %.2f" % precision_at_k(model, data['train'], k=5).mean())
print("Test precision: %.2f" % precision_at_k(model, data['test'], k=5).mean())<jupyter_output>Train precision: 0.40
Test precision: 0.05<jupyter_text>Let's sample a couple of users and get their recommendations. To make predictions for given user, we pass the id of that user and the ids of all products we want predictions for into the predict method.<jupyter_code>def sample_recommendation(model, data, user_ids):
    
    n_users, n_items = data['train'].shape
    for user_id in user_ids:
        known_positives = data['item_labels'][data['train'].tocsr()[user_id].indices]
        
        scores = model.predict(user_id, np.arange(n_items))
        top_items = data['item_labels'][np.argsort(-scores)]
        
        print("User %s" % user_id)
        print("     Known positives:")
        
        for x in known_positives[:3]:
            print("        %s" % x)

        print("     Recommended:")
        
        for x in top_items[:3]:
            print("        %s" % x)
        
sample_recommendation(model, data, [3, 25, 450])<jupyter_output>User 3
     Known positives:
        Contact (1997)
        Air Force One (1997)
        In & Out (1997)
     Recommended:
        Kiss the Girls (1997)
        <NAME> (1997)
        Lost Highway (1997)
User 25
     Known positives:
        Fargo (1996)
        Godfather, The (1972)
        L.A. Confidential (1997)
     Recommended:
        Fargo (1996)
        L.A. Confidential (1997)
        Star Wars (1977)
User 450
     Known positives:
        Event Horizon (1997)
        Scream (1996)
        Conspiracy Theory (1997)
     Recommended:
        Scream (1996)
        Game, The (1997)
        Air Force One (1997)
{'fraction_non_alphanumeric': 0.09155766944114149, 'fraction_numerical': 0.02883472057074911, 'mean_word_length': 4.310970797158642, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, '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': '433003', 'license': 'MIT', 'n_tokens_mistral': 2123, 'n_tokens_neox': 1930, 'n_words': 755, 'path': 'HackerNews/#7 Model - Learning to Rank.ipynb', 'repo_name': 'Nayananga/recommendation', 'size': '6731'}