0– 前言:
对于个性化推荐来说,最核心、重要的算法是相关性度量算法。相关性从网站对象来分,可以针对商品、用户、旺铺、资讯、类目等等,从计算方式看可以分为文本相关性计算和行为相关性计算,具体的实现方法有很多种,最常用的方法有余弦夹角(Cosine)方法、杰卡德(Jaccard)方法等。Google对新闻的相似性计算采用的是余弦夹角,CBU的个性化推荐以往也主要采用此方法。从9月份开始,CBU个性化推荐团队实现了杰卡德计算方法计算文本相关性和行为相关性,并且分别在线上做了算法效果测试。本文基于测试结果,进行了对比及一些分析比较。
1、行为相关性的度量比较
通过前段时间在CBU1688.COM网站上的多个场景的线上测试,我们发现:在CTR指标上,针对行为相关性计算的Jaccard的推荐精准度比Cosine方法要高的多。
将两种方法的算法结果,直接放到线上应用的三个应用场景,通过跟踪不同算法结果的实际的CTR(曝光点击率),详细数据如下:
场景 | 推荐策略 | CTR(Jaccard VS Cosine) |
收藏offer成功后的提示页面 | 相关商品的推荐普通商品 | 提升21% |
进货单页面的相关商品推荐 | 相关商品推荐普通商品 | 提升9% |
阿里巴巴每日焦点–热卖tab | 猜你喜欢推荐P4P商品 | 提升12% |
简要分析:
(1) 如果是完全以相关性推荐为主题的页面,比如“收藏offer成功后的提示页面”,Jaccard方法对应的CTR提升最大;
(2) 提升达到9%的进货单页面,该页面的核心价值是促进加入进货单的商品进入交易付款环节,并不是推荐,因此在推荐场景布置上有很大局限;
(3) 提升达到12%的阿里巴巴每日焦点–热卖,虽然整个页面的主题就是推荐,但是毕竟推荐的是P4P商品,因为P4P商品覆盖率不是很高,行为相关性粘稠度肯定不如普通商品,所以覆盖率也没有达到20%。
2、文本相关性的度量比较(cosine好一点点,但是Jaccard利于map/red计算)
同样,在文本相关性计算中,分别使用Cosine和Jaccard,再将算法结果在线上做测试。线上场景是1688的资讯画报推荐。数据显示,两者的CTR基本一致。
不过,
Jaccard
方法在
hadoop
上的分布式计算,其计算效率上比
Cosine
有一定的优势。
3, 文本相似度的那些算法(转载)
子序列与子字符串
这个系列问题包含这么几种:最大子序列、最长递增子序列、最长公共子串、最长公共子序列。
几个子问题都可以用动态规划的思路来求解。对于长度为i、j的两个字符串 ,使用m[i][j]矩阵来存放中间结果。
更详细的算法可以看这篇文档:
http://www.cnblogs.com/zhangchaoyang/articles/2012070.html
字符串编辑距离
精确计算两个字符串的编辑距离,可以使用经典的动态规划思路。
这里来看下如何判断字符串A与B的编辑是否>N?这样我们就可以比较两个字符串的相似度了。
可以构建一个编辑距离自动机(超酷算法:Levenshtein自动机),把测试字符集合输入自动机进行判断。
可用于拼写检查,模糊匹配等场景。
向量相似度
使用TF-IDF计算出文本中词的词频集合,把该集合作一个向量,比较不同集合向量在线性空间中的相似度。如:余弦距离、欧氏距离、概率分布距离(K-L距离)等。
更详细的介绍看这篇文档:
http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html
SimHash
simhash算法的主要思想是降维,将高维的特征向量映射成一个f-bit的指纹(fingerprint),通过比较两篇文章的f-bit指纹的Hamming Distance来确定文章是否重复或者高度近似。
主要分以下几步:
1、抽取文本中的关键词及其权重。
2、对关键词取传统hash,并与权重叠加,算出文本的fingerprint值。
3、计算出两个文本之间fingerprint值的海明距离。
更详细的介绍可以看这篇文档:
http://blog.csdn.net/heiyeshuwu/article/details/44117473
总之,对于行为相关性的度量,Jaccard一般效果更好;而对于文本相关性的度量,Cosine效果略好于Jaccard;但是,但是Jaccard利于map/red计算
补充:Jaccard相似度和广义Jaccard相似度
1. 狭义Jaccard相似度,计算两个集合之间的相似程度,元素的“取值”为0或1
对集合A和B,Jaccard相似度计算如下:
Jaccard(A, B)= |A intersectB| / |A union B|
相似度数值在[0, 1]之间,当A==B的时候,为1. 优缺点,就是元素的取值只能是0或者1,无法利用更丰富的信息
由相似度,可以转换成Jaccard距离:
Jaccard distance (A, B) = 1- Jaccard(A, B)
2. 广义Jaccard相似度,元素的取值可以是实数。又称为Tanimoto系数,用EJ来表示,计算方式如下:
EJ(A,B)=(A*B)/(||A||^2+||B||^2-A*B)
其中A、B分别表示为两个向量,集合中每个元素表示为向量中的一个维度,在每个维度上,取值通常是[0, 1]之间的值,A*B表示向量乘积,||A||^2表示向量的模,即 ||A||^2 = sqrt (a1^2 + a2^2 + a3^2 +……)。
广义Jaccard相似度计算公式中,如果把分母的A*B去掉,并将||A||^2+||B||^2替换为(||A||^2)*(||B||^2),就转成了余弦相似度(cosine similarity)。
EJ中每个分量的取值可以是实数,通常在[0, 1]之间。对于两篇文档,分词之后,形成两个“词语—词频向量”,词语可以做为EJ的维度,如何将词频转换为实数值。借鉴tf/idf的思路。对于每个词语,有两个频度:1.在当前文档中的频度;2. 在所有文档中的频度。其中1相当于tf,与权重正相关;2相当于df,与权重反相关。
对于2,计算权重为
idf (w) = log (TotalWC/C(w))
C(w)是词语w在所有文档中出现的次数,TotalWC是所有文档中所有词的总词频。
对于1,权重就可以取词频本身 tf(w) = D(w),D(w)表示在当前文档中w出现的次数
具体计算的代码可以参考 “http://www.cnblogs.com/TtTiCk/archive/2007/08/04/842819.html”的Documents.cs中的“SimilitudeValueToDocumentUsingGeneralizedJaccardCoefficient”函数。
3. 其他扩展方法
文章“http://www.docin.com/p-461291267.html”给出了一种扩展方法,用最大最小值函数来代替乘积和模计算,如下:
EJ(A,B) = sum ( min(a1, b1) + min (a2, b2)… ) / sum ( max(a1, b1) +max (a2, b2).. )
即用向量中每个分量的的最小值和最大值来参与计算。
个人理解,这个可以做如下解释。当集合A中的元素a1出现C(a1)次的时候,我们可以认为集合中的元素是允许重复存在的,即集合A中有C(a1)个元素;集合B也是这样,有C(b1)个相同的元素,则A和B在这个元素上的交集就是min(a1, b1) ,并集就是max(a1,b1) ,这样上述公式就是利用狭义Jaccard相似度计算的结果。