铺垫
基于物品的协同过滤
什么是基于物品的协同过滤(ICF)呢?就比如你曾经购买过item A, item B, 如果现在有一个item C和A B是类似项目,那么就推荐C给你.
ICF涉及到一个item之间距离的问题,由距离来判断两个物品是否为相似物品.一般用到相似度矩阵:
– a b c d e
a 0 2 1 1 0
b 2 0 0 1 0
c 1 0 0 0 0
d 1 1 0 0 0
e 0 0 0 0 0
提出问题
现有的基于项目的协同过滤方法(ICF)只利用了协同相似性的关系,比如用户交互(评级、购买)证明的项目相似性。但是,现实场景中,项目存在多种关系,比如两部电影共享一个导演、两个产品互相补充。与从用户角度隐含共同交互模式的协同相似性不同,这些关系揭示了来自元数据不同角度的细粒度知识。
本文提出了关系协同过滤(RCF)来挖掘推荐系统中的多项关系。关系类型(比如共享导演)和关系值(比如某演员)在推断用户喜好的时候都是很重要的。所以本文提出一种两级分层注意机制来建模用户偏好。第一级注意区分哪些类型的关系更重要,第二级注意考虑特定关系值来估计历史项目的贡献。
ICF目前很流行,但是仍有不足。因为ICF只考虑了协作相似关系,这种关系很宏观、粗粒度,缺乏具体语义。在现实中,拥有具体语义的项目之间存在多种关系,对理解用户行为很有帮助。
举个例子:两个用户 u 1 , u 2 u_1,u_2 u1,u2看完同一部电影 m 1 m_1 m1后, u 1 u_1 u1点赞导演,选择此导演的另一部作品接下来看, u 2 u_2 u2喜欢这种题材,于是接下来看同题材的电影。如果不对物品之间这种细粒度的关系进行明确建模,从概念上很难说明用户决定背后的原因,就更难去推荐有说服力的解释的物品了。
背景:基于项目的协同过滤方法流行
问题:现有方法只利用了协同相似性, 忽视了项目间的多种关系
改进:提出关系协同过滤(RCF), 用两级注意力机制来建模用户喜好,第一级注意力辨析哪种关系类型更重要,第二级注意力考虑特定关系值来估计历史项目的贡献.
关系
本文将关系表示为一个具有两集层次的概念:
- 关系类型
如:电影共享导演、类型。以抽象的方式描述了项目之间如何关联。
- 关系值
给出两个项目的共享关系的详细信息。比如电影 m 1 m_1 m1和 m 2 m_2 m2的关系“共享导演”的值是 d 1 d_1 d1,而关系“共享类型”的值包括小说、动作、浪漫等。关系值为仔细检查用户的偏好时提供重要线索,因为用户在做出决定时可以不同地权衡不同关系的不同值。
举个例子,上图说明两个项目间可能存在多个关系。比如羽毛球和羽毛球拍具有类别共享和功能互补两种关系。并且一个关系值可能出现在不同类型的关系中,比如电影 m 1 m_1 m1导演 d 1 d_1 d1可能也是电影 m 2 m_2 m2的演员,所以两种关系可能有相同的值,指的是同一个东西。在设计处理多项关系方法时,应该考虑这些情况,比标准的ICF更复杂。
为了将这些关系数据集成到ICF中,本文设计了一个两级神经注意机制来模拟历史上相互作用的项目:
第一级注意力检查连接交互项与目标项的关系的类型,并区分哪些类型对用户影响更大。
第二级注意力是对每个关系类型下的交互项进行操作,以估计交互项目在推荐中的贡献。
方法说明
问题表述
在给定用户及其交互历史的情况下,传统ICF方法是基于对项目同交互模式进行编码的协作相似度来生成推荐。交互图如下,项之间的链接就是隐含的协作相似性。然而现实中存在多种具有语义意义的项关系,在本文中,将项目定义为:
D e f i n i t i o n 1 : Definition\ 1: Definition 1:给定一个项目对 ( i , j ) (i,j) (i,j), 它们之间的关系定义为 r = ⟨ t , v ⟩ r=\langle t,v\rangle r=⟨t,v⟩的集合,其中 t t t是关系类型, v v v是关系值。
RCF的目标是基于用户-项目交互历史和项目关系数据生成推荐,RCF交互图中的项之间的链接不仅包含隐式协作链接,还包含显示的多项关系,如下图:
用户-项目偏好建模
建模动机:用户倾向为不同类型的关系支付不同的权重。
在给定项关系数据的情况下,我们首先根据用户 u u u中交互的项与目标项之间的关系类型将这些项划分成不同的集合, I u + I_{u}^{+} Iu+表示和用户 u u u有关的项目集合, I u , i t I_{u,i}^{t} Iu,it表示在 I u + I_{u}^{+} Iu+里和目标项 i i i有关系类型 t t t的项目集合,有些项目和目标项目没有明确关系,为了处理就引入一个潜在关系 r 0 = ⟨ t 0 , v 0 ⟩ r_0=\lang t_0,v_0\rang r0=⟨t0,v0⟩并将这些项目放入 I u , i t 0 I_{u,i}^{t_0} Iu,it0,于是目标感知用户embedding可以表示为 m u , i = p u + ∑ t ∈ T a ( u , t ) ⋅ s u , i t \textrm m_{u,i}=\mathrm p_u+\sum_{t\in\mathcal T}a(u,t)\cdot s^t_{u,i} mu,i=pu+t∈T∑a(u,t)⋅su,it
其中 a ( u , t ) a(u,t) a(u,t)是旨在计算不同关系类型对该用户的重要性的第一级关注度, s u , i t s^t_{u,i} su,it根据 I u , i t I_{u,i}^{t} Iu,it中的项目描述用户的配置文件,更准确点,用标准softmax函数定义 a ( u , t ) a(u,t) a(u,t)
首先用 p u \textrm p_u pu和 x t \textrm x_t xt在第一级注意机制得到 a ( p u , x t ) a(\textrm p_u,\textrm x_t) a(pu,xt),再用softmax得到 a ( u , t ) a(u,t) a(u,t),这里是对应一个用户 u u u和一个关系类型 t t t.
然后看 s u , i t = ∑ j ∈ I u , i t β t ( i , j , v ) ⋅ q j s^t_{u,i}=\sum_{j\in\mathcal I^t_{u,i}}\beta_t(i,j,v)\cdot \mathrm q_j su,it=j∈Iu,it∑βt(i,j,v)⋅qj,其中, β t ( i , j , v ) \beta_t(i,j,v) βt(i,j,v)用平滑softmax得到,主要是为了防止项目过多让分母太大,所以分母加上平滑系数 ρ ρ ρ, ρ ρ ρ取(0,1],通常取0.5. b t ( q i , q j , z v ) b_t(\mathrm q_i,\mathrm q_j,\mathrm z_v) bt(qi,qj,zv)和 a ( p u , x t ) a(\textrm p_u,\textrm x_t) a(pu,xt)相似,
其中 M 2 , t , b 2 , t , h 2 , t \mathrm M_{2,t},\mathrm b_{2,t},\mathrm h_{2,t} M2,t,b2,t,h2,t都是注意参数。
至此,求得 m u , i \mathrm m_{u,i} mu,i, 完成目标感知用户嵌入的建模,在此基础上用多层感知器(MLP)计算出用户 u u u在项目 i i i上的最终预测得分 y ^ u i = M L P ( m u , i ⊗ q i ) \hat y_{ui}=MLP(\mathrm m_{u,i}\otimes\mathrm q_i) y^ui=MLP(mu,i⊗qi)
我们希望正面项目的排名高于负面项目。用BPR成对学习框架来定义目标函数
L r e c = − ∑ ( u , i , k ) ∈ D I ln σ ( y ^ u i − y ^ u k ) L_{rec}=-\sum_{(u,i,k)\in\mathcal D_I}\ln \sigma(\hat y_{ui}-\hat y_{uk}) Lrec=−(u,i,k)∈DI∑lnσ(y^ui−y^uk)
其中 σ \sigma σ是sigmoid函数, D I \mathcal D_I DI是训练三元组 D I = { ( u , i , k ) ∣ u ∈ U ∧ i ∈ I u + ∧ k ∈ I ∖ I u + } \mathcal D_I=\{(u,i,k)|u\in\mathcal U\land i\in \mathcal I^+_u\land k\in\mathcal I\setminus\mathcal I^+_u\} DI={(u,i,k)∣u∈U∧i∈Iu+∧k∈I∖Iu+}
总结:
User-Item Preference Modeling
首先用user ID embedding, relation type embedding计算对应的attention score.
用softmax计算对应权重. 得到 a ( u , t ) a(u,t) a(u,t)
再根据type的分类,将目标item和用户历史交互item进行计算得到对应的second-level attention score: b t ( q i , q j , z v ) b_t(\mathrm q_i,\mathrm q_j,\mathrm z_v) bt(qi,qj,zv),这里为了防止item太多的数据集的分母太大,采用smooth softmax, 即分母加上指数,一般取0.5,得到每个type划分后的数据集的加权和 s u , i t s^t_{u,i} su,it.
最后用之前的 a ( u , t ) a(u,t) a(u,t)对 s u , i t s^t_{u,i} su,it进行加权和,就得到了user的表示 m u , i \mathrm m_{u,i} mu,i,为了使正例的得分大于负例的得分,因此使用了BPR pairwise的目标函数 L r e c L_{rec} Lrec.
step2
RCF的第二个任务是对项目关系数据建模.
代码part
LoadData_ML
def __init__(self):
self.trainfile = "./ML100K/train.txt"
self.testfile = "./ML100K/test.txt"
self.num_users, self.num_items = self.map_features()
self.user_positive_list = self.get_positive_list(self.trainfile) # userID positive itemID
self.Train_data, self.Test_data = self.construct_data()
loader=movie_loader()
self.movie_dict = loader.movie_dict
self.all_genres=loader.genre_list
self.all_directors = loader.director_list
self.all_actors = loader.actor_list
self.num_genres=len(self.all_genres)
self.num_directors=len(self.all_directors)
self.num_actors=len(self.all_actors)
items={‘286’: 0, ‘315’: 1, …} len=1674
items_traverse={0: ‘286’, 1: ‘315’, …}
user一样 len = 943
user_positive_list = {
0:[0,1, 2, …],
1:[147, 189, ],
…
}
这里的0,1, 2,…就是上面的 0,1,2
construct_data():
User = [0,…0, 1, …,942]
Item = [0, 1, …] 似乎用于矩阵
Data_Dic[‘User’] Data_Dic[‘Item’] 字典 存User Item --> Train_Data
movie_loader
从 auxiliary-mapping.txt 读取,生成:
movie_dict = {
'1': movie对象 {actor:[0,1,2,3], director:[0], genre:[0,1,2]},
'2': ...
}
load_attribute() : 得到genre_list, actor_list, director_list 存一共有哪些
genre_list : [0…25] --> all_genre
director_list : [0…1153] --> all_directors
actor_list : [0…3945] --> all_actors