推荐算法之AFM模型(注意力机制的引入)

AFM(Attentional Factorization Machines)是2017年提出的推荐系统模型,由NFM进化而来,引入注意力机制解决特征交互的权重问题。AFM模型保留了二阶交叉特征池化层,通过注意力网络赋予不同交互特征权重,提高预测效果。模型结构包括注意力网络和二阶交叉池化层,适用于回归和分类任务。
摘要由CSDN通过智能技术生成

前言

前面已经将结果很多推荐系统+深度学习的基础模型了,从这篇文章开始也进入到了注意力机制的章节。在AFM开始,大家都不再局限于将特征进行两两交互问题上面,而是开始探索一些新的结构。"Attention Mechanism"这个词现在已经不是新东西了,它来源于人类自然的选择注意习惯, 最典型的例子就是我们观察一些物体或者浏览网页时,不会聚焦于整个物体或者页面,而是会选择性的注意某些特定区域,忽视一些区域,往往会把注意力放到某些显眼的地方。 如果在建模过程中考虑到注意力机制对预测结果的影响,往往效果会更好。 近年来,注意力机制在各个领域大放异彩,比如NLP,CV等, 2017年开始,推荐领域也开始尝试将注意力机制加入模型,比如今天的AFM。

今天也是先介绍一些推荐系统+注意力机制的开胃菜AFM,首先还是看一下王喆老师的《深度学习推荐系统》已经梳理好了的知识体系。

在这里插入图片描述

1、AFM模型

 AFM(Attentional Factorization Machines)模型也是2017年由浙江大学和新加坡国立大学研究员提出的一个模型,AFM模型其实就是从前面讲解过的NFM模型的进化升级版, 该模型和NFM模型结构上非常相似, 算是NFM模型的一个延伸,在NFM中, 不同特征域的特征embedding向量经过特征交叉池化层的交叉,将各个交叉特征向量进行“加和”, 然后后面跟了一个DNN网络,但是NFM中的加和池化,它相当于“一视同仁”地对待所有交叉特征, 没有考虑不同特征对结果的影响程度,作者认为这可能会影响最后的预测效果, 因为不是所有的交互特征都能够对最后的预测起作用。 没有用的交互特征可能会产生噪声。或者说加大对预测结果重要的特征,抑制噪声特征。

举个例子来说如果应用场景是预测一位男性用户是否购买一款键盘的可能性, 那么“性别=男且购买历史包含鼠标”这个交叉特征, 很可能比“性别=男且用户年龄=30”这一个交叉特征重要。所以对于NFM来说对所有的二阶交叉特征进行无差别加和池化就不是很合理了。因此引入注意力机制就显得非常合理!

首先来看一下AFM的模型架构:

在这里插入图片描述

 可以看到的是,在这个模型之中并没有DNN模块,但是保存了NFM的二阶交叉特征池化层。

2、二阶交叉池化层

这里的二阶交叉池化层和前面讲过的NFM是一模一样的,在这里我也就不多做叙述了。但是在这里需要注意的是Attention的加入,并不是单单给某一个二维交叉特征一个权重,这样子的话对于未在训练数据中出现的交叉特征就无法进行权重赋予。所以在上图中

AFM(Attentional Factorization Machines)是一种结合了因子分解机(Factorization Machines)和注意力机制(Attention Mechanism)的推荐算法。它的目的是在因子分解机的基础上引入注意力机制,从而提高推荐系统的效果。下面是利用 PyTorch 实现 AFM 的基本步骤: 首先,需要导入所需的库和数据集。例如: ``` import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset from sklearn.model_selection import train_test_split import pandas as pd # 读取数据集 data = pd.read_csv('data.csv') ``` 然后,需要对数据进行预处理,包括将类别特征进行 one-hot 编码、将数值特征进行归一化等。例如: ``` # 对类别特征进行 one-hot 编码 cat_cols = ['user_id', 'item_id', 'genre'] for col in cat_cols: data[col] = data[col].astype('category') data = pd.get_dummies(data, columns=cat_cols) # 对数值特征进行归一化 num_cols = ['age', 'rating'] for col in num_cols: min_val = data[col].min() max_val = data[col].max() data[col] = (data[col] - min_val) / (max_val - min_val) ``` 接下来,需要将数据集划分为训练集和测试集,并将其转换为 PyTorch 的 Dataset 和 DataLoader。例如: ``` # 划分训练集和测试集 train_data, test_data = train_test_split(data, test_size=0.2) # 将数据集转换为 PyTorch 的 Dataset class AFMDataset(Dataset): def __init__(self, data): self.X = torch.tensor(data.drop('rating', axis=1).values, dtype=torch.float32) self.y = torch.tensor(data['rating'].values, dtype=torch.float32) def __len__(self): return len(self.X) def __getitem__(self, idx): return self.X[idx], self.y[idx] train_dataset = AFMDataset(train_data) test_dataset = AFMDataset(test_data) # 将数据集转换为 PyTorch 的 DataLoader train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) ``` 然后,需要定义 AFM 模型AFM 模型由两个部分组成:FM 层和注意力层。FM 层用于学习特征之间的交互关系,注意力层用于计算每个特征的权重。例如: ``` class FM(nn.Module): def __init__(self, num_features): super().__init__() self.num_features = num_features self.w = nn.Parameter(torch.randn(num_features)) self.bias = nn.Parameter(torch.randn(1)) def forward(self, x): interactions = torch.sum(torch.mm(x, x.t()) * self.w, dim=1) return interactions + self.bias class Attention(nn.Module): def __init__(self, num_features): super().__init__() self.num_features = num_features self.W = nn.Parameter(torch.randn(num_features, num_features)) self.bias = nn.Parameter(torch.randn(1)) def forward(self, x): scores = torch.mm(x, self.W) scores = torch.mm(scores, x.t()) scores = nn.functional.softmax(scores, dim=1) outputs = torch.mm(scores, x) return outputs + self.bias class AFM(nn.Module): def __init__(self, num_features): super().__init__() self.fm = FM(num_features) self.attention = Attention(num_features) def forward(self, x): fm_output = self.fm(x) attention_output = self.attention(x) output = fm_output + attention_output return torch.sigmoid(output) ``` 最后,需要定义损失函数和优化器,并训练模型。例如: ``` # 定义损失函数和优化器 criterion = nn.BCELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 训练模型 model = AFM(num_features=train_data.shape[1]-1) for epoch in range(10): for i, (inputs, targets) in enumerate(train_loader): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() # 计算测试集上的准确率 correct = 0 total = 0 with torch.no_grad(): for inputs, targets in test_loader: outputs = model(inputs) predicted = torch.round(outputs) total += targets.size(0) correct += (predicted == targets).sum().item() accuracy = correct / total print(f'Epoch {epoch+1}, Test Accuracy: {accuracy:.2f}') ``` 通过以上步骤,就可以利用 PyTorch 实现 AFM 推荐算法了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值