C#实现协同过滤算法的实例代码

时间:2023-03-11 12:26:27 


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);
            }
        }
    }
}
标签:协同,过滤,算法
0
投稿

猜你喜欢

  • Springboot通过谷歌Kaptcha 组件生成图形验证码功能

    2021-07-24 23:42:47
  • C#装箱和拆箱的原理介绍

    2022-06-18 02:33:17
  • Android编程之页面切换测试实例

    2022-04-03 22:13:11
  • Java实现递归计算n的阶乘

    2021-06-26 14:34:26
  • Springboot使用@Valid 和AOP做参数校验及日志输出问题

    2023-12-05 04:39:12
  • Android仿微信雷达扫描效果的实现方法

    2022-07-28 01:49:17
  • 详解Unity安卓共享纹理

    2022-07-10 08:18:21
  • Spring实战之@Autowire注解用法详解

    2021-11-17 20:37:19
  • Java基础知识之CharArrayReader流的使用

    2023-02-12 10:40:29
  • Unity实现ScrollView滑动吸附功能

    2022-07-07 00:38:14
  • Java学习关于循环和数组练习题整理

    2022-07-19 21:01:24
  • Java实现字符串解析为日期时间的方法示例

    2021-10-29 17:43:34
  • c语言定时器示例分享

    2023-11-04 09:44:52
  • 深入解析Java多态进阶学习

    2022-05-16 16:06:55
  • 解决mybatis 中collection嵌套collection引发的bug

    2023-03-20 20:55:39
  • Android以对话框形式制作数字软键盘示例

    2022-12-07 07:37:03
  • 浅谈Mybatis传参类型如何确定

    2023-11-12 12:13:21
  • Android实现的数字格式化用法示例

    2023-09-30 09:03:28
  • java 获取字节码文件的几种方法总结

    2023-11-29 15:17:57
  • Java比较两个对象大小的三种方法详解

    2021-07-11 18:55:16
  • asp之家 软件编程 m.aspxhome.com