对于一个标准的推荐系统,最主要的步骤就是建立用户画像,我们需要从从用户和商品的数据找出其关联性。
用户画像建立所需要解决的三个问题:
- 都是谁
- 从哪来
- 到哪去
针对上面的三个问题,我们会有以下的建立步骤:
-
统一标识:用户唯一标识是用户画像的的核心,比如UserID
-
给用户打标签:用户标签的四个维度:
-
基于标签指导业务:业务赋能的三个阶段
有了用户画像的建立,我们会根据一定的业务流对数据流进行处理:
上面提到的用户画像会生成一个个标签tag,我们会利用tag计算用户或者物品之间的相似度,这里会用到Kmeans等聚类的算法,其原理就是通过计算各字段(标签tag)的距离,距离越近,越相似。其中,计算距离的方法有以下几种:
-
欧氏距离:通过计算不同维度的距离并相加。
d i s t a n c e = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 distance = \sqrt{(x_2-x_1)^2+(y_2-y_1)^2} distance=(x2−x1)2+(y2−y1)2 -
曼哈顿距离:从A点到B点走几步
-
切比雪夫距离:计算两个点的坐标距离的最大值
-
余弦距离:余弦距离相对于欧氏距离更注重于方向是否一致
c o s θ = x ⃗ ⋅ y ⃗ ∣ x ∣ ⋅ ∣ y ∣ cos\theta = \frac{\vec{x}\cdot\vec{y}}{|x|\cdot|y|} cosθ=∣x∣⋅∣y∣x⋅y
在距离的计算过程中,需要注意的是得先对数据进行规范化,因为数据的量级的不同会影响到距离计算的权重偏向,以下是数据规范化的方式: -
Min-Max归一化
将原始数据投射到指定的空间[min,max]
x n e w = x o r i − x m i n x m a x − x m i n x_{new} = \frac{x_{ori}-x_{min}}{x_{max}-x_{min}} xnew=xmax−xminxori−xmin
-
Z-score标准化
将原始数据转换成正态分布的形式
x n e w = x o r i − x m e a n s t d x_{new} = \frac{x_{ori}-x_{mean}}{std} xnew=stdxori−xmean
讲完了距离计算,再讲回聚类,聚类是属于无监督学习的范畴,而具体含义是需要我们人为定义的,那为什么使用聚类呢?
- 可能缺乏足够的先验知识
- 人工打标签的成本太过昂贵
使用聚类对标签进行归类分组后,我们会采用不同算法通过标签向用户做推荐,在讲算法前,先了解一下在推荐算法中有不同数据结构的定义:
- 用户打标签的纪录:records[i] = {user,item,tag}
- 用户打过的标签:user_tags[u][t]
- 用户打过标签的商品:user_items[u][i]
- 打上某标签的商品:tag_items[t][i]
- 某标签使用过的用户:tag_users[t][u]
推荐算法
- SimpleTagBased算法:
1.统计每个用户常用的标签
2.对每个标签,统计被打过这个标签次数最多的商品
3.对于每一个用户,找到他们常用的标签,然后找到具有这些标签的最热门的物品推荐给他们
4.为此,有如下计算公式:
用 户 u 对 物 品 i 的 兴 趣 : s c o r e ( u , i ) = ∑ t u s e r _ t a g s [ u , t ] ∗ t a g _ i t e m s [ t , i ] u s e r _ t a g s [ u , t ] : 用 户 u 使 用 过 标 签 t 的 次 数 t a g _ i t e m s [ t , i ] : 商 品 i 被 打 过 标 签 t 的 次 数 用户u对物品i的兴趣:\\ score(u,i) = \sum_t{user\_tags[u,t]*tag\_items[t,i]}\\user\_tags[u,t]:用户u使用过标签t的次数\\tag\_items[t,i]:商品i被打过标签t的次数 用户u对物品i的兴趣:score(u,i)=t∑user_tags[u,t]∗tag_items[t,i]user_tags[u,t]:用户u使用过标签t的次数tag_items[t,i]:商品i被打过标签t的次数 - NormTagBased算法:
对score进行归一化:
s c o r e ( u , i ) = ∑ t u s e r _ t a g s [ u , t ] u s e r _ t a g s [ u ] ∗ t a g _ i t e m s [ t , i ] t a g _ i t e m s [ t ] score(u,i) = \sum_t{\frac{user\_tags[u,t]}{user\_tags[u]}*\frac{tag\_items[t,i]}{tag\_items[t]}} score(u,i)=t∑user_tags[u]user_tags[u,t]∗tag_items[t]tag_items[t,i]
归一化的主要原因是有用户打的标签虽然次数多,但并不是最多的;又或者有些商品被打上某个标签的次数多,但在所有标签中并不是最多的。所以需要对标签的使用次数进行归一化。 - TagBased-TFIDF算法:
如果一个tag很热门,会导致user_tags[u,t]很大,所以即使tag_items[t,i]很小,也会导致score(u,i)很大。给热门标签过大的权重,不能反映用户个性化的兴趣。所以这里借鉴了TFIDF的思想:
s c o r e ( u , i ) = ∑ t u s e r _ t a g s [ u , t ] l o g ( 1 + t a g _ u s e r s [ t ] ) ∗ t a g _ i t e m s [ t , i ] t a g _ u s e r s [ t ] : 表 示 某 标 签 被 多 少 个 不 同 用 户 使 用 score(u,i) = \sum_t{\frac{user\_tags[u,t]}{log(1+tag\_users[t])}*tag\_items[t,i]}\\tag\_users[t]:表示某标签被多少个不同用户使用 score(u,i)=t∑log(1+tag_users[t])user_tags[u,t]∗tag_items[t,i]tag_users[t]:表示某标签被多少个不同用户使用
这里提到了TF-IDF,那就顺便插一嘴简单讲一下:
TF-Term Frequency:指的是词频,一个单词的重要性与它在文档中出现的次数成正比。
IDF-Inverse Document Frequency,逆向文档频率,一个单词在文档中的区分度。这个单词在文档中出现的次数越小,区分度越大,IDF越大:
最后我们将TF的值和IDF的值相乘即可。
当用户u给物品i打标签时,可以给用户推荐和物品i相关的标签。方法如下:
- 方法1:给用户u推荐整个系统最热门的标签
- 方法2:给用户u推荐物品i上热门的标签
- 方法3:给用户u推荐他自己经常使用的标签
- 方法4:将方法2和方法3做加权融合,生成最终的标签的推荐结果
总结以上的内容的话可以大概生成一个推荐系统的基本架构:
- 物品表示Item Representation:为每个物品抽取feature。
- 特征学习Profile Learning:利用一个用户过去喜欢的(不喜欢)的item的特征数据,来学习该用户的喜好特征(profile)。
- 生成Recommendation Generation:通过用户profile与候选item的特征,推荐相关性最大的的item。