1.BPR
1.1 做法
- 构建样本对
- 假设背后是某个常见模型:如MF
- 排序对成立情况下倒推U/V向量,计算UV乘积,得到完整评分矩阵
矩阵分解:
贝叶斯:
<u,i,j> :,i在j前面,用户u,是W、H,是个模型
极大似然估计
D:已有的评分矩阵
->这是在预测矩阵X的对应的值
假设是高斯分布
计算:求导,使用梯度上升
1.1.1 构建样本对
- 构建样本对:
- 假设我们现在有 N 个视频,每个视频有两种用户行为:被用户点击,没有被用户点击。
- 现在设定用户给物品的评分如下:
- 正例:被用户点击过的视频得分 +1 ,
- 负例:从没有被用户点击过的视频中进行采样得到一部分视频,这部分视频被认为是用户不喜欢的视频,得分 -1 。
1.1.2 假设
-
假设
假设用户对物品的评分背后的模型是某个常见模型,比如矩阵分解模型,也就是用户对物品的评分 R = U’ * V ,其中 U 是用户向量,而 V 是物品向量。算法假定所有得分 +1 的物品和所有得分 -1 的物品,如果用评分矩阵 R 重新对物品进行打分,原本得分 +1 的物品的新得分将高于原本得分 -1 的物品的新得分。 -
诉求/流程
本质诉求是在**可能的满足原有的 +1 物品得分高于 -1 物品得分的排序对成立的情况下,倒推出 R 评分分解后的 U 和 V 向量。**通过计算 U和 V 的乘积,得到用户对物品的完整评分矩阵,完成整个算法过程
1.2 实现/代码
class BPR(nn.Module):
def __init__(self, user_num, item_num, factor_num):
super(BPR, self).__init__()
"""
user_num: number of users;
item_num: number of items;
factor_num: number of predictive factors.
"""
self.embed_user = nn.Embedding(user_num, factor_num)
self.embed_item = nn.Embedding(item_num, factor_num)
nn.init.normal_(self.embed_user.weight, std=0.01)
nn.init.normal_(self.embed_item.weight, std=0.01)
def forward(self, user, item_i, item_j):
user = self.embed_user(user)
item_i = self.embed_item(item_i)
item_j = self.embed_item(item_j)
prediction_i = (user * item_i).sum(dim=-1)
prediction_j = (user * item_j).sum(dim=-1)
return prediction_i, prediction_j
loss = - (prediction_i - prediction_j).sigmoid().log().sum()
2. AutoInt
AutoInt
paper
挑战:
- (1)输入特征通常是稀疏高维的;
- (2)高阶特征组合能够带来效果,但耗费时间和人力
摘要
AutoInt,能够自动的学习输入特征的高阶特征交互。AutoInt是非常普适的,可以用于数值和类别输入特征。特别地,我们将数值化和类别化特征映射到同一个低维空间,然后,带有残差连接的multi-head self-attentive神经网络在低维空间显示地建模特征交互。由于multi-head self-attentive神经网络不同层的存在,不同阶的特征组合可以被建模。
贡献
- 我们提出研究显示学习高阶特征交互的问题,以及寻找可解释好的模型的问题;
- 我们提出基于self-attentive神经网络的方法,能够自动的学习高阶特征交互,有效的处理大规模高维稀疏数据;
- 我们通过实验证明了所提出方法,不仅有显著的效果,还有很好的模型解释性;
相关工作:
低阶特征交互:FM/FFM/AFM/GBFM
高阶特征交互:
- 隐式的方式:NFM,PNN、FNN、DeepCrossing、Wide&Deep、DeepFM-可解释性差
- 显示:Deep&Cross、xDeepFM-很难解释哪些组合特征是有用的
- 有效的训练方法:HOFM-参数过多
模型结构
优缺点
优点:
1.找到意思相近的embedding并进行组合,形成一些可解释性较强的组合特征;
2.大量的实验也验证这种方式的高阶交叉组合的优势;
缺点:
1.个人感觉还是未能充分挖掘有意义的高阶交叉特征;此处的组合只是找到了关系相近的特征,关系相近的特征进行组合并不一定是合适的方式,也就是说multi-head selfattention能做到有意义的特征组合,但却不能说明关系不相近的特征的意义就不大。
————————————————
原文链接:https://blog.csdn.net/pearl8899/article/details/106747210
实验效果
代码
class AutomaticFeatureInteractionModel(torch.nn.Module):
"""
A pytorch implementation of AutoInt.
Reference:
W Song, et al. AutoInt: Automatic Feature Interaction Learning via Self-Attentive Neural Networks, 2018.
"""
def __init__(self, field_dims, embed_dim, atten_embed_dim, num_heads, num_layers, mlp_dims, dropouts, has_residual=True):
super().__init__()
self.num_fields = len(field_dims)
self.linear = FeaturesLinear(field_dims)
self.embedding = FeaturesEmbedding(field_dims, embed_dim)
self.atten_embedding = torch.nn.Linear(embed_dim, atten_embed_dim)
self.embed_output_dim = len(field_dims) * embed_dim
self.atten_output_dim = len(field_dims) * atten_embed_dim
self.has_residual = has_residual
self.mlp = MultiLayerPerceptron(self.embed_output_dim, mlp_dims, dropouts[1])
self.self_attns = torch.nn.ModuleList([
torch.nn.MultiheadAttention(atten_embed_dim, num_heads, dropout=dropouts[0]) for _ in range(num_layers)
])
self.attn_fc = torch.nn.Linear(self.atten_output_dim, 1)
if self.has_residual:
self.V_res_embedding = torch.nn.Linear(embed_dim, atten_embed_dim)
def forward(self, x):
"""
:param x: Long tensor of size ``(batch_size, num_fields)``
"""
embed_x = self.embedding(x)
atten_x = self.atten_embedding(embed_x)
cross_term = atten_x.transpose(0, 1)
for self_attn in self.self_attns:
cross_term, _ = self_attn(cross_term, cross_term, cross_term)
cross_term = cross_term.transpose(0, 1)
if self.has_residual:
V_res = self.V_res_embedding(embed_x)
cross_term += V_res
cross_term = F.relu(cross_term).contiguous().view(-1, self.atten_output_dim)
x = self.linear(x) + self.attn_fc(cross_term) + self.mlp(embed_x.view(-1, self.embed_output_dim))
return torch.sigmoid(x.squeeze(1))