一、概念
FM模型(Factorization Machine,因子分解机)是 2010 年提出的一种机器学习模型,专门针对高维稀疏数据场景下的特征交互问题设计,在推荐系统中主要用于预测用户对某个商品的评分或兴趣等任务。
它的核心思想是通过数学方法捕捉数据中不同特征之间的交叉关系(通过隐向量内积建模特征交叉),从而能有效处理用户行为数据稀疏性问题,更好地进行预测。例如,特征“用户A”和“商品X”的交互参数可通过“用户A”与其他商品、“商品X”与其他用户的交互间接学习,即使 “用户A-商品X”的样本极少,仍能通过隐向量的内积预测其交互强度。
轻量级FM变体可用于粗排初筛,平衡效果与计算效率(例如过滤低相关商品)。常规情况下,FM模型大都在精排阶段应用,例如需要显式建模特征组合的场景(如用户年龄×商品价格段)或者数据稀疏但需捕获隐式关系的任务(如冷启动用户推荐)。
二、原理
给定一个特征向量,FM模型的预测公式为:
其中,是全局偏置;
是特征i的权重;
是特征i的隐向量,维度为k;
表示隐向量之间的内积。从公式上看,FM模型由一个线性部分
和非线性部分
所组成,这使得FM具有比传统线性模型更好的特征捕捉能力。
传统的交叉项建模参数量庞大,FM将每个特征 i 映射到一个 k 维的隐向量
,另一个隐向量为
,从而使用两者的内积来代替
,即
。隐向量的维度 k 通常在100以内,远小于特征数 n,从而将参数数量从
降低到
。
三、python实现
import numpy as np
class FactorizationMachine:
def __init__(self, n_features, k=5, reg_w=0.01, reg_v=0.01):
self.n_features = n_features
self.k = k
self.reg_w = reg_w
self.reg_v = reg_v
self.w0 = 0.0
self.w = np.zeros(n_features)
self.V = np.random.normal(scale=0.1, size=(n_features, k))
def predict(self, X):
linear_terms = np.dot(X, self.w) + self.w0
interactions = 0.5 * np.sum(
np.power(np.dot(X, self.V), 2) - np.dot(np.power(X, 2), np.power(self.V, 2)),
axis=1
)
return linear_terms + interactions
def fit(self, X, y, epochs=10, learning_rate=0.01, decay_rate=0.9):
n_samples = X.shape[0]
for epoch in range(epochs):
current_lr = learning_rate / (1 + decay_rate * epoch)
indices = np.random.permutation(n_samples)
for i in indices:
xi = X[i]
yi = y[i]
pred = self.predict(xi.reshape(1, -1))[0]
error = yi - pred
# 更新偏置项
self.w0 += current_lr * (error - self.reg_w * self.w0)
# 更新一次项权重
self.w += current_lr * (error * xi - self.reg_w * self.w)
# 更新隐向量
for f in range(self.k):
v_f = self.V[:, f]
xiv_f = np.dot(xi, v_f)
self.V[:, f] += current_lr * (error * (xi * xiv_f - xi**2 * v_f) - self.reg_v * v_f)
# 每10个epoch打印一次MSE
if epoch % 10 == 0:
predictions = self.predict(X)
mse = np.mean((y - predictions) ** 2)
print(f"Epoch {epoch}, MSE: {mse:.4f}")
# 示例数据:用户-商品交互
# 假设有3个特征:用户ID、商品ID、商品类别
X = np.array([
[1, 1, 0],
[1, 2, 1],
[2, 1, 0],
[2, 2, 1],
[3, 1, 0],
[3, 2, 1]
])
# 假设的评分
y = np.array([5, 3, 4, 2, 1, 5])
# 初始化FM模型
fm = FactorizationMachine(n_features=3, k=2, reg_w=0.01, reg_v=0.01)
# 训练模型
fm.fit(X, y, epochs=100, learning_rate=0.01, decay_rate=0.9)
# 预测
predictions = fm.predict(X)
print("Predictions:", predictions)
四、模型对比
模型 | 应用场景 | 优势 | 劣势 |
---|---|---|---|
FM | 精排阶段(特征交叉建模) | 1. 自动学习二阶特征交叉 2. 计算复杂度O(kn) 3. 适合稀疏数据 | 1. 无法捕捉高阶非线性关系 2. 依赖特征工程质量 |
协同过滤CF | 召回阶段(相似度匹配) | 1. 无需显式特征 2. 直观可解释 | 1. 冷启动问题严重 2. 无法利用辅助信息 |
GBDT-LR | 精排阶段 | 1. 自动特征组合筛选 2. 树模型鲁棒性强 | 1. 特征交叉为硬性分桶 2. 无法端到端优化 |
Wide&Deep | 精排阶段 | 1. 兼顾记忆与泛化能力 2. 支持高阶特征交互 | 1. 训练复杂度高 2. 需要大量数据支撑 |