算法工程师修仙之路:推荐系统实践(二)

第一章 好的推荐系统

推荐系统评测


推荐系统实验方法

  • 在推荐系统中,主要有三种评测推荐效果的实验方法,即离线实验(offline experiment)、用户调查(user study)和在线实验(online experiment)。

  • 离线实验

    • 离线实验的方法一般由如下几个步骤构成:
      • 通过日志系统获得用户行为数据,并按照一定格式生成一个标准的数据集;
      • 将数据集按照一定的规则分成训练集和测试集;
      • 在训练集上训练用户兴趣模型,在测试集上进行预测;
      • 通过事先定义的离线指标评测算法在测试集上的预测结果。
    • 推荐系统的离线实验都是在数据集上完成的,也就是说它不需要一个实际的系统来供它实验,而只要有一个从实际系统日志中提取的数据集即可。
    • 这种实验方法的好处是不需要真实用户参与,可以直接快速地计算出来,从而方便、快速地测试大量不同的算法。
    • 它的主要缺点是无法获得很多商业上关注的指标,如点击率、转化率等,而找到和商业指标非常相关的离线指标也是很困难的事情。
    • 离线实验的优缺点
      • 优点
        • 不需要有对实际系统的控制权;
        • 不需要用户参与实验;
        • 速度快,可以测试大量算法。
      • 缺点
        • 无法计算商业上关心的指标;
        • 离线实验的指标和商业指标存在差距。
  • 用户调查

    • 离线实验的指标和实际的商业指标存在差距,比如预测准确率和用户满意度之间就存在很大差别,高预测准确率不等于高用户满意度。
    • 如果要准确评测一个算法,需要相对比较真实的环境。
    • 最好的方法就是将算法直接上线测试,但在对算法会不会降低用户满意度不太有把握的情况下,上线测试具有较高的风险,所以在上线测试前一般需要做一次称为用户调查的测试。
    • 用户调查需要有一些真实用户,让他们在需要测试的推荐系统上完成一些任务。在他们完成任务时,我们需要观察和记录他们的行为,并让他们回答一些问题。最后,我们需要通过分析他们的行为和答案了解测试系统的性能。
    • 用户调查的优缺点
      • 优点是可以获得很多体现用户主观感受的指标,相对在线实验风险很低,出现错误后很容易弥补。
      • 缺点是招募测试用户代价较大,很难组织大规模的测试用户,因此会使测试结果的统计意义不足。此外,在很多时候设计双盲实验非常困难,而且用户在测试环境下的行为和真实环境下的行为可能有所不同,因而在测试环境下收集的测试指标可能在真实环境下无法重现。
  • 在线实验

    • 在完成离线实验和必要的用户调查后,可以将推荐系统上线做AB测试,将它和旧的算法进行比较。
    • AB 测试是一种很常用的在线评测算法的实验方法。它通过一定的规则将用户随机分成几组,并对不同组的用户采用不同的算法,然后通过统计不同组用户的各种不同的评测指标比较不同算法,比如可以统计不同组用户的点击率,通过点击率比较不同算法的性能。
    • AB 测试的优缺点
      • AB 测试的优点是可以公平获得不同算法实际在线时的性能指标,包括商业上关注的指标。
      • AB 测试的缺点主要是周期比较长,必须进行长期的实验才能得到可靠的结果。
        • 一般不会用 AB 测试测试所有的算法,而只是用它测试那些在离线实验和用户调查中表现很好的算法。
      • 另一个缺点是一个大型网站的 AB 测试系统的设计也是一项复杂的工程。
        • 一个大型网站的架构分前端和后端,从前端展示给用户的界面到最后端的算法,中间往往经过了很多层,这些层往往由不同的团队控制,而且都有可能做 AB 测试。
        • 如果为不同的层分别设计 AB 测试系统,那么不同的 AB 测试之间往往会互相干扰。
        • 因此,切分流量是 AB 测试中的关键,不同的层以及控制这些层的团队需要从一个统一的地方获得自己 AB 测试的流量,而不同层之间的流量应该是正交的。
    • AB 测试系统
      在这里插入图片描述
      • 用户进入网站后,流量分配系统决定用户是否需要被进行AB测试,如果需要的话,流量分配系统会给用户打上在测试中属于什么分组的标签。
      • 然后用户浏览网页,而用户在浏览网页时的行为都会被通过日志系统发回后台的日志数据库。
      • 此时,如果用户有测试分组的标签,那么该标签也会被发回后台数据库。
      • 在后台,实验人员的工作首先是配置流量分配系统,决定满足什么条件的用户参加什么样的测试。
      • 其次,实验人员需要统计日志数据库中的数据,通过评测系统生成不同分组用户的实验报告,并比较和评测实验结果。
  • 一般来说,一个新的推荐算法最终上线,需要完成上面所说的三个实验。

    • 首先,需要通过离线实验证明它在很多离线指标上优于现有的算法。
    • 然后,需要通过用户调查确定它的用户满意度不低于现有的算法。
    • 最后,通过在线的AB测试确定它在我们关心的指标上优于现有的算法。

评测指标

  • 用户满意度

    • 用户作为推荐系统的重要参与者,其满意度是评测推荐系统的最重要指标。但是,用户满意度没有办法离线计算,只能通过用户调查或者在线实验获得。
    • 用户对推荐系统的满意度分为不同的层次。
    • 用户调查获得用户满意度主要是通过调查问卷的形式。
      • 这个调查问卷不是简单地询问用户对结果是否满意,而是从不同的侧面询问用户对结果的不同感受。
      • 比如,如果仅仅问用户是否满意,用户可能心里认为大体满意,但是对某个方面还有点不满,因而可能很难回答这个问题。
      • 因此在设计问卷时需要考虑到用户各方面的感受,这样用户才能针对问题给出自己准确的回答。
    • 在在线系统中,用户满意度主要通过一些对用户行为的统计得到。更一般的情况下,我们可以用点击率、用户停留时间和转化率等指标度量用户的满意度。
  • 预测准确度

    • 预测准确度度量一个推荐系统或者推荐算法预测用户行为的能力。

    • 这个指标是最重要的推荐系统离线评测指标,从推荐系统诞生的那一天起,几乎99%与推荐相关的论文都在讨论这个指标。这主要是因为该指标可以通过离线实验计算,方便了很多学术界的研究人员研究推荐算法。

    • 在计算该指标时需要有一个离线的数据集,该数据集包含用户的历史行为记录。然后,将该数据集通过时间分成训练集和测试集。最后,通过在训练集上建立用户的行为和兴趣模型预测用户在测试集上的行为,并计算预测行为和测试集上实际行为的重合度作为预测准确度。

    • 评分预测

      • 很多提供推荐服务的网站都有一个让用户给物品打分的功能。

      • 那么,如果知道了用户对物品的历史评分,就可以从中习得用户的兴趣模型,并预测该用户在将来看到一个他没有评过分的物品时,会给这个物品评多少分。

      • 预测用户对物品评分的行为称为评分预测。

      • 评分预测的预测准确度一般通过均方根误差(RMSE)和平均绝对误差(MAE)计算。

        • 对于测试集中的一个用户 u u 和物品 i i ,令 r u i r_{ui} 是用户 u u 对物品 i i 的实际评分,而 r ^ u i \hat r_{ui} 是推荐算法给出的预测评分,那么RMSE的定义为: R M S E = u , i T ( r u i r ^ u i ) 2 T RMSE=\frac{\sqrt{\sum_{u,i\in T}(r_{ui}-\hat r_{ui})^2}}{\lvert T \rvert}
        • MAE 采用绝对值计算预测误差,它的定义为: M A E = u , i T r u i r ^ u i T MAE=\frac{\sum_{u,i\in T}\lvert r_{ui}-\hat r_{ui}\rvert}{\lvert T \rvert}
      • 假设我们用一个列表 records 存放用户评分数据,令 records[i] = [u, i, rui, pui],其
        中 rui 是用户 u 对物品i的实际评分, pui 是算法预测出来的用户 u 对物品 i 的评分,那么下面的代码分别实现了 RMSE 和 MAE 的计算过程。

        def RMSE(records):
            return math.sqrt(sum([(rui - pui) * (rui - pui) for 
                            u, i, rui, pui in records]) / float(len(records)))
        
        def MAE(records):
            return sum([abs(rui - pui) for u, i, rui, pui in records] / float(len(records)))
        
      • 关于RMSE和MAE这两个指标的优缺点,Netflix 认为 RMSE 加大了对预测不准的用户物品评分的惩罚(平方项的惩罚),因而对系统的评测更加苛刻。如果评分系统是基于整数建立的(即用户给的评分都是整数),那么对预测结果取整会降低MAE的误差。

    • TopN 推荐

      • 网站在提供推荐服务时,一般是给用户一个个性化的推荐列表,这种推荐叫做TopN 推荐。
      • TopN 推荐的预测准确率一般通过准确率(precision) / 召回率(recall)度量。
        • R ( u ) R(u) 是根据用户在训练集上的行为给用户作出的推荐列表,而 T ( u ) T(u) 是用户在测试集上的行为列表。那么,推荐结果的召回率定义为: R e c a l l = u U R ( u ) T ( u ) u U T ( u ) Recall=\frac{\sum_{u\in U}|R(u)\bigcap T(u)|}{\sum_{u\in U}|T(u)|}
        • 推荐结果的准确率定义为: P r e c i s i o n = u U R ( u ) T ( u ) u U R ( u ) Precision=\frac{\sum_{u\in U}|R(u)\bigcap T(u)|}{\sum_{u\in U}|R(u)|}
      • 下面的 Python 代码同时计算出了一个推荐算法的准确率和召回率:
        def PrecisionRecall(test, N):
            hit = 0		// hit指的是R和T的交集的长度,初始值为0
            n_recall = 0
            n_precision = 0
            for user, items in test.items():
                rank = Recommend(user, N)
                hit += len(rank & items)
                n_recall += len(items)		// recall的分母是用户列表的长度
                n_precision += N		// precision的分母是推荐列表的长度N
            return [hit / (1.0 * n_recall), hit / (1.0 * n_precision)]
        
      • 有的时候,为了全面评测 TopN 推荐的准确率和召回率,一般会选取不同的推荐列表长度 N,计算出一组准确率/召回率,然后画出准确率/召回率曲线(precision / recall curve)。
  • 覆盖率

    • 覆盖率(coverage)描述一个推荐系统对物品长尾的发掘能力。

    • 覆盖率有不同的定义方法,最简单的定义为推荐系统能够推荐出来的物品占总物品集合的比例。

    • 假设系统的用户集合为 U U ,推荐系统给每个用户推荐一个长度为 N N 的物品列表 R ( u ) R(u) 。那么推荐系统的覆盖率可以通过下面的公式计算: C o v e r a g e = U u U R ( u ) I Coverage=\frac{|U_{u\in U}R(u)|}{|I|}

    • 覆盖率是一个内容提供商会关心的指标。覆盖率为100%的推荐系统可以将每个物品都推荐给至少一个用户。

    • 热门排行榜的推荐覆盖率是很低的,它只会推荐那些热门的物品,这些物品在总物品中占的比例很小。一个好的推荐系统不仅需要有比较高的用户满意度,也要有较高的覆盖率。

    • 覆盖率为100%的系统可以有无数的物品流行度分布。

      • 为了更细致地描述推荐系统发掘长尾的能力,需要统计推荐列表中不同物品出现次数的分布。
      • 如果所有的物品都出现在推荐列表中,且出现的次数差不多,那么推荐系统发掘长尾的能力就很好。因此,可以通过研究物品在推荐列表中出现次数的分布描述推荐系统挖掘长尾的能力。如果这个分布比较平,那么说明推荐系统的覆盖率较高,而如果这个分布较陡峭,说明推荐系统的覆盖率较低。
    • 在信息论和经济学中有两个著名的指标可以用来定义覆盖率。

      • 第一个是信息熵:这里 p ( i ) p(i) 是物品 i i 的流行度除以所有物品流行度之和。 H = i = 1 n p ( i ) log p ( i ) H=-\sum_{i=1}^np(i)\log p(i)
      • 第二个指标是基尼系数(Gini Index):这里 i j i_j 是按照物品流行度 p ( i ) p(i) 从小到大排序的物品列表中第 j j 个物品。 G = 1 n 1 j = 1 n ( 2 j n 1 ) p ( i j ) G=\frac{1}{n-1}\sum_{j=1}^n(2j-n-1)p(i_j)
    • 下面的代码可以用来计算给定物品流行度分布后的基尼系数:

      def GiniIndex(p):
          j = 1
          n = len(p)
          G = 0
          for item, weight in sorted(p.items(), key=itemgetter(1)):
              G += (2 * j - n - 1) * weight
          return G / float(n - 1)
      
    • 基尼系数的计算原理
      在这里插入图片描述

      • 首先,我们将物品按照热门程度从低到高排列,那么图中的黑色曲线表示最不热门的 x % x\% 物品的总流行度占系统的比例 y % y\%
      • 这条曲线肯定是在 y = x y=x 曲线之下的,而且和 y = x y=x 曲线相交在 ( 0 , 0 ) (0, 0) ( 1 , 1 ) (1, 1)
      • S A S_A A A 的面积, S B S_B B B 的面积,那么基尼系数的形象定义就是 S A / ( S A + S B ) S_A / (S_A + S_B) ,从定义可知,基尼系数属于区间 [ 0 , 1 ] [0, 1]
      • 如果系统的流行度很平均,那么 S A S_A 就会很小,从而基尼系数很小。
      • 如果系统物品流行度分配很不均匀,那么 S A S_A 就会很大,从而基尼系数也会很大。
    • 社会学领域有一个著名的马太效应,即所谓强者更强,弱者更弱的效应。

      • 如果一个系统会增大热门物品和非热门物品的流行度差距,让热门的物品更加热门,不热门的物品更加不热门,那么这个系统就有马太效应。现在主流的推荐算法(比如协同过滤算法)是具有马太效应的。
      • 推荐系统的初衷是希望消除马太效应,使得各种物品都能被展示给对它们感兴趣的某一类人群。
      • 评测推荐系统是否具有马太效应的简单办法就是使用基尼系数。如果 G 1 G1 是从初始用户行为中计算出的物品流行度的基尼系数, G 2 G2 是从推荐列表中计算出的物品流行度的基尼系数,那么如果 G 2 > G 1 G2 > G1 ,就说明推荐算法具有马太效应。
  • 多样性

    • 为了满足用户广泛的兴趣,推荐列表需要能够覆盖用户不同的兴趣领域,即推荐结果需要具有多样性。
    • 尽管用户的兴趣在较长的时间跨度中是一样的,但具体到用户访问推荐系统的某一刻,其兴趣往往是单一的,那么如果推荐列表只能覆盖用户的一个兴趣点,而这个兴趣点不是用户这个时刻的兴趣点,推荐列表就不会让用户满意。
    • 如果推荐列表比较多样,覆盖了用户绝大多数的兴趣点,那么就会增加用户找到感兴趣物品的概率。因此给用户的推荐列表也需要满足用户广泛的兴趣,即具有多样性。
    • 多样性描述了推荐列表中物品两两之间的不相似性。因此,多样性和相似性是对应的。
    • 假设 s ( i , j ) s(i, j) \in [ 0 , 1 ] [0,1] 定义了物品 i i j j 之间的相似度,那么用户 u u 的推荐列表 R ( u ) R(u) 的多样性定义如下: D i v e r s i t y = 1 i , j R ( u ) , i ̸ = j s ( i , j ) 1 2 R ( u ) ( R ( u ) 1 ) Diversity=1-\frac{\sum_{i, j\in R(u), i \not= j}s(i, j)}{\frac{1}{2}|R(u)|(|R(u)|-1)}
    • 推荐系统的整体多样性可以定义为所有用户推荐列表多样性的平均值: D i v e r s i t y = 1 U u U D i v e r s i t y ( R ( u ) ) Diversity=\frac{1}{|U|}\sum_{u\in U}Diversity(R(u))
    • 不同的物品相似度度量函数 s ( i , j ) s(i, j) 可以定义不同的多样性。如果用内容相似度描述物品间的相似度,我们就可以得到内容多样性函数,如果用协同过滤的相似度函数描述物品间的相似度,就可以得到协同过滤的多样性函数。
  • 新颖性

    • 新颖的推荐是指给用户推荐那些他们以前没有听说过的物品。
    • 在一个网站中实现新颖性的最简单办法是,把那些用户之前在网站中对其有过行为的物品从推荐列表中过滤掉。
    • 评测新颖度的最简单方法是利用推荐结果的平均流行度,因为越不热门的物品越可能让用户觉得新颖。
    • 如果推荐结果中物品的平均热门程度较低,那么推荐结果就可能有比较高的新颖性。但是,用推荐结果的平均流行度度量新颖性比较粗略,因为不同用户不知道的东西是不同的。因此,要准确地统计新颖性需要做用户调查。
    • 通过牺牲精度来提高多样性和新颖性是很容易的,而困难的是如何在不牺牲精度的情况下提高多样性和新颖性。
  • 惊喜度

    • 惊喜度(serendipity)是最近这几年推荐系统领域最热门的话题。
    • 如果推荐结果和用户的历史兴趣不相似,但却让用户觉得满意,那么就可以说推荐结果的惊喜度很高,而推荐的新颖性仅仅取决于用户是否听说过这个推荐结果。
    • 定义惊喜度需要首先定义推荐结果和用户历史上喜欢的物品的相似度,其次需要定义用户对推荐结果的满意度。
    • 用户满意度只能通过问卷调查或者在线实验获得,而推荐结果和用户历史上喜欢的物品相似度一般可以用内容相似度定义。
    • 提高推荐惊喜度需要提高推荐结果的用户满意度,同时降低推荐结果和用户历史兴趣的相似度。
  • 信任度

    • 对于基于机器学习的自动推荐系统,同样存在信任度(trust)的问题,如果用户信任推荐系统,那就会增加用户和推荐系统的交互。
    • 特别是在电子商务推荐系统中,让用户对推荐结果产生信任是非常重要的。同样的推荐结果,以让用户信任的方式推荐给用户就更能让用户产生购买欲,而以类似广告形式的方法推荐给用户就可能很难让用户产生购买的意愿。
    • 度量推荐系统的信任度只能通过问卷调查的方式,询问用户是否信任推荐系统的推荐结果。
    • 提高推荐系统的信任度主要有两种方法。
      • 首先需要增加推荐系统的透明度(transparency),而增加推荐系统透明度的主要办法是提供推荐解释。
        • 只有让用户了解推荐系统的运行机制,让用户认同推荐系统的运行机制,才会提高用户对推荐系统的信任度。
      • 其次是考虑用户的社交网络信息,利用用户的好友信息给用户做推荐,并且用好友进行推荐解释。
        • 这是因为用户对他们的好友一般都比较信任,因此如果推荐的商品是好友购买过的,那么他们对推荐结果就会相对比较信任。
  • 实时性

    • 在很多网站中,因为物品(新闻、微博等)具有很强的时效性,所以需要在物品还具有时效性时就将它们推荐给用户。
    • 推荐系统的实时性包括两个方面。
      • 首先,推荐系统需要实时地更新推荐列表来满足用户新的行为变化。
        • 很多推荐系统都会在离线状态每天计算一次用户推荐列表,然后于在线期间将推荐列表展示给用户。这种设计显然是无法满足实时性的。
        • 与用户行为相应的实时性,可以通过推荐列表的变化速率来评测。如果推荐列表在用户有行为后变化不大,或者没有变化,说明推荐系统的实时性不高。
      • 实时性的第二个方面是推荐系统需要能够将新加入系统的物品推荐给用户。
        • 这主要考验了推荐系统处理物品冷启动的能力。
        • 对于新物品推荐能力,我们可以利用用户推荐列表中有多大比例的物品是当天新加的来评测。
  • 健壮性

    • 任何一个能带来利益的算法系统都会被人攻击,这方面最典型的例子就是搜索引擎。搜索引擎的作弊和反作弊斗争异常激烈,这是因为如果能让自己的商品成为热门搜索词的第一个搜索果,会带来极大的商业利益。
    • 推荐系统目前也遇到了同样的作弊问题,健壮性(即 robust,鲁棒性)指标衡量了一个推荐系统抗击作弊的能力
    • 算法健壮性的评测主要利用模拟攻击。
      • 首先,给定一个数据集和一个算法,可以用这个算法给这个数据集中的用户生成推荐列表。
      • 然后,用常用的攻击方法向数据集中注入噪声数据,然后利用算法在注入噪声后的数据集上再次给用户生成推荐列表。
      • 最后,通过比较攻击前后推荐列表的相似度评测算法的健壮性。
      • 如果攻击后的推荐列表相对于攻击前没有发生大的变化,就说明算法比较健壮。
    • 在实际系统中,提高系统的健壮性,除了选择健壮性高的算法,还有以下方法。
      • 设计推荐系统时尽量使用代价比较高的用户行为。
        • 比如,如果有用户购买行为和用户浏览行为,那么主要应该使用用户购买行为,因为购买需要付费,所以攻击购买行为的代价远远大于攻击浏览行为。
      • 在使用数据前,进行攻击检测,从而对数据进行清理。
  • 商业目标

    • 很多时候,网站评测推荐系统更加注重网站的商业目标是否达成,而商业目标和网站的盈利模式是息息相关的。
    • 一般来说,最本质的商业目标就是平均一个用户给公司带来的盈利。不过这种指标不是很难计算,只是计算一次需要比较大的代价。因此,很多公司会根据自己的盈利模式
      设计不同的商业目标。
    • 不同的网站具有不同的商业目标。因此,设计推荐系统时需要考虑最终的商业目标,而网站使用推荐系统的目的除了满足用户发现内容的需求,也需要利用推荐系统加快实现商业上的指标。

评测维度

  • 比如一个推荐算法,虽然整体性能不好,但可能在某种情况下性能比较好,而增加评测维度的目的就是知道一个算法在什么情况下性能最好,这样可以为融合不同推荐算法取得最好的整体性能带来参考。
  • 一般来说,评测维度分为如下三种:
    • 用户维度
      • 主要包括用户的人口统计学信息、活跃度以及是不是新用户等。
    • 物品维度
      • 包括物品的属性信息、流行度、平均分以及是不是新加入的物品等。
    • 时间维度
      • 包括季节,是工作日还是周末,是白天还是晚上等。
  • 如果能够在推荐系统评测报告中包含不同维度下的系统评测指标,就能帮我们全面地了解推荐系统性能,找到一个看上去比较弱的算法的优势,发现一个看上去比较强的算法的缺点。

猜你喜欢

转载自blog.csdn.net/faker1895/article/details/86680913