在推荐算法中,计算相似性或距离度量是最常见的事情,也有非常多的相似性计算公式,比如基于集合的方法(谷本系数、J accard相似性系数),基于几何的方法(余弦相似性公式)等。
这里介绍下来自信息检索领域的方法 TF-IDF、BM25模型用于计算相似性。
参考文章 Distance Metrics for Fun and Profit
假设我们有用户收听过音乐家音乐的数据,我们想要计算与某位音乐家相似的Top-N音乐家,用于音乐推荐或其他。
一、TF-IDF模型用于计算相似性
使用TF-IDF模型计算相似性,这里我们需要把音乐家当成原模型中的Document文档,把每个收听音乐家音乐的用户当作原模型中的term单词。
第一步,统计TF,即用户收听音乐家音乐次数(单词在文章中出现频次数据)数据使用收听次数的平方根 代替。(传统的做法是log项,主要是为了处理长尾现象。)
第二步,IDF 计算逆文档频次。这一步是为了区分对待对收听音乐有选择的人 和那些没有选择的人,把用户的整体活动倾向考虑进来。IDF通过乘以一个用户听一个艺术家的反概率的对数来实现这一点。
# calculate IDF for each user
N = len(artists)
idf = [1. + log(N / (1. + p)) for p in data.groupby('userid').size()]
第三步,TF-IDF距离计算。上面我们有了TF,并且计算出来了IDF,那么TF-IDF距离的计算公式就是权重向量的余弦公式:
# weights a sparse vector by tfidf
def tfidf_weight(artist, idf):
ret = csr_matrix(artist)
ret.data = array([(sqrt(plays) * idf[userid]
for plays, userid in zip(artist.data, artist.indices)])
return ret
# tfidf distance is just the cosine between tfidf weighted vectors
def tfidf(a, b, idf):
return cosine(tfidf_weight(a, idf), tfidf_weight(b, idf))
TF-IDF方法在计算这类问题时Maybe是最明智的初始尝试方案,它忽略了余弦的噪声,仍能返回比Jaccard距离更好的结果。当然信息检索领域中也有模型可能它的效果更好。
BM25通常比TF-IDF产生更好的效果。
二、BM25模型用于计算相似性
第一步,BM25没有使用平方根这样的TF函数,而是使用了一个可以根据参数K1进行调整的加权函数:
def bm25_tf_weight(plays):
return plays * (K1 + 1.0) / (K1 + plays)
第二步,BM25的另一个主要变化是如何处理长度标准化。播放次数按文档大小与平均大小的比率缩放。但是,由于有时更喜欢较长的文档(或者更受欢迎的艺术家),BM25还引入了一个参数B,它控制长度规格化对结果的影响程度。放在一起就是:
def bm25(a, b, idf, average_plays):
return dot(bm25_weight(a, idf, average_plays),
bm25_weight(b, idf, average_plays).T)[0, 0]
def bm25_weight(artist, idf, average_plays):
ret = csr_matrix(artist)
length_norm = (1.0 - B) + B * artist.sum() / average_plays
ret.data = array([(plays * (K1 + 1.0) / (K1 * length_norm + plays)) * idf[userid]
for plays, userid in zip(artist.data, artist.indices)])
return ret
文本搜索中通常使用的K1值约为1.2,这对于文本查询来说是有意义的,因为匹配包含查询中所有术语的文档比匹配重复的术语更为重要。对于音乐数据,将K1设为100,似乎能产生不错的结果。在这里将B设置为0.5,引入了对流行艺术家的一点偏见。
三、比较不同算法在相似性度量上的效果
这里作者用了可视化的方式呈现,方便直观感受,并不是严谨的评估、AB测试。
这里展示下 Smoothed Cosine相似性 Vs BM25 【左图】, 以及 TF-IDF Vs BM25【右图】
(正如作者的个人经验偏好, Smoothed Cosine 和 BM25 效果更好些)
附:
BM25模型用于计算相似性时,通过调整参数K1值,可以得到介于Jaccard与Cosine距离之间的距离。
下图显示了改变K1值时,BM25算法得到的相似性距离与 Jaccard、Cosine、TF-IDF相似性距离的比较。
各图依次截取 K1 =0 , K1=0.1 , K1 =1, K1=10, K1=100, K1=1000 六种情况:
【注:图中唯一改变的函数是BM25,作者以和K1值相同的速率改变比例,所以看起来其他函数都在改变。这清楚地显示了这个函数中(K1+1)处的渐近线,并且K1主要改变这个函数的比例,而不是K1较高值的形状】