协同过滤_协同过滤算法 - CSDN
精华内容
参与话题
  • 协同过滤推荐算法的原理及实现

    万次阅读 多人点赞 2017-02-08 23:15:44
    一、协同过滤算法的原理及实现 二、基于物品的协同过滤算法详解 一、协同过滤算法的原理及实现 协同过滤推荐算法是诞生最早,并且较为著名的推荐算法。主要的功能是预测和推荐。算法通过对用户历史...

    一、协同过滤算法的原理及实现

    二、基于物品的协同过滤算法详解


    一、协同过滤算法的原理及实现


    协同过滤推荐算法是诞生最早,并且较为著名的推荐算法。主要的功能是预测和推荐。算法通过对用户历史行为数据的挖掘发现用户的偏好,基于不同的偏好对用户进行群组划分并推荐品味相似的商品。协同过滤推荐算法分为两类,分别是基于用户的协同过滤算法(user-based collaboratIve filtering),和基于物品的协同过滤算法(item-based collaborative filtering)。简单的说就是:人以类聚,物以群分。下面我们将分别说明这两类推荐算法的原理和实现方法。

      

      1.基于用户的协同过滤算法(user-based collaboratIve filtering)

      基于用户的协同过滤算法是通过用户的历史行为数据发现用户对商品或内容的喜欢(如商品购买,收藏,内容评论或分享),并对这些喜好进行度量和打分。根据不同用户对相同商品或内容的态度和偏好程度计算用户之间的关系。在有相同喜好的用户间进行商品推荐。简单的说就是如果A,B两个用户都购买了x,y,z三本图书,并且给出了5星的好评。那么A和B就属于同一类用户。可以将A看过的图书w也推荐给用户B。

      

      1.1寻找偏好相似的用户

      我们模拟了5个用户对两件商品的评分,来说明如何通过用户对不同商品的态度和偏好寻找相似的用户。在示例中,5个用户分别对两件商品进行了评分。这里的分值可能表示真实的购买,也可以是用户对商品不同行为的量化指标。例如,浏览商品的次数,向朋友推荐商品,收藏,分享,或评论等等。这些行为都可以表示用户对商品的态度和偏好程度。

      

      从表格中很难直观发现5个用户间的联系,我们将5个用户对两件商品的评分用散点图表示出来后,用户间的关系就很容易发现了。在散点图中,Y轴是商品1的评分,X轴是商品2的评分,通过用户的分布情况可以发现,A,C,D三个用户距离较近。用户A(3.3 6.5)和用户C(3.6 6.3),用户D(3.4 5.8)对两件商品的评分较为接近。而用户E和用户B则形成了另一个群体。

      

      散点图虽然直观,但无法投入实际的应用,也不能准确的度量用户间的关系。因此我们需要通过数字对用户的关系进行准确的度量,并依据这些关系完成商品的推荐。

      1.2欧几里德距离评价

      欧几里德距离评价是一个较为简单的用户关系评价方法。原理是通过计算两个用户在散点图中的距离来判断不同的用户是否有相同的偏好。以下是欧几里德距离评价的计算公式。

      通过公式我们获得了5个用户相互间的欧几里德系数,也就是用户间的距离。系数越小表示两个用户间的距离越近,偏好也越是接近。不过这里有个问题,太小的数值可能无法准确的表现出不同用户间距离的差异,因此我们对求得的系数取倒数,使用户间的距离约接近,数值越大。在下面的表格中,可以发现,用户A&C用户A&D和用户C&D距离较近。同时用户B&E的距离也较为接近。与我们前面在散点图中看到的情况一致。

      

      1.3皮尔逊相关度评价

      皮尔逊相关度评价是另一种计算用户间关系的方法。他比欧几里德距离评价的计算要复杂一些,但对于评分数据不规范时皮尔逊相关度评价能够给出更好的结果。以下是一个多用户对多个商品进行评分的示例。这个示例比之前的两个商品的情况要复杂一些,但也更接近真实的情况。我们通过皮尔逊相关度评价对用户进行分组,并推荐商品。

      

      1.4皮尔逊相关系数

      皮尔逊相关系数的计算公式如下,结果是一个在-1与1之间的系数。该系数用来说明两个用户间联系的强弱程度。

      相关系数的分类

    1. 0.8-1.0 极强相关
    2. 0.6-0.8 强相关
    3. 0.4-0.6 中等程度相关
    4. 0.2-0.4 弱相关
    5. 0.0-0.2 极弱相关或无相关

      通过计算5个用户对5件商品的评分我们获得了用户间的相似度数据。这里可以看到用户A&B,C&D,C&E和D&E之间相似度较高。下一步,我们可以依照相似度对用户进行商品推荐。

      

      2,为相似的用户提供推荐物品

      为用户C推荐商品

      当我们需要对用户C推荐商品时,首先我们检查之前的相似度列表,发现用户C和用户D和E的相似度较高。换句话说这三个用户是一个群体,拥有相同的偏好。因此,我们可以对用户C推荐D和E的商品。但这里有一个问题。我们不能直接推荐前面商品1-商品5的商品。因为这这些商品用户C以及浏览或者购买过了。不能重复推荐。因此我们要推荐用户C还没有浏览或购买过的商品。

      加权排序推荐

      我们提取了用户D和用户E评价过的另外5件商品A—商品F的商品。并对不同商品的评分进行相似度加权。按加权后的结果对5件商品进行排序,然后推荐给用户C。这样,用户C就获得了与他偏好相似的用户D和E评价的商品。而在具体的推荐顺序和展示上我们依照用户D和用户E与用户C的相似度进行排序。

      

      以上是基于用户的协同过滤算法。这个算法依靠用户的历史行为数据来计算相关度。也就是说必须要有一定的数据积累(冷启动问题)。对于新网站或数据量较少的网站,还有一种方法是基于物品的协同过滤算法。

      基于物品的协同过滤算法(item-based collaborative filtering)

      基于物品的协同过滤算法与基于用户的协同过滤算法很像,将商品和用户互换。通过计算不同用户对不同物品的评分获得物品间的关系。基于物品间的关系对用户进行相似物品的推荐。这里的评分代表用户对商品的态度和偏好。简单来说就是如果用户A同时购买了商品1和商品2,那么说明商品1和商品2的相关度较高。当用户B也购买了商品1时,可以推断他也有购买商品2的需求。

      

      1.寻找相似的物品

      表格中是两个用户对5件商品的评分。在这个表格中我们用户和商品的位置进行了互换,通过两个用户的评分来获得5件商品之间的相似度情况。单从表格中我们依然很难发现其中的联系,因此我们选择通过散点图进行展示。

      

      在散点图中,X轴和Y轴分别是两个用户的评分。5件商品按照所获的评分值分布在散点图中。我们可以发现,商品1,3,4在用户A和B中有着近似的评分,说明这三件商品的相关度较高。而商品5和2则在另一个群体中。

      

      欧几里德距离评价

      在基于物品的协同过滤算法中,我们依然可以使用欧几里德距离评价来计算不同商品间的距离和关系。以下是计算公式。

      通过欧几里德系数可以发现,商品间的距离和关系与前面散点图中的表现一致,商品1,3,4距离较近关系密切。商品2和商品5距离较近。

      

      皮尔逊相关度评价

      我们选择使用皮尔逊相关度评价来计算多用户与多商品的关系计算。下面是5个用户对5件商品的评分表。我们通过这些评分计算出商品间的相关度。

      

      皮尔逊相关度计算公式

      通过计算可以发现,商品1&2,商品3&4,商品3&5和商品4&5相似度较高。下一步我们可以依据这些商品间的相关度对用户进行商品推荐。

      

      2,为用户提供基于相似物品的推荐

      这里我们遇到了和基于用户进行商品推荐相同的问题,当需要对用户C基于商品3推荐商品时,需要一张新的商品与已有商品间的相似度列表。在前面的相似度计算中,商品3与商品4和商品5相似度较高,因此我们计算并获得了商品4,5与其他商品的相似度列表。

      

      以下是通过计算获得的新商品与已有商品间的相似度数据。

      

      加权排序推荐

      这里是用户C已经购买过的商品4,5与新商品A,B,C直接的相似程度。我们将用户C对商品4,5的评分作为权重。对商品A,B,C进行加权排序。用户C评分较高并且与之相似度较高的商品被优先推荐。

      


    二、基于物品的协同过滤算法详解


    最近参加KDD Cup 2012比赛,选了track1,做微博推荐的,找了推荐相关的论文学习。“Item-Based Collaborative Filtering Recommendation Algorithms”这篇是推荐领域比较经典的论文,现在很多流行的推荐算法都是在这篇论文提出的算法的基础上进行改进的。

            一、协同过滤算法描述

            推荐系统应用数据分析技术,找出用户最可能喜欢的东西推荐给用户,现在很多电子商务网站都有这个应用。目前用的比较多、比较成熟的推荐算法是协同过滤Collaborative Filtering,简称CF推荐算法,CF的基本思想是根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品。


            如图1所示,在CF中,用m×n的矩阵表示用户对物品的喜好情况,一般用打分表示用户对物品的喜好程度,分数越高表示越喜欢这个物品,0表示没有买过该物品。图中行表示一个用户,列表示一个物品,Uij表示用户i对物品j的打分情况。CF分为两个过程,一个为预测过程,另一个为推荐过程。预测过程是预测用户对没有购买过的物品的可能打分值,推荐是根据预测阶段的结果推荐用户最可能喜欢的一个或Top-N个物品。

            二、User-based算法与Item-based算法对比

            CF算法分为两大类,一类为基于memory的(Memory-based),另一类为基于Model的(Model-based),User-based和Item-based算法均属于Memory-based类型,具体细分类可以参考wikipedia的说明。

            User-based的基本思想是如果用户A喜欢物品a,用户B喜欢物品a、b、c,用户C喜欢a和c,那么认为用户A与用户B和C相似,因为他们都喜欢a,而喜欢a的用户同时也喜欢c,所以把c推荐给用户A。该算法用最近邻居(nearest-neighbor)算法找出一个用户的邻居集合,该集合的用户和该用户有相似的喜好,算法根据邻居的偏好对该用户进行预测。

            User-based算法存在两个重大问题:

            1. 数据稀疏性。一个大型的电子商务推荐系统一般有非常多的物品,用户可能买的其中不到1%的物品,不同用户之间买的物品重叠性较低,导致算法无法找到一个用户的邻居,即偏好相似的用户。

            2. 算法扩展性。最近邻居算法的计算量随着用户和物品数量的增加而增加,不适合数据量大的情况使用。

            Iterm-based的基本思想是预先根据所有用户的历史偏好数据计算物品之间的相似性,然后把与用户喜欢的物品相类似的物品推荐给用户。还是以之前的例子为例,可以知道物品a和c非常相似,因为喜欢a的用户同时也喜欢c,而用户A喜欢a,所以把c推荐给用户A。

            因为物品直接的相似性相对比较固定,所以可以预先在线下计算好不同物品之间的相似度,把结果存在表中,当推荐时进行查表,计算用户可能的打分值,可以同时解决上面两个问题。

            三、Item-based算法详细过程

            (1)相似度计算

            Item-based算法首选计算物品之间的相似度,计算相似度的方法有以下几种:

            1. 基于余弦(Cosine-based)的相似度计算,通过计算两个向量之间的夹角余弦值来计算物品之间的相似性,公式如下:


            其中分子为两个向量的内积,即两个向量相同位置的数字相乘。

            2. 基于关联(Correlation-based)的相似度计算,计算两个向量之间的Pearson-r关联度,公式如下:


            其中表示用户u对物品i的打分,表示第i个物品打分的平均值。

            3. 调整的余弦(Adjusted Cosine)相似度计算,由于基于余弦的相似度计算没有考虑不同用户的打分情况,可能有的用户偏向于给高分,而有的用户偏向于给低分,该方法通过减去用户打分的平均值消除不同用户打分习惯的影响,公式如下:


            其中表示用户u打分的平均值。

            (2)预测值计算

            根据之前算好的物品之间的相似度,接下来对用户未打分的物品进行预测,有两种预测方法:

            1. 加权求和。

            用过对用户u已打分的物品的分数进行加权求和,权值为各个物品与物品i的相似度,然后对所有物品相似度的和求平均,计算得到用户u对物品i打分,公式如下:


            其中为物品i与物品N的相似度,为用户u对物品N的打分。

            2. 回归。

            和上面加权求和的方法类似,但回归的方法不直接使用相似物品N的打分值,因为用余弦法或Pearson关联法计算相似度时存在一个误区,即两个打分向量可能相距比较远(欧氏距离),但有可能有很高的相似度。因为不同用户的打分习惯不同,有的偏向打高分,有的偏向打低分。如果两个用户都喜欢一样的物品,因为打分习惯不同,他们的欧式距离可能比较远,但他们应该有较高的相似度。在这种情况下用户原始的相似物品的打分值进行计算会造成糟糕的预测结果。通过用线性回归的方式重新估算一个新的值,运用上面同样的方法进行预测。重新计算的方法如下:


            其中物品N是物品i的相似物品,通过对物品N和i的打分向量进行线性回归计算得到,为回归模型的误差。具体怎么进行线性回归文章里面没有说明,需要查阅另外的相关文献。

            四、结论

            作者通过实验对比结果得出结论:1. Item-based算法的预测结果比User-based算法的质量要高一点。2. 由于Item-based算法可以预先计算好物品的相似度,所以在线的预测性能要比User-based算法的高。3. 用物品的一个小部分子集也可以得到高质量的预测结果。

            转载请注明出处,原文地址:http://blog.csdn.net/huagong_adu/article/details/7362908


    展开全文
  • 超级详细的协同过滤推荐系统+完整Python实现及结果

    万次阅读 多人点赞 2018-09-07 10:58:57
    协同过滤推荐系统在我们的日常生活之中无处不在,例如,在电子商城购物,系统会根据用户的记录或者其他的 信息来推荐相应的产品给客户,是一种智能的生活方式。之所以交协同过滤,是因为在实现过滤推荐的时候是根据...

    协同过滤推荐系统在我们的日常生活之中无处不在,例如,在电子商城购物,系统会根据用户的记录或者其他的

    信息来推荐相应的产品给客户,是一种智能的生活方式。之所以交协同过滤,是因为在实现过滤推荐的时候是根据

    其他人的行为来做预测的,基于相似用户的喜好来实现用户的喜好预测。

    简要介绍:         

    通过找到兴趣相投,或者有共同经验的群体,来向用户推荐感兴趣的信息。

    举例,如何协同过滤,来对用户A进行电影推荐?

    答:简要步骤如下

    找到用户A(user_id_1)的兴趣爱好

    找到与用户A(user_id_1)具有相同电影兴趣爱好的用户群体集合Set<user_id>

    找到该群体喜欢的电影集合Set<movie_id>

    将这些电影Set<Movie_id>推荐给用户A(user_id_1)

    具体实施步骤如何?

    答:简要步骤如下

    (1)画一个大表格,横坐标是所有的movie_id,纵坐标所有的user_id,交叉处代表这个用户喜爱这部电影

     

    Move_id_1

    Move_id_2

    Move_id_3

    Move_id_4

    Move_id_5

    ……

    Move_id_110w

    User_id_1

    1

    1

    1

     

     

     

     

    User_id_2

    1

    1

    1

    1

     

     

     

    User_id_3

    1

    1

    1

     

    1

     

     

    ………….

     

     

     

     

     

     

     

    ………….

     

     

     

     

     

     

     

    User_id_10w

    1

     

    1

     

    1

     

     

    如上表:

    横坐标,假设有10w部电影,所以横坐标有10w个movie_id,数据来源自数据库

    纵坐标,假设有100w个用户,所以纵坐标有100w个user_id,数据也来自数据库

    交叉处,“1”代表用户喜爱这部电影,数据来自日志

    画外音:什么是“喜欢”,需要人为定义,例如浏览过,查找过,点赞过,反正日志里有这些数据

    (2)找到用户A(user_id_1)的兴趣爱好

    如上表,可以看到,用户A喜欢电影{m1, m2, m3}

    (3)找到与用户A(user_id_1)具有相同电影兴趣爱好的用户群体集合Set<user_id>

    如上表,可以看到,喜欢{m1, m2, m3}的用户,除了u1,还有{u2, u3}

    (4)找到该群体喜欢的电影集合Set<movie_id>

    如上表,具备相同喜好的用户群里{u2, u3},还喜好的电影集合是{m4, m5}

    画外音:“协同”就体现在这里。

    (5)未来用户A(use_id_1)来访问网站时,要推荐电影{m4, m5}给ta。

    具体实现步骤:

    第一步:计算两者之间的相似度

                           通常会先把二维表格绘制在一个图中总,每个用户数据表示一个点。

                           度量相似度计算的方法:a.曼哈顿距离计算(计算迅速,节省时间)

                                                                   b.欧氏距离计算(计算两个点之间的直线距离)

    数据预处理:

    去网站:https://grouplens.org/datasets/movielens/           下载movieLen数据集

                  或者

                          ml-latest-small(1MB): http://files.grouplens.org/datasets/movielens/ml-latest-small.zip
                          ml-latest(234.2MB): http://files.grouplens.org/datasets/movielens/ml-latest.zip

    解压读取movies.csv和ratings.csv文件

    两个文件的数据格式如下:

    通过如下程序提取数据:
    
    #!/usr/bin/env python
    # encoding: utf-8
    """
    @Company:华中科技大学电气学院聚变与等离子研究所
    @version: V1.0
    @author: YEXIN
    @contact: 1650996069@qq.com or yexin@hust.edu.cn 2018--2020
    @software: PyCharm
    @file: recommend.py
    @time: 2018/8/19 17:32
    @Desc:读取用户的电影数据和评分数据
    """
    import  pandas as pd
    movies = pd.read_csv("E:\PycharmWorks\ML\CollaborativeFiltering\ml-latest\movies.csv")
    ratings = pd.read_csv("E:\PycharmWorks\ML\CollaborativeFiltering\ml-latest\\ratings.csv")##这里注意如果路径的中文件名开头是r,要转义。
    data = pd.merge(movies,ratings,on = 'movieId')#通过两数据框之间的movieId连接
    data[['userId','rating','movieId','title']].sort_values('userId').to_csv('E:\PycharmWorks\ML\CollaborativeFiltering\ml-latest\data.csv',index=False)

    结果:

    采用python字典来表示每位用户评论的电影和评分
    #!/usr/bin/env python
    # encoding: utf-8
    """
    @Company:华中科技大学电气学院聚变与等离子研究所
    @version: V1.0
    @author: YEXIN
    @contact: 1650996069@qq.com or yexin@hust.edu.cn 2018--2020
    @software: PyCharm
    @file: movie_rating_user.py
    @time: 2018/8/19 17:50
    @Desc:采用python字典来表示每位用户评论的电影和评分
    """
    file = open("E:\PycharmWorks\ML\CollaborativeFiltering\ml-latest\data.csv",'r', encoding='UTF-8')#记得读取文件时加‘r’, encoding='UTF-8'
    ##读取data.csv中每行中除了名字的数据
    data = {}##存放每位用户评论的电影和评分
    for line in file.readlines()[1:100]:
        #注意这里不是readline()
        line = line.strip().split(',')
        #如果字典中没有某位用户,则使用用户ID来创建这位用户
        if not line[0] in data.keys():
            data[line[0]] = {line[3]:line[1]}
        #否则直接添加以该用户ID为key字典中
        else:
            data[line[0]][line[3]] = line[1]
    
    print(data)

    结果(部分):

    计算任何两位用户之间的相似度,由于每位用户评论的电影不完全一样,所以兽先要找到两位用户共同评论过的电影

    然后计算两者之间的欧式距离,最后算出两者之间的相似度。

    #!/usr/bin/env python
    # encoding: utf-8
    """
    @Company:华中科技大学电气学院聚变与等离子研究所
    @version: V1.0
    @author: YEXIN
    @contact: 1650996069@qq.com or yexin@hust.edu.cn 2018--2020
    @software: PyCharm
    @file: movie_rating_user.py
    @time: 2018/8/19 17:50
    @Desc:采用python字典来表示每位用户评论的电影和评分
    """
    file = open("E:\PycharmWorks\ML\CollaborativeFiltering\ml-latest\data.csv",'r', encoding='UTF-8')#记得读取文件时加‘r’, encoding='UTF-8'
    ##读取data.csv中每行中除了名字的数据
    data = {}##存放每位用户评论的电影和评分
    for line in file.readlines()[1:100]:
        #注意这里不是readline()
        line = line.strip().split(',')
        #如果字典中没有某位用户,则使用用户ID来创建这位用户
        if not line[0] in data.keys():
            data[line[0]] = {line[3]:line[1]}
        #否则直接添加以该用户ID为key字典中
        else:
            data[line[0]][line[3]] = line[1]
    
    #print(data)
    
    
    """计算任何两位用户之间的相似度,由于每位用户评论的电影不完全一样,所以兽先要找到两位用户共同评论过的电影
           然后计算两者之间的欧式距离,最后算出两者之间的相似度
    """
    from math import *
    def Euclidean(user1,user2):
        #取出两位用户评论过的电影和评分
        user1_data=data[user1]
        user2_data=data[user2]
        distance = 0
        #找到两位用户都评论过的电影,并计算欧式距离
        for key in user1_data.keys():
            if key in user2_data.keys():
                #注意,distance越大表示两者越相似
                distance += pow(float(user1_data[key])-float(user2_data[key]),2)
    
        return 1/(1+sqrt(distance))#这里返回值越小,相似度越大
    
    #计算某个用户与其他用户的相似度
    def top10_simliar(userID):
        res = []
        for userid in data.keys():
            #排除与自己计算相似度
            if not userid == userID:
                simliar = Euclidean(userID,userid)
                res.append((userid,simliar))
        res.sort(key=lambda val:val[1])
        return res[:4]
    
    RES = top10_simliar('1')
    print(RES)

    用户之间相似度结果:0表示两位的影评几乎一样,1表示没有共同的影评

    根据相似度来推荐用户:

    ########################################################################
    #根据用户推荐电影给其他人
    def recommend(user):
        #相似度最高的用户
        top_sim_user = top10_simliar(user)[0][0]
        #相似度最高的用户的观影记录
        items = data[top_sim_user]
        recommendations = []
        #筛选出该用户未观看的电影并添加到列表中
        for item in items.keys():
            if item not in data[user].keys():
                recommendations.append((item,items[item]))
        recommendations.sort(key=lambda val:val[1],reverse=True)#按照评分排序
        #返回评分最高的10部电影
        return recommendations[:10]
    
    Recommendations = recommend('1')
    print(Recommendations)

    推荐结果:

    ==================================================================================

    但有时我们会碰到因为两个用户之间数据由于数据膨胀,一方数据大,一方数据小,但是两者称明显的线性关系

    我们引入Pearson相关系数来衡量两个变量之间的线性相关性。

    Pearson:-1~1   -1:完全负相关  1:完全正相关  0:不相关              

    相关系数 0.8-1.0 极强相关

    0.6-0.8 强相关

    0.4-0.6 中等程度相关

    0.2-0.4 弱相关

    0.0-0.2 极弱相关或无相关

    公式:

    python代码:

    #########################################################################
    ##计算两用户之间的Pearson相关系数
    def pearson_sim(user1,user2):
        # 取出两位用户评论过的电影和评分
        user1_data = data[user1]
        user2_data = data[user2]
        distance = 0
        common = {}
    
        # 找到两位用户都评论过的电影
        for key in user1_data.keys():
            if key in user2_data.keys():
                common[key] = 1
        if len(common) == 0:
            return 0#如果没有共同评论过的电影,则返回0
        n = len(common)#共同电影数目
        print(n,common)
    
        ##计算评分和
        sum1 = sum([float(user1_data[movie]) for movie in common])
        sum2 = sum([float(user2_data[movie]) for movie in common])
    
        ##计算评分平方和
        sum1Sq = sum([pow(float(user1_data[movie]),2) for movie in common])
        sum2Sq = sum([pow(float(user2_data[movie]),2) for movie in common])
    
        ##计算乘积和
        PSum = sum([float(user1_data[it])*float(user2_data[it]) for it in common])
    
        ##计算相关系数
        num = PSum - (sum1*sum2/n)
        den = sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
        if den == 0:
            return 0
        r = num/den
        return r
    
    R = pearson_sim('1','3')
    print(R)

    pearson系数结果:

    注意:通过Pearson系数得到用户的相似度和通过欧式距离得到结果可能不一样

     

     

     

     

    展开全文
  • 协同过滤

    2020-07-25 21:29:52
    1,什么是协同过滤 推荐系统应用数据分析技术,找出用户最可能喜欢的东西推荐给用户,现在很多电子商务网站都应用这个算法。 2,协同过滤的种类 协同过滤推荐分为三种类型。第一种是基于用户(user-based)的协同过滤...

    1,什么是协同过滤

    推荐系统应用数据分析技术,找出用户最可能喜欢的东西推荐给用户,现在很多电子商务网站都应用这个算法。

    2,协同过滤的种类

    协同过滤推荐分为三种类型。第一种是基于用户(user-based)的协同过滤,第二种是基于项目(item-based)的协同过滤,第三种是基于模型(model based)的协同过滤。

    3.协同过滤的相似度计算有哪几种

    \1. 基于余弦(Cosine-based)的相似度计算,通过计算两个向量之间的夹角余弦值来计算物品之间的相似性,公式如下:

    ​ 其中分子为两个向量的内积,即两个向量相同位置的数字相乘。

    在这里插入图片描述

    ​ \2. 基于关联(Correlation-based)的相似度计算,计算两个向量之间的Pearson-r关联度,公式如下:

    在这里插入图片描述

    ​ 其中表示用户u对物品i的打分,表示第i个物品打分的平均值。

    ​ \3. 调整的余弦(Adjusted Cosine)相似度计算,由于基于余弦的相似度计算没有考虑不同用户的打分情况,可能有的用户偏向于给高分,而有的用户偏向于给低分,该方法通过减去用户打分的平均值消除不同用户打分习惯的影响,公式如下:

    在这里插入图片描述

    ​ 其中表示用户u打分的平均值。

    在这里插入图片描述

    4.关于物品和用户(https://www.cnblogs.com/baihuaxiu/p/6617389.html)

    基于用户的 CF 的基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到 K 邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。 下图给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算得到一个邻居 - 用户 C,然后将用户 C 喜欢的物品 D 推荐给用户 A。

    缺点:1. 数据稀疏性。一个大型的电子商务推荐系统一般有非常多的物品,用户可能买的其中不到1%的物品,不同用户之间买的物品重叠性较低,导致算法无法找到一个用户的邻居,即偏好相似的用户。

        2. 算法扩展性。最近邻居算法的计算量随着用户和物品数量的增加而增加,不适合数据量大的情况使用。
    

    这里写图片描述
    基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算的角度看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。下图给出了一个例子,对于物品 A,根据所有用户的历史偏好,喜欢物品 A 的用户都喜欢物品 C,得出物品 A 和物品 C 比较相似,而用户 C 喜欢物品 A,那么可以推断出用户 C 可能也喜欢物品 C。
    这里写图片描述

    5.py及例子(https://blog.csdn.net/u012995888/article/details/79077681)

    1)用户

    根据电影点评网站数据,给目标用户推荐电影。

       思路步骤:
    

    计算其他用户和目标用户的相似度(使用欧氏距离算法);
    根据相似度的高低找出K个目标用户最相似的邻居;
    在这些邻居喜欢的电影中,根据邻居与你的远近程度算出每个电影的推荐度;
    根据每一件物品的推荐度高低给你推荐物品。

    package ai;
    
    import java.util.*;
    
    /**
     * 描述:对电影打星1~5,最低打1星,0代表没打星过。大于平均推荐度代表喜欢。
     * 给目标用户推荐相似度最高用户喜欢的电影
     */
    public class UserCFDemo {
    
        //系统用户
        private static String[] users={"小明","小花","小美","小张","小李"};
        //和这些用户相关的电影
        private static String[] movies={"电影1","电影2","电影3","电影4","电影5","电影6","电影7"};
        //用户点评电影打星数据,是users对应用户针对movies对应电影的评分
        private static int[][] allUserMovieStarList={
                {3,1,4,4,1,0,0},
                {0,5,1,0,0,4,0},
                {1,0,5,4,3,5,2},
                {3,1,4,3,5,0,0},
                {5,2,0,1,0,5,5}
        };
        //相似用户集合
        private static List<List<Object>> similarityUsers=null;
        //推荐所有电影集合
        private static List<String> targetRecommendMovies=null;
        //点评过电影集合
        private static List<String> commentedMovies=null;
        //用户在电影打星集合中的位置
        private static Integer targetUserIndex=null;
    
        public static void main(String[] args) {
            Scanner scanner=new Scanner(System.in);
            String user=scanner.nextLine();
            while (user!=null && !"exit".equals(user)){
                targetUserIndex=getUserIndex(user);
                if(targetUserIndex==null){
                    System.out.println("没有搜索到此用户,请重新输入:");
                }else{
                    //计算用户相似度
                    calcUserSimilarity();
                    //计算电影推荐度,排序
                    calcRecommendMovie();
                    //处理推荐电影列表
                    handleRecommendMovies();
                    //输出推荐电影
                    System.out.print("推荐电影列表:");
                    for (String item:targetRecommendMovies){
                        if(!commentedMovies.contains(item)){
                            System.out.print(item+"  ");
                        }
                    }
                    System.out.println();
                }
    
                user=scanner.nextLine();
                targetRecommendMovies=null;
            }
    
        }
    
        /**
         * 把推荐列表中用户已经点评过的电影剔除
         */
        private static void handleRecommendMovies(){
            commentedMovies=new ArrayList<>();
            for (int i=0;i<allUserMovieStarList[targetUserIndex].length;i++){
                if(allUserMovieStarList[targetUserIndex][i]!=0){
                    commentedMovies.add(movies[i]);
                }
            }
        }
    
    
        /**
         * 获取全部推荐电影,计算平均电影推荐度
         */
        private static void calcRecommendMovie(){
            targetRecommendMovies=new ArrayList<>();
            List<List<Object>> recommendMovies=new ArrayList<>();
            List<Object> recommendMovie=null;
            double recommdRate=0,sumRate=0;
            for (int i=0;i<7;i++){
                recommendMovie=new ArrayList<>();
                recommendMovie.add(i);
                recommdRate=allUserMovieStarList[Integer.parseInt(similarityUsers.get(0).get(0).toString())][i]*Double.parseDouble(similarityUsers.get(0).get(1).toString())
                        +allUserMovieStarList[Integer.parseInt(similarityUsers.get(1).get(0).toString())][i]*Double.parseDouble(similarityUsers.get(1).get(1).toString());
                recommendMovie.add(recommdRate);
                recommendMovies.add(recommendMovie);
                sumRate+=recommdRate;
            }
    
            sortCollection(recommendMovies,-1);
    
            for (List<Object> item:recommendMovies){
                if(Double.parseDouble(item.get(1).toString()) > sumRate/7){ //大于平均推荐度的商品才有可能被推荐
                    targetRecommendMovies.add(movies[Integer.parseInt(item.get(0).toString())]);
                }
            }
        }
    
        /**
         * 获取两个最相似的用户
         */
        private static void calcUserSimilarity(){
            similarityUsers=new ArrayList<>();
            List<List<Object>> userSimilaritys=new ArrayList<>();
            for (int i=0;i<5;i++){
                if(i==targetUserIndex){
                    continue;
                }
                List<Object> userSimilarity=new ArrayList<>();
                userSimilarity.add(i);
                userSimilarity.add(calcTwoUserSimilarity(allUserMovieStarList[i],allUserMovieStarList[targetUserIndex]));
                userSimilaritys.add(userSimilarity);
            }
    
            sortCollection(userSimilaritys,1);
    
            similarityUsers.add(userSimilaritys.get(0));
            similarityUsers.add(userSimilaritys.get(1));
        }
    
        /**
         * 根据用户数据,计算用户相似度
         * @param user1Stars
         * @param user2Starts
         * @return
         */
        private static double calcTwoUserSimilarity(int[] user1Stars,int[] user2Starts){
            float sum=0;
            for(int i=0;i<7;i++){
                sum+=Math.pow(user1Stars[i]-user2Starts[i],2);
            }
            return Math.sqrt(sum);
        }
    
        /**
         * 查找用户所在的位置
         * @param user
         * @return
         */
        private static Integer getUserIndex(String user){
            if(user==null || "".contains(user)){
                return null;
            }
    
            for(int i=0;i<users.length;i++){
                if(user.equals(users[i])){
                    return i;
                }
            }
    
            return null;
        }
    
        /**
         * 集合排序
         * @param list
         * @param order  1正序 -1倒序
         */
        private static void sortCollection(List<List<Object>> list,int order){
            Collections.sort(list, new Comparator<List<Object>>() {
                @Override
                public int compare(List<Object> o1, List<Object> o2) {
                    if(Double.valueOf(o1.get(1).toString()) > Double.valueOf(o2.get(1).toString())){
                        return order;
                    }else if(Double.valueOf(o1.get(1).toString()) < Double.valueOf(o2.get(1).toString())){
                        return -order;
                    }else{
                        return 0;
                    }
                }
            });
        }
    }
    
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BU4hH3da-1595682802024)(C:\Users\Administrator\Pictures\QQ浏览器截图\20180119114407243.png)]

    2)物品

    思路步骤:

    1. 计算物品之间的相似度(同样使用杰卡德相似性度量算法);
    2. 根据物品之间的相似度以及用户历史行为给用户生成推荐列表。

    ​ 简单的代码模拟实现:

    
    import java.util.*;
    
    /**
     * 描述:对电影点评过用1表示,0代表没点评过。
     * 给目标用户推荐相似度最高用户喜欢的电影
     */
    public class ItemCFDemo {
    
        //系统用户
        private static String[] users={"小明","小花","小美","小张","小李"};
        //和这些用户相关的电影
        private static String[] movies={"电影1","电影2","电影3","电影4","电影5","电影6","电影7"};
        //用户点评电影情况
        private static Integer[][] allUserMovieCommentList={
                {1,1,1,0,1,0,0},
                {0,1,1,0,0,1,0},
                {1,0,1,1,1,1,1},
                {1,1,1,1,1,0,0},
                {1,1,0,1,0,1,1}
        };
        //用户点评电影情况,行转列
        private static Integer[][] allMovieCommentList=new Integer[allUserMovieCommentList[0].length][allUserMovieCommentList.length];
        //电影相似度
        private static HashMap<String,Double> movieABSimilaritys=null;
        //待推荐电影相似度列表
        private static HashMap<Integer,Object> movieSimilaritys=null;
        //用户所在的位置
        private static Integer targetUserIndex=null;
        //目标用户点评过的电影
        private static List<Integer> targetUserCommentedMovies=null;
        //推荐电影
        private static  List<Map.Entry<Integer, Object>> recommlist=null;
    
        public static void main(String[] args) {
            Scanner scanner=new Scanner(System.in);
            String user=scanner.nextLine();
            while (user!=null && !"exit".equals(user)){
                targetUserIndex=getUserIndex(user);
                if(targetUserIndex==null){
                    System.out.println("没有搜索到此用户,请重新输入:");
                }else{
                    //转换目标用户电影点评列表
                    targetUserCommentedMovies=Arrays.asList(allUserMovieCommentList[targetUserIndex]);
                    //计算电影相似度
                    calcAllMovieSimilaritys();
                    //获取全部待推荐电影
                    calcRecommendMovie();
                    //输出推荐电影
                    System.out.print("推荐电影列表:");
                    for (Map.Entry<Integer, Object> item:recommlist){
                        System.out.print(movies[item.getKey()]+"  ");
                    }
                    System.out.println();
                }
    
                user=scanner.nextLine();
            }
    
        }
    
        /**
         * 获取全部推荐电影
         */
        private static void calcRecommendMovie(){
            movieSimilaritys=new HashMap<>();
            for (int i=0;i<targetUserCommentedMovies.size()-1;i++){
                for (int j=i+1;j<targetUserCommentedMovies.size();j++){
                    Object similarity=null;
                    if(targetUserCommentedMovies.get(i)==1 &&  targetUserCommentedMovies.get(j)==0 && ( movieABSimilaritys.get(i+""+j)!=null || movieABSimilaritys.get(j+""+i)!=null)){
                        similarity=movieABSimilaritys.get(i+""+j)!=null?movieABSimilaritys.get(i+""+j):movieABSimilaritys.get(j+""+i);
                        movieSimilaritys.put(j,similarity);
                    }else if(targetUserCommentedMovies.get(i)==0 &&  targetUserCommentedMovies.get(j)==1 && (movieABSimilaritys.get(i+""+j)!=null || movieABSimilaritys.get(j+""+i)!=null)){
                        similarity=movieABSimilaritys.get(i+""+j)!=null?movieABSimilaritys.get(i+""+j):movieABSimilaritys.get(j+""+i);
                        movieSimilaritys.put(i,similarity);
                    }
                }
            }
    
            recommlist = new ArrayList<Map.Entry<Integer, Object>>(movieSimilaritys.entrySet());
            Collections.sort(recommlist, new Comparator<Map.Entry<Integer, Object>>() {
                @Override
                public int compare(Map.Entry<Integer, Object> o1, Map.Entry<Integer, Object> o2) {
                    return o1.getValue().toString().compareTo(o2.getValue().toString());
                }
            });
    
            System.out.println("待推荐相似度电影列表:"+recommlist);
        }
    
        /**
         * 计算全部物品间的相似度
         */
        private static void calcAllMovieSimilaritys(){
            converRow2Col();
            movieABSimilaritys=new HashMap<>();
            for (int i=0;i<allMovieCommentList.length-1;i++){
                for (int j=i+1;j<allMovieCommentList.length;j++){
                    movieABSimilaritys.put(i+""+j,calcTwoMovieSimilarity(allMovieCommentList[i],allMovieCommentList[j]));
                }
            }
    
            System.out.println("电影相似度:"+movieABSimilaritys);
        }
    
    
        /**
         * 根据电影全部点评数据,计算两个电影相似度
         * @param movie1Stars
         * @param movie2Starts
         * @return
         */
        private static double calcTwoMovieSimilarity(Integer[] movie1Stars,Integer[] movie2Starts){
            float sum=0;
            for(int i=0;i<movie1Stars.length;i++){
                sum+=Math.pow(movie1Stars[i]-movie2Starts[i],2);
            }
            return Math.sqrt(sum);
        }
    
        /**
         * 数组行转列
         */
        private static void converRow2Col(){
            for (int i=0;i<allUserMovieCommentList[0].length;i++){
                for(int j=0;j<allUserMovieCommentList.length;j++){
                    allMovieCommentList[i][j]=allUserMovieCommentList[j][i];
                }
            }
            System.out.println("电影点评转行列:"+Arrays.deepToString(allMovieCommentList));
        }
    
        /**
         * 查找用户所在的位置
         * @param user
         * @return
         */
        private static Integer getUserIndex(String user){
            if(user==null || "".contains(user)){
                return null;
            }
    
            for(int i=0;i<users.length;i++){
                if(user.equals(users[i])){
                    return i;
                }
            }
    
            return null;
        }
    }
    
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M8AaNmN6-1595682802025)(C:\Users\Administrator\Pictures\QQ浏览器截图\20180119182344930.png)]

    展开全文
  • 基于协同过滤算法的电影推荐系统

    热门讨论 2020-07-30 23:30:48
    电影推荐系统中运用的推荐算法是基于协同过滤算法(Collaborative Filtering Recommendation)。协同过滤是在信息过滤和信息系统中正迅速成为一项很受欢迎的技术。与传统的基于内容过滤直接分析内容进行推荐不同,...
  • 【推荐系统】协同过滤推荐算法

    万次阅读 2018-08-28 10:41:42
    协同过滤推荐算法中的基于用户的最近邻推荐、基于物品的最近邻推荐、矩阵因子分解SVD、关联规则挖掘等各种推荐算法的详细介绍。

    1、协同过滤概述

    协同过滤(CF, Collaborative Filtering)的主要思想是:利用已有的用户群过去的行为或者意见预测当前用户最可能喜欢哪些东西或者对哪些东西感兴趣。主要应用场景是在线零售系统,目的是进行商品促销和提高销售额。
    算法输入是一个用户-物品评分矩阵,输出的数据一般有两类:当前用户对物品喜欢和不喜欢程度的预测数值和n项的推荐物品的列表(不包含当前用户已经购买过的物品)。
    主要/最基础的实现方式有:
    (1)基于用户的最近邻推荐;
    (2)基于物品的最近邻推荐。

    2、基于用户的最近邻推荐

    (1)基于用户的最近邻推荐概述
    基于用户的最近邻推荐(user-based nearest neighbor recommendation)主要思想是:首先,对输入的评分数据集和当前用户ID作为输入,找出与当前用户过去有相似偏好的其它用户,这些用户叫做对等用户或者最近邻;然后,对当前用户没有见过的每个产品p,利用用户的近邻对产品p的评分进行预测;最后,选择所有产品评分最高的TopN个产品推荐给当前用户。
    (2)前提/假设
    如果用户过去有相似的偏好,那么该用户在未来也会有相似的偏好,用户的偏好不会随着时间而变化。
    (3)计算方式
    使用皮尔森/皮尔逊相关系数(Pearson Correlation Coefficient)来表示两个用户之间的相关性,取值范围为[-1,+1],-1表示强负相关,+1表示强正相关,0表示不相关。

    Pearson相关系数的应用要求两个变量的标准差都不为零的时候,该相关系数才具有定义,使用场景如下:
    (1)两个变量之间是线性关系,都是连续数据;
    (2)两个变量的总体是正态分布或者解决正态的单峰分布;
    (3)两个变量的观察值是成对的,每对观测值之间是相互对立的;
    (4)当计算出用户a和其它用户的相关性的时候,我们可以选择出最相似的N个近邻用户计算对物品p的评分预测值(N个近邻用户对物品p都有评分值)。

    3、基于物品的最近邻推荐

    (1)基于物品的最近邻推荐概述
    基于物品的最近邻推荐(item-based nearest neighbor recommendation)的思想是基于物品之间的相似度,而不是基于用户之间的相似度来进行预测评分值。
    (2)计算方式
    在基于物品的最近邻推荐算法中使用余弦相似度来计算两个物品中间的相似度的值,相似度取值范围:[0,1],值越接近1表示越相似。

    由于余弦相似度不考虑用户评分平均值之间的差异性,所以一般使用改进余弦相似度公式来计算相似度,做法是在评分值中减去平均值,改进余弦相似度公式的取值范围为[-1,1],和Pearson相关系数一样。

    基于计算出来的物品之间的相似度,选择最相似的前N个物品出来,可以预测用户u对物品p的评分为:

    (3)计算过程
    基于物品的最近邻推荐可以离线进行数据预计算,先构建出一个物品相似度矩阵,用于描述两个物品之间的相似度。在线上运行的时候,通过确定与物品p最相似的物品并计算u对这些邻近物品评分的加权总和来得到u对p的预测评分;近邻数量受限于用户有评分的物品个数,由于这样的物品数量一般都比较少,因此计算预测值的过程可以在线上交互应用允许的短时间内完成。
    原则上来讲,这种离线的计算方式也适合于基于用户的最近邻推荐,但是实际情况下,两个用户评分重叠的情况非常少,这样的话就会导致其它的评分值影响到最终用户间的相似度的计算。换言之,物品之间的相似度比用户之间的相似度更加稳定,这种计算的方式不会改变物品之间的相似度。

    4、基于近邻方法的优势

    (1)简单性:实现简单,而且在调整参数的过程中只有一个近邻数需要调整;
    (2)合理性:对于预测推荐提供了简洁并直观的理由;
    (3)高效性:基于近邻方法的推荐的效果特别高,因为可以先进行预处理,构建出相似度矩阵,在实际应用过程中,可以提供近似实时的推荐结果;
    (4)稳定性:当相似度矩阵构建完成后,如果有一个新的用户或者新的物品有评分的时候,只需要计算这个个体和其它个体之间的相似性即可完成更新操作。

    5、协同过滤中的评分

    由于在CF算法中,需要输入的是用户-物品评分矩阵,所以构建用户-物品评分矩阵是一个在进行协同过滤的重点。评分一般采用两分制、五分制、七分制和十分制这四种。可以通过以下两种方式收集用户对物品的评分,分别是:
    (1)显式评分:通过问卷调查的方式收集用户对于商品的评分,优点是数据比较准确,缺点是当用户看不到好处的时候可能不会提供评分。
    (2)隐式评分:当用户购买一个商品或者浏览一个商品的时候,我们可以认为这是一个正向评分/正向意图,根据既定的规则,可以将其转换为评分值;这种方式的优点是可以收集到最够多的数据,缺点是很难保证得到的评分数据是一个准确的用户评分数据。

    6、评分矩阵数据稀疏

    在实际的应用中,由于用户一般只会评价(或者购买、浏览)少部分商品,这样就会导致评分矩阵一般比较稀疏。这种情况下的挑战就是使用相对较少的有效评分来得到一个比较准确的预测。最直接的方式就是利用用户/物品的额外特征属性数据,进行数据的分类、聚类操作,来求解相似用户/物品列表。除此之外,可以使用缺省投票的形式补全物品的评价分数,思想是给那些只有一两个用户评价的物品给定一个缺省值。

    7、冷启动问题

    在CF算法中,存在着冷启动的问题,主要包括:
    (1)如何向还没有任何物品评分的新用户进行推荐;
    (2)如何处理从未被评过分或者购买过的商品。
    解决方案:
    (1)利用混合方法进行推荐,即利用额外的外部特征属性;对样本进行分类、聚类建模即可完成推荐;
    (2)结合基于用户的近邻推荐和基于物品的近邻推荐算法;
    (3)推荐Top10热门商品或者专门给定一个最近新加商品推荐列表。

    8、相似度度量

    (1)皮尔逊相关系数(Pearson Correlation, PC): 在基于用户近邻推荐算法中,常用的一种度量公式,效果最佳。
    (2)改进余弦向量相似度(Adjuested Cosine, AC):在基于物品近邻推荐算法中,最常用的一个相似度度量计算公式,效果最佳。
    除此之外,还有不太常用的两种度量公式(效果不佳,不推荐使用):
    (3)均方差(Mean Squared Difference, MSD):使用用户u和用户v对相同物品评分差的平方和均值的倒数来表示两个人的相似度。缺点是:无法表示负关联。
    (4)斯皮尔曼等级关联(Spearman Rank Correlation, SRC):利用用户对物品评分的排名来计算两个用户之间的相似度。缺点是:计算排名,消耗比较大,对于用户评分只有少量可选值的情况下,会产生大量并列的排名,效果不佳。
    当两个用户对物品进行评分的时候,如果评分商品都比较少,而且分数比较一致的情况下,我们就会认为,这两个用户比较相似,基于物品近邻算法也是一样的。但是这个时候实际上这两个用户的爱好事实上可能是完全不同的,解决这个问题,我们可以通过在相似度上添加一个重要性权重或者进行相似度缩放的方式对相似度进行转换。
    (5)重要性权重:当两个用户/物品之间的共同评分的物品/用户数量小于给定阈值的时候,就降低相似度重要性的权重。阈值大于等于25的时候,有比较好的预测结果。
    (6)相似度缩放:给定一个收缩因子对相似度进行收缩转换,当共同评分数量远远大于收缩因子的时候,物品的相似度几乎没有变化;当收缩因子为100的时候,效果不错。

    另外两个用户对物品给出一致的喜欢和不喜欢的评分,可能会不如他们给出差异更大的评分时提供的信息量多。可以通过使用(7)反用户频率(Inverse User Frequence, IUF)来对相似度计算公式进行转换,每个物品i都会赋以权重ci,对应评论了物品i的用户比例的log值:

    (8)频率加权皮尔逊相关系数(Frequencey-Weighted Pearson Correlation, FWPC)公式为:

    类似于反用户频率,在基于物品近邻推荐中,可以使用(9)反物品频率(Inverse ItemFrequence, IIF)来对相似度计算公式进行转换,每个用户u都会赋予一个权重cu,对应用户u进行评论的物品数量比例的log值:

    (10)频率加权改进余弦相似度(Frequencey-Weighted Adjusted Cosine, FWAC)公式为:

    9、近邻的选择

    在基于近邻进行推荐的算法中,近邻数量的选择和选择近邻的规则对于推荐系统的质量会产生重要的影响,一般现在近邻可以通过以下方式来选择:
    先过滤出预选近邻:Top-N过滤、阈值过滤、负数过滤。
    再从预选近邻列表中获取k个近邻;如果k的数目过小,会导致预测精度非常低,随着k的增大,预测精度会有一定的提升,但是达到一定值的时候(>50),由于存在一些重要的关联被不重要的关联所削弱,会导致预测精度下降,推荐选值一般为:25~50之间,当然在实际工作中,最优k的值一般需要通过进行交叉验证获取。

    10、基于近邻推荐算法的缺陷

    基于近邻的算法是基于评分之间的关联性进行推荐的,所以存在两个重要的缺陷:
    (1)覆盖有限:由于计算两个用户之间的相似性是基于他们对相同物品的评分,而且只有对相同物品进行评分的用户才能作为近邻,但是在实际应用中,有些用户有很少或者没有共同评分,但是他们可能具有相似的爱好,所以推荐算法的覆盖将会受到影响。
    (2)对稀疏数据的敏感:由于用户只会对一部分物品进行评分,所以评分矩阵的稀疏性是大多数推荐系统的共同问题。当数据是稀疏的时候,两个用户或者物品之间的相似性计算仅适用很少量有限的近邻。另外,相似性权重的计算也可能依赖小部分评分,从而有可能导致推荐偏差。这也是一个比较重要的问题:冷启动问题。
    解决方案:默认值填充、额外特性属性关联(非评分,内容信息填充)

    11、矩阵因子分解(SVD)推荐算法

    (1)SVD算法的概述
    SVD(Singular Value Decomposition)的想法是根据已有的评分情况,分析出评分者对各个物品因子的喜好程度,以及各个物品对于这些因子的包含程度,最后再反过来根据分析结果预测评分。通过SVD的方式可以找出影响评分的显示因子和隐藏因子,这样更多有意义的关联关系就会被发现出来。
    (2)SVD算法的计算
    SVD的数学定义:将给定评分矩阵R分解成为三个矩阵的乘积,其中U、V称为左、右奇异向量,Σ对角线上的值称为奇异值;其中R为n*m的矩阵,U为n*n的矩阵,Σ为n*m的矩阵,V为m*m的矩阵;可以使用前k个奇异值来近似的替代R矩阵,因为前1%的奇异值的和就占了全部奇异值和的99%以上。

    将U、V矩阵进行转换得到用户因子矩阵P和物品因子矩阵Q:

    评分预测为rui为:

    用户因子矩阵P和物品因子矩阵Q的计算可以通过随机梯度下降的方式进行学习,迭代式的更新相关参数即可,使用SVD矩阵因子分解推荐算法对于评分稀疏矩阵也可以进行正常处理,对于没有评分的不用计算误差值,直接令误差值为0:

    12、关联规则挖掘推荐算法

    关联规则挖掘是一种在大规模交易中识别类似规则关系模式的通用技术,可以应用到CF类型的推荐系统中。
    交易T是所有有效产品集合P={p,p,…,p}的子集,表示被一起购买的产品集合,关联规则X=>Y表示只要交易T中包含了X里面的元素,那么认为Y里面的元素也有可能被T包含。常见的规则挖掘算法是Apriori算法,关联规则的衡量指标是:支持度(support)和可信度(confidence)。
    将关联规则应用到推荐系统的主要问题就是需要将评分转换为交易,一般情况把所有的向前(正向)的评分集合<可以是做过去均值化操作后的评分矩阵>或者用户的购买行为可以看做一次交易。

    展开全文
  • 1. 协同过滤算法 协同过滤(Collaborative Filtering)推荐算法是最经典、最常用的推荐算法。 所谓协同过滤, 基本思想是根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品(基于对用户历史行为数据的...
  • 协同过滤 协同过滤算法是诞生最早,最为基础的推荐算法。该算法是通过对用户的历史浏览以及历史评分等信息通过计算相似度来发现用户对于某一类项目的偏好的算法。 目前应用比较广泛的协同过滤算法是基于邻域的方法,...
  • 协同过滤算法(collaborative filtering)

    万次阅读 2018-08-05 17:51:06
    协同过滤算法(collaborative filtering) https://www.cnblogs.com/xuanku/p/recsys.html 简介 CF算法的原理是汇总所有&lt;user,item&gt;的行为对, 利用集体智慧做推荐。其原理很像朋友推荐, 比如通过对...
  • 推荐系统:协同过滤collaborative filtering

    万次阅读 多人点赞 2017-05-01 16:54:12
    http://blog.csdn.net/pipisorry/article/details/51788955(个性化)推荐系统构建三大方法:基于内容的推荐content-based,协同过滤collaborative filtering,隐语义...协同过滤Collaborative Filtering协同过滤:使用
  • 【推荐系统】基于用户的协同过滤

    千次阅读 2019-07-28 21:10:45
    基于用户的协同过滤 原文链接:https://www.jianshu.com/p/e56665c54df8 一、基于用户的协同过滤 我们经常会找身边的朋友给我们推荐电影、电视剧,我们会发现一个规律,跟我们兴趣类似的人,推荐的往往比较符合...
  • UserCF:基于用户的协同过滤算法 ItemCF:基于物品的协同过滤算法 UserCF和ItemCF优缺点的对比 UserCF ItemCF 性能 适用于用户较少的场合,如果用户很多,计算用户相似度矩阵代价很大 适用于物品数明显小于用户...
  • 首先回顾一下,协同过滤算法主要有两种,一种是基于用户的协同过滤算法(UserCF),另一种是基于物品的协同过滤算法(ItemCF)。 基于用户的协同过滤算法主要有两步: 1)找到和目标用户兴趣相似的用户集合    ...
  • 1.1.协同过滤 协同过滤是目前应用最广泛的推荐算法,它仅仅通过了解用户与物品之间的关系进行推荐,而根本不会考虑到物品本身的属性。 可分成两类: 1、基于用户(user-based)的协同过滤 2、基于商品(item-...
  • 简单的协同过滤算法流程如下 (1)、计算其他用户和你的相似度,可以使用反差表忽略一部分用户 (2)、根据相似度的高低找出K个与你最相似的邻居 (3)、在这些邻居喜欢的物品中,根据邻居与你的远近程度算出每一...
  • 基于SSM协同过滤音乐推荐管理系统

    万次阅读 2020-10-17 16:35:35
    运行环境: jdk 1.8 IDE环境: Eclipse,Myeclipse,IDEA都可以 tomcat环境: Tomcat 9.0 硬件环境: windows 7/8/10 1G内存以上 可以实现: 管理员角色包含以下功能:管理员登录,音乐管理,添加音乐,评论管理,用户管理...
  • 最近lz在研究推荐系统,对利用基于协同过滤算法来实现推荐非常感兴趣,因此,就自学了这一方面的内容,并且看了《推荐系统实践》一书,对这方面的理解也进了一步。首先协同过滤算法在1992年被提出来,最初的设想是,...
  • 推荐算法--基于物品的协同过滤算法

    万次阅读 2019-07-27 01:13:41
    ItemCF:ItemCollaborationFilter,基于物品的协同过滤 算法核心思想:给用户推荐那些和他们之前喜欢的物品相似的物品。 比如,用户A之前买过《数据挖掘导论》,该算法会根据此行为给你推荐《机器...
  • 基于用户的协同过滤推荐算法原理和实现

    万次阅读 多人点赞 2018-05-09 14:48:03
    在推荐系统众多方法中,基于用户的协同过滤推荐算法是最早诞生的,原理也较为简单。该算法1992年提出并用于邮件过滤系统,两年后1994年被 GroupLens 用于新闻过滤。一直到2000年,该算法都是推荐系统领域最著名的...
  • 典型推荐算法总结

    万次阅读 多人点赞 2018-11-23 21:05:42
    推荐算法种类很多,但是目前应用最广泛的应该是协同过滤类别的推荐算法,本文就对协同过滤类别的推荐算法做一个概括总结,后续也会对一些典型的协同过滤推荐算法做原理总结。 1. 推荐算法概述  推荐算法是非常...
  • “无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。” 目前推荐系统研宄的主要...
1 2 3 4 5 ... 20
收藏数 39,394
精华内容 15,757
关键字:

协同过滤