《推荐系统》基于图的推荐算法

1:概述

2:原理简介

3:代码实现

4:问题说明

一:概述

基于图的模型(graph-based model)是推荐系统中的重要内容。其实,很多研究人员把基于邻域的模型也称为基于图的模型,因为可以把基于邻域的模型看做基于图的模型的简单形式

在研究基于图的模型之前,首先需要将用户的行为数据,表示成图的形式,下面我们讨论的用户行为数据是用二元数组组成的,其中每个二元组(u,i)表示用户u对物品i的产生过行为,这种数据很容易用一个二分图表示

令G(V,E)表示用户物品二分图,其中 由用户顶点集合 和物品顶点集合 组成。对于数据集中每一个二元组(u,
i),图中都有一套对应的边 ,其中是用户u对应的顶点,
是物品i对应的顶点。图2-18是一个简单的用户物品二分图模型,其中圆形节点代表用户,方形节点代表物品,圆形节点和方形节点之间的边代表用户对物品的行为。比如图中用户节点A和物品节点a、b、d相连,说明用户A对物品a、b、d产生过行为。

二:原理简介

将用户的行为数据表示为二分图后,接下来的就是基于二分图为用户进行推荐,那么给用户u推荐物品就可以转化为度量用户顶点Vu和Vu没有直接边相连的顶点在图上的相关性,相关性越高的物品在推荐列表上的权重九越高,推荐位置就越靠前。

那么如何评价两个顶点的相关性?一般取决于三个因素

1:两个顶点之间的路径数

2:两个顶点之间路径的长度

3:两个顶点之间的路径经过的顶点

而相关性较高的一对顶点一般具有如下特征:

1:两个顶点之间有很多路径相连

2:连接两个顶点之间的路径长度都比较短

3:连接两个顶点之间的路径不会经过出度比较大的顶点

举一个简单的例子,如图2-19所示,用户A和物品c、e没有边相连,但是用户A和物品c有两条长度为3的路径相连,用户A和物品e有两条长度为3的路径相连。那么,顶点A与e之间的相关性要高于顶点A与c,因而物品e在用户A的推荐列表中应该排在物品c之前,因为顶点A与e之间有两条路径——(A, b, C, e)和(A, d, D, e)。其中,(A, b, C, e)路径经过的顶点的出度为(3,
2, 2,2),而(A, d, D, e)路径经过的顶点的出度为(3, 2, 3, 2)。因此,(A, d, D, e)经过了一个出度比较大的顶点D,所以(A, d, D, e)对顶点A与e之间相关性的贡献要小于(A, b, C, e)。

下面介绍一种基于随机游走的PersonalRank算法(和PangRank算法相似,pageRank算法参考)

假设要给用户u进行个性化推荐,可以从用户u对应的节点Vu开始在用户物品二分图上进行随机游走。游走到任何一个节点时,首先按照概率α决定是继续游走,还是停止这次游走并从Vu节点开始重新游走。如果决定继续游走,那么就从当前节点指向的节点中按照均匀分布随机选择一个节点作为游走下次经过的节点。这样,经过很多次随机游走后,每个物品节点被访问到的概率会收敛到一个数。最终的推荐列表中物品的权重就是物品节点的访问概率。

如果将上面的描述表示成公式,可以得到如下公式:

alpha表示随机游走的概率        PR(v‘)表示访问v‘的概率 
     out(v‘)表示v‘指向的顶点集合

三:代码实现

#-*-coding:utf-8-*-
'''
Created on 2016年6月16日

@author: Gamer Think
'''

'''
G:二分图   alpha:随机游走的概率   root:游走的初始节点     max_step;最大走动步数
'''
def PersonalRank(G, alpha, root, max_step):
    rank = dict()
    rank = {x:0 for x in G.keys()}
    rank[root] = 1
    #开始迭代
    for k in range(max_step):
        tmp = {x:0 for x in G.keys()}
        #取节点i和它的出边尾节点集合ri
        for i, ri in G.items():  #i是顶点。ri是与其相连的顶点极其边的权重
            #取节点i的出边的尾节点j以及边E(i,j)的权重wij, 边的权重都为1,在这不起实际作用
            for j, wij in ri.items():   #j是i的连接顶点,wij是权重
                #i是j的其中一条入边的首节点,因此需要遍历图找到j的入边的首节点,
                #这个遍历过程就是此处的2层for循环,一次遍历就是一次游走
                tmp[j] += alpha * rank[i] / (1.0 * len(ri))
        #我们每次游走都是从root节点出发,因此root节点的权重需要加上(1 - alpha)
        #在《推荐系统实践》上,作者把这一句放在for j, wij in ri.items()这个循环下,我认为是有问题。
        tmp[root] += (1 - alpha)
        rank = tmp  

        #输出每次迭代后各个节点的权重
        print 'iter:  ' + str(k) + "\t",
        for key, value in rank.items():
            print "%s:%.3f, \t"%(key, value),
        print  

    return rank  

'''
主函数,G表示二分图,‘A’表示节点,后边对应的字典的key是连接的顶点,value表示边的权重
'''
if __name__ == '__main__':
    G = {'A' : {'a' : 1, 'c' : 1},
         'B' : {'a' : 1, 'b' : 1, 'c':1, 'd':1},
         'C' : {'c' : 1, 'd' : 1},
         'a' : {'A' : 1, 'B' : 1},
         'b' : {'B' : 1},
         'c' : {'A' : 1, 'B' : 1, 'C':1},
         'd' : {'B' : 1, 'C' : 1}}  

    PersonalRank(G, 0.85, 'A', 100)  

运行结果:

结果说明:

与A相关度最高的依次是 A(0.269),c(0.190),B(0.185),a(0.154),C(0.086),d(0.076),b(0.039),去除A已经连接的a,c,剩下的推荐依次为B,a,C,d,b

四:问题说明

虽然PersonalRank算法可以通过随机游走进行比较好的理论解释,但该算法在时间复杂度上有明显的缺点。因为在为每个用户进行推荐时,都需要在整个用户物品二分图上进行迭代,直到整个图上的每个顶点的PR值收敛。这一过程的时间复杂度非常高,不仅无法在线提供实时推荐,甚至离线生成推荐结果也很耗时。

为了解决PersonalRank每次都需要在全图迭代并因此造成时间复杂度很高的问题,这里给出两种解决方案。第一种很容易想到,就是减少迭代次数,在收敛之前就停止。这样会影响最终的精度,但一般来说影响不会特别大。另一种方法就是从矩阵论出发,重新设计算法。

对矩阵运算比较熟悉的读者可以轻松将PersonalRank转化为矩阵的形式。令M为用户物品二分图的转移概率矩阵,即:

那么,迭代公式可以转化为:

对矩阵论稍微熟悉的读者都可以解出上面的方程,得到:

时间: 2024-08-04 22:04:55

《推荐系统》基于图的推荐算法的相关文章

基于特征的推荐算法【转】

http://in.sdo.com/?p=2779 推荐算法准确度度量公式: 其中,R(u)表示对用户推荐的N个物品,T(u)表示用户u在测试集上喜欢的物品集合. 集合相似度度量公式(N维向量的距离度量公式): Jaccard公式: 其中,N(u)表示用户u有过正反馈的物品集合. 余弦相似度公式: UserCF公式: 其中,S(u,k)表示和用户u兴趣最接近的K个用户集合:N(i)表示对物品i有过正反馈的用户集合:w(u,v)表示用户u和用户v的兴趣相似度:r(v,i)表示用户v对物品i的兴趣.

新闻推荐系统:基于内容的推荐算法(Recommender System:Content-based Recommendation)

因为开发了一个新闻推荐系统的模块,在推荐算法这一块涉及到了基于内容的推荐算法(Content-Based Recommendation),于是借此机会,基于自己看了网上各种资料后对该分类方法的理解,用尽量清晰明了的语言,结合算法和自己开发推荐模块本身,记录下这些过程,供自己回顾,也供大家参考~ 目录 一.基于内容的推荐算法 + TFIDF 二.在推荐系统中的具体实现技巧 正文 一.基于内容的推荐算法 + TFIDF 主流推荐算法大致可分为: 基于内容(相似度)的推荐 基于用户/物品相似度的协同过

一个简单的基于内容的推荐算法

最近闲下来又开始继续折腾推荐系统了,声明一下,本文只是介绍一下最基础的基于内容的推荐系统(Content-based recommender system)的工作原理,其实基于内容的推荐系统也分三六九等Orz,这里只是简单的较少一下最原始的.最基本的工作流程. 基于内容的推荐算法思路很简单,它的原理大概分为3步: 1.为每个物品(Item)构建一个物品的属性资料(Item Profile) 2.为每个用户(User)构建一个用户的喜好资料(User Profile) 3.计算用户喜好资料与物品属

基于内容的推荐算法

输入 输入1:包含200部电影的数据集,集合中包含两列,一列为电影的id,一列为电影的流派集合,如下图所示: 输入2:一个用户的电影兴趣记录,like字段为1表示喜欢,0表示不喜欢,如下图所示: 输出 输出1:输入1的One-Hot编码形式,类似下图所示: 输出2:根据输入2和输出1,从电影数据集中给用户推荐用户没有看过的与用户相似度最高的k个电影. 前言 基于内容的推荐算法是一种比较经典的推荐算法,应用较广,可解释性强,准确率高,尤其是当今社会信息丰富,比如文本.音频等,有比较多的内容可以利用

基于邻域的推荐算法

基于邻域的算法,就是最常见的CF协同过滤算法.分为 基于用户的 user based CF 和 基于物品的 item based CF. 1.user based CF 对目标用户u, 找出与之相似的用户集合 U,将U中用户感兴趣而u没见过的物品推荐给u. 用户相似度,通过将用户表示成商品的向量后计算. 如果两两用户都计算相似度,那么计算复杂度为O(|U|^2),而对每个u来说,它的向量都是稀疏的.也就是说很多用户间没有交集,相似度计算为0.所以可以先过滤掉这些用户组合后再进行计算.一个方法是建

加入商品分类信息,考虑用户所处阶段的 图模型 推荐算法 Rws(random walk with stage)

场景: 一个新妈妈给刚出生的宝宝买用品,随着宝宝的长大,不同的阶段需要不同的物品. 这个场景中涉及到考虑用户所处阶段,给用户推荐物品的问题. 如果使用用户协同过滤,则需要根据购买记录,找到与用户处于同一阶段的用户. 不加入分类信息,单纯使用物品信息,则可能因为买了不同牌子的尿布,而判断为非相似用户, 所以加入商品分类信息 算法步骤: 1.   加入分类信息 1)   根据时间将用户交易记录分成若干阶段(比如,近90天,近360天-近90天,...) 2)   对于中的记录(以中的为例),在向量的

(5)基于协同过滤推荐算法的图书推荐研究

协同过滤算法以其出色的计算速度和健壮性,在全球范围内特别是在互联网领域中取得了巨大成功.文章介绍了基于物品的协同过滤算法的基本思想和实现步骤,以及应用于实际图书推荐项目中的效果和产生的问题.基于物品的协同过滤算法的基本原理是和某用户历史上感兴趣的物品,越相似的物品,越有可能在用户的推荐列表中获得比较高的排名.算法的基本步骤为收集用户偏好,计算物品之间的相似度,计算用户对某一个物品的兴趣度.文章中介绍的系统在实际应用中效果良好.今后该系统的升级版将重点研究如何解决算法的稀疏性以及如何提高图书推荐质

python 新闻推荐系统(基于新闻内容推荐)

# -*- coding:utf-8 -*-__version__ = '1.0.0.0'"""@brief : 基于新闻的内容推荐系统@details: 详细信息@author : zhphuang@date : 2019-08-07"""import jieba from pandas import *from sklearn.metrics import pairwise_distancesfrom bs4 import Beautiful

基于用户的协同过滤推荐算法

什么是推荐算法 推荐算法最早在1992年就提出来了,但是火起来实际上是最近这些年的事情,因为互联网的爆发,有了更大的数据量可以供我们使用,推荐算法才有了很大的用武之地. 最开始,所以我们在网上找资料,都是进yahoo,然后分门别类的点进去,找到你想要的东西,这是一个人工过程,到后来,我们用google,直接搜索自 己需要的内容,这些都可以比较精准的找到你想要的东西,但是,如果我自己都不知道自己要找什么肿么办?最典型的例子就是,如果我打开豆瓣找电影,或者我去 买说,我实际上不知道我想要买什么或者看