예제 #1
0
        protected virtual void CacheSplitData()
        {
            // make sure the train and test items are specified in the Container
            Split.UpdateFeedbackSlices();
            TrainFeedback = Split.Train.ToList();
            Levels        = Split.Train.Select(f => f.Level).Distinct().OrderByDescending(l => l).ToArray();
            PosLevels     = new List <int>();

            UserFeedback       = new Dictionary <string, List <Feedback> >();
            UserPosFeedback    = new Dictionary <string, List <Feedback> >();
            UserNegFeedback    = new Dictionary <string, List <Feedback> >();
            UserFeedbackLevels = new Dictionary <string, List <int> >();
            UserLevelFeedback  = new MultiKeyDictionary <string, int, List <Core.Feedback> >();
            AllPosFeedback     = new List <Feedback>();
            AllItems           = Split.Train.Select(f => f.Item.Id).Distinct().ToList();
            SampledCount       = AllItems.ToDictionary(i => i, i => 1);

            LevelPosFeedback = new Dictionary <int, List <Feedback> >();


            var usersFeedback = Split.Train.GroupBy(f => f.User);

            foreach (var g in usersFeedback)
            {
                string userId = g.Key.Id;
                UserFeedback[userId]       = new List <Feedback>();
                UserPosFeedback[userId]    = new List <Feedback>();
                UserNegFeedback[userId]    = new List <Feedback>();
                UserFeedbackLevels[userId] = g.Select(f => f.Level).Distinct().OrderByDescending(l => l).ToList();

                float ratingAvg = -1f;
                if (g.First() is Rating)
                {
                    ratingAvg = g.Average(f => ((Rating)f).Value);
                }

                foreach (Feedback f in g)
                {
                    UserFeedback[f.User.Id].Add(f);

                    if (!UserLevelFeedback.ContainsKey(f.User.Id, f.Level))
                    {
                        UserLevelFeedback.Add(f.User.Id, f.Level, new List <Feedback>());
                    }

                    UserLevelFeedback[f.User.Id][f.Level].Add(f);

                    // determine whether the feedback is positive, negative or rating and add that to the right list
                    switch (f.FeedbackType)
                    {
                    case FeedbackType.Positive:
                        UserPosFeedback[f.User.Id].Add(f);
                        AllPosFeedback.Add(f);

                        if (!LevelPosFeedback.ContainsKey(f.Level))
                        {
                            LevelPosFeedback[f.Level] = new List <Feedback>();
                            PosLevels.Add(f.Level);
                        }
                        LevelPosFeedback[f.Level].Add(f);
                        break;

                    case FeedbackType.Negative:
                        UserNegFeedback[f.User.Id].Add(f);
                        break;

                    case FeedbackType.Rating:
                        if (((Rating)f).Value >= ratingAvg)
                        {
                            UserPosFeedback[f.User.Id].Add(f);
                            AllPosFeedback.Add(f);
                            if (!LevelPosFeedback.ContainsKey(f.Level))
                            {
                                LevelPosFeedback[f.Level] = new List <Feedback>();
                                PosLevels.Add(f.Level);
                            }
                            LevelPosFeedback[f.Level].Add(f);
                        }
                        else
                        {
                            UserNegFeedback[f.User.Id].Add(f);
                        }
                        break;

                    default:
                        break;
                    }
                }
            }

            PosLevels   = PosLevels.OrderByDescending(l => l).ToList();
            _levelIndex = new Dictionary <int, int>();

            for (int i = 0; i < PosLevels.Count; i++)
            {
                _levelIndex.Add(PosLevels[i], i);
            }

            Logger.Current.Info("Number of feedbacks:");
            LevelPosFeedback.Select(kv => new { Level = kv.Key, Count = kv.Value.Count })
            .OrderByDescending(l => l.Level)
            .Select(l => string.Format("Level {0}: {1}", l.Level, l.Count))
            .ForEach(l => Logger.Current.Info(l));
            Logger.Current.Info("");
        }