예제 #1
0
        public List <KeyValuePair <int, double> > predict(UserPreferences targetUser, List <ScoreClass> neighbours)
        {
            Dictionary <int, double> predictedRatings = new Dictionary <int, double>();
            List <int> articlesToCheck = new List <int>();

            foreach (var neighbour in neighbours)
            {
                foreach (var rating in neighbour.User.Prefs)
                {
                    if (!targetUser.Prefs.ContainsKey(rating.Key) && !articlesToCheck.Contains(rating.Key))
                    {
                        articlesToCheck.Add(rating.Key);
                    }
                }
            }

            while (articlesToCheck.Any())
            {
                var    article               = articlesToCheck.Last();
                double sumWeightedRatings    = 0;
                double sumCoefficients       = 0;
                var    neighboursWithArticle = 0;


                foreach (var neighbour in neighbours)
                {
                    if (neighbour.User.Prefs.ContainsKey(article))
                    {
                        neighboursWithArticle++;
                        sumWeightedRatings += (neighbour.User.Prefs[article] * neighbour.Score);
                        sumCoefficients    += neighbour.Score;
                    }
                }
                var predictedRating = sumWeightedRatings / sumCoefficients;
                articlesToCheck.Remove(article);

                if (neighboursWithArticle > 2)
                {
                    predictedRatings.Add(article, predictedRating);
                }
            }

            var sortedPredictions = predictedRatings.ToList();

            sortedPredictions.Sort((firstPair, nextPair) =>
            {
                return(-firstPair.Value.CompareTo(nextPair.Value));
            });

            return(sortedPredictions);
        }
예제 #2
0
        public double Measure(UserPreferences user1, UserPreferences user2)
        {
            double x = 0;

            foreach (var pair in user1.Prefs)
            {
                if (user2.Prefs.ContainsKey(pair.Key))
                {
                    double pi = pair.Value;
                    double qi = user2.Prefs[pair.Key];
                    x += Math.Pow((pi - qi), 2);
                }
            }
            double distance = Math.Round(Math.Sqrt(x), 3);
            double score    = 1 / (1 + distance);

            return(score);
        }
예제 #3
0
        public double Measure(UserPreferences user1, UserPreferences user2)
        {
            double xy    = 0;
            double rootX = 0;
            double rootY = 0;

            foreach (var pair in user1.Prefs)
            {
                var a = pair.Value;
                rootX += Math.Pow(Math.Abs(a), 2);

                if (user2.Prefs.ContainsKey(pair.Key))
                {
                    var b = user2.Prefs[pair.Key];
                    xy    += (a * b);
                    rootY += Math.Pow(Math.Abs(b), 2);
                }
            }
            var score = (xy / (Math.Sqrt(rootX) * Math.Sqrt(rootY)));

            return(score);
        }
예제 #4
0
        public double Measure(UserPreferences user1, UserPreferences user2)
        {
            double sumXiYi  = 0;
            double sumXi    = 0;
            double sumYi    = 0;
            double sumXiPow = 0;
            double sumYiPow = 0;
            double n        = 0;

            foreach (var pair in user1.Prefs)
            {
                if (user2.Prefs.ContainsKey(pair.Key))
                {
                    n += 1;
                    var xi = pair.Value;
                    var yi = user2.Prefs[pair.Key];

                    //upper part of formula
                    //left part
                    sumXiYi += (xi * yi);
                    //right part
                    sumXi += xi;
                    sumYi += yi;

                    //bottom part also uses sumXi and sumYi
                    //bottom left
                    sumXiPow += Math.Pow(xi, 2);
                    sumYiPow += Math.Pow(yi, 2);
                }
            }
            var topPart         = sumXiYi - ((sumXi * sumYi) / n);
            var bottomLeftPart  = Math.Sqrt(sumXiPow - (Math.Pow(sumXi, 2) / n));
            var bottomRightPart = Math.Sqrt(sumYiPow - (Math.Pow(sumYi, 2) / n));

            var score = Math.Round(topPart / (bottomLeftPart * bottomRightPart), 3);

            return(score);
        }
예제 #5
0
        private static void ApplicationCode()
        {
            var dataSet = new Dictionary <int, UserPreferences>();
            var nearestNeighboursFinder = new NearestNeighboursFinder();
            var predictor = new Predictor();

            var minimumThreshold = 0.35;
            var targetUserId     = 3;
            var neighbourAmount  = 3;
            var recommendAmount  = 3;

            StreamReader reader = null;
            ////////////////////////////////////////////////
            //  load dataset from file with a filereader
            //  movielens.data = 100k dataset
            //  UserItem.data = default dataset
            ////////////////////////////////////////////////

            var chooseDataset = SelectDataset();

            if (chooseDataset.Equals("movielens"))
            {
                reader          = new StreamReader(File.OpenRead("../../movielens.data"));
                targetUserId    = 186;
                neighbourAmount = 25;
                recommendAmount = 8;
            }
            else
            {
                reader          = new StreamReader(File.OpenRead("../../UserItem.data"));
                targetUserId    = 7;
                neighbourAmount = 3;
                recommendAmount = 3;
            }


            while (!reader.EndOfStream)
            {
                var line   = reader.ReadLine();
                var values = line.Split(',');

                var userId  = Convert.ToInt32(values[0]);
                var article = Convert.ToInt32(values[1]);
                var rating  = Convert.ToDouble(values[2], CultureInfo.InvariantCulture);

                if (dataSet.ContainsKey(userId))
                {
                    dataSet[userId].AddRating(article, rating);
                }
                else
                {
                    var up = new UserPreferences(userId, article, rating);
                    dataSet.Add(userId, up);
                }
            }

            //Comment / Uncomment to toggle writing all users and their ratings to the console
            //foreach (var user in dataSet)
            //{
            //    user.Value.PrintAllRatings();
            //}

            ////////////////////////////////////////////////
            // Write scores of comparing users to console //
            ////////////////////////////////////////////////

            var algorithm = SelectAlgorithm();

            var neighbours = nearestNeighboursFinder.Find(dataSet, targetUserId, minimumThreshold, algorithm, neighbourAmount);

            Console.WriteLine("\n15 Nearest neighbours: \n");
            foreach (var i in neighbours)
            {
                Console.WriteLine(i.User.OwnerId + " With score " + i.Score.ToString("0.0000"));
            }
            Console.WriteLine("");

            //Make predictions based on target user with the set of neighbours from previous step.
            List <KeyValuePair <int, double> > predictions = predictor.predict(dataSet[targetUserId], neighbours);
            var suggestions = predictions.Take(recommendAmount);

            foreach (var suggestion in suggestions)
            {
                Console.WriteLine("Recommended article " + suggestion.Key + " With score " + suggestion.Value.ToString("0.0000"));
            }

            // wait for R or Esc before restarting/exiting
            Console.WriteLine("\npress Escape to quit the application or type R to restart");
            restartOrNot();
        }