Exemple #1
0
        public async Task <int> GenerateRecommendation(RecommendationParameters parameters)
        {
            var context = new Database.DatabaseContext(_dbContextOptions);

            var recommendedMovieIds = await GetRecommendedMovieIds(context, parameters);

            var recommendation = new Database.Recommendation()
            {
                Date   = DateTime.Now,
                UserId = parameters.UserId
            };

            context.Add(recommendation);
            await context.SaveChangesAsync();

            var recommendedMovies = recommendedMovieIds.Select(rm => new Database.RecommendedMovie()
            {
                RecommendationId = recommendation.Id,
                MovieId          = rm,
                PossibleRating   = 0.0f,
            });

            context.AddRange(recommendedMovies);
            await context.SaveChangesAsync();

            return(0);
        }
Exemple #2
0
        public int Add(RecommendationParameters parameters)
        {
            var id   = GetNewRecommendationId();
            var hash = new HashEntry[] {
                new HashEntry("recommendationParameters", JsonConvert.SerializeObject(parameters)),
                new HashEntry("status", (int)RecommendationStatus.Queued),
                new HashEntry("startTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)),
            };

            DataBase.HashSet($"recommendation:{id}", hash);
            return(id);
        }
Exemple #3
0
        public int Add(RecommendationParameters parameters)
        {
            var recommendation = new QueuedRecommendation
            {
                Id = GetNewRecommendationId(),
                RecommendationParameters = parameters,
                Status    = Database.RecommendationStatus.Queued,
                StartTime = DateTime.Now
            };

            _recommendations.Add(recommendation);

            return(recommendation.Id);
        }
        public async Task <int> GenerateRecommendation(RecommendationParameters parameters)
        {
            var context = new Database.DatabaseContext(_dbContextOptions);

            var recommendedMovies = (
                from movies in context.Movies
                join tags in context.MovieTags on movies.Id equals tags.MovieId
                where parameters.RequestedTagIds.Contains(tags.TagId)
                select new { movies.Id, Rating = movies.AverageRating, }
                ).Distinct().OrderByDescending(movie => movie.Rating).Take(10);

            if (recommendedMovies.Count() == 0)
            {
                return(0);
            }

            var recommendation = new Database.Recommendation()
            {
                UserId = parameters.UserId,
            };

            context.Recommendations.Attach(recommendation);
            context.Recommendations.Add(recommendation);
            await context.SaveChangesAsync();

            foreach (var movie in await recommendedMovies.ToListAsync())
            {
                var recommendedMovie = new Database.RecommendedMovie()
                {
                    MovieId          = movie.Id,
                    PossibleRating   = movie.Rating,
                    RecommendationId = recommendation.Id,
                };

                context.RecommendedMovies.Attach(recommendedMovie);
                context.RecommendedMovies.Add(recommendedMovie);
            }

            await context.SaveChangesAsync();

            context.Dispose();

            return(recommendation.Id);
        }
Exemple #5
0
        private bool[] CreateSimilarityMatrixFilter(
            double[][] similarityMatrix, int[] movieIds, Database.DatabaseContext context, RecommendationParameters parameters, IEnumerable <UserMovie> userMovies)
        {
            var movies = context.Movies.Include(m => m.Tags).ToArray();
            var isSimilarityAllowedFilters = new bool[similarityMatrix.GetLength(0)];
            var userMovieIds = userMovies.Select(um => um.Id).ToHashSet();

            for (int i = 0; i < movieIds.Length; i++)
            {
                var movieId = movieIds[i];
                var movie   = movies.First(m => m.Id == movieId);

                isSimilarityAllowedFilters[i] = DoesMovieContainTags(movie, parameters.RequestedTagIds) && !userMovieIds.Contains(movieId);
            }

            return(isSimilarityAllowedFilters);
        }
Exemple #6
0
 private IQueryable <int> GetMostPopularMovies(Database.DatabaseContext context, RecommendationParameters parameters) =>
 context.Movies.Include(m => m.Tags)
 .Where(m => DoesMovieContainTags(m.Tags.Select(t => t.TagId), parameters.RequestedTagIds))
 .Select(m => m.Id)
 .Take(RecommendedMovieLimit);
Exemple #7
0
 private IQueryable <UserMovie> GetUserMoviesByGenres(Database.DatabaseContext context, RecommendationParameters parameters) =>
 context.UserMovies.Include(um => um.Movie.Tags)
 .Where(um => um.UserId == parameters.UserId &&
        DoesMovieContainTags(um.Movie.Tags.Select(t => t.TagId), parameters.RequestedTagIds))
 .Select(um => new UserMovie {
     Id = um.MovieId, Rating = um.Rating
 });
Exemple #8
0
        private async Task <IEnumerable <int> > GetRecommendedMovieIds(Database.DatabaseContext context, RecommendationParameters parameters)
        {
            if (!_cache.IsPopulated)
            {
                await PrepareData();
            }

            var movieIds         = _cache.RetrieveMovieIdsFromCache();
            var similarityMatrix = _cache.RetrieveSimilarityMatrixFromCache(movieIds);

            var userMovies = GetUserMoviesByGenres(context, parameters);

            if (userMovies.Count() == 0)
            {
                userMovies = GetUserMovies(context);
            }

            if (userMovies.Count() == 0)
            {
                return(GetMostPopularMovies(context, parameters));
            }

            // Limit matrix to only include requested tags and exclude user movies
            var isSimilarityAllowedFilters = CreateSimilarityMatrixFilter(similarityMatrix, movieIds, context, parameters, userMovies);

            // Gather the most similar movies
            var allSimilarities = new List <SimilarityObject>();

            foreach (var userMovie in userMovies)
            {
                var movieIndex = FindMovieIndex(movieIds, userMovie.Id);

                // Weight similarities by how good the movies are rated and include indicies in selection
                var similarities = similarityMatrix[movieIndex]
                                   .Select((s, index) => new SimilarityObject {
                    Similarity = s * (userMovie.Rating / 10), Index = index
                })
                                   .Where(s => isSimilarityAllowedFilters[s.Index])
                                   .OrderByDescending(s => s.Similarity)
                                   .Take(RecommendedMovieLimit);

                allSimilarities.AddRange(similarities);
            }

            var equalityComparer = new SimilarityObjectComparer();

            // Get top recommended movie ids
            var userMoviesIds = userMovies.Select(um => um.Id);

            return(allSimilarities
                   .Distinct(equalityComparer)
                   .Where(id => !userMoviesIds.Contains(id.Index))
                   .OrderByDescending(s => s.Similarity)
                   .Take(RecommendedMovieLimit)
                   .Select(s => movieIds[s.Index]));
        }