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);
            }
        }
    }
}

C#实现的协同过滤算法的更多相关文章

  1. SVD++:推荐系统的基于矩阵分解的协同过滤算法的提高

    1.背景知识 在讲SVD++之前,我还是想先回到基于物品相似的协同过滤算法.这个算法基本思想是找出一个用户有过正反馈的物品的相似的物品来给其作为推荐.其公式为:

  2. GBDT(Gradient Boosting Decision Tree)算法&协同过滤算法

    GBDT(Gradient Boosting Decision Tree)算法参考:http://blog.csdn.net/dark_scope/article/details/24863289 理 ...

  3. Spark机器学习之协同过滤算法

    Spark机器学习之协同过滤算法 一).协同过滤 1.1 概念 协同过滤是一种借助"集体计算"的途径.它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度.其内在思想是相 ...

  4. Collaborative Filtering(协同过滤)算法详解

    基本思想 基于用户的协同过滤算法是通过用户的历史行为数据发现用户对商品或内容的喜欢(如商品购买,收藏,内容评论或分享),并对这些喜好进行度量和打分.根据不同用户对相同商品或内容的态度和偏好程度计算用户 ...

  5. 【机器学习笔记一】协同过滤算法 - ALS

    参考资料 [1]<Spark MLlib 机器学习实践> [2]http://blog.csdn.net/u011239443/article/details/51752904 [3]线性 ...

  6. Spark机器学习(11):协同过滤算法

    协同过滤(Collaborative Filtering,CF)算法是一种常用的推荐算法,它的思想就是找出相似的用户或产品,向用户推荐相似的物品,或者把物品推荐给相似的用户.怎样评价用户对商品的偏好? ...

  7. 亚马逊 协同过滤算法 Collaborative filtering

    这节课时郭强的三维课.他讲的是MAYA和max .自己对这个也不怎么的感兴趣.而且这个课感觉属于数字媒体.自己对游戏,动画,这些东西一点都不兴趣,比如大一的时候刚开学的时候,张瑞的数字媒体的导论课.还 ...

  8. win7下使用Taste实现协同过滤算法

    如果要实现Taste算法,必备的条件是: 1) JDK,使用1.6版本.需要说明一下,因为要基于Eclipse构建,所以在设置path的值之前要先定义JAVA_HOME变量. 2) Maven,使用2 ...

  9. Slope one—个性化推荐中最简洁的协同过滤算法

    Slope One 是一系列应用于 协同过滤的算法的统称.由 Daniel Lemire和Anna Maclachlan于2005年发表的论文中提出. [1]有争议的是,该算法堪称基于项目评价的non ...

  10. Mahout实现基于用户的协同过滤算法

    Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...

随机推荐

  1. Android-Menu菜单使用一

    创建菜单 在AndroidSDK中,无需从头创建菜单对象.因为一个活动只与一个菜单关联,所以Android会为该活动创建此菜单,然后将它传给Activity类的onCreateOptionsMenu回 ...

  2. python序列函数

    zip:序列并行处理 >>> name=['ghostwu','wukong','bajie'] >>> age=['] >>> sex=['ma ...

  3. php面向对象精要(3)

    1,final关键字定义的方法,不能被重写 由于final修饰了show方法,子类中重写show方法会报错 <?php class MyClass { final function show() ...

  4. HDU4565(SummerTrainingDay05-C 矩阵快速幂)

    So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  5. 超强、超详细Redis入门教程

    (1)什么是redis? Redis 是一个基于内存的高性能key-value数据库. (有空再补充,有理解错误或不足欢迎指正) (2)Reids的特点 Redis本质上是一个Key-Value类型的 ...

  6. python-备忘录模式

    源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 一个成熟的软件应当允许用户取消不确定的操作或者从错误的状态中恢复过来.复制,粘体 ...

  7. 微信小程序获取当前地址以及选择地址详解 地点标记

    首先定义事件: bindtap='getLocation' <view class='store-bot' bindtap='getLocation'> <view class='c ...

  8. element-ui Steps步骤条组件源码分析整理笔记(九)

    Steps步骤条组件源码: steps.vue <template> <!--设置 simple 可应用简洁风格,该条件下 align-center / description / ...

  9. 常用,好用的js代码

    记录看到或者用到的js代码,长期更新! 判断是否是正整数 (number-0)|0 !== number-0 解析: number-0 转换成数字,再通过位移运算(|)判断是否跟原数字相等 安全检查j ...

  10. flutter 异步async、await和Future的使用技巧

    由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果.Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞, ...