DeepFM 算法详解
1. 什么是 DeepFM?
DeepFM 是一种结合了**因子分解机(FM)和深度神经网络(DNN)**的混合模型,主要用于解决推荐系统、广告点击率(CTR)预测等任务中的特征组合学习问题。它能够同时捕捉低阶(如二阶)和高阶特征交互,无需人工特征工程。
2. 用途
- CTR预测:预测用户点击广告、商品的可能性。
- 推荐系统:根据用户行为和历史数据推荐内容。
- 排序任务:在信息检索中对候选项目进行排序。
3. 原理
DeepFM 包含两个并行组件:
- FM部分:处理低阶特征交互,通过隐向量内积建模二阶组合。
- DNN部分:通过多层神经网络捕捉高阶特征交互。
模型结构:
- 输入层:原始特征(包括数值型和类别型)。
- 嵌入层:将稀疏的类别特征转换为稠密向量(所有特征共享同一嵌入层)。
- FM组件:
- 一阶项:特征的线性加权和。
- 二阶项:特征隐向量的两两内积之和(优化计算方式)。
- DNN组件:将嵌入向量展平后输入全连接网络。
- 输出层: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)
代码说明
- 数据生成:使用虚拟数据模拟5个类别型特征,每个特征取值为0-9。
- 嵌入层:每个特征映射到8维向量,嵌入层共享。
- FM部分:
- 一阶项:对嵌入向量加权求和。
- 二阶项:通过公式 ((Σv_i)^2 - Σv_i^2) 高效计算。
- DNN部分:拼接嵌入向量后输入全连接网络。
- 模型训练:使用二元交叉熵损失和Adam优化器。
关键点
- 共享嵌入:FM和DNN共享同一嵌入层,减少参数量。
- 高效二阶计算:避免显式计算所有特征对,降低复杂度至 (O(kn))。
- 端到端训练:两部分联合训练,无需分阶段。
改进方向
- 处理数值型特征:将数值特征与嵌入向量拼接后输入DNN。
- 调整超参数:如嵌入维度、网络层数、学习率等。
- 添加正则化:如Dropout或L2正则防止过拟合。
DeepFM通过结合FM和DNN的优势,在特征交互建模上表现出色,是CTR预测任务中的经典模型。