zoukankan      html  css  js  c++  java
  • C#实现的协同过滤算法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace SlopeOne
    {
        public class Rating
        {
            public float Value { get; set; }
            public int Freq { get; set; }

            public float AverageValue
            {
                get { return Value / Freq; }
            }
        }

        public class RatingDifferenceCollection : Dictionary<string, Rating>
        {
            private string GetKey(int Item1Id, int Item2Id)
            {
                return (Item1Id < Item2Id) ? Item1Id + "/" + Item2Id : Item2Id + "/" + Item1Id ;
            }

            public bool Contains(int Item1Id, int Item2Id)
            {
                return this.Keys.Contains<string>(GetKey(Item1Id, Item2Id));
            }

            public Rating this[int Item1Id, int Item2Id]
            {
                get {
                        return this[this.GetKey(Item1Id, Item2Id)];
                }
                set { this[this.GetKey(Item1Id, Item2Id)] = value; }
            }
        }

         public class SlopeOne
        {       
            public RatingDifferenceCollection _DiffMarix = new RatingDifferenceCollection();  // The dictionary to keep the diff matrix
            public HashSet<int> _Items = new HashSet<int>();  // Tracking how many items totally

            public void AddUserRatings(IDictionary<int, float> userRatings)
            {
                foreach (var item1 in userRatings)
                {
                    int item1Id = item1.Key;
                    float item1Rating = item1.Value;
                    _Items.Add(item1.Key);

                    foreach (var item2 in userRatings)
                    {
                        if (item2.Key <= item1Id) continue; // Eliminate redundancy
                        int item2Id = item2.Key;
                        float item2Rating = item2.Value;

                        Rating ratingDiff;
                        if (_DiffMarix.Contains(item1Id, item2Id))
                        {
                            ratingDiff = _DiffMarix[item1Id, item2Id];
                        }
                        else
                        {
                            ratingDiff = new Rating();
                            _DiffMarix[item1Id, item2Id] = ratingDiff;
                        }

                        ratingDiff.Value += item1Rating - item2Rating;
                        ratingDiff.Freq += 1;
                    }
                }
            }

            // Input ratings of all users
            public void AddUerRatings(IList<IDictionary<int, float>> Ratings)
            {
                foreach(var userRatings in Ratings)
                {
                    AddUserRatings(userRatings);
                }
            }

            public IDictionary<int, float> Predict(IDictionary<int, float> userRatings)
            {
                Dictionary<int, float> Predictions = new Dictionary<int, float>();
                foreach (var itemId in this._Items)
                {
                    if (userRatings.Keys.Contains(itemId))    continue; // User has rated this item, just skip it

                    Rating itemRating = new Rating();

                    foreach (var userRating in userRatings)
                    {
                        if (userRating.Key == itemId) continue;
                        int inputItemId = userRating.Key;
                        if (_DiffMarix.Contains(itemId, inputItemId))
                        {
                            Rating diff = _DiffMarix[itemId, inputItemId];
                            itemRating.Value += diff.Freq * (userRating.Value + diff.AverageValue * ((itemId < inputItemId) ? 1 : -1));
                            itemRating.Freq += diff.Freq;
                        }
                    }
                    Predictions.Add(itemId, itemRating.AverageValue);               
                }
                return Predictions;
            }

            public static void Test()
            {
                SlopeOne test = new SlopeOne();

                Dictionary<int, float> userRating = new Dictionary<int, float>();
                userRating.Add(1, 5);
                userRating.Add(2, 4);
                userRating.Add(3, 4);
                test.AddUserRatings(userRating);

                userRating = new Dictionary<int, float>();
                userRating.Add(1, 4);
                userRating.Add(2, 5);
                userRating.Add(3, 3);
                userRating.Add(4, 5);
                test.AddUserRatings(userRating);

                userRating = new Dictionary<int, float>();
                userRating.Add(1, 4);
                userRating.Add(2, 4);
                userRating.Add(4, 5);
                test.AddUserRatings(userRating);

                userRating = new Dictionary<int, float>();
                userRating.Add(1, 5);
                userRating.Add(3, 4);

                IDictionary<int, float> Predictions = test.Predict(userRating);
                foreach (var rating in Predictions)
                {
                    Console.WriteLine("Item " + rating.Key + " Rating: " + rating.Value);
                }
            }
        }
    }

  • 相关阅读:
    一些总结与思考(聊聊最近,希望对大家有所帮助)
    操作符、语句、函数——Javascript高级程序设计
    Javascript高级程序设计——语法、关键字、保留字、变量、数据类型
    Javascript高级程序设计——Javascript简史+使用Javascript
    Angular.js!(附:聊聊非原生框架项目)
    JS事件绑定深入
    Javascript事件绑定及深入
    实现API管理系统的几个重要关键词
    实现API优先设计的重要性和实现方式
    对API进行版本控制的重要性和实现方式
  • 原文地址:https://www.cnblogs.com/marsblog/p/3169033.html
Copyright © 2011-2022 走看看