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. css溢出滚动条及去除滚动条的方法

    <div class="father"> <div class="childern"></div> </div> ...

  2. Spring基础(5): 构造函数注入无法处理循环依赖

    public class Person{ public Leader leader; public Person(Leader l){ this.leader= l; } } public class ...

  3. javascript学习之路之元素获取和设置属性

    收拾心情,学习学习js!总结下自己的学习所得! 现有的有三种方法可以获取元素的节点,分别是通过元素ID,通过标签名和类名来获取的 1.GetElmentById:将返回一个与那个有给定ID属性的值的元 ...

  4. Java基础——iO(三)

    一.管道流 演示:PipedInputStream  , PipedOutputStream 注意:管道流本身就不建议在一个线程中使用,这是因为向输出流中写的数据,都会存到输入流内部的一个1024字节 ...

  5. WebServer搭建过程

    第一步,新建Web网站项目 第二步: 右击项目解决方案,选择添加新建项 选择Web服务项 第三步,在asmx方法中将Hello World注释掉,然后编写自己的方法,这里根据项目的不同可以做不同的处理 ...

  6. Javascript 匿名函数与闭包

    请见如下一个闭包示例: color = "red"; var obj = { color: "blue", getColor: function () { fu ...

  7. iOS设备上出现的click,live,on点击失去效果

    iOS设备上出现的点击事件失效,但是在Android上可以正常使用, 1.iOS设备对标签点击限制,不认为是可点击的标签,需要给要绑定点击事件的标签加上一个样式,cursor:pointer:这样就可 ...

  8. SQL SERVER 将表字段值0和1互转的几种方法

    需求: 如果表字段的值为 0 则将其修改为1 ,如果表字段的值为 1 则将其修改为 0. 方法一 end 方法二 ) 方法三 )

  9. SQLServer 学习笔记之超详细基础SQL语句 Part 4

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 3------------------- 17 带比较运算符的嵌套查询 ...

  10. Android中使用Log4j及配置说明

    目前在进行Android开发时使用到了log4j,现在对其配置进行记录. 1. android-logging-log4j 下载地址 https://code.google.com/archive/p ...