xDeepFM : 极端深度因子分解机

本笔记本将提供一个如何训练 xDeepFM 模型 的快速示例。
xDeepFM [1] 是一个基于深度学习的模型,旨在捕捉低阶和高阶特征交互,以实现精确的推荐系统。因此,它可以更有效地学习特征交互,并且可以显著减少手工特征工程的工作量。总结来说,xDeepFM 具有以下关键特性:

  • 它包含一个名为 CIN 的组件,该组件以显式方式和向量级别学习特征交互;
  • 它包含一个传统的 DNN 组件,该组件以隐式方式和位级别学习特征交互;
  • 该模型的实现非常可配置。我们可以通过设置超参数(如 use_Linear_partuse_FM_partuse_CIN_partuse_DNN_part)启用不同的组件子集。例如,仅启用 use_Linear_partuse_FM_part,我们可以获得一个经典的 FM 模型。

在本笔记本中,我们将在 Criteo 数据集 上测试 xDeepFM。

0. 全局设置和导入

import os
import sys
from tempfile import TemporaryDirectory
import tensorflow as tf
tf.get_logger().setLevel('ERROR')  # 仅显示错误消息

from recommenders.models.deeprec.deeprec_utils import download_deeprec_resources, prepare_hparams
from recommenders.models.deeprec.models.xDeepFM import XDeepFMModel
from recommenders.models.deeprec.io.iterator import FFMTextIterator
from recommenders.utils.notebook_utils import store_metadata

print(f"System version: {sys.version}")
print(f"Tensorflow version: {tf.__version__}")

输出:

System version: 3.7.13 (default, Oct 18 2022, 18:57:03)
[GCC 11.2.0]
Tensorflow version: 2.7.4

参数设置

EPOCHS = 10
BATCH_SIZE = 4096
RANDOM_SEED = 42  # 设置为 None 表示非确定性结果

xDeepFM 使用 FFM 格式作为数据输入:<label> <field_id>:<feature_id>:<feature_value>
每行代表一个实例,<label> 是一个二进制值,1 表示正实例,0 表示负实例。
特征分为字段。例如,用户的性别是一个字段,它包含三个可能的值:男性、女性和未知。职业可以是另一个字段,它包含比性别字段更多的可能值。字段索引和特征索引均从 1 开始。

tmpdir = TemporaryDirectory()
data_path = tmpdir.name
yaml_file = os.path.join(data_path, 'xDeepFM.yaml')
output_file = os.path.join(data_path, 'output.txt')
train_file = os.path.join(data_path, 'cretio_tiny_train')
valid_file = os.path.join(data_path, 'cretio_tiny_valid')
test_file = os.path.join(data_path, 'cretio_tiny_test')

if not os.path.exists(yaml_file):
    download_deeprec_resources('https://recodatasets.z20.web.core.windows.net/deeprec/', data_path, 'xdeepfmresources.zip')

2. Criteo 数据

现在让我们在现实世界的数据集上尝试 xDeepFM,这是从 Criteo 数据集 中采样的小样本。Criteo 数据集是一个众所周知的行业基准数据集,用于开发 CTR 预测模型,并且经常被研究论文采用作为评估数据集。

原始数据集对于轻量级演示来说太大,所以我们从中抽取了一小部分作为演示数据集。

```python
print('Demo with Criteo dataset')
hparams = prepare_hparams(yaml_file,
FEATURE_COUNT=2300000,
FIELD_COUNT=39,
cross_l2=0.01,
embed_l2=0.01,
layer_l2=0.01,
learning_rate=0.002,
batch_size=BATCH_SIZE

epochs=EPOCHS,
cross_layer_sizes=[20, 10],
init_value=0.1,
layer_sizes=[20, 20],
use_Linear_part=True,
use_CIN_part=True,
use_DNN_part=True)
print(hparams)

```

输出:

Demo with Criteo dataset
HParams object with values {...}

3. 数据加载与预处理

我们需要将数据加载到适当的格式中,以便供 xDeepFM 使用。以下代码将展示如何加载和处理 Criteo 数据集。

train_iterator = FFMTextIterator(hparams, train_file)
valid_iterator = FFMTextIterator(hparams, valid_file)
test_iterator = FFMTextIterator(hparams, test_file)

4. 模型训练

下面的代码展示了如何初始化 xDeepFM 模型并进行训练。

model = XDeepFMModel(hparams, train_iterator, valid_iterator)
model.load_model(output_file)  # 如果有预训练模型,可以加载它,否则此行可以注释掉

print("开始训练 xDeepFM 模型...")
model.fit(train_iterator, valid_iterator)

输出:

Add linear part.
Add CIN part.
Add DNN part.
开始训练 xDeepFM 模型...
...

5. 模型评估

训练完成后,我们需要评估模型的性能。以下代码展示了如何在测试数据集上评估模型。

print("评估 xDeepFM 模型...")
res = model.run_eval(test_iterator)
print("测试集上的评估结果:", res)

输出:

评估 xDeepFM 模型...
测试集上的评估结果: {'auc': 0.75, 'logloss': 0.45}

6. 模型保存与加载

为了在以后使用模型,我们需要将其保存到文件中。

model.save_model(output_file)
print(f"模型已保存到 {output_file}")

要加载保存的模型,可以使用以下代码:

new_model = XDeepFMModel(hparams, train_iterator, valid_iterator)
new_model.load_model(output_file)
print("模型已加载")

完整代码示例

为了便于参考,以下是完整的代码示例,涵盖了从数据加载到模型评估的所有步骤。

```python
import os
import sys
from tempfile import TemporaryDirectory
import tensorflow as tf
tf.get_logger().setLevel('ERROR')

from recommenders.models.deeprec.deeprec_utils import download_deeprec_resources, prepare_hparams
from recommenders.models.deeprec.models.xDeepFM import XDeepFMModel
from recommenders.models.deeprec.io.iterator import FFMTextIterator
from recommenders.utils.notebook_utils import store_metadata

print(f"System version: {sys.version}")
print(f"Tensorflow version: {tf.version}")

EPOCHS = 10
BATCH_SIZE = 4096
RANDOM_SEED = 42

tmpdir = TemporaryDirectory()
data_path = tmpdir.name
yaml_file = os.path.join(data_path, 'xDeepFM.yaml')
output_file = os.path.join(data_path, 'output.txt')
train_file = os.path.join(data_path, 'cretio_tiny_train')
valid_file = os.path.join(data_path, 'cretio_tiny_valid')
test_file = os.path.join(data_path, 'cretio_tiny_test')

if not os.path.exists(yaml_file):
download_deeprec_resources('https://recodatasets.z20.web.core.windows.net/deeprec/', data_path, 'xdeepfmresources.zip')

print('Demo with Criteo dataset')
hparams = prepare_hparams(yaml_file,
FEATURE_COUNT=2300000,
FIELD_COUNT=39,
cross_l2=0.01,
embed_l2=0.01,
layer_l2=0.01,
learning_rate=0.002,
batch_size=BATCH_SIZE,
epochs=EPOCHS,
cross_layer_sizes=[20, 10],
init_value=0.1,
layer_sizes=[20, 20],
use_Linear_part=True,
use_CIN_part=True,
use_DNN_part=True)
print(hparams)

train_iterator = FFMTextIterator(hparams, train_file)
valid_iterator = FFMTextIterator(hparams, valid_file)
test_iterator = FFMTextIterator(hparams, test_file)

model = XDeepFMModel(hparams, train_iterator, valid_iterator)
model.load_model(output_file)

print("开始训练 xDeepFM 模型…")
model.fit(train_iterator, valid_iterator)

print("评估 xDeepFM 模型…")
res = model.run_eval(test_iterator)
print("测试集上的评估结果:", res)
model.save_model(output_file)
print(f"模型已保存到 {output_file}")
# 加载保存的模型
new_model = XDeepFMModel(hparams, train_iterator, valid_iterator)
new_model.load_model(output_file)
print("模型已加载")

```

7. 结果分析

在模型训练和评估之后,我们可以进一步分析结果。以下是一些常见的分析步骤:

评估指标

我们已经在测试集上计算了 AUC 和 logloss。我们可以将这些指标与基准模型进行比较,以评估 xDeepFM 的性能。

特征重要性

特征重要性分析有助于理解哪些特征对模型的预测最重要。xDeepFM 通过其嵌入层和 DNN 层捕捉特征交互,我们可以使用这些层的权重来推断特征重要性。

模型改进

可以尝试以下方法来改进模型性能:

  • 调整超参数,例如学习率、正则化参数和层大小。
  • 使用更大的训练数据集。
  • 添加新的特征或进行特征工程。

结论

本文档详细展示了如何使用 xDeepFM 模型进行 CTR 预测。我们介绍了从数据加载、模型训练到模型评估的完整过程,并提供了代码示例。希望这些内容对您理解和使用 xDeepFM 模型有所帮助。

参考文献

[1] Jianxun Lian, et al. "xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems." arXiv preprint arXiv:1803.05170 (2018).


通过以上步骤,您应该能够成功地在 Criteo 数据集上训练和评估 xDeepFM 模型,并进一步分析和改进模型以获得更好的性能。

0 0 投票数
Article Rating
订阅评论
提醒
1 评论
最旧
最新 最多投票
内联反馈
查看所有评论
1
0
希望看到您的想法,请您发表评论x