此文是根据《推荐系统实践》部分整理而来。
PART 1 介绍
GroupLens在一篇文章中表示目前流行的推荐系统基本上通过3种方式联系用户兴趣和物品:
- 喜欢过的物品
- 有相似兴趣的用户
- 特征
其中,这里的特征有不同的表现方式,比如尅表现为物品的属性集合,也可以表现为隐语义向量。本文将讨论一种重要的特征表现方式----标签。
标签应用一般分为两种:一种是让作者或者专家给物品打标签;另一种是让普通用户给物品打标签,也就是UGC的标签应用。
UGC的标签应用对用户来说有几个好处:
- 表达。标签系统帮助用户表达对物品的看法。
- 组织。打标签帮助用户组织喜欢的物品。
- 学习。打标签帮助用户增加对物品的了解。
- 发现。标签系统帮助用户更容易发现喜欢的物品。
- 决策。标签系统帮助用户判定是否去购买/使用某个物品。
PART 2 标签系统中的推荐问题
标签系统中的推荐问题主要有以下两个:
- 如何利用用户打标签的行为为其推荐物品(基于标签的推荐)?
- 如何在用户给物品打标签时为其推荐适合该物品的标签(标签推荐)?
为了研究上面两个问题,我们首先需要解答下面3个问题:
- 用户为什么要打标签?
- 用户怎么打标签?
- 用户打什么样的标签?
第一个问题从两个维度进行探讨:
- 社会维度,有些用户标注是给内容上传者使用的,有些用户标注是给广大用户使用的。
- 功能维度,有些标注用于更好地组织内容,方便用户的查找,另一些标注用于传达某种信息,比如照片的拍摄时间地点。
第二个问题,尽管每个用户的行为看起来的随机的,但是之前提到,用户行为中用户活跃度和物品流行度都是遵循着长尾分布。研究后发现标签流行度的分布也遵循长尾分布,下图横坐标是流行度k,纵坐标是流行度为k的标签总数n(k):
第三个问题,用户会给物品打上奇奇怪怪的标签,分为以下几类:
- 表明物品是什么
- 表明物品的种类
- 表明谁的物品
- 表达用户的观点
- 用户相关的标签
- 用户的任务
- 类型
- 时间
- 任务
- 地点
- 语言
- 奖项
- 其他
PART 2 基于标签的推荐系统
之前的一个问题是:如何利用用户的标签数据提高个性化推荐结果的质量。
以豆瓣为例,将标签系统融入产品线,在每本书的页面上,都提供了这本书上用户最常打的标签,同时在用户给书做评价时,豆瓣也会让用户给图书打标签。最后,豆瓣利用标签将用户的推荐结果做了聚类,显示了对不同标签下用户的推荐结果,从而增加了推荐的多样性和可解释性。
一个用户标签行为的数据集一般由一个三元组的集合表示,其中记录(u,i,b)表示用户u给物品i打上了标签b,当然实际上维度会更多,这里只考虑最简单的形式。中间的实验设置略过,直接进入算法。
首先一个最简单的算法是:
- 统计每个用户最常用的标签。
- 对于每个标签,统计被打过这个标签次数最多的物品。
- 对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品推荐给这个用户。
对于上面的算法,用户u对物品i的兴趣公式如下:
这里,B(u)是用户u打过的标签集合,B(i)是物品i被打过的标签集合,Nu,b是用户u打过标签b的次数,Nb,i是物品i被打过标签b的次数。这个算法被作者称为SimpleTagBased。
评测结果为:
上面的公式会有很多缺点,以下逐条分析并且提出修改意见:
-
TF-IDF
前面这个公式倾向于给热门标签对应的热门物品很大的权重,因此会降低新颖性,并且不能反映个性化的兴趣。在这里可以借鉴 TF-IDF的思想,对这一公式进行改进:
这里nb(u)记录了标签b被多少个不同的用户使用过,这个算法记为TagBasedTFIDF。下图给出了这个算法在两个数据集上的离线实验性能,可以看到所有指标上都比SimpleTagBased高。
同理,借鉴TF-IDF的思想对热门物品进行惩罚,从而得到如下公式:
ni(u)记录了物品i被多少个不同的用户打过标签,这个算法记为TagBasedTFIDF++。下图展示了这个算法的离线实验性能,和TagBasedTFIDF相比,除了多样性有所下降,其他指标都有明显提高。这一结果表明,适当惩罚热门标签和热门物品,在增进推荐结果个性化的同时并不会降低推荐结果的离线精度:
- 数据的稀疏性
由于用户兴趣和物品是通过B(u)∩B(i)中的标签建立的,但是对于新用户或者新物品,这个集合中的标签数量会很少,为了提高推荐的准确率,我们可能要对标签集合做扩展,进行标签扩展有很多方法,其中常用的有话题模型,不过这里遵循简单的原则介绍一种基于邻域的方法。
标签扩展本质是对每个标签找到和它相似的标签,也就是计算标签的相似度。如果认为同一个物品上的不同标签具有某种相似度,那么当两个标签同时出现在很多物品的标签集合中时,我们就可以认为这两个标签具有较大的相似度。对于标签b,令N(b)为有标签b的物品的集合,n_{b,i}为给物品i打上标签b的用户数,我们可以通过如下余弦相似度公式计算标签b和标签b'的相似度:
为了测试性能进行试验,对于曾经打过标签数少于20的用户,我们找到其所打标签的相关标签,然后将这些标签聚合排序,结果前20标签作为用户相关的标签,下表展示了离线实验的性能,相比之前而言,进行标签扩展确实能提高准确率和召回率,但可能会稍微降低推荐结果的覆盖率和新颖度。
- 标签清理
有些标签不能反应用户的兴趣,比如一个用户说一个物品“差”,那么就并不是他喜欢的标签。标签清理的另一个重要意义在于将标签作为推荐解释,如果我们要把标签呈现给用户,将其作为给用户推荐某一物品的解释,对标签的质量要求就很高。首先标签不能包含没有意义的停止词或者表示情绪的词,其次这些推荐解释里不能包含很多意义相同的词语。一般来说有以下清理方法:
- 去除词频很高的停止词;
- 去除因词根不同造成的同义词;
- 去除因分隔符造成的同义词。
为了控制标签的质量,很多网站也采用了让用户进行反馈的思想,即让用户告诉系统某个标签是否合适。
同样这里基于图的推荐算法也不介绍了。介绍下基于标签的推荐解释,这是基于标签的推荐的一个好处。举例豆瓣,豆瓣有一个标签云,表示用户的兴趣分布,标签的尺寸越大,表示用户对这个标签相关的图书越感兴趣。这样组织页面,首先提高了推荐结果的多样性,让用户自己根据他今天的兴趣选择相关的标签,从而得到推荐结果。同时,标签云也提供了推荐解释功能,其他的也不多做介绍,下图为豆瓣的页面:
PART 4 给用户推荐标签
首先,给用户推荐标签有以下好处:
- 方便用户输入标签
- 提高标签质量
如何给用户推荐标签呢?
用户u给物品i打标签时,我们有很多方法可以给用户推荐和物品i相关的标签,比较简单的方法有 4 种:
- 给用户u推荐整个系统最热门的标签,称为PopularTags;
- 给用户u推荐物品i上最热门的标签,称为ItemPopularTags;
- 给用户u推荐他自己经常使用的标签,称为UserPopularTags;
- 前面两种的融合,该方法通过一个系数将上面的推荐结果线性加权,然后生成最终的推荐结果,称为HybirdPopularTags.
下图列出了PopularTags、ItemPopularTags、UserPopularTags三种算法在N=10(N为推荐标签数量)的准确率和召回率:
结果看出,ItemPopularTags具有最好的准确率和召回率,这一点是直观的,因为用户兴趣广泛,基于物品的精度理应是最高的。
再看下HybirdPopularTags算法,下图给出了在不同显性融合系数α下的准确率和召回率:
其中α=0.8时(ItemPopularTags权重更大),取得了最好的准确度,并且超过了ItemPopularTags的精度。
不过有一个缺点,就是对新用户或者不热门的物品很难有推荐结果,解决这个问题有两个思路:
- 从内容数据中抽取关键词作为标签;
- 针对有结果,但结果不太多的情况,进行标签扩展。