public void preferencesFetchedOnlyOnce()
        {
            var dataModelMock = new DynamicMock(typeof(IDataModel));

            var itemSimilarityMock         = new DynamicMock(typeof(IItemSimilarity));
            var candidateItemsStrategyMock = new DynamicMock(typeof(ICandidateItemsStrategy));
            var mostSimilarItemsCandidateItemsStrategyMock =
                new DynamicMock(typeof(IMostSimilarItemsCandidateItemsStrategy));

            IPreferenceArray preferencesFromUser = new GenericUserPreferenceArray(
                new List <IPreference>()
            {
                new GenericPreference(1L, 1L, 5.0f), new GenericPreference(1L, 2L, 4.0f)
            });

            dataModelMock.ExpectAndReturn("GetMinPreference", float.NaN);
            dataModelMock.ExpectAndReturn("GetMaxPreference", float.NaN);
            dataModelMock.ExpectAndReturn("GetPreferencesFromUser", preferencesFromUser, 1L);
            var dataModel = (IDataModel)dataModelMock.MockInstance;

            candidateItemsStrategyMock.ExpectAndReturn("GetCandidateItems", new FastIDSet(new long[] { 3L, 4L }),
                                                       1L, preferencesFromUser, dataModel);

            itemSimilarityMock.ExpectAndReturn("ItemSimilarities", new double[] { 0.5, 0.3 },
                                               3L, preferencesFromUser.GetIDs());
            itemSimilarityMock.ExpectAndReturn("ItemSimilarities", new double[] { 0.4, 0.1 },
                                               4L, preferencesFromUser.GetIDs());



            //EasyMock.replay(dataModel, itemSimilarity, candidateItemsStrategy, mostSimilarItemsCandidateItemsStrategy);

            IRecommender recommender = new GenericItemBasedRecommender((IDataModel)dataModel,
                                                                       (IItemSimilarity)itemSimilarityMock.MockInstance,
                                                                       (ICandidateItemsStrategy)candidateItemsStrategyMock.MockInstance,
                                                                       (IMostSimilarItemsCandidateItemsStrategy)mostSimilarItemsCandidateItemsStrategyMock.MockInstance);

            recommender.Recommend(1L, 3);

            dataModelMock.Verify();
            itemSimilarityMock.Verify();
            candidateItemsStrategyMock.Verify();
            mostSimilarItemsCandidateItemsStrategyMock.Verify();
            //EasyMock.verify(dataModel, itemSimilarity, candidateItemsStrategy, mostSimilarItemsCandidateItemsStrategy);
        }
Ejemplo n.º 2
0
        public List <MovieRecommendationDto> GetRecommendedMovies(int[] preferredMovieIds)
        {
            var dataModel = GetDataModel();

            // recommendation is performed for the user that is missed in the preferences data
            var plusAnonymModel = new PlusAnonymousUserDataModel(dataModel);
            var prefArr         = new GenericUserPreferenceArray(preferredMovieIds.Length);

            prefArr.SetUserID(0, PlusAnonymousUserDataModel.TEMP_USER_ID);
            for (int i = 0; i < preferredMovieIds.Length; i++)
            {
                prefArr.SetItemID(i, preferredMovieIds[i]);

                // in this example we have no ratings of movies preferred by the user
                prefArr.SetValue(i, 5); // lets assume max rating
            }
            plusAnonymModel.SetTempPrefs(prefArr);

            var similarity       = new LogLikelihoodSimilarity(plusAnonymModel);
            var neighborhood     = new NearestNUserNeighborhood(15, similarity, plusAnonymModel);
            var recommender      = new GenericUserBasedRecommender(plusAnonymModel, neighborhood, similarity);
            var recommendedItems = recommender.Recommend(PlusAnonymousUserDataModel.TEMP_USER_ID, 5, null);

            var movieIds = recommendedItems.Select(ri => (int)ri.GetItemID()).ToArray();
            var movieIdToTitleDictionary = _unitOfWork.MovieRepository.GetMovieIdToTileDictionary(movieIds);

            var recommendedMovies = new List <MovieRecommendationDto>();

            foreach (var item in recommendedItems)
            {
                var movieId    = (int)item.GetItemID();
                var movieTitle = movieIdToTitleDictionary[movieId];

                recommendedMovies.Add(
                    new MovieRecommendationDto
                {
                    MovieId    = movieId,
                    MovieTitle = movieTitle,
                    Rating     = item.GetValue()
                });
            }

            return(recommendedMovies);
        }
        public ActionResult Recommend(string filmIdsJson)
        {
            var filmIds        = (new JavaScriptSerializer()).Deserialize <long[]>(filmIdsJson);
            var pathToDataFile =
                Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, "data/albums.dat");

            if (dataModel == null)
            {
                try
                {
                    dataModel = new FileDataModel(pathToDataFile, false, FileDataModel.DEFAULT_MIN_RELOAD_INTERVAL_MS, false);
                }
                catch (Exception e)
                {
                    var exe = e.ToString();
                }
            }

            var plusAnonymModel = new PlusAnonymousUserDataModel(dataModel);
            var prefArr         = new GenericUserPreferenceArray(filmIds.Length);

            prefArr.SetUserID(0, PlusAnonymousUserDataModel.TEMP_USER_ID);
            for (int i = 0; i < filmIds.Length; i++)
            {
                prefArr.SetItemID(i, filmIds[i]);
                prefArr.SetValue(i, 5);                 // lets assume max rating
            }
            plusAnonymModel.SetTempPrefs(prefArr);

            var similarity       = new LogLikelihoodSimilarity(plusAnonymModel);
            var neighborhood     = new NearestNUserNeighborhood(15, similarity, plusAnonymModel);
            var recommender      = new GenericBooleanPrefUserBasedRecommender(plusAnonymModel, neighborhood, similarity);
            var recommendedItems = recommender.Recommend(PlusAnonymousUserDataModel.TEMP_USER_ID, 5, null);

            return(Json(recommendedItems.Select(ri => new Dictionary <string, object>()
            {
                { "id", ri.GetItemID() },
                { "rating", ri.GetValue() },
            }).ToArray()));
        }
        public void testStrategy()
        {
            FastIDSet itemIDsFromUser123 = new FastIDSet();

            itemIDsFromUser123.Add(1L);

            FastIDSet itemIDsFromUser456 = new FastIDSet();

            itemIDsFromUser456.Add(1L);
            itemIDsFromUser456.Add(2L);

            List <IPreference> prefs = new List <IPreference>();

            prefs.Add(new GenericPreference(123L, 1L, 1.0f));
            prefs.Add(new GenericPreference(456L, 1L, 1.0f));
            IPreferenceArray preferencesForItem1 = new GenericItemPreferenceArray(prefs);

            var dataModelMock = new DynamicMock(typeof(IDataModel));

            dataModelMock.ExpectAndReturn("GetPreferencesForItem", preferencesForItem1, (1L));
            dataModelMock.ExpectAndReturn("GetItemIDsFromUser", itemIDsFromUser123, (123L));
            dataModelMock.ExpectAndReturn("GetItemIDsFromUser", itemIDsFromUser456, (456L));

            IPreferenceArray prefArrayOfUser123 =
                new GenericUserPreferenceArray(new List <IPreference>()
            {
                new GenericPreference(123L, 1L, 1.0f)
            });

            ICandidateItemsStrategy strategy = new PreferredItemsNeighborhoodCandidateItemsStrategy();

            //EasyMock.replay(dataModel);

            FastIDSet candidateItems = strategy.GetCandidateItems(123L, prefArrayOfUser123, (IDataModel)dataModelMock.MockInstance);

            Assert.AreEqual(1, candidateItems.Count());
            Assert.True(candidateItems.Contains(2L));

            dataModelMock.Verify(); //  EasyMock.verify(dataModel);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 推荐
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="showCount">显示数量</param>
        /// <returns></returns>
        public List <Books> RecommendBooks(int pageIndex, int pageSize, int showCount)
        {
            #region 推荐
            List <Books> books = null;
            if (Session["user"] != null)
            {
                Users user = Session["user"] as Users;

                #region 构建用户行为数组
                var           loglist = logbll.LoadEntities(c => c.userID == user.Id).ToList();
                StringBuilder sb      = new StringBuilder();
                if (loglist.Count > 0)
                {
                    sb.Append("[");
                    int j = 0;
                    foreach (var item in loglist)
                    {
                        j++;
                        sb.Append(item.itemID.ToString());
                        if (j != loglist.Count)
                        {
                            sb.Append(",");
                        }
                    }
                    sb.Append("]");
                }
                #endregion

                if (string.IsNullOrEmpty(sb.ToString()))
                {
                    //冷启动
                    books = booksbll.LoadEntities(c => true).OrderByDescending(c => c.rating).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                }
                else
                {
                    var filmIds = (new JavaScriptSerializer()).Deserialize <long[]>(sb.ToString());

                    var    logmodel = settingbll.LoadEntities(c => c.id == 16).FirstOrDefault();
                    string path     = "";
                    if (logmodel != null && logmodel.value == "true")
                    {
                        path = "data/ratings1.dat";
                    }
                    else
                    {
                        path = "data/ratings.dat";
                    }

                    var pathToDataFile =
                        Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, path);

                    if (dataModel == null)
                    {
                        dataModel = new FileDataModel(pathToDataFile, false, FileDataModel.DEFAULT_MIN_RELOAD_INTERVAL_MS, false);
                    }

                    var plusAnonymModel = new PlusAnonymousUserDataModel(dataModel);
                    var prefArr         = new GenericUserPreferenceArray(filmIds.Length);
                    prefArr.SetUserID(0, PlusAnonymousUserDataModel.TEMP_USER_ID);
                    for (int i = 0; i < filmIds.Length; i++)
                    {
                        prefArr.SetItemID(i, filmIds[i]);
                        prefArr.SetValue(i, 5); // lets assume max rating
                    }
                    plusAnonymModel.SetTempPrefs(prefArr);

                    var          similarity       = new LogLikelihoodSimilarity(plusAnonymModel);
                    var          neighborhood     = new NearestNUserNeighborhood(15, similarity, plusAnonymModel);
                    var          recommender      = new GenericUserBasedRecommender(plusAnonymModel, neighborhood, similarity);
                    var          recommendedItems = recommender.Recommend(PlusAnonymousUserDataModel.TEMP_USER_ID, showCount, null);
                    List <Books> newbooks         = new List <Books>();
                    foreach (var item in recommendedItems)
                    {
                        int bid = Convert.ToInt32(item.GetItemID());
                        newbooks.Add(booksbll.LoadEntities(c => c.Id == bid).FirstOrDefault());
                    }

                    books = newbooks.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                }
            }
            else //不推荐
            {
                books = booksbll.LoadEntities(c => true).OrderByDescending(c => c.rating).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            }
            #endregion

            return(books.Count() <= 0 ? booksbll.LoadEntities(c => true).OrderByDescending(c => c.rating).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList() : books);
        }
        public ActionResult GetRecommendedbooks()
        {
            var csv            = new CsvReader(new StreamReader(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/books.csv")));
            var records        = csv.GetRecords <BookRecord>().ToList();
            int favouriteGenre = db.Users.Where(u => u.UserName == User.Identity.Name).Select(u => u.genreID).SingleOrDefault();
            var userRentals    = db.Rentals.Where(m => m.rentalUser == User.Identity.Name).Join(db.Books,
                                                                                                r => r.rentalBook,
                                                                                                m => m.bookName,
                                                                                                (r, m) => new
            {
                genreId   = m.genreID,
                bookName  = m.bookName,
                rentalUer = r.rentalUser
            });

            if (userRentals.Count() == 0)
            {
                return(Json(new Dictionary <string, object>()
                {
                    { "book_id", 0 },
                    { "rating", 0 },
                }));
            }
            else if (userRentals.Where(m => m.genreId == favouriteGenre).Count() != 0)
            {
                userRentals = userRentals.Where(m => m.genreId == favouriteGenre);
            }

            long[] bookIdsTemp = new long[userRentals.Count()];
            int    bookCounter = 0;

            foreach (var item in userRentals)
            {
                foreach (var record in records)
                {
                    if (item.bookName == record.title)
                    {
                        if (!bookIdsTemp.Contains(record.bookId))
                        {
                            bookIdsTemp[bookCounter] = record.bookId;
                            bookCounter++;
                        }
                    }
                }
            }
            long[] bookIds = new long[bookCounter];
            for (int i = 0; i < bookCounter; i++)
            {
                bookIds[i] = bookIdsTemp[i];
            }

            var dataModel = GetDataModel();

            // recommendation is performed for the user that is missed in the preferences data
            var plusAnonymModel = new PlusAnonymousUserDataModel(dataModel);
            var prefArr         = new GenericUserPreferenceArray(userRentals.Count());

            prefArr.SetUserID(0, PlusAnonymousUserDataModel.TEMP_USER_ID);
            for (int i = 0; i < bookIds.Length; i++)
            {
                prefArr.SetItemID(i, bookIds[i]);

                // in this example we have no ratings of books preferred by the user
                prefArr.SetValue(i, 5); // lets assume max rating
            }
            plusAnonymModel.SetTempPrefs(prefArr);

            var similarity       = new LogLikelihoodSimilarity(plusAnonymModel);
            var neighborhood     = new NearestNUserNeighborhood(15, similarity, plusAnonymModel);
            var recommender      = new GenericUserBasedRecommender(plusAnonymModel, neighborhood, similarity);
            var recommendedItems = recommender.Recommend(PlusAnonymousUserDataModel.TEMP_USER_ID, 1, null);

            if (recommendedItems.Count() == 0)
            {
                return(Json(new Dictionary <string, object>()
                {
                    { "book_id", 0 },
                    { "rating", 0 },
                }));
            }

            return(Json(recommendedItems.Select(ri => new Dictionary <string, object>()
            {
                { "book_id", ri.GetItemID() },
                { "rating", ri.GetValue() },
            }).ToArray()[0]));
        }
Ejemplo n.º 7
0
        protected void processLine <T>(string line, FastByIDMap <T> data, FastByIDMap <FastByIDMap <DateTime?> > timestamps, bool fromPriorData)
        {
            bool            flag2;
            int             num5;
            PreferenceArray array2;
            int             num6;
            float           num7;

            if ((line.Length == 0) || (line[0] == COMMENT_CHAR))
            {
                return;
            }
            string[] strArray        = line.Split(new char[] { this.delimiter });
            string   str             = strArray[0];
            string   str2            = strArray[1];
            string   str3            = strArray[2];
            bool     flag            = strArray.Length > 3;
            string   timestampString = flag ? strArray[3] : null;
            long     key             = this.readUserIDFromString(str);
            long     itemID          = this.readItemIDFromString(str2);

            if (this.transpose)
            {
                long num3 = key;
                key    = itemID;
                itemID = num3;
            }
            T local = data.get(key);

            if (!fromPriorData)
            {
                IEnumerable <Preference> source = (IEnumerable <Preference>)local;
                if (flag || !string.IsNullOrWhiteSpace(str3))
                {
                    num7  = float.Parse(str3, CultureInfo.InvariantCulture);
                    flag2 = false;
                    if (this.uniqueUserItemCheck && (source != null))
                    {
                        foreach (Preference preference in source)
                        {
                            if (preference.getItemID() == itemID)
                            {
                                flag2 = true;
                                preference.setValue(num7);
                                break;
                            }
                        }
                    }
                    if (!flag2)
                    {
                        if (source == null)
                        {
                            source = new List <Preference>(5);
                            data.put(key, (T)source);
                        }
                        if (source is IList <Preference> )
                        {
                            ((IList <Preference>)source).Add(new GenericPreference(key, itemID, num7));
                        }
                    }
                    this.addTimestamp(key, itemID, timestampString, timestamps);
                    return;
                }
                if (source != null)
                {
                    IEnumerator <Preference> enumerator = ((IEnumerable <Preference>)source.ToArray <Preference>()).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        Preference current = enumerator.Current;
                        if (current.getItemID() == itemID)
                        {
                            if (source is IList <Preference> )
                            {
                                ((IList <Preference>)local).Remove(current);
                            }
                            break;
                        }
                    }
                }
                removeTimestamp(key, itemID, timestamps);
                return;
            }
            PreferenceArray array = (PreferenceArray)local;

            if (flag || !string.IsNullOrWhiteSpace(str3))
            {
                num7  = float.Parse(str3, CultureInfo.InvariantCulture);
                flag2 = false;
                if (this.uniqueUserItemCheck && (array != null))
                {
                    for (num5 = 0; num5 < array.length(); num5++)
                    {
                        if (array.getItemID(num5) == itemID)
                        {
                            flag2 = true;
                            array.setValue(num5, num7);
                            break;
                        }
                    }
                }
            }
            else
            {
                if (array != null)
                {
                    flag2 = false;
                    int num4 = array.length();
                    for (num5 = 0; num5 < num4; num5++)
                    {
                        if (array.getItemID(num5) == itemID)
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (flag2)
                    {
                        if (num4 == 1)
                        {
                            data.remove(key);
                        }
                        else
                        {
                            array2 = new GenericUserPreferenceArray(num4 - 1);
                            num5   = 0;
                            for (num6 = 0; num5 < num4; num6++)
                            {
                                if (array.getItemID(num5) == itemID)
                                {
                                    num6--;
                                }
                                else
                                {
                                    array2.set(num6, array.get(num5));
                                }
                                num5++;
                            }
                            data.put(key, (T)array2);
                        }
                    }
                }
                removeTimestamp(key, itemID, timestamps);
                goto Label_02F1;
            }
            if (!flag2)
            {
                if (array == null)
                {
                    array = new GenericUserPreferenceArray(1);
                }
                else
                {
                    array2 = new GenericUserPreferenceArray(array.length() + 1);
                    num5   = 0;
                    for (num6 = 1; num5 < array.length(); num6++)
                    {
                        array2.set(num6, array.get(num5));
                        num5++;
                    }
                    array = array2;
                }
                array.setUserID(0, key);
                array.setItemID(0, itemID);
                array.setValue(0, num7);
                data.put(key, (T)array);
            }
Label_02F1:
            this.addTimestamp(key, itemID, timestampString, timestamps);
        }
Ejemplo n.º 8
0
        /// <p>
        /// Reads one line from the input file and adds the data to a {@link FastByIDMap} data structure which maps user IDs
        /// to preferences. This assumes that each line of the input file corresponds to one preference. After
        /// reading a line and determining which user and item the preference pertains to, the method should look to
        /// see if the data contains a mapping for the user ID already, and if not, add an empty data structure of preferences
        /// as appropriate to the data.
        /// </p>
        ///
        /// <p>
        /// Note that if the line is empty or begins with '#' it will be ignored as a comment.
        /// </p>
        ///
        /// @param line
        ///          line from input data file
        /// @param data
        ///          all data read so far, as a mapping from user IDs to preferences
        /// @param fromPriorData an implementation detail -- if true, data will map IDs to
        ///  {@link PreferenceArray} since the framework is attempting to read and update raw
        ///  data that is already in memory. Otherwise it maps to {@link Collection}s of
        ///  {@link Preference}s, since it's reading fresh data. Subclasses must be prepared
        ///  to handle this wrinkle.
        protected void processLine <T>(string line,
                                       FastByIDMap <T> data,
                                       FastByIDMap <FastByIDMap <DateTime?> > timestamps,
                                       bool fromPriorData)
        {
            // Ignore empty lines and comments
            if (line.Length == 0 || line[0] == COMMENT_CHAR)
            {
                return;
            }

            var    tokens                = SplitLine(line);
            string userIDString          = tokens[0];
            string itemIDString          = tokens[1];
            string preferenceValueString = tokens[2];
            bool   hasTimestamp          = tokens.Length > 3;
            string timestampString       = hasTimestamp ? tokens[3] : null;

            long userID = readUserIDFromString(userIDString);
            long itemID = readItemIDFromString(itemIDString);

            if (transpose)
            {
                long tmp = userID;
                userID = itemID;
                itemID = tmp;
            }

            // This is kind of gross but need to handle two types of storage
            var maybePrefs = data.Get(userID);

            if (fromPriorData)
            {
                // Data are PreferenceArray

                IPreferenceArray prefs = (IPreferenceArray)maybePrefs;
                if (!hasTimestamp && String.IsNullOrWhiteSpace(preferenceValueString))
                {
                    // Then line is of form "userID,itemID,", meaning remove
                    if (prefs != null)
                    {
                        bool exists = false;
                        int  length = prefs.Length();
                        for (int i = 0; i < length; i++)
                        {
                            if (prefs.GetItemID(i) == itemID)
                            {
                                exists = true;
                                break;
                            }
                        }
                        if (exists)
                        {
                            if (length == 1)
                            {
                                data.Remove(userID);
                            }
                            else
                            {
                                IPreferenceArray newPrefs = new GenericUserPreferenceArray(length - 1);
                                for (int i = 0, j = 0; i < length; i++, j++)
                                {
                                    if (prefs.GetItemID(i) == itemID)
                                    {
                                        j--;
                                    }
                                    else
                                    {
                                        newPrefs.Set(j, prefs.Get(i));
                                    }
                                }
                                data.Put(userID, (T)newPrefs);
                            }
                        }
                    }

                    removeTimestamp(userID, itemID, timestamps);
                }
                else
                {
                    float preferenceValue = float.Parse(preferenceValueString, CultureInfo.InvariantCulture);

                    bool exists = false;
                    if (uniqueUserItemCheck && prefs != null)
                    {
                        for (int i = 0; i < prefs.Length(); i++)
                        {
                            if (prefs.GetItemID(i) == itemID)
                            {
                                exists = true;
                                prefs.SetValue(i, preferenceValue);
                                break;
                            }
                        }
                    }

                    if (!exists)
                    {
                        if (prefs == null)
                        {
                            prefs = new GenericUserPreferenceArray(1);
                        }
                        else
                        {
                            IPreferenceArray newPrefs = new GenericUserPreferenceArray(prefs.Length() + 1);
                            for (int i = 0, j = 1; i < prefs.Length(); i++, j++)
                            {
                                newPrefs.Set(j, prefs.Get(i));
                            }
                            prefs = newPrefs;
                        }
                        prefs.SetUserID(0, userID);
                        prefs.SetItemID(0, itemID);
                        prefs.SetValue(0, preferenceValue);
                        data.Put(userID, (T)prefs);
                    }
                }

                addTimestamp(userID, itemID, timestampString, timestamps);
            }
            else
            {
                // Data are IEnumerable<Preference>

                IEnumerable <IPreference> prefs = ((IEnumerable <IPreference>)maybePrefs);

                if (!hasTimestamp && String.IsNullOrWhiteSpace(preferenceValueString))
                {
                    // Then line is of form "userID,itemID,", meaning remove
                    if (prefs != null)
                    {
                        // remove pref
                        var prefsIterator = ((IEnumerable <IPreference>)prefs.ToArray()).GetEnumerator();
                        while (prefsIterator.MoveNext())
                        {
                            IPreference pref = prefsIterator.Current;
                            if (pref.GetItemID() == itemID)
                            {
                                if (prefs is IList <IPreference> )
                                {
                                    ((IList <IPreference>)maybePrefs).Remove(pref);// prefsIterator.remove()
                                }
                                break;
                            }
                        }
                    }

                    removeTimestamp(userID, itemID, timestamps);
                }
                else
                {
                    float preferenceValue = float.Parse(preferenceValueString, CultureInfo.InvariantCulture);

                    bool exists = false;
                    if (uniqueUserItemCheck && prefs != null)
                    {
                        foreach (IPreference pref in prefs)
                        {
                            if (pref.GetItemID() == itemID)
                            {
                                exists = true;
                                pref.SetValue(preferenceValue);
                                break;
                            }
                        }
                    }

                    if (!exists)
                    {
                        if (prefs == null)
                        {
                            prefs = new List <IPreference>(5);
                            data.Put(userID, (T)prefs);
                        }

                        if (prefs is IList <IPreference> )
                        {
                            ((IList <IPreference>)prefs).Add(new GenericPreference(userID, itemID, preferenceValue));
                        }
                    }

                    addTimestamp(userID, itemID, timestampString, timestamps);
                }
            }
        }