How to make predictions for users not in the trainset with Surprise (SVD model)?

Viewed 36

I'm trying to build a Collaborative Filtering movie recommender system using the Surprise SVD model, and so far what I've done is split the data into 80:10:10 sets for training, validation and testing respectively. The model was trained on 90% of the data and then I chose the best number of features (n_factors in Surprise SVD) based on results on the validation data, and finally output my RMSE by testing on the test data.

I've then refit the best model on the whole data. Now I want to deploy this on a website. I understand that I probably need a RESTful API to expose my model on the internet. What I'm struggling with is:

I want to be able to allow a user to open the website, rate (say) 5-10 movies and then get the top 5 movies recommended back to them. How can I make the Surprise module to find predictions on the new user that rates it? I can predict the estimated ratings for users that they have not already rated but only for the items in the trainset as follows:

# Refit model to all of the data
data = Dataset.load_from_df(df, reader)
data = data.build_full_trainset()

final_algo.fit(data)
from collections import defaultdict


def get_top_n(predictions, n=10):
    """Return the top-N recommendation for each user from a set of predictions.

    Args:
        predictions(list of Prediction objects): The list of predictions, as
            returned by the test method of an algorithm.
        n(int): The number of recommendation to output for each user. Default
            is 10.

    Returns:
    A dict where keys are user (raw) ids and values are lists of tuples:
        [(raw item id, rating estimation), ...] of size n.
    """

    # First map the predictions to each user.
    top_n = defaultdict(list)
    for uid, iid, true_r, est, _ in predictions:
        top_n[uid].append((iid, est))

    # Then sort the predictions for each user and retrieve the k highest ones.
    for uid, user_ratings in top_n.items():
        user_ratings.sort(key=lambda x: x[1], reverse=True)
        top_n[uid] = user_ratings[:n]

    return top_n

anti_testset = data.build_anti_testset()
predictions1 = algo.test(anti_testset)

top_n = get_top_n(predictions1, n=5)

But how do I allow a user to rate new the movies and then give them recommendations based on that? In this case they wouldn't be in the trainset. From their docs

We can now predict ratings by directly calling the predict() method. Let’s say you’re interested in user 196 and item 302 (make sure they’re in the trainset!), and you know that the true rating...

I want to be able to introduce a new user with the the items that the user rates, and then predict for that user. Is this possible?

0 Answers
Related