想象你开了一家餐厅,一面是「点菜老师傅」,他几十年经验,深知番茄配鸡蛋、土豆配牛肉这类两两搭配的经典组合;另一面是「创意主厨」,他脑洞大开,能把七八种食材融合成一道分子料理。两位大师共享同一间厨房、同一只冰箱——这就是 DeepFM 的精髓:让擅长低阶组合的 FM 与擅长高阶创意的 DNN 在同一「厨房」里协作,端到端输出一道完美预测菜:用户到底会不会点这道菜。 CTR 预估(点击率预估)正是推荐系统的核心任务——预测用户会不会点击某个商品或广告。DeepFM 用一个模型同时捕获低阶和高阶特征交互,既不需要人工构造交叉特征,又能端到端联合训练,是当前工业界最实用的深度推荐模型之一。

岗位关联

掌握 DeepFM,你将理解「低阶记忆 + 高阶泛化」如何在一个模型里协同工作,这是推荐系统工程师设计排序模型、提升点击率的核心基本功。

目录
  1. 可视化演示
  2. 模型总览
  3. FM因子分解
  4. DNN深度网络
  5. Wide&Deep对比
  6. 特征交互
  7. 模型训练
  8. 应用场景
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示DeepFM共享Embedding的FM+DNN联合架构、FM二阶特征交叉的内积计算,以及低阶高阶交互的分工协作。

本节配有交互动效(进入视口后自动加载,约 3KB)。

'+_captions.arch+'

模型总览

你经营一家餐厅,想预测每位食客会不会点某道招牌菜。你请来两位大师:点菜老师傅(FM)经验老到,对「番茄配鸡蛋」「土豆配牛肉」这类两两搭配如数家珍;创意主厨(DNN)则擅长把多种食材层层融合,做出令人惊喜的分子料理。更妙的是,他们共享同一间厨房和同一只冰箱——不搞「各做各的再拼盘」,而是互相协作、一起出菜。这个「同一厨房」的设计,就是 DeepFM 的灵魂。

在推荐系统里,这家餐厅要解决的问题正是 CTR(点击率)预估:给定用户、商品、场景等特征,预测用户点击的概率。传统方法分两条路:FM 擅长二阶特征交互,但对高阶交互无能为力;DNN 能自动学习高阶非线性,却往往忽略了低阶的显式组合。DeepFM 把两者并入一个模型,让 FM 负责低阶(一阶权重 + 二阶交叉),DNN 负责高阶,最后把两路分数相加。

DeepFM 的最终输出用一个简单公式概括:

所以 DeepFM 的哲学很朴素:经验丰富的老师傅与脑洞大开的主厨在同一厨房协作,既不需要人工设计菜谱(交叉特征),又能同时端出低阶与高阶两道「交互菜」。

y^=σ(y^FM(x)+y^DNN(x))\displaystyle \hat{y} = \sigma\left( \hat{y}_{FM}(\mathbf{x}) + \hat{y}_{DNN}(\mathbf{x}) \right)
这个公式说明:预测值 = 老师傅的点菜分数 + 主厨的创意分数,再统一换算成 0~1 的概率。
  1. FM 部分输出老师傅的经验分,包含全局偏置、一阶权重和两两特征交互
    y^FM(x)=w0+∑i=1nwixi+∑i=1n∑j=i+1n⟨vi,vj⟩xixj\displaystyle \hat{y}_{FM}(\mathbf{x}) = w_0 + \sum_{i=1}^{n} w_i x_i + \sum_{i=1}^{n}\sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j
  2. DNN 部分输出主厨的创意分,把特征 Embedding 拼接后经过多层全连接网络
    y^DNN(x)=MLP(concat(e1,e2,…,em))\displaystyle \hat{y}_{DNN}(\mathbf{x}) = \text{MLP}\left( \text{concat}(\mathbf{e}_1, \mathbf{e}_2, \ldots, \mathbf{e}_m) \right)
  3. σ 函数将两路相加的分数压缩到 0~1 之间,成为可解释的点击概率
    σ(z)=11+e−z\displaystyle \sigma(z) = \frac{1}{1 + e^{-z}}

FM因子分解

点菜老师傅的经验不是死记硬背「番茄必须配鸡蛋」,而是给每样食材赋予一个「风味档案」。番茄的档案是「酸甜、多汁」,鸡蛋的档案是「蛋香、绵密」,两个档案越匹配,这道经典菜就越受欢迎。这个「风味档案」在数学上就是隐向量,而判断两个食材是否匹配,就看它们的隐向量内积是否够大。

FM(因子分解机)处理的正是这样的场景:推荐系统的输入往往是大规模稀疏的 one-hot 特征——用户 100 万个 ID,只有当前用户那一位是 1。如果直接为每一对特征学习交叉权重 w_ij,绝大多数组合从未在训练集中出现过,权重根本学不出来。FM 的破局之道是:把交叉权重拆成两个隐向量的内积。

FM 的二阶交互部分长这样:

这个设计妙在:即使「某个用户 × 某个商品」从未一起出现,只要用户隐向量和商品隐向量各自被其他样本训练过,就能算出它们的内积——这就是 FM「冷启动」的底气。

y^FM(2)(x)=∑i=1n∑j=i+1n⟨vi,vj⟩xixj\displaystyle \hat{y}_{FM}^{(2)}(\mathbf{x}) = \sum_{i=1}^{n}\sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j
意思是:对所有特征对 (i, j),用隐向量 v_i 与 v_j 的内积来衡量它们的搭配效果,再乘以特征的取值。
  1. 遍历所有特征对外层 i 从 1 到 n,内层 j 从 i+1 到 n,保证每对只算一次
    ∑i=1n∑j=i+1n\displaystyle \sum_{i=1}^{n}\sum_{j=i+1}^{n}
  2. 隐向量内积⟨v_i, v_j⟩ 表示第 i 个特征与第 j 个特征的「风味契合度」
    ⟨vi,vj⟩=∑f=1kvi,fvj,f\displaystyle \langle \mathbf{v}_i, \mathbf{v}_j \rangle = \sum_{f=1}^{k} v_{i,f} v_{j,f}
  3. 乘以特征实际值x_i 和 x_j 为 0/1 时表示特征是否存在,连续特征则表示强度
    xixj\displaystyle x_i x_j

DNN深度网络

创意主厨的做法则完全不同。他不满足于两两搭配,而是把食材先切碎(提取 Embedding),再一层层搅拌、加热、乳化(多层感知机),让看似无关的食材在多次「化学反应」中产生全新风味。这就是 DNN 捕捉高阶特征交互的方式。

在 DeepFM 中,DNN 的输入不是原始 one-hot 向量,而是每个特征域查表得到的 Embedding 向量拼接结果。假设用户域查到 4 维向量,商品域查到 4 维向量,拼接后就是 8 维的「食材碎末」,然后送进多层全连接网络。每经过一层,网络就做一次线性变换加非线性激活,信息不断重组,最终形成高阶交互表达。

DNN 部分的逐层传播公式:

有了这些层层的非线性变换,DNN 就能自动组合「深夜 + 美食 + 健身」这类三阶甚至更高阶的兴趣信号,这是老师傅的单层经验无法企及的。

a(l+1)=ReLU(W(l)a(l)+b(l))\displaystyle \mathbf{a}^{(l+1)} = \text{ReLU}\left( \mathbf{W}^{(l)} \mathbf{a}^{(l)} + \mathbf{b}^{(l)} \right)
每一层都把上一层的信号做加权组合,再通过 ReLU 去掉负值,让网络具备非线性拟合能力。
  1. 第 l 层输入a⁽ˡ⁾ 是上一层的输出向量,首层是拼接后的 Embedding
    a(l)∈Rdl\displaystyle \mathbf{a}^{(l)} \in \mathbb{R}^{d_l}
  2. 线性变换权重矩阵 W⁽ˡ⁾ 与输入相乘,加上偏置 b⁽ˡ⁾,相当于一次「食材调味」
    W(l)a(l)+b(l)\displaystyle \mathbf{W}^{(l)} \mathbf{a}^{(l)} + \mathbf{b}^{(l)}
  3. ReLU 激活把负值截断为 0,引入非线性,让网络能表达复杂交互
    ReLU(z)=max⁡(0,z)\displaystyle \text{ReLU}(z) = \max(0, z)

Wide&Deep对比

你可能听过 Wide&Deep——它像两家餐厅的「拼盘合作」:Wide 餐厅负责提供几道人工设计的固定搭配(比如「晴天 + 冰淇淋」这种规则特征),Deep 餐厅负责做自由创意菜,最后把两道菜拼在一个盘子里端给顾客。问题是,Wide 那几道固定菜需要厨师长(算法工程师)手工研发,费时费力。

DeepFM 则让老师傅(FM)和主厨(DNN)在同一厨房协作。FM 部分自己就能自动挖掘二阶搭配,不需要任何人手工指定「番茄配鸡蛋」,而且 FM 和 DNN 共享 Embedding 层,互相促进,这是拼盘模式的 Wide&Deep 做不到的。

Wide&Deep 的输出公式对照:

正因为 DeepFM 用 FM 替换了 Wide,二阶交叉特征不再依赖人力,模型效率与效果都上了一个台阶。

y^Wide&Deep=σ(wwideT[x,ϕ(x)]+wdeepTa(lf)+b)\displaystyle \hat{y}_{Wide\&Deep} = \sigma\left( \mathbf{w}_{wide}^{T} [\mathbf{x}, \phi(\mathbf{x})] + \mathbf{w}_{deep}^{T} \mathbf{a}^{(l_f)} + b \right)
Wide 部分需要人工构造交叉特征 φ(x),Deep 部分负责自动化高阶学习。
  1. Wide 部分对原始特征和人工交叉特征 φ(x) 做线性加权,像点菜谱上的固定套餐
    wwideT[x,ϕ(x)]\displaystyle \mathbf{w}_{wide}^{T} [\mathbf{x}, \phi(\mathbf{x})]
  2. Deep 部分深层网络最后一层输出 a^(l_f) 再做线性加权,像创意主厨的收尾摆盘
    wdeepTa(lf)\displaystyle \mathbf{w}_{deep}^{T} \mathbf{a}^{(l_f)}
  3. 拼接求和两路结果相加再过 σ,输出点击概率
    σ(⋅+⋅)\displaystyle \sigma(\cdot + \cdot)

特征交互

共享冰箱的秘密在于:老师傅在思考「番茄配鸡蛋」时,主厨可能正在用鸡蛋做一道分子料理的「绑合剂」。双方看到的食材(Embedding)完全相同,一个人对食材的理解进步,另一个人也立刻受益。这正是共享 Embedding 带来的低阶与高阶交互的信息互补。

低阶交互指两个特征之间的显式组合,比如「星期天 + 电影票」,直观、可解释、在少量样本下就能学稳;高阶交互指多个特征经过多层网络融合后的隐式表达,比如「年轻用户 + 晚上十点 + 外卖 App + 小龙虾」,这种组合在原始样本中极稀疏,必须靠 DNN 泛化出来。FM 捕捉前者,DNN 捕捉后者,而共享 Embedding 让两者使用同一套特征表示,谁学到了新知识都会传递给另一方。

这种互补关系可以这样理解:

这种「一套特征两路复用」的设计,让 DeepFM 既能记住稳定的规律,又能探索新奇的偏好,在推荐场景中尤其珍贵。

y^=y^FM(x)⏟低阶显式交互+y^DNN(x)⏟高阶隐式交互\displaystyle \hat{y} = \underbrace{\hat{y}_{FM}(\mathbf{x})}_{\text{低阶显式交互}} + \underbrace{\hat{y}_{DNN}(\mathbf{x})}_{\text{高阶隐式交互}}
低阶项保证了推荐的「记忆」与可解释性,高阶项保证了「泛化」与惊喜度。
  1. FM 低阶项显式计算所有两两组合,类似老师傅的经典菜谱,稳定可靠
    y^FM(x)=w0+∑wixi+∑i<j⟨vi,vj⟩xixj\displaystyle \hat{y}_{FM}(\mathbf{x}) = w_0 + \sum w_i x_i + \sum_{i<j}\langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j
  2. DNN 高阶项隐式学习复杂组合,像主厨的即兴创意,覆盖长尾需求
    y^DNN(x)=MLP(concat(Embedding(x)))\displaystyle \hat{y}_{DNN}(\mathbf{x}) = \text{MLP}\left( \text{concat}(\text{Embedding}(\mathbf{x})) \right)
  3. 共享基础两者使用相同的 Embedding 查表结果,保证信息一致性
    Embedding(x) 同时供给 FM 与 DNN\displaystyle \text{Embedding}(\mathbf{x}) \text{ 同时供给 FM 与 DNN}

模型训练

店长(损失函数)要用一套统一的「满意评分」来同时考核两位厨师:食客真的点了这道菜,满分;点了别家菜,零分。所有厨师——不管是老师傅还是主创——都要根据这份评分调整自己的手法,谁对结果贡献大,谁就改得多。这套奖惩机制就是反向传播。

DeepFM 是一个端到端模型,FM 与 DNN 的所有参数(包括共享 Embedding)一起参与训练。由于 CTR 预估是二分类问题,最常用的损失是交叉熵(LogLoss):

训练时,梯度会沿两条路径同时回传,老师傅的经典菜谱(FM 参数)和主厨的创新配方(DNN 参数)同步改进,共享冰箱里的食材(Embedding)也在每一次迭代中被两家共同打磨。

L=−1N∑t=1N[ytlog⁡y^t+(1−yt)log⁡(1−y^t)]\displaystyle \mathcal{L} = -\frac{1}{N}\sum_{t=1}^{N}\left[ y_t \log \hat{y}_t + (1-y_t) \log (1-\hat{y}_t) \right]
当真实点击 y=1 而模型预测趋近 0 时,损失趋近无穷大,模型会被强烈惩罚。
  1. 遍历 N 个样本每个训练样本(用户-商品-行为)都算一次损失
    1N∑t=1N\displaystyle \frac{1}{N}\sum_{t=1}^{N}
  2. 正样本项真实点击 y_t=1 时只保留第一项,预测越接近 1 损失越小
    ytlog⁡y^t\displaystyle y_t \log \hat{y}_t
  3. 负样本项真实未点击 y_t=0 时只保留第二项,惩罚把负样本预测为高概率
    (1−yt)log⁡(1−y^t)\displaystyle (1-y_t) \log (1-\hat{y}_t)
  4. 负号与平均让损失为正数并求平均,方便梯度下降优化
    −1N∑t=1N[⋅]\displaystyle -\frac{1}{N}\sum_{t=1}^{N}[\cdot]

应用场景

这家「双厨餐厅」一旦运营成熟,就可以开连锁店了。DeepFM 在工业界遍地开花,凡是需要预测用户会不会点的场景,都有它的身影——信息流里会不会点开文章,广告位上会不会点击商品,搜索结果里会不会点进详情页。

在信息流推荐中,输入通常是「用户 ID + 文章类别 + 阅读时长 + 时间段」等特征。DeepFM 的 FM 部分能快速学到「足球迷 + 体育频道」这种稳定搭配,DNN 部分则能捕捉「深夜 + 美食类 + 健身人群」这种复杂的上下文兴趣,两者融合后 CTR(点击率)预估更准。在广告场景,CTR 预估直接决定广告排序和出价,DeepFM 的精准度直接影响营收。实际部署时,Embedding 表常驻内存,FM 二阶项可写成稀疏格式快速计算,DNN 部分用 TensorRT 或 ONNX 加速推理,单次预估耗时控制在毫秒级。

衡量这类场景效果的标准指标是 AUC:

AUC=1N+N−∑i∈pos∑j∈negI(y^i>y^j)\displaystyle AUC = \frac{1}{N^+ N^-} \sum_{i \in \text{pos}} \sum_{j \in \text{neg}} \mathbb{I}\left( \hat{y}_i > \hat{y}_j \right)
AUC 表示随机抽一个正样本和一个负样本,正样本得分更高的概率,越接近 1 越好。
  1. 正负样本配对遍历所有正样本 i 和负样本 j
    ∑i∈pos∑j∈neg\displaystyle \sum_{i \in \text{pos}} \sum_{j \in \text{neg}}
  2. 比较大小指示函数 I(·) 在正样本预测值大于负样本时为 1
    I(y^i>y^j)\displaystyle \mathbb{I}\left( \hat{y}_i > \hat{y}_j \right)
  3. 求平均除以正负样本总数 N⁺N⁻,得到 0~1 之间的排名指标
    1N+N−\displaystyle \frac{1}{N^+ N^-}

AI 应用场景

信息流推荐系统的 CTR 预估

阶段:推荐排序(Ranking)

解决的问题:传统 LR 需要人工构造「用户 × 文章」交叉特征,工程量大且覆盖不了长尾组合。DeepFM 的 FM 部分自动做二阶交叉,DNN 部分挖掘三阶以上的复杂兴趣组合,端到端预测点击概率,无需手工交叉。

具体案例:某新闻 App 在排序层引入 DeepFM,输入「用户 ID、文章 ID、类目、时段、历史点击序列」等特征后,CTR 提升 12%,原本每周手工产出交叉特征报表的团队得以转向更上层的策略优化。

广告竞价排序

阶段:广告排序与出价

解决的问题:广告平台需对每次曝光预估点击率,用于竞价排序。百亿级稀疏特征下,DeepFM 既能用 FM 自动组合「设备 × 广告位」等低阶模式,又能用 DNN 学习「年轻用户 + 深夜 + 美妆广告」的高阶上下文,提升预估精度与广告收入。

具体案例:某广告平台用 DeepFM 替换 LR 后,AUC 提升约 0.02,在相同预算下点击量提升 8%,ECPM 显著改善。

电商搜索排序

阶段:搜索召回与排序

解决的问题:电商搜索的「查询词 × 商品」组合空间巨大,人工交叉不现实。DeepFM 的共享 Embedding 让「保暖」「羽绒服」这类语义相关信息同时被 FM 与 DNN 利用,缓解稀疏性问题。

具体案例:某电商平台将 DeepFM 应用于搜索排序特征层后,发现「猫咪图案」与「宠物用品」这类跨域长尾组合被模型自动学到,长尾搜索转化率提升 9%。

Python 演示

python56 行
import numpy as np  class DeepFM:    """简化版 DeepFM:FM 二阶交叉 + DNN 高阶交叉(NumPy 实现)"""    def __init__(self, n_fields, n_symbols, k=8, hidden=(16, 8), seed=42):        rng = np.random.default_rng(seed)        self.n_fields = n_fields            # 特征域数量,如 用户、商品、场景        self.n_symbols = n_symbols          # 每个域的词表大小(one-hot 维度)        self.k = k                          # Embedding 维度        self.w0 = 0.0        self.w = np.zeros(n_fields * n_symbols)   # 一阶权重        self.V = rng.normal(0, 0.01, (n_fields * n_symbols, k))  # 隐向量表        self.offsets = [i * n_symbols for i in range(n_fields)]   # 每个域起始索引        dims = [n_fields * k] + list(hidden)        self.Ws = [rng.normal(0, 0.1, (dims[i], dims[i + 1])) for i in range(len(hidden))]        self.bs = [np.zeros(dims[i + 1]) for i in range(len(hidden))]     def _embed(self, x_idx):        """把每个域选中的符号索引映射为拼接后的 Embedding 向量"""        emb_list = []        for f in range(self.n_fields):            idx = self.offsets[f] + x_idx[f]            emb_list.append(self.V[idx])        return np.concatenate(emb_list)     def fm_part(self, x_idx):        """FM 部分:一阶线性 + 二阶两两隐向量内积"""        x_flat = np.zeros(self.n_fields * self.n_symbols)        for f in range(self.n_fields):            x_flat[self.offsets[f] + x_idx[f]] = 1.0        linear = self.w0 + x_flat @ self.w        embeds = [self.V[self.offsets[f] + x_idx[f]] for f in range(self.n_fields)]        interaction = 0.0        for i in range(self.n_fields):            for j in range(i + 1, self.n_fields):                interaction += embeds[i] @ embeds[j]        return linear + interaction     def dnn_part(self, x_idx):        """DNN 部分:拼接 Embedding 过多层 ReLU 网络"""        a = self._embed(x_idx).reshape(1, -1)        for W, b in zip(self.Ws, self.bs):            a = np.maximum(0, a @ W + b)        return float(a.sum())     def predict(self, x_idx):        """两路输出相加,过 Sigmoid 得到点击概率"""        z = self.fm_part(x_idx) + self.dnn_part(x_idx)        return 1.0 / (1.0 + np.exp(-z))  if __name__ == "__main__":    model = DeepFM(n_fields=3, n_symbols=10, k=4)    sample = np.array([2, 5, 8])  # 用户=2,商品=5,场景=8    print("CTR 预估值:", round(model.predict(sample), 4))
目的:用 NumPy 从零实现 DeepFM 前向传播,演示 FM 二阶交叉与 DNN 高阶交叉如何共享 Embedding 并相加输出。
  1. self.V = rng.normal(0, 0.01, (n_fields * n_symbols, k))初始化每个特征 ID 的隐向量,供 FM 二阶内积和 DNN 共享使用
  2. self.offsets = [i * n_symbols for i in range(n_fields)]记录每个特征域在扁平词表中的起点,方便查 Embedding
  3. emb_list.append(self.V[self.offsets[f] + x_idx[f]])取出当前域选中的那个 ID 对应的向量,这是共享 Embedding 的查表核心
  4. interaction += embeds[i] @ embeds[j]FM 二阶核心:对每对特征域的隐向量做内积
  5. linear = self.w0 + x_flat @ self.w一阶部分:全局偏置加一阶权重加权和
  6. a = self._embed(x_idx).reshape(1, -1)DNN 输入:拼接后的 Embedding 向量
  7. a = np.maximum(0, a @ W + b)ReLU 激活,逐层前向传播
  8. z = self.fm_part(x_idx) + self.dnn_part(x_idx)两路分数相加,模拟「老师傅 + 主厨」协同出菜

常见误区

误区我以为 DeepFM 只是把 Wide&Deep 的 Wide 部分换成 FM,本质没区别,甚至觉得 Wide&Deep 更先提出、更新。

正解两者内核差异很大。Wide 的逻辑回归需要人工构造交叉特征来「记忆」,Deep 侧负责「泛化」;而 DeepFM 用 FM 在 Embedding 层自动学习二阶交叉,完全不需要人工设计交叉特征,且 FM 与 DNN 共享 Embedding 端到端同步训练,信息利用效率更高。

为何常见:两者结构图都是「浅层 + 深层」双塔,形状相似,初学者容易只看结构轮廓而忽略浅层部分的工作方式差别。

误区既然 DNN 是万能的函数逼近器,能自动学习特征组合,那 FM 就是画蛇添足,直接去掉也能达到类似效果。

正解对高维稀疏特征,DNN 要学二阶交叉需要经过多层非线性组合,优化难度大、收敛慢,且容易欠拟合。FM 的显式二阶内积为低阶交互提供了「快捷键」,同时 FM 的梯度还能反向帮助共享 Embedding 层训练得更充分。大量实验证明,去掉 FM 部分后 AUC 会明显下降。

为何常见:深度学习的「万能逼近定理」让人产生深度可以替代一切的直觉,忽略了稀疏数据下优化难度的现实。

误区我认为 k 越大信息越丰富,于是把隐向量维度设置成 512 甚至 1024,觉得模型一定会更强。

正解隐向量维度决定特征表示的容量,但并非越大越好。维度太大容易在稀疏 ID 特征上过拟合,同时计算量剧增。实际工程中 k=8~16 已经足够,因为 FM 的特征交互只依赖两个 k 维向量的内积,DNN 也共享同一套低维稠密表示。

为何常见:深度学习中「更宽更大的网络更好」的经验被错误迁移到 Embedding 维度上,忽略了稀疏特征与小样本的矛盾。

误区模型能自动做交叉特征,那我应该把所有原始字段直接丢进模型,什么都不用准备了。

正解DeepFM 只是替你完成了「交叉特征」这一步,基础的清洗、去重、归一化、缺失值处理仍然必不可少。离散字段要编码成稳定的 ID 并做频次过滤,连续字段要归一化或分桶,否则 Embedding 查表的稳定性和训练效率都会大受影响。

为何常见:技术宣传常说「自动特征交叉」,让新手误以为连数据预处理都可以省略,忽略了特征工程是模型效果的基础保障。

误区DeepFM 效果这么好,我把所有推荐任务都换成 DeepFM 就行了,肯定最优。

正解模型选择取决于数据形态与业务约束。当特征极稀疏但样本量很小时,单独 FM 甚至 LR 可能更稳;当用户行为序列信息丰富时,含注意力序列建模的 DIN 系列更合适;当业务强依赖可解释性时,LR 或 GBDT 依然不可替代。DeepFM 最擅长的是「海量稀疏 ID 特征 + 大规模样本」的 CTR 预估场景。

为何常见:论文 SOTA 效果让人忽略适用边界,而工业界「没有免费午餐」——每种模型都有自己的前提条件。

面试题

Q1. DeepFM 中的 FM 部分主要负责什么?

单选题 · easy

  • A.捕捉高阶特征交互
  • B.捕捉低阶一二阶交互← 正确答案
  • C.只做全局线性加权
  • D.代替 DNN 筛选特征

答案:B。FM 部分负责一阶权重和二阶两两特征交叉,相当于老师傅的经典搭配经验;高阶交互由 DNN 负责。A 是 DNN 的职责,C 只描述了部分,D 不符合 FM 的设计。

Q2. DeepFM 输出层采用什么函数将分数转为 0~1 概率?

单选题 · easy

  • A.ReLU 激活函数
  • B.Softmax 归一化
  • C.Sigmoid 函数← 正确答案
  • D.Tanh 双曲正切

答案:C。CTR 预估是二分类问题,DeepFM 将 FM 与 DNN 的两路分数相加后过 Sigmoid(σ),把任意实数压缩到 (0,1) 区间作为点击概率。

Q3. DeepFM 相比 Wide&Deep 最核心的改进是?

单选题 · easy

  • A.去掉了 DNN 部分
  • B.用 FM 替代 Wide 部分← 正确答案
  • C.增加了注意力机制
  • D.无法端到端训练

答案:B。Wide&Deep 的 Wide 部分需要人工构造交叉特征,DeepFM 用 FM 自动学习二阶交叉来替代它,因此不再依赖人工特征工程,同时保持端到端训练。

Q4. FM 通过什么方式解决稀疏特征下二阶交叉参数难学习?

单选题 · mid

  • A.人工构造所有组合特征
  • B.用隐向量内积拆解权重← 正确答案
  • C.把稀疏特征转为稠密编码
  • D.用决策树做特征组合

答案:B。FM 将交叉权重 w_ij 拆成隐向量 v_i 与 v_j 的内积。即使某对特征从未共同出现,每个特征自身的隐向量也能从其他样本学到,内积仍然有效。A 是 Wide&Deep 的做法,C 描述的是 Embedding 而非交叉策略。

Q5. DeepFM 中 DNN 部分的输入是什么?

单选题 · mid

  • A.原始 one-hot 向量
  • B.FM 的一阶输出
  • C.特征 Embedding 拼接← 正确答案
  • D.FM 的二阶交互结果

答案:C。DNN 的输入是各特征域查表得到的 Embedding 向量拼接结果,这与 FM 共享同一张 Embedding 表。A 维度太高难以训练,B 和 D 是 FM 的输出而非 DNN 输入。

Q6. 关于 DeepFM 的结构,以下说法正确的有?

多选题 · mid

  • A.FM 与 DNN 共享 Embedding 层← 正确答案
  • B.两路输出相加后过 Sigmoid← 正确答案
  • C.FM 部分与输入特征完全无关
  • D.DNN 学习高阶非线性交互← 正确答案

答案:ABD。DeepFM 的 FM 和 DNN 确实共享 Embedding,输出相加过 Sigmoid,DNN 负责高阶交互。C 错误,FM 正是基于输入特征做二阶交叉。

Q7. CTR 预估任务在推荐系统中的核心作用是什么?

单选题 · mid

  • A.统计用户活跃天数
  • B.预测用户点击概率← 正确答案
  • C.降低服务器存储成本
  • D.自动清洗异常数据

答案:B。CTR 预估,即点击率预估,预测用户点击某个商品或广告的概率,直接用于排序与竞价,是推荐系统的核心环节。其余选项都不是 CTR 预估的职责。

Q8. 为什么 DeepFM 比「单独训练 FM + DNN 再融合」效果更好?

多选题 · hard

  • A.端到端联合训练相互协同← 正确答案
  • B.共享 Embedding 互相促进← 正确答案
  • C.模型总参数量必然更少
  • D.完全不需要输入特征处理

答案:AB。端到端训练让 FM 与 DNN 在同一个损失函数下协同优化,共享 Embedding 使低阶和高阶交互学习互相增强。C 不一定成立,参数量取决于配置;D 错误,输入特征处理仍然必要。

Q9. DeepFM 训练时通常选择的损失函数是?

单选题 · hard

  • A.均方误差 MSE
  • B.交叉熵 LogLoss← 正确答案
  • C.合页损失 Hinge
  • D.感知机损失函数

答案:B。CTR 预估是二分类,模型输出经过 Sigmoid 后是概率,交叉熵(LogLoss)能更好地度量概率分布差异并加速收敛。MSE 更适合回归,Hinge 主要用于 SVM 类模型。

Q10. 关于 DeepFM 的特征交互,下列说法正确的有?

多选题 · extreme

  • A.FM 仅做两两内积交互← 正确答案
  • B.DNN 多层非线性捕捉高阶← 正确答案
  • C.共享 Embedding 统一表示← 正确答案
  • D.稀疏特征需人工先交叉

答案:ABC。FM 的显式二阶交互只覆盖两两组合,高阶由 DNN 隐式学习;两者共享 Embedding 保证了特征表示的同一性。D 错误,DeepFM 的卖点正是无需人工交叉特征。