• 基于邻域的算法


    基于邻域的算法分为两大类,一类是基于用户的协同过滤算法,另一类是基于物品的协同过滤算法。
    一、基于用户的协同过滤算法:

    基于用户的协同过滤算法主要包括两个步骤
    (1) 找到和目标用户兴趣相似的用户集合
    (2) 找到这个集合中的用户喜欢的,且目标用户没有听说过的物品推荐给目标用户

    步骤(1)的关键就是计算两个用户的兴趣相似度。给定用户u和用户v,令N(u)表示用户u曾经有过正反馈的物品集合,令N(v)为用户v曾经有过正反馈的物品集合。那么,我们可以通过如下的Jaccard公式简单地计算u和v的兴趣相似度:

    或者通过余弦相似度计算:

    train = {'A':set(['a','b','d']),'B':set(['a','c']),'C':set(['b','e']),'D':set(['c','d','e'])}
    
    #余弦相似度
    def UserSimilarity(train):
        W = {}
        for u in train.keys():
            for v in train.keys():
                if u == v:
                    continue
                W.setdefault(u,{})
                W[u].setdefault(v,0)
                W[u][v] = len(train[u] & train[v])
                W[u][v] /= math.sqrt(len(train[u]) * len(train[v]) * 1.0)
        return W
    
    print UserSimilarity(train)

    该代码对两两用户都利用余弦相似度计算相似度。这种方法的时间复杂度是O(|U|*|U|),这在用户数很大时非常耗时。事实上,很多用户相互之间并没有对同样的物品产生过行为,即很多时候

    可以首先建立物品到用户的倒排表,对于每个物品都保存对该物品产生过行为的用户列表.这样来自同一物品映射的两个用户肯定是有交集的。这样一来只用计算有交集的用户的相似度,其他初始化为0即可

    def UserSimilarity1(train):
        #建立倒排表
        item_users = dict()
        for u,items in train.items():
            for i in items:
                if i not in item_users:
                    item_users[i] = set()
                item_users[i].add(u)
    
        #记录用户U V 共有的物品个数
        C = dict()
        #记录每个用户所拥有的物品个数
        N = dict()
        for i ,users in item_users.items():
            for u in users:
                N.setdefault(u,0)
                N[u] += 1
                for v in users:
                    if u == v:
                        continue
                    C.setdefault(u,{})
                    C[u].setdefault(v,0)
                    C[u][v] += 1
    
        #相似矩阵
        W = {}
        for u , related_users in C.items():
            for v ,cur in related_users.items():
                W.setdefault(u,{})
                W[u].setdefault(v,0)
                W[u][v] = cur / math.sqrt(N[u] * N[v])
    
        return W

    得到用户之间的兴趣相似度后, UserCF算法会给用户推荐和他兴趣最相似的K个用户喜欢的物品。如下的公式度量了UserCF算法中用户u对物品i的感兴趣程度:

    S(u, K)包含和用户u兴趣最接近的K个用户, N(i)是对物品i有过行为的用户集合, wuv是用户u和用户v的兴趣相似度, rvi代表用户v对物品i的兴趣,因为使用的是单一行为的隐反馈数据,所以所有的rvi=1。

    UserCF只有一个重要的参数K,即为每个用户选出K个和他兴趣最相似的用户,然后推荐那K个用户感兴趣的物品。


    准确率和召回率:推荐系统的精度指标(准确率和召回率)并不和参数K成线性关系在MovieLens数据集中,选择K=80左右会获得比较高的准确率和召回率。因此选择合适的K对于获得高的推荐系统精度比较重要。当然,推荐结果的精度对K也不是特别敏感,只要选在一定的区域内,就可以获得不错的精度。
    流行度:可以看到,在3个数据集上K越大则UserCF推荐结果就越热门。这是因为K决定了UserCF在给你做推荐时参考多少和你兴趣相似的其他用户的兴趣,那么如果K越大,参考的人越多,结果就越来越趋近于全局热门的物品
    覆盖率:可以看到,在3个数据集上, K越大则UserCF推荐结果的覆盖率越低。覆盖率的降低是因为流行度的增加,随着流行度增加, UserCF越来越倾向于推荐热门的物品,从而对长尾物品的推荐越来越少,因此造成了覆盖率的降低。

    用户相似度计算的改进
    两个用户对冷门物品采取过同样的行为更能说明他们兴趣的相似度。如下公式,根据用户行为计算用户的兴趣相似度:

    该公式通过惩罚了用户u和用户v共同兴趣列表中热门物品对他们相似度的影响,基于上述用户相似度公式的UserCF算法记为User-IIF算法,UserCF-IIF在各项性能上略优于UserCF

    上述公式记号有问题,N(i)应该是物品i对应的用户个数。

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

    基于物品的协同过滤(item-based collaborative filtering)算法是目前业界应用最多的算法。基于物品的协同过滤算法 (简称ItemCF)给用户推荐那些和他们之前喜欢的物品相似的物品。

    ItemCF算法并不利用物品的内容属性计算物品之间的相似度,它主要通过分析用户的行为记录计算物品之间的相似度。该算法认为,物品A和物品B具有很大的相似度是因为喜欢物品A的用户大都也喜欢物品B.

    基于物品的协同过滤算法主要分为两步。
    (1) 计算物品之间的相似度。
    (2) 根据物品的相似度和用户的历史行为给用户生成推荐列表。

    我们可以用下面的公式定义物品的相似度:

    分母|N(i)|是喜欢物品i的用户数,而分子是同时喜欢物品i和物品j的用户.如果物品j很热门,很多人都喜欢,那么Wij就会很大,接近1。因此,该公式会造成任何物品都会和热门的物品有很大的相似度.为了避免推荐出热门的物品,可以用下面的公式:

    这个公式惩罚了物品j的权重,因此减轻了热门物品会和很多物品相似的可能性。

    在得到物品之间的相似度后, ItemCF通过如下公式计算用户u对一个物品j的兴趣:

     

    这里N(u)是用户喜欢的物品的集合, S(j,K)是和物品j最相似的K个物品的集合, wji是物品j和i的相似度, rui是用户u对物品i的兴趣。(对于隐反馈数据集,如果用户u对物品i有过行为,即可令rui=1。)

    该公式的含义是,和用户历史上感兴趣的物品越相似的物品,越有可能在用户的推荐列表中获得比较高的排名。

    用户活跃度对物品相似度的影响 

    John S. Breese在论文中提出了一个称为IUF(Inverse User Frequence),即用户活跃度对数的倒数的参数,他也认为活跃用户对物品相似度的贡献应该小于不活跃的用户,他提出应该增加IUF参数来修正物品相似度的计算公式:

     

    上面的公式只是对活跃用户做了一种软性的惩罚,但对于很多过于活跃的用户,为了避免相似度矩阵过于稠密,我们在实际计算中一般直接忽略他的兴趣列表,而不将其纳入到相似度计算的数据集中。将上面的算法记为ItemCF-IUF。

    物品相似度的归一化 

    如果将ItemCF的相似度矩阵按最大值归一化,可以提高推荐的准确率(为什么?)。 如果已经得到了物品相似度矩阵w,那么可以用如下公式得到归一化之后的相似度矩阵w'

    归一化的好处不仅仅在于增加推荐的准确度,它还可以提高推荐的覆盖率和多样性。

    三、UserCF和ItemCF的综合比较 

    UserCF给用户推荐那些和他有共同兴趣爱好的用户喜欢的物品,而ItemCF给用户推荐那些和他之前喜欢的物品类似的物品。从这个算法的原理可以看到, UserCF的推荐结果着重于反映和用户兴趣相似的小群体的热点,而ItemCF 的推荐结果着重于维系用户的历史兴趣。换句话说, UserCF的推荐更社会化,反映了用户所在的小型兴趣群体中物品的热门程度,而ItemCF的推荐更加个性化,反映了用户自己的兴趣传承。

    热门程度和时效性是个性化新闻推荐的重点,而个性化相对于这两点略显次要。UserCF可以给用户推荐和他有相似爱好的一群其他用户今天都在看的新闻,这样在抓住热点和时效性的同时,保证了一定程度的个性化。这是Digg在新闻推荐中使用UserCF的最重要原因。

    UserCF适合用于新闻推荐的另一个原因是从技术角度考量的。因为作为一种物品,新闻的更 新非常快,每时每刻都有新内容出现,而ItemCF需要维护一张物品相关度的表,如果物品更新很快,那么这张表也需要很快更新,这在技术上很难实现。绝大多数物品相关度表都只能做到一天一次更新,这在新闻领域是不可以接受的。而UserCF只需要用户相似性表,虽然UserCF对于新用户也需要更新相似度表,但在新闻网站中,物品的更新速度远远快于新用户的加入速度,而且对于新用户,完全可以给他推荐最热门的新闻,因此UserCF显然是利大于弊。

  • 相关阅读:
    wc
    wbinfo
    wall -- 向所有人的终端发送消息
    w
    vt-is-UTF8
    vmstat
    vimtutor
    vim
    centos7
    Web 在线文件管理器学习笔记与总结(8)删除文件
  • 原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/5776936.html
Copyright © 2020-2023  润新知