Exemple #1
0
def get_new_users_matrix():
    """
    Author: Gustaf Norberg
    Date: 2017-11-06
    Last update: 2017-11-14 by Alexander Dahl
    Purpose: returns the new users matrix. The matrix is 10 % of the user ratings.
    Is used for showing that model is evolving

    :return: new users matrix in the form of a numpy matrix
    """

    user_list = []
    movie_list = []
    rating_list = []

    ratings = RetrieveRating().retrieve_ratings()

    counter = 0
    # Puts every 10th row (10, 20, 30...) in new_users_matrix
    for rating in ratings:
        if counter % 10 == 0:
            user_list.append(rating.user_id)
            movie_list.append(rating.movie_id)
            rating_list.append(rating.rating)
        counter += 1
    # TODO Change dimensions to greater than 1 if problem with dimensions
    new_users_matrix = coo_matrix(
        (rating_list, (user_list, movie_list)),
        shape=(RetrieveUser().retrieve_largest_user_id() + 1,
               RetrieveMovie().retrieve_largest_movie_id() + 1))

    return new_users_matrix
Exemple #2
0
def get_test_matrix():
    """
    Author: Gustaf Norberg / Alexander Dahl
    Date: 2017-11-06
    Last update: 2017-11-14 by Alexander Dahl
    Purpose:
    returns the test matrix. The matrix is 10% of the user ratings at the moment

    :return: test matrix in the form of a numpy matrix
    """
    test_user_list = []
    test_movie_list = []
    test_rating_list = []

    ratings = RetrieveRating().retrieve_ratings()

    counter = 0
    # Puts every 10th row (5, 15, 25...) in test_matrix
    for rating in ratings:
        if counter % 5 == 0 and counter % 2 == 1:
            test_user_list.append(rating.user_id)
            test_movie_list.append(rating.movie_id)
            test_rating_list.append(rating.rating)
        counter += 1
    # TODO Change dimensions to greater than 1 if problem with dimensions
    test_matrix = coo_matrix(
        (test_rating_list, (test_user_list, test_movie_list)),
        shape=(RetrieveUser().retrieve_largest_user_id() + 1,
               RetrieveMovie().retrieve_largest_movie_id() + 1))
    return test_matrix
Exemple #3
0
def get_train_matrix():
    """
    Author: Marten Bolin / John Lidquist
    Date: 2017-10-02
    Last update: 2017-11-14 by Alexander Dahl
    Purpose:
    returns the train matrix. The matrix is 80% (4/5) of the user ratings at the moment
    OBS! coo_matrix is a sparse matrix and will (most likely) have the same
    dimensions for train_matrix, test_matrix and new_user_matrix

    :return: training matrix in the form of a numpy matrix
    """

    user_list = []
    movie_list = []
    rating_list = []
    ratings = RetrieveRating().retrieve_ratings()

    counter = 0
    # Puts everything but every 5th row (1, 2, 3, 4, 6, 7, 8, 9, 11...) in train_matrix
    for rating in ratings:
        if counter % 5 != 0:
            user_list.append(rating.user_id)
            movie_list.append(rating.movie_id)
            rating_list.append(rating.rating)
        counter += 1

    # Added +1 because else the matrix will be to small
    # TODO Change dimensions to greater than 1 if problem with dimensions
    train_matrix = coo_matrix(
        (rating_list, (user_list, movie_list)),
        shape=(RetrieveUser().retrieve_largest_user_id() + 1,
               RetrieveMovie().retrieve_largest_movie_id() + 1))
    return train_matrix
Exemple #4
0
    def insert_feedback(user_id, movie_id, watched=None, rating=None):
        """
        Author: Alexander Dahl, Marten Bolin
        Date: 2017-11-17
        Last update:
        Purpose: Make Insert of Feedback to the database.
        if a feedback has a rating this will be used to evolve the lightFM model.
        :param user_id : The id of the user that has made the rating or watched
        :type int
        :param movie_id : The id of the movie that has been rated or watched
        :type int
        :param watched : 1 if has watched (optional)
        :type int
        :param rating : the rating that was made, 1-5 (optional)
        :type float
        """
        InsertFeedback().insert_feedback(user_id, movie_id, watched, rating)

        if rating:
            model = generate_model.load_model(generate_model.get_path())
            # Converting to lists because otherwise it is not possible to convert them to
            # coo matrices
            rating_list = [rating]
            user_list = [user_id]
            movie_list = [movie_id]

            # Need to define shape so that it is coherent with the previous model
            # TODO Change dimensions to greater than 1 if problem with dimensions
            user_matrix = sp.coo_matrix(
                (rating_list, (user_list, movie_list)),
                shape=(RetrieveUser().retrieve_largest_user_id() + 1,
                       RetrieveMovie().retrieve_largest_movie_id() + 1))
            generate_model.evolve_model(generate_model.get_path(), model,
                                        user_matrix)
    def generate_recommendation_list(self):
        # TODO Do not recommened already viewed movies
        """
        Author: Sebastian Maghsoudi / Alexander Dahl
        Date: 2017-11-01
        Last update: 2017-11-29 by Alexander Dahl
        Purpose: Generates a recommendation list of size length for a given user.

        :return: a dictionary with user_id and a recommendation_list for that user
        example:
        {'user_id': 55, 'recommendation_list' :
        [{'title': 'It', 'score': 1.586134233975164, 'id': 24}]}
        """
        trending_id = [id.movie_id for id in self.trending_content_meta]
        # print(np.array(trending_id
        trending_score = [score.total_score for score in self.trending_content_meta]
        # normalize trending score
        norm_trending_score = self.normalize_user_scores(trending_score)
        # trending_weight is 0.5 at the moment
        # TODO document why trending weight is 0.5
        trending_weight = 0.5
        # checks if the user has ratings in the database
        # if there are no ratings the user preferences does not matter and
        # the user only gets the trendings as recommendations
        if RetrieveUser().check_if_user_in_rating(self.user_id):
            rec_list_score = self.model.predict(self.user_id, np.array(trending_id))
            norm_rec_list_score = self.normalize_user_scores(rec_list_score).tolist()
            final_rec_list_score = [rec+trending_weight*trend for rec, trend
                                    in zip(norm_rec_list_score, norm_trending_score)]
        else:
            final_rec_list_score = [trending_weight*trend for trend in norm_trending_score]
        # gets the movie titles for the movie ids
        movie_titles = [gets_from_database.get_movie_title(id.movie_id) for id
                        in self.trending_content_meta]
        # combines the movie_ids and movie_titles with the recommendation scores
        full_rec_list = list(map(list, zip(trending_id, movie_titles, final_rec_list_score)))
        # sorts the list on scores (index 2)
        sorted_rec_list = sorted(full_rec_list,
                                 key=lambda x: x[2],
                                 reverse=True)

        sorted_complete_rec_list = []
        for item in sorted_rec_list[:self.size]:
            sorted_complete_rec_list.append({'id': item[0],
                                             'title': item[1],
                                             'score': item[2]})
        # Creates an instance of InsertRecommendation that handles database insertions.
        # Calls the insert_recommendation method in it and makes the db insertion
        # This will not remove old recommendations and will add new ones.
        InsertRecommendation().insert_recommendation(user_id=self.user_id,
                                                     movie_list=sorted_complete_rec_list)
        return RecommendationList(self.user_id, sorted_complete_rec_list)
 def _run(self):
     """
     Author: Marten Bolin
     Date:2017-11-22
     Last update:
     Purpose: The process that is ran, checks for updates and updates model
     """
     # Get current state
     current_number_of_users = len(RetrieveUser().retrieve_all_users())
     current_number_of_movies = len(RetrieveMovie().retrieve_movie())
     current_number_of_ratings = len(RetrieveRating().retrieve_ratings())
     # Checks rating first due to most likely to change
     if (self.number_of_ratings == current_number_of_ratings
             and self.number_of_users == current_number_of_users
             and self.number_of_movies == current_number_of_movies):
         print("Nothing new, no changes made.")
     else:
         print("Changes detected, adjusting model")
         CreateNewModel.create_new_model()
         self.number_of_users = len(RetrieveUser().retrieve_all_users())
         self.number_of_movies = len(RetrieveMovie().retrieve_movie())
         self.number_of_ratings = len(RetrieveRating().retrieve_ratings())
 def execute(number_of_users=None):
     """
     Author: Alexander Dahl, Marten Bolin
     Date: 2017-11-15
     Last update: 2017-11-28 by Alexander Dahl
     Purpose:
     This method populates the database with recommendations for all users.
     :param number_of_users : how many users to create recommendations for
     """
     # TODO only retrieve users that are needed and not all of them from number_of_users.
     users = RetrieveUser().retrieve_all_users()
     if not number_of_users:
         number_of_users = len(users)
     # populates the database with all the recommendations for all users
     # TODO user_number variable is useless, change the code so it works without it
     for user, user_number in zip(users, range(0, number_of_users)):
         # the Recommendation class will insert it to the database when it is generated
         Recommendation(user.id).generate_recommendation_list()
from Product.Database.DatabaseManager.Retrieve.RetrieveUser import RetrieveUser
"""
Author: John Andree Lidquist, Marten Bolin
Date: 2017-10-12
Last update: 2017-11-9
Purpose: Script that will fill the database with the small data set (40 movies) by running
DbFillMovieLens files
"""

# This script will
# 1. Create the a new database (by running DBConn)
# 2. Fill it with the data from the data set (by running DBFillUsers, DBFillMovies,
# and DBFillRatings)

# 1. Create the a new database (by running DBConn)
# The import is grayed out, but will run anyway.
import Product.Database.DBConn

retriever = RetrieveUser()
# 2. Fill it with the data from the data set (by running DBFillUsers, DBFillMovies
# and DBFillRatings)
if retriever.check_if_user_in_rating(1) is None:
    use_small_set = True
    FillUsers()
    FillMovies(use_small_set)
    FillRatings(use_small_set)
    print("No links added (not necessary)")
    # There are no Links created for the small data set
else:
    print("There is already an existing database.")