基于标签的推荐系统
基于标签的推荐系统
参考书本: 项亮, 推荐系统实践. 2012
对于用户 u ,令 R(u) 为给用户 u 的长度为 N的推荐列表,里面包含我们认为用户会打标签的物品。令 T(u) 是测试集中用户 u 实际上打过标签的物品集合。然后,我们利用准确率( precision )和召回率( recall )评测个性化推荐算法的精度。
为了全面评测个性化推荐的性能,我们同时评测了推荐结果的覆盖率( coverage )、多样性( diversity )和新颖度。
对于每个物品 i , item_tags[i] 存储了物品 i 的标签向量,其中 item_tag[i][b] 是对物品 i 打标签 b 的次数,那么物品 i 和 j 的余弦相似度可以通过如下程序计算。
def CosineSim(itrm_tags,i,j):
ret=0;
for b,wib in item_tags[i].items():
if b in item_tags[j]:
ret+=wib*item_tags[j][b]
ni=0;
nj=0;
for b, w in item_tags[i].items():
ni += w * w
for b, w in item_tags[j].items():
nj += w * w
if ret == 0:
return 0
return ret / math.sqrt(ni * nj)#相同的标签上面乘加一下
体现多样性的公式
def Diversity(item_tags, recommend_items):
ret = 0
n = 0
for i in recommend_items.keys():
for j in recommend_items.keys():
if i == j:
continue
ret += CosineSim(item_tags, i, j)
n += 1
return ret / (n * 1.0)
一种比较简单的思路
这个算法的描述如下所示。
统计每个用户最常用的标签。
对于每个标签,统计被打过这个标签次数最多的物品。
对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品推荐给这个用户。
对于上面的算法,用户 u 对物品 i 的兴趣公式如下:
[简单来说,这个公式表明了用户与物品的标签重合度]
这里, B(u) 是用户 u 打过的标签集合, B(i) 是物品 i 被打过的标签集合, 是用户 u 打过标签 b的次数, 是物品 i 被打过标签 b 的次数。本章用 SimpleTagBased 标记这个算法。
在 Python 中,我们遵循如下约定:
用 records 存储标签数据的三元组,其中 records[i] = [user, item, tag] ;
用 user_tags 存储 ,其中 user_tags[u][b] = ;
用 tag_items 存储 ,其中 tag_items[b][i] = 。
如下程序可以从 records 中统计出 user_tags 和 tag_items :
def InitStat(records):
user_tags = dict()
tag_items = dict()
user_items = dict()
for user, item, tag in records.items():
addValueToMat(user_tags, user, tag, 1)
addValueToMat(tag_items, tag, item, 1)
addValueToMat(user_items, user, item, 1)
统计出 user_tags 和 tag_items 之后,我们可以通过如下程序对用户进行个性化推荐:
【这里细节还是很模糊】
def Recommend(user):
recommend_items = dict()
tagged_items = user_items[user]
for tag, wut in user_tags[user].items():
for item, wti in tag_items[tag].items():
#if items have been tagged, do not recommend them
if item in tagged_items:
continue
if item not in recommend_items:
recommend_items[item] = wut * wti
else:
recommend_items[item] += wut * wti
return recommend_items
改进
TF-IDF
前面这个公式倾向于给热门标签对应的热门物品很大的权重,因此会造成推荐热门的物品给用户,从而降低推荐结果的新颖性。另外,这个公式利用用户的标签向量对用户兴趣建模,其中每个标签都是用户使用过的标签,而标签的权重是用户使用该标签的次数。这种建模方法的缺点是给热门标签过大的权重,从而不能反应用户个性化的兴趣。这里我们可以借鉴 TF-IDF 的思想,对这一公式进行改进:
TagBasedTFIDF ,记录了标签b被多少用户使用过。
也可以对热门物品进行惩罚,得到公式;
和 TagBasedTFIDF 算法相比,除了多样性有所下降,其他指标都有明显提高。这一结果表明,适当惩罚热门标签和热门物品,在增进推荐结果个性化的同时并不会降低推荐结果的离线精度。
数据稀疏性
在前面的算法中,用户兴趣和物品的联系是通过 B(u)\cap B(i)中的标签建立的。但是,对于新用户或者新物品,这个集合 B(u)\cap B(i)中的标签数量会很少。为了提高推荐的准确率,我们可能要对标签集合做扩展,比如若用户曾经用过“推荐系统”这个标签,我们可以将这个标签的相似标签也加入到用户标签集合中,比如“个性化”、“协同过滤”等标签。
扩展标签可以使用话题模型,
标签扩展的本质是对每个标签找到和它相似的标签,也就是计算标签之间的相似度。最简单的相似度可以是同义词。如果有一个同义词词典,就可以根据这个词典进行标签扩展。如果没有这个词典,我们可以从数据中统计出标签的相似度。
利用相似度公式(这里可以看书)计算两个标签的相似度。然后进行标签1扩展。
标签清理
不是所有的标签都是代表正面情绪的,把具有负面情绪的标签清理出去。
标签清理的另一个重要意义在于将标签作为推荐解释。如果我们要把标签呈现给用户,将其作为给用户推荐某一个物品的解释,对标签的质量要求就很高。首先,这些标签不能包含没有意义的停止词或者表示情绪的词,其次这些推荐解释里不能包含很多意义相同的词语。
为了控制标签的质量,很多网站也采用了让用户进行反馈的思想,即让用户告诉系统某个标签是否合适。 MovieLens 在实验系统中就采用了这种方法。关于这方面的研究可以参考 GroupLens的 Shilad Wieland Sen 同学的博士论文。此外,电影推荐网站 Jinni 也采用了这种方式。
基于图的推荐
而在用户标签数据集上,有 3 种不同的元素,即用户、物品和标签。因此,我们需要定义 3 种不同的顶点,即用户顶点、物品顶点和标签顶点。然后,如果我们得到一个表示用户 u给物品 i 打了标签 b 的用户标签行为 ( u , i , b ) ,那么最自然的想法就是在图中增加 3 条边,首先需要在用户 u 对应的顶点 v ( u ) 和物品 i 对应的顶点 v ( i ) 之间增加一条边(如果这两个顶点已经有边相连,那么就应该将边的权重加 1 ),同理,在 v ( u ) 和 v ( b ) 之间需要增加一条边, v ( i ) 和 v ( b ) 之间也需要边相连接。
summary:
GroupLens 的研究人员 Jesse Vig 对基于标签的解释进行了深入研究。作者得出了以下结论:
用户对标签的兴趣对帮助用户理解为什么给他推荐某个物品更有帮助;
用户对标签的兴趣和物品标签相关度对于帮助用户判定自己是否喜欢被推荐物品具有同样的作用;
物品标签相关度对于帮助用户判定被推荐物品是否符合他当前的兴趣更有帮助;
客观事实类标签相比主观感受类标签对用户更有作用。
【后续内容讲了一下如何给用户推荐标签】