利用用户标签数据
Poblog 08月09日 2018
推荐系统的目的:联系用户的兴趣和物品
流行的推荐系统基本上通过3种方式联系用户兴趣和物品
1.利用用户喜欢过的物品,给用户推荐与他喜欢过的物品相似的物品,这就是前面提到的基于物品的算法
2.利用和用户兴趣相似的其他用户,给用户推荐那些和他们兴趣爱好相似的其他用户喜欢的物品,这是前面提到的基于用户的算法
3.通过一些特征(feature)联系用户和物品,给用户推荐那些具有用户喜欢的特征的物品
特征有不同的表现方式,比如可以表现为物品的属性集合(比如对于图书,属性集合包括作者、出版社、主题和关键词等) ,也可以表现为隐语义向量
讨论一种重要的特征表现方式——标签
标签是一种无层次化结构的、用来描述信息的关键词,它可以用来描述物品的语义
标签应用一般分为两种:
让作者或者专家给物品打标签
让普通用户给物品打标签,也就是UGC
用户对一个物品打上一个标签,这个标签一方面描述了用户的兴趣,另一方面则表示了物品的语义,从而将用户和物品联系了起来
主要讨论UGC的标签应用,研究用户给物品打标签的行为,探讨如何通过分析这种行为给用户进行个性化推荐
UGC 标签系统的代表应用
鼻祖Delicious
论文书签网站CiteULike
音乐网站Last.fm
视频网站Hulu
书和电影评论网站豆瓣
标签系统中的推荐问题
标签系统中的推荐问题主要有以下两个
如何利用用户打标签的行为为其推荐物品(基于标签的推荐)
如何在用户给物品打标签时为其推荐适合该物品的标签(标签推荐)
需要解答下面3个问题
用户为什么要打标签
用户怎么打标签
用户打什么样的标签
用户的标注行为:
有些用户标注是给内容上传者使用的(便于上传者组织自己的信息)
有些用户标注是给广大用户使用的(便于帮助其他用户找到信息)
用户如何打标签:
尽管每个用户的行为看起来是随机的,但其实这些表面随机的行为背后蕴含着很多规律
打什么样的标签
用户往往不是按照我们的想法操作,而是可能会给物品打上各种各样奇奇怪怪的标签
总结了 Delicious 上的标签,将它们分为如下几类:
表明物品是什么
表明物品的种类
表明谁拥有物品
表达用户的观点
用户相关的标签
用户的任务
Hulu 对视频的标签就做了分类:
类型
时间
人物
地点
语言
奖项
其他
基于标签的推荐系统
豆瓣
在每本书的页面上,豆瓣都提供了一个叫做“豆瓣成员常用标签”的应用,它给出了这本书上用户最常打的标签。同时,在用户给书做评价时,豆瓣也会让用户给图书打标签
最终的个性化推荐结果里,豆瓣利用标签将用户的推荐结果做了聚类,显示了对不同标签下用户的推荐结果,从而增加了推荐的多样性和可解释性
一个用户标签行为的数据集一般由一个三元组的集合表示,其中记录 (u, i, b) 表示用户 u 给物品 i 打上了标签 b
用物品标签向量的余弦相似度度量物品之间的相似度
其中 item_tags[i][b] 是对物品 i 打标签 b 的次数,那么物品 i 和 j 的余弦相似度可以通过如下程序计算
#计算余弦相似度
def CosineSim(item_tags,i,j):
//item_tags:物品出现tag的次数
{'196': {'tag1':9,'tag2':19,...},...}
i:'196'
j:'197'
//
ret = 0
for b,wib in item_tags[i].items(): #求物品i,j的标签交集数目
//b:'tag1' 标签
wib:9 被打标签的次数
//
if b in item_tags[j]:
//标签出现在物品j的列表中
//
ret += wib * item_tags[j][b]
//ret:记录共有标签的乘积
//
ni = 0
nj = 0
for b, w in item_tags[i].items(): #统计 i 的标签数目
//b:'tag1' 标签
w:9 被打标签的次数
//
ni += w * w
//ni:记录物品i标签的平方和
//
for b, w in item_tags[j].items(): #统计 j 的标签数目
//b:'tag1' 标签
w:9 被打标签的次数
//
nj += w * w
//nj:记录物品j标签的平方和
//
if ret == 0:
return 0
return ret/math.sqrt(ni * nj) #返回余弦值
//余弦相似度
//
#计算推荐列表多样性
def Diversity(item_tags,recommend_items):
//item_tags:物品出现tag的次数
{'196': {'tag1':9,'tag2':19,...},...}
recommend_items:{'196','197',...} 推荐物品列表
//
ret = 0
n = 0
for i in recommend_items.keys():
//i:'196'
//
for j in recommend_items.keys():
//j:'197'
//
if i == j:
continue
ret += CosineSim(item_tags,i,j)
//ret:记录推荐物品余弦相似度和
//
n += 1
//n记录全部物品个数
//
return ret/(n * 1.0)
//返回平均余弦相似度
//
推荐系统的多样性为所有用户推荐列表多样性的平均值
一个最简单的算法
统计每个用户最常用的标签
对于每个标签,统计被打过这个标签次数最多的物品
对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品推荐给这
个用户
#推荐算法
def Recommend(usr):
recommend_list = dict();
tagged_item = user_items[usr];#得到该用户所有推荐过的物品
//tagged_item:该用户的标签记录
{'tag1':9,'tag2':19,...}
//
for tag_,wut in user_tags[usr].items():#用户打过的标签及次数
//tag_:'tag1' 用户打过的标签
wut:9 用户打过该标签次数
//
for item_,wit in tag_items[tag_].items():
// tag_items[tag_].items() 存放打过该标签的物品及标签次数
item_:'196' 被打过该标签的物品
wit:9 被打过该标签的物品被打过该标签的次数
//
if item_ not in tagged_item:#已经推荐过的不再推荐
if item_ not in recommend_list:
recommend_list[item_]=wut*wit;#根据公式
else:
recommend_list[item_]+=wut*wit;
//计算推荐权重
//
return sorted(recommend_list.iteritems(), key=lambda a:a[1],reverse=True)
//返回推荐列表按推荐权重的排序
算法的改进:
TF-IDF
前面这个公式倾向于给热门标签对应的热门物品很大的权重, 因此会造成推荐热门的物品给用户,从而降低推荐结果的新颖性.
解决:推荐权重/log(1+标签 b 被多少个不同的用户使用过),这个算法记为 TagBasedTFIDF
实验结果相对比,可以看到该算法在所有指标上相比 SimpleTagBased 算法都有提高
同理,我们也可以借鉴 TF-IDF 的思想对热门物品进行惩罚,从而得到如下公式
解决:推荐权重/log(1+标签 b 被多少个不同的用户使用过)/log(1+物品 i 被多少个不同的用户打过标签)
这个算法记为 TagBasedTFIDF++
和 TagBasedTFIDF 算法相比,除了多样性有所下降,其他指标都有明显提高。
结果表明,适当惩罚热门标签和热门物品,在增进推荐结果个性化的同时并不会降低推荐结果的离线精度
数据稀疏性
对于新用户或者新物品,为了提高推荐的准确率,我们可能要对标签集合做扩展,比如若用户曾经用过“推荐系统”这个标签,我们可以将这个标签的相似标签也加入到用户标签集合中,比如“个性化” 、 “协同过滤”等标签
标签扩展有很多方法,其中常用的有话题模型(topic model) ,不过这里遵循简单的原则介绍一种基于邻域的方法.
标签扩展的本质是对每个标签找到和它相似的标签,也就是计算标签之间的相似度
最简单的相似度可以是同义词。如果有一个同义词词典,就可以根据这个词典进行标签扩展。如果没有这个词典,我们可以从数据中统计出标签的相似度.
如果认为同一个物品上的不同标签具有某种相似度, 那么当两个标签同时出现在很多物品的标签集合中时,我们就可以认为这两个标签具有较大的相似度.
进行标签扩展确实能够提高基于标签的物品推荐的准确率和召回率,但可能会稍微降低推荐结果的覆盖率和新颖度
标签清理
不是所有标签都能反应用户的兴趣。比如,在一个视频网站中,用户可能对一个视频打了一个表示情绪的标签,比如“不好笑” ,但我们不能因此认为用户对“不好笑”有兴趣,并且给用户推荐其他具有“不好笑”这个标签的视频.标签系统里经常出现词形不同、词义相同的标签.
标签清理的另一个重要意义在于将标签作为推荐解释。如果我们要把标签呈现给用户,将其作为给用户推荐某一个物品的解释,对标签的质量要求就很高.标签不能包含没有意的停止词或者表示情绪的词,其次这些推荐解释里不能包含很多意义相同的词语
一般来说有如下标签清理方法:
去除词频很高的停止词
去除因词根不同造成的同义词,比如 recommender system 和 recommendation system
去除因分隔符造成的同义词,比如 collaborative_filtering 和 collaborative-filtering
为了控制标签的质量,很多网站也采用了让用户进行反馈的思想,即让用户告诉系统某个标签是否合适