全部产品
阿里云办公

基于ItemCF的协同过滤

更新时间:2017-10-09 14:45:54

输入数据

数据 是否必选 描述
ITEM_META 必选 物品表
USER_BEHAVIOR 必选 离线用户行为表
REC_ITEM_INFO 必选 可推荐物品表
REALTIME_LOG 可选 用户实时行为日志(仅限开启”使用日志数据”时生效)

输出数据

数据 数据类型 描述
OFFLINE_USER_ITEM_REC REC_SET 用户对物品的推荐候选集(离线产出)。基于离线用户历史存量行为(一般是过去N天,N在算法参数里可以配置)产出的“综合”推荐结果,即在“全局的推荐池”里基于用户对物品的预测打分进行Top召回,这里建模的是用户的“中长期兴趣”。
NEARLINE_USER_ITEM_REC REC_SET 根据用户实时行为产生的用户对物品的推荐候选集(近线/实时产出)。当您的业务系统通过推荐引擎“日志API”上报了用户实时行为后,本算法策略会“准实时”(秒级latency)地自动分析用户最新行为,并生成一份与用户最新有过行为的物品相关的、并且用户可能感兴趣的推荐列表,这里建模的是用户的“瞬时/短期兴趣”。
OFFLINE_MULTICLASS_USER_ITEM_REC REC_SET 不同分类下的用户对物品推荐候选集(离线产出)。用于带限制条件下的用户推荐(如在指定类目、关键词下对用户进行推荐),不同于上面第一条推荐结果,这个推荐是在一个“按指定条件筛选后的、缩小的推荐池”里进行推荐召回。
OFFLINE_ITEM_ITEM_REC REC_SET 基于物品行为相似度产生的相似物品列表(离线产出)。可以实现在物品详情页的关联推荐(如”看过该物品的用户还看了“),同时这个结果还会作为基础数据应用于上面第二条的用户实时推荐(用于发现和用户实时行为对象相似的其他物品)。
OFFLINE_MULTICLASS_ITEM_ITEM_REC REC_SET 不同分类下的物品对物品推荐候选集(离线产出)。用于带限制条件的物品关联推荐(如指定类目、关键词等),一般情况下不用,可以实现一些简单的“跨分类搭配购买”策略,如通过事先的数据分析发现母婴类目和酒水类目是一个频繁项集,则可以在用户购买了尿布之后为他推荐啤酒。
NEARLINE_MULTICLASS_USER_ITEM_REC REC_SET 【1.0.11版本后支持】不同分类下的用户对物品推荐候选集(近线产出)。根据用户实时有过行为的物品,扩展出与这些物品在分类条件下相似的其他物品,并推荐给用户。

参数

参数名 默认值 描述
用户行为时间跨度 30 基于过去最近N天的行为数据来建模用户偏好。假设当前数据日期为20170830,设置本参数为30,直观上来看,这个参数:
1、决定了算法在运行时需要读取用户行为表(通过MaxCompute表提供或日志API上传)从当前数据日期向前多少个分区的数据,比如您配置了用户行为表为A,则会读取A表从ds=20170801到ds=20170830共30个分区的数据来进行计算。
2、决定了用户兴趣的时间窗口大小,即只有在这个窗口内的用户行为才被认为能够反映用户喜好,假设某用户的最近一次行为发生在30天之前的20170731,则该用户会被认为没有发生过任何历史行为,因此无法获得个性化推荐结果,需要用一些全局默认结果来进行抄底补足。
行为权重 view:1.0;click:0.8 用于计算用户偏好的有效行为及权重。
1、每一种行为类型匹配的是用户行为表的bhv_type字段,因此本参数需要根据您根据实际行为数据中的真实情况进行配置,否则可能导致运行出错或结果为空。
2、不同的行为类型对反映用户喜好的程度不尽相同,如购买、点赞行为相比浏览要更珍贵,因此也理应获得更高的权重,这里需要根据实际业务情况和业务经验进行配置。
3、行为权重与最终推荐效果的关系:由于行为权重会参与到用户兴趣的建模评分计算中,因此如果用户对物品集合A发生过权重较高的行为,算法会对与A中物品相似的其他物品集合A’赋予更高的推荐权重,从而更倾向于推荐A’中的物品,因此在这里我们可以有针对性地将业务中期待用户发生的目标行为(如购买)设置更高的权重,以获得更好的推荐效果。
推荐结果数 100 最多生成多少个推荐结果,本参数会作用在上文提到的“输出数据”的五类推荐结果集上。【注:关于推荐结果数最大可以设置多少,由于不同业务中的item_id长度各异,因此没有一个固定的值,总体原则是:最终拼接生成的推荐字符串大小不超过1兆。其中推荐字符串的格式为i1\u0003s1…\u0002…in\u0003sn,i1~in为实际item_id,s1~sn为权重(一般保留小数点后4位),\u0002和\u0003为Unicode的2和3。】
相似度计算方法 Cosin 在ItemCF算法中,每个物品会基于对它有过行为的用户表示为特征向量,向量每一维是一个<user_id, score>元组,score表示对应user_id的权重,本参数决定了使用何种函数计算物品向量之间的相似度,可选取值包括:
- Cosin:向量余弦夹角
- BiNetwork:基于二分图的节点亲密度计算方法(不常用)
- ModifiedCosin:调整向量余弦夹角(或修正余弦相似度),与Cosine的区别可以自行搜索了解
- PearsonRelation:皮尔逊相关系数
- Jaccard:Jaccard相似系数
UV阈值 0 生成的推荐候选集需要满足的UV约束条件(描述的是共有多少个不同的用户对物品发生过行为),即只有UV大于设置值的物品才会被放入推荐候选集,避免推荐出过于冷门的物品。【注:只要某用户对一个物品发生过“行为权重”参数中设置的任意一种行为,不论发生都少次,该用户对该物品都只有一次UV贡献】
过滤用户历史行为 false 产生推荐候选集时,是否针对每个用户过滤他曾经有过历史行为的物品,设置为true可以实现类似“看过不再推荐”的逻辑。【注:只要用户对某物品发生过“行为权重”参数中设置的任意一种行为,就认为用户对该物品对有过历史行为】
多分类推荐 false 默认关闭多分类推荐特性,开启的情况下请参考下文的“<多分类推荐>子模板参数”说明。
<多分类推荐>子模板参数

1、物品类别数据来源

参数取值 描述
ITEM_META 类别来源为物品表ITEM_META.category字段,可实现针对指定类目的推荐,在线请求时传入category参数可获取仅属于该category下的推荐结果。【注:由于物品表的category字段只能取单一值,若实际应用中物品可以属于多个类目,请参考下面REC_ITEM_INFO的使用方法】
REC_ITEM_INFO 类别来源为REC_ITEM_INFO.class字段,可实现针对指定单分类/组合分类的推荐,要求class字段的多个取值之间用\002分隔,如concat(‘体育’,’\002’,’时事’)表示物品属于“体育”和“时事”两个分类。在线请求时传入class参数(多个取值之间用逗号分隔,请注意做UrlEncode,如’class=体育,时事’encode后为’class=%E4%BD%93%E8%82%B2,%E6%97%B6%E4%BA%8B’)可获取指定分类条件下的推荐结果。
REC_ITEM_INFO+ITEM_META 综合前两个选项。

2、多分类组合

仅限“物品类别数据来源”包含REC_ITEM_INFO时生效,即“REC_ITEM_INFO”或“REC_ITEM_INFO+ITEM_META”。

参数取值 描述
false 关闭此特性,可以实现单一分类条件下的推荐,如“体育”分类下的推荐。
true 开启此特性,系统会对REC_ITEM_INFO.class中定义的多个属性进行自由组合(最多支持4维属性组合),可实现多分类组合下的推荐,如在同时限定”体育“和“时事”分类下的推荐。【注:N维属性的自由组合可以生成2^N-1种组合方式,例如有A,B,C三个属性,自由组合后会生成A,B,C,AB,AC,BC,ABC共7个组合(组合内有序)】

主要算法逻辑

ItemCF算法的基本原理用户可自行在网上搜索了解,这里不做展开介绍。

  1. 离线模块

    step1:评分矩阵建模

    ​ 基于设置的<用户行为时间跨度>、<行为权重>参数,综合考虑用户的兴趣分布和随时间的衰减因素,对用户有过历史行为的物品进行建模评分,生成<user_id, item_id, score>三元组(注意这里的三元组只是针对用户历史上发生过行为的物品,与后面即将生成的推荐(如其他的、用户没有过行为的)物品并不相同)。在这一步中,可以顺便得到每一个物品总共被多少不同用户有过行为(即UV值),可以结合<UV阈值>参数在后续步骤中进行过滤。

    step2:物品相似度计算

    ​ 对step1建模得到的评分矩阵,使用ItemCF算法计算有过“共现”的物品之间的相似度得分(基于配置的<相似度计算方法>参数)。这里两个物品A和B的“共现”指的是它们同时被“一个及以上”的用户看过,基于ItemCF算法的基本假设,同一个用户看过的多个物品之间是具有一定相似性的,那么便可以评估A和B的相似程度,同时在越多不同用户的行为中观测到A和B的共现,我们认为A和B的相似可信度越高。也正是因为使用了大量不同的用户行为来做协同计算,所以基于行为分析的CF类算法才被称为协同过滤(Collaborative Filtering)、集体智慧(Collective Intelligence)。所以如果您只是简单地使用一些手动生成的假数据来做测试,很有可能因为不满足上面的基本假设(比如所有用户都只看过一个物品),而导致最终产出结果为空。

    ​ 此外,系统在实现过程中做了一些默认的数据调优(后续会陆续开放出来供用户自行配置),如下:

    1. 如果一个用户看过的物品数小于minRelatedItem(默认为2)时,该用户行为对物品相似度的贡献会被过滤忽略,因为这可能只是一个随机噪声,默认为2表示不过滤(因为一个用户至少看过一个物品才有可能进入计算流程)。

    2. 如一个用户的行为涉及的物品数N大于maxRelatedItem(默认为10000)时,该用户行为对物品相似度的贡献也会被忽略。一方面,这是基于计算复杂度考虑所做的优化,按照ItemCF的假设,算法运行过程中会对每个用户涉及到的所有物品两两计算相似度,产生N*(N-1)/2个组合,这个计算量(复杂度O(N^2))在N很大时是相当高的;另一方面,当一个用户看过太多(不合理的多)的物品时,很有可能是类爬虫行为,极端情况下,这个用户看过所有物品,那么会直接导致所有物品两两之间都“相似”。

    3. 如一个物品被看过的用户数小于minRelatedUser(默认为2)时,会过滤该物品的行为,即不会计算该物品与其他物品的相似度,默认为2表示不过滤。

    4. 如一个物品被看过的用户数大于maxRelatedUser(默认为10000000)时,为避免“哈利波特”效应(可自行搜索进行了解),该物品不会被用于计算和其他物品的相似度,因为它实在是太热门了,几乎所有看过其他物品的用户都看过它,ItemCF的假设会使得它和所有物品都很“相似”,最直接的结果是可能导致所有关联推荐和用户推荐结果里排名第一位都是它,这显然并不是我们想要的。

    5. 由于CF类算法都是基于行为支撑的,因此物品的“共现”频率实际上扮演了一个类似于可信度的角色。举例来说,假设两个物品A和B有且仅有被唯一一个用户看过,那么基于很多相似度策略他们的相似度s(A,B)会等于1,这显然是不合理的,因此算法会针对这种情况自动进行Shrink Down,用s‘(A,B)=s(A,B)*n/(n+lambda)来代替s(A,B)作为最终的相似度值,其中n为A和B的共现次数(也即有多少个不同的用户同时看过A和B),lambda为shrink因子(默认为100)。考虑一下,由于加入了lambda,共现次数少的物品的相似度会削减得比较厉害,而对共现次数多的物品相似度影响却很小,这样可信度、支持度得到了相应的体现。

    step3:推荐候选集生成

    ​ 对step1得到的用户原始建模评分和step2得到的物品相似度权重进行加权求和,扩展得到和用户历史看过的物品相似的其他物品。值得注意的是,尽管针对用户历史看过的每一个物品,这里扩展出来的是和这个物品相似的“其他”物品,但由于用户可能看过多个物品,最终进行相似度扩展后得到的结果中仍然可能包含用户之前看过的物品(比如用户看过A和B,A和B相似,则根据A会扩展出B,根据B会扩展出A),这一步骤中会根据配置的<过滤用户历史行为>参数决定是否进行进行过滤,最终最多保留参数<推荐结果数>指定的数目。

    step4:数据合并汇总

    ​ 将计算结果进行汇总,导入到在线存储。

  2. 近线/实时模块

    step1:接受实时日志,针对用户实时看过的物品进行和离线计算方法相同的建模评分。

    step2:针对实时日志中涉及的所有物品,从在线存储拉取离线已经计算好的物品对物品的相似度,与离线计算方法相同地进行相似物品扩展,得到用户短期/瞬时可能感兴趣的推荐结果。

    step3:将实时推荐结果更新到在线存储。

  3. 在线模块

    根据用户配置读取解析在线存储上的推荐结果。

最佳实践

1、在配置<行为权重>参数时,建议首先分析一下实际行为表中的bhv_type字段的取值,避免配置不当导致结果为空。

2、若确认输入数据无误的情况下,如果最终没有计算出物品与物品的相似度,可以尝试其他<相似度计算方法>参数取值进行试验。

3、推荐结果数的最大取值,上文在参数说明中已有描述,请结合自身业务数据情况进行推算。

4、建议配合一个默认推荐策略组合使用,避免出现没有推荐结果的情况。

5、视频专题讲解:点这里