[推荐]DeepFM算法(实战)

619 阅读3分钟

DeepFM 算法详解

1. 什么是 DeepFM?

DeepFM 是一种结合了**因子分解机(FM)深度神经网络(DNN)**的混合模型,主要用于解决推荐系统、广告点击率(CTR)预测等任务中的特征组合学习问题。它能够同时捕捉低阶(如二阶)和高阶特征交互,无需人工特征工程。

2. 用途

  • CTR预测:预测用户点击广告、商品的可能性。
  • 推荐系统:根据用户行为和历史数据推荐内容。
  • 排序任务:在信息检索中对候选项目进行排序。

3. 原理

DeepFM 包含两个并行组件:

  • FM部分:处理低阶特征交互,通过隐向量内积建模二阶组合。
  • DNN部分:通过多层神经网络捕捉高阶特征交互。

模型结构

  1. 输入层:原始特征(包括数值型和类别型)。
  2. 嵌入层:将稀疏的类别特征转换为稠密向量(所有特征共享同一嵌入层)。
  3. FM组件
    • 一阶项:特征的线性加权和。
    • 二阶项:特征隐向量的两两内积之和(优化计算方式)。
  4. DNN组件:将嵌入向量展平后输入全连接网络。
  5. 输出层:FM和DNN的输出相加,通过Sigmoid得到预测概率。

完整 Python 代码示例(使用 TensorFlow/Keras)

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Input, Embedding, Dense, Flatten, Concatenate
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam

# 生成虚拟数据
num_samples = 10000
num_features = 5  # 假设5个类别型特征,每个特征有10个不同类别
embedding_dim = 8

# 随机生成输入数据(每个特征的索引)
X = np.random.randint(0, 10, size=(num_samples, num_features))
y = np.random.randint(0, 2, size=(num_samples))

# 定义模型输入
inputs = []
for i in range(num_features):
    inputs.append(Input(shape=(1,), name=f'feature_{i}'))

# 共享嵌入层
embeddings = []
embedding_layer = Embedding(input_dim=10, output_dim=embedding_dim, input_length=1)
for inp in inputs:
    emb = Flatten()(embedding_layer(inp))
    embeddings.append(emb)

# FM 部分
# 一阶项:直接求和
fm_first_order = Concatenate()(embeddings)
fm_first_order = Dense(1, use_bias=False)(fm_first_order)  # 权重求和

# 二阶项:使用优化公式计算
sum_square = tf.square(tf.reduce_sum(embeddings, axis=0))
square_sum = tf.reduce_sum(tf.square(embeddings), axis=0)
fm_second_order = 0.5 * tf.subtract(sum_square, square_sum)
fm_second_order = Dense(1, use_bias=False)(fm_second_order)

# DNN 部分
dnn = Concatenate()(embeddings)
dnn = Dense(128, activation='relu')(dnn)
dnn = Dense(64, activation='relu')(dnn)
dnn_output = Dense(1)(dnn)

# 合并FM和DNN
output = tf.keras.layers.add([fm_first_order, fm_second_order, dnn_output])
output = tf.keras.layers.Activation('sigmoid')(output)

# 构建模型
model = Model(inputs=inputs, outputs=output)
model.compile(optimizer=Adam(0.001), loss='binary_crossentropy', metrics=['accuracy'])

# 模型结构概览
model.summary()

# 训练模型(输入需转换为列表形式)
X_list = [X[:, i] for i in range(num_features)]
model.fit(X_list, y, epochs=10, batch_size=32, validation_split=0.2)
代码说明
  1. 数据生成:使用虚拟数据模拟5个类别型特征,每个特征取值为0-9。
  2. 嵌入层:每个特征映射到8维向量,嵌入层共享。
  3. FM部分
    • 一阶项:对嵌入向量加权求和。
    • 二阶项:通过公式 ((Σv_i)^2 - Σv_i^2) 高效计算。
  4. DNN部分:拼接嵌入向量后输入全连接网络。
  5. 模型训练:使用二元交叉熵损失和Adam优化器。
关键点
  • 共享嵌入:FM和DNN共享同一嵌入层,减少参数量。
  • 高效二阶计算:避免显式计算所有特征对,降低复杂度至 (O(kn))。
  • 端到端训练:两部分联合训练,无需分阶段。
改进方向
  • 处理数值型特征:将数值特征与嵌入向量拼接后输入DNN。
  • 调整超参数:如嵌入维度、网络层数、学习率等。
  • 添加正则化:如Dropout或L2正则防止过拟合。

DeepFM通过结合FM和DNN的优势,在特征交互建模上表现出色,是CTR预测任务中的经典模型。