深夜十一点,街角的川菜馆里,老板盯着后厨的出菜单发呆。他想知道:顾客今晚会不会点这道“麻辣牛油火锅”?他手里有一沓厚厚的食材档案——辣度、价格、上菜时辰、顾客口味——每一条单独看都清清楚楚。可真正让人心动的,往往是组合出来的“化学反应”:深夜、细雨、爱辣的年轻人,看到麻辣火锅就忍不住下单;同样的火锅摆进中午的商务套餐,却无人问津。 这家餐厅的难题,就是推荐系统里的 CTR(点击率)预估。传统做法是请老师傅手写“搭配宝典”,把“深夜×火锅”“雨天×酸梅汤”这类组合一条条人工列出来。可特征一多,组合呈指数爆炸,宝典永远写不完。 DeepFM 这家“新派餐厅”只招了两位员工:一位美食家(FM 因子分解机),专精两两搭配的经典规律;一位创意大厨(深度网络),擅长把多种食材融合成高阶创意菜。两人共用一本食材手账(共享嵌入向量),各练绝活,最后把判断汇到一处——全程不需要人工写搭配清单。这就是 DeepFM:低阶交叉交给 FM,高阶交叉交给 Deep,共享嵌入、联合训练,在广告点击率预估和推荐排序中既能省下人工特征工程的力气,又能提升预测效果。

岗位关联

掌握 DeepFM,意味着理解“低阶交叉 + 高阶交叉 + 共享嵌入”这套组合拳,这是从事推荐系统、广告 CTR 预估等 AI 应用岗位的必备底层认知。

目录
  1. 可视化演示
  2. 模型背景:餐厅的翻牌难题
  3. FM因子分解机:两两搭配的美食家
  4. Deep深度网络:创意大厨的高阶融合
  5. 架构融合设计:共享食材笔记的双剑合璧
  6. WideDeep对比:老菜谱 vs 新团队
  7. 训练部署实践:让新团队上岗
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示DeepFM双路架构(FM+Deep共享嵌入)、FM二阶特征交叉计算与DIN注意力机制,支持模式切换对比。

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

DeepFM:FM+Deep双路共享嵌入架构 FM组件学习二阶特征交互,Deep组件学习高阶交互 两路共享底层embedding,端到端联合训练 y = σ(y_FM + y_Deep) 无需人工特征工程即可自动学习特征交叉

模型背景:餐厅的翻牌难题

街角有家川菜馆,老板每天最关心的不是菜品口味,而是“顾客会不会点这道菜”。他手里有一沓厚厚的食材档案——辣度、价格、上菜时辰、顾客身份——每一条单独看都清清楚楚。但真正让顾客心动的,往往是组合出来的“化学反应”:深夜十点、下着小雨、一位爱辣的年轻人,看到“麻辣牛油火锅”就会忍不住下单;而同样的火锅摆在中午的商务套餐里,反而无人问津。

推荐系统里的 CTR 预估(点击率预估),本质上就是这位老板的难题:给定一堆特征(用户、商品、场景),预测用户点击的概率。难点在于特征交叉——“深夜 × 火锅 × 年轻人”这类组合信息量巨大,不是单条特征能表达的。

传统做法是人工构造交叉特征,比如让工程师手动写下“深夜_火锅=1”这种组合。可特征一旦多起来,交叉组合呈指数爆炸,人工根本写不完。DeepFM 的思路是:让模型自己学会两两交叉(低阶)和多特征组合(高阶),彻底解放人工。

DeepFM 就像这位老板雇来的新团队,不靠老师傅的经验清单,而是自己从数据里摸清“什么组合让人心动”。接下来,我们看看团队里的两位核心成员:美食家(FM)和创意大厨(Deep)。

y^=P(y=1∣x)\displaystyle \hat{y} = P(y=1 \mid \mathbf{x})
这个公式定义了 CTR 预估的核心:给定特征向量,输出点击概率。
  1. $\hat{y}$(预测概率)模型输出的点击概率,取值在 0 到 1 之间。像老板给每道菜打的“翻牌指数”。
    y^\displaystyle \hat{y}
  2. $y=1$(点击事件)表示用户真实点击了商品。$y=0$ 则代表没有点击。
    y∈{0,1}\displaystyle y \in \{0, 1\}
  3. $\mathbf{x}$(特征向量)把所有特征(用户、商品、场景)拼成一个向量,作为模型的输入。
    x=[x1,x2,…,xn]\displaystyle \mathbf{x} = [x_1, x_2, \ldots, x_n]
  4. $P(\cdot \mid \cdot)$(条件概率)在给定特征 $\mathbf{x}$ 的条件下,点击事件发生的概率。
    P(y=1∣x)\displaystyle P(y=1 \mid \mathbf{x})

FM因子分解机:两两搭配的美食家

餐厅里的美食家有套独门绝技:他熟记所有“两两搭配”的火候规律——红酒配牛排是经典,麻辣配牛油是绝配,酸梅汤配火锅能解腻。他从不需要老板告诉他这些搭配,只要尝过足够多的菜,自己就总结出来了。

FM(因子分解机)就是这位美食家。它把每个特征映射成一个隐向量(可以理解为特征的“口味标签”),再用两个隐向量的内积表示“这对特征的搭配强度”。这样即使某对特征在训练数据中从未同时出现,只要各自的隐向量学到手,模型也能推断它们的搭配效果——这正是 FM 擅长处理稀疏数据的原因。

FM 的完整输出包含三部分:全局偏置(餐厅基础客流)、每个特征的独立权重(单条特征的吸引力)、以及最重要的二阶交叉项。下式第一项是基础值,第二项是线性部分,第三项就是美食家的“搭配心得”:

美食家负责的“两两搭配”就是低阶特征交叉。但餐厅里还有更高阶的创意——三种、四种食材叠加出的复杂风味,这就需要另一位成员登场了。

yFM=w0+∑i=1nwixi+∑i=1n∑j=i+1n⟨vi,vj⟩xixj\displaystyle y_{FM} = 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
FM 把“两两交叉”变成可学习的隐向量内积,让模型自己总结搭配规律。
  1. $w_0$(全局偏置)所有样本共有的基准值,类似餐厅的基础客流量。
    w0\displaystyle w_0
  2. $\sum_{i=1}^{n} w_i x_i$(线性部分)每条特征的独立贡献。$x_i$ 表示第 $i$ 个特征的值(如“深夜”=1),$w_i$ 是其权重。
    ∑i=1nwixi\displaystyle \sum_{i=1}^{n} w_i x_i
  3. $\sum_{i=1}^{n}\sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j$(二阶交叉)遍历所有特征对,计算两两搭配的强度。限制 $i<j$ 保证每对特征只计算一次。
    ∑i=1n∑j=i+1n⟨vi,vj⟩xixj\displaystyle \sum_{i=1}^{n}\sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j
  4. $\langle \mathbf{v}_i, \mathbf{v}_j \rangle$(隐向量内积)$\mathbf{v}_i$ 是第 $i$ 个特征的隐向量(口味标签),内积越大表示搭配越合拍。“深夜”与“火锅”的隐向量内积高,就代表它们组合起来很诱人。
    ⟨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}

Deep深度网络:创意大厨的高阶融合

如果说美食家熟记两两搭配,那创意大厨则擅长整桌宴席的统筹。他看到的不是“红酒”和“牛排”两两分开,而是“深夜、细雨、爵士乐、红酒牛排”这一整套场景。他把每一种食材信息压缩成一段风味笔记(嵌入向量),再通过层层加工,得出一个复杂的综合判断。

Deep 部分就是这套“层层加工”的流程。首先,每个特征经过嵌入层变成稠密向量;然后将所有嵌入向量拼接成一个大向量;最后送入多层全连接网络,逐层提炼高阶交互特征。嵌入层的好处是:把几百维的稀疏 one-hot 向量压缩成几十维的稠密向量,既降维又保留语义。

每一层网络都在做非线性变换。所谓“非线性”,就像大厨不会简单地“食材加调料”,而是通过火候、顺序、比例的相互作用,创造出单靠加法表达不出的味道。层数越深,能捕捉的组合越复杂:

美食家管两两搭配,大厨管多层融合,两套功夫缺一不可。但真正让 DeepFM 脱颖而出的是——两人共用同一本食材笔记。

a(l)=ReLU(W(l)a(l−1)+b(l))\displaystyle \mathbf{a}^{(l)} = \text{ReLU}\left( \mathbf{W}^{(l)} \mathbf{a}^{(l-1)} + \mathbf{b}^{(l)} \right)
深度网络通过多层非线性变换,自动学习多特征组合的高阶交互。
  1. $\mathbf{a}^{(l-1)}$(上一层输出)第 $l-1$ 层输出的特征向量。第 0 层就是拼接好的嵌入向量。
    a(0)=Concat(e1,e2,…,em)\displaystyle \mathbf{a}^{(0)} = \text{Concat}(\mathbf{e}_1, \mathbf{e}_2, \ldots, \mathbf{e}_m)
  2. $\mathbf{W}^{(l)}, \mathbf{b}^{(l)}$(权重与偏置)第 $l$ 层的可学习参数,像大厨手中的调味配方,训练时自动更新。
    z(l)=W(l)a(l−1)+b(l)\displaystyle \mathbf{z}^{(l)} = \mathbf{W}^{(l)} \mathbf{a}^{(l-1)} + \mathbf{b}^{(l)}
  3. $\text{ReLU}$(非线性激活)把负值压为 0,让网络能表达非线性关系;否则多层线性变换就退化成单层。
    ReLU(z)=max⁡(0,z)\displaystyle \text{ReLU}(z) = \max(0, z)
  4. $\mathbf{a}^{(l)}$(本层输出)经过激活后的结果,继续作为下一层输入。层数越深,能捕捉的高阶组合越复杂。
    a(L)=Deep(x)\displaystyle \mathbf{a}^{(L)} = \text{Deep}(\mathbf{x})

架构融合设计:共享食材笔记的双剑合璧

如果美食家和创意大厨各记各的笔记,就会出现“美食家觉得麻辣配火锅是绝配,大厨却把火锅的标签记成了清淡”这样的乌龙。DeepFM 的高明之处在于:两人共用同一套食材档案(嵌入向量),所有判断基于同一个事实基础。

在 DeepFM 架构中,FM 部分和 Deep 部分共享底层的嵌入矩阵 $\mathbf{V}$。输入特征先过嵌入层,得到的嵌入向量既用来计算 FM 的二阶交叉,也拼接起来送给 Deep 网络。也就是说,同一个“深夜”特征,在美食家眼里是“适合配火锅”的口味标签,在大厨眼里也是同一份标签——语义完全一致。

前向传播分两条路:低阶路径 $y_{FM}$ 由 FM 层输出,捕捉两两交叉;高阶路径 $y_{DNN}$ 由深度网络输出,捕捉复杂组合。两条路的标量结果相加,再过 sigmoid 得到最终点击概率。整个模型端到端训练,反向传播同时更新 FM 和 Deep 的参数:

共享嵌入让两条路“劲往一处使”:既节省参数,又避免两个模块对同一特征的理解出现分裂。这正是 DeepFM 相比“两个独立模型随意拼接”的核心设计智慧。

y^=σ(yFM+yDNN)\displaystyle \hat{y} = \sigma\left( y_{FM} + y_{DNN} \right)
双路输出相加后过 sigmoid,兼顾低阶与高阶特征交互。
  1. $y_{FM}$(FM 路输出)包含线性项和二阶交叉项的得分,捕捉低阶交互。
    yFM=w0+∑i=1nwixi+∑i=1n∑j=i+1n⟨vi,vj⟩xixj\displaystyle y_{FM} = 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. $y_{DNN}$(深度路输出)多层网络最后一层的输出,捕捉高阶交互。
    yDNN=W(L+1)a(L)+b(L+1)\displaystyle y_{DNN} = \mathbf{W}^{(L+1)} \mathbf{a}^{(L)} + b^{(L+1)}
  3. $\sigma$(sigmoid 激活)把任意实数压到 $(0,1)$ 区间,变成概率。
    σ(z)=11+e−z\displaystyle \sigma(z) = \frac{1}{1 + e^{-z}}
  4. $\hat{y}$(最终预测)两条路得分相加后,经 sigmoid 得到的点击概率。
    y^∈(0,1)\displaystyle \hat{y} \in (0, 1)

WideDeep对比:老菜谱 vs 新团队

在 DeepFM 之前,Google 提出了 Wide&Deep 模型。它的 Wide 部分像一本老师傅手写的“搭配宝典”——每条经典搭配都要人工写进去;Deep 部分则同样由大厨负责。问题在于:宝典永远写不全,而且宝典里用的食材名称和大厨笔记里的叫法对不上。

Wide&Deep 的 Wide 部分依赖人工构造的交叉特征 $\phi(\mathbf{x})$,Deep 部分虽有嵌入,但两者各自为政,嵌入并不完全共享(Wide 侧的交叉特征直接喂线性层)。DeepFM 则用 FM 层取代人工 Wide 部分,自动生成所有二阶交叉,同时让 FM 与 Deep 共享嵌入向量,这是两者最本质的两点差异。

从效果上看,DeepFM 在大量 CTR 预估数据集上能达到与 Wide&Deep 相当甚至更好的精度,同时省去了人工构造特征的成本。更重要的是,FM 与 Deep 共享嵌入让梯度更新更稳定,训练过程更顺畅:

DeepFM 相当于删掉了那本永远写不完的宝典,把“两两搭配”的判断交给美食家自动完成。省力、全面、效果好,这就是它在工业界广受欢迎的原因。

yWide&Deep=σ(wwide⊤[x,ϕ(x)]+wdeep⊤a(L))\displaystyle y_{Wide\&Deep} = \sigma\left( \mathbf{w}_{wide}^{\top} [\mathbf{x}, \phi(\mathbf{x})] + \mathbf{w}_{deep}^{\top} \mathbf{a}^{(L)} \right)
Wide&Deep 的 Wide 侧需要人工构造交叉特征,而 DeepFM 用 FM 自动完成。
  1. $\phi(\mathbf{x})$(人工交叉特征)由工程师预先定义的交叉组合,如“深夜_火锅=1”。这是 Wide&Deep 与 DeepFM 的最大区别。
    ϕ(x)=[xixj,…]\displaystyle \phi(\mathbf{x}) = [x_i x_j, \ldots]
  2. $\mathbf{w}_{wide}^{\top} [\mathbf{x}, \phi(\mathbf{x})]$(Wide 侧)线性模型直接作用于原始特征加人工交叉特征,本质是逻辑回归。
    wwide⊤[x,ϕ(x)]\displaystyle \mathbf{w}_{wide}^{\top} [\mathbf{x}, \phi(\mathbf{x})]
  3. $\mathbf{w}_{deep}^{\top} \mathbf{a}^{(L)}$(Deep 侧)深度网络的输出再接一层线性映射,得到高阶得分。
    wdeep⊤a(L)\displaystyle \mathbf{w}_{deep}^{\top} \mathbf{a}^{(L)}
  4. $\sigma$(sigmoid)与 DeepFM 一样,用 sigmoid 把得分转为概率。
    σ(z)=11+e−z\displaystyle \sigma(z) = \frac{1}{1 + e^{-z}}

训练部署实践:让新团队上岗

新团队招进来了,怎么培训?老板给美食家和厨师准备了一大批历史点单记录(训练数据),每道菜都标注了顾客当时点没点。团队根据预测偏差不断调整判断标准——预测偏了,就狠狠“纠错”。

DeepFM 采用标准的有监督训练。损失函数用二分类交叉熵(BCE Loss),优化器常用 Adam 或 Adagrad。由于稀疏特征占比高,论文中推荐对嵌入层使用 $L_2$ 正则,并配合小批量梯度下降。对小白来说,可以把损失函数理解为“老板的打分表”:预测越离谱,扣分越狠;模型的任务就是让总扣分越来越小。

工程部署上,FM 的二阶交叉可以改写成“和的平方减平方和”,把计算复杂度从 $O(n^2 k)$ 降为 $O(nk)$。这个技巧在在线推理时非常关键——推荐系统每天要处理海量请求,少一个数量级的计算量就意味着更低的时延和带宽。实际系统中还会做特征哈希分桶、嵌入字典压缩,并配合缓存和批量预测来进一步提速:

团队上岗后,一边翻历史记录一边校正口味,最终能快速、稳定地给出每道菜的“翻牌指数”。这套“美食家+大厨”的组合,就是 DeepFM 在真实推荐系统里每天服务的模样。

L=−1N∑k=1N[yklog⁡y^k+(1−yk)log⁡(1−y^k)]\displaystyle L = -\frac{1}{N}\sum_{k=1}^{N}\left[ y_k \log \hat{y}_k + (1-y_k)\log(1-\hat{y}_k) \right]
二分类交叉熵损失:预测越接近真实标签,损失越小。
  1. $N$(样本数)一个 batch 或全量训练样本的个数。
    N=∣D∣\displaystyle N = |\mathcal{D}|
  2. $y_k$(真实标签)第 $k$ 个样本是否点击,1 表示点击,0 表示未点击。
    yk∈{0,1}\displaystyle y_k \in \{0, 1\}
  3. $y_k \log \hat{y}_k$ 与 $(1-y_k)\log(1-\hat{y}_k)$(对数似然)当 $y_k=1$ 时只看第一项,鼓励预测接近 1;当 $y_k=0$ 时只看第二项,鼓励预测接近 0。
    yklog⁡y^k+(1−yk)log⁡(1−y^k)\displaystyle y_k \log \hat{y}_k + (1-y_k)\log(1-\hat{y}_k)
  4. $-\frac{1}{N}\sum$(负平均)对所有样本取平均再取负号,让“平均损失越小越好”,方便梯度下降优化。
    L=−1N∑k=1N[yklog⁡y^k+(1−yk)log⁡(1−y^k)]\displaystyle L = -\frac{1}{N}\sum_{k=1}^{N} \left[ y_k \log \hat{y}_k + (1-y_k)\log(1-\hat{y}_k) \right]

AI 应用场景

信息流广告点击率预估

阶段:模型训练与在线推理

解决的问题:广告系统需要在每次曝光时预估用户点击概率,传统逻辑回归需要人工构造海量交叉特征,工程量大且容易遗漏重要组合。DeepFM 自动学习低阶与高阶特征交互,省去人工特征工程。

具体案例:某信息流广告平台每天处理数十亿次曝光请求。将排序模型从“LR + 人工交叉特征”替换为 DeepFM 后,离线 AUC 提升约 1.5%,人工特征工作量下降 80%。上线后结合特征哈希分桶与批量推理,单次请求时延保持在 20ms 以内。

电商商品推荐排序

阶段:召回与精排阶段

解决的问题:电商“猜你喜欢”需要在排序阶段综合用户、商品、上下文三类特征预测购买概率。传统 Wide&Deep 需要人工设计商品类目与价格区间等交叉特征,DeepFM 用 FM 自动完成二阶交叉,Deep 部分捕捉用户行为序列与当前场景的高阶组合。

具体案例:某电商 App 的商品流精排使用 DeepFM 后,低阶特征如“品类 × 价格区间”、高阶特征如“用户历史点击序列 × 当前促销活动”均被自动学习。模型上线后整体 GMV 提升 2.3%,且新场景(如大促活动)上线时无需再手动补充交叉特征。

短视频内容推荐

阶段:粗排候选集打分

解决的问题:短视频平台每天有海量新内容产生,粗排阶段需要用轻量模型快速过滤候选。DeepFM 的 FM 部分计算高效,Deep 部分可适当减小宽度,在保证精度的同时满足高吞吐要求。

具体案例:某短视频平台将粗排模型升级为 DeepFM 轻量版,利用“用户兴趣标签 × 视频内容标签 × 时段”的低阶交叉快速筛选,再配合精排大模型做最终排序。粗排阶段 CTR 提升 5%,整体推荐时长提升 1.8%。

Python 演示

python54 行
import torchimport torch.nn as nn  class DeepFM(nn.Module):    def __init__(self, n_features, n_factors=8, hidden=[64, 32]):        super().__init__()        self.w0 = nn.Parameter(torch.zeros(1))        self.w = nn.Parameter(torch.randn(n_features) * 0.01)        self.V = nn.Parameter(torch.randn(n_features, n_factors) * 0.01)        dims = [n_factors] + hidden + [1]        layers = []        for i in range(len(dims) - 1):            layers.append(nn.Linear(dims[i], dims[i + 1]))            if i < len(dims) - 2:                layers.append(nn.ReLU())        self.mlp = nn.Sequential(*layers)     def forward(self, x):        linear = self.w0 + x @ self.w        emb = x.unsqueeze(-1) * self.V        sum_sq = emb.sum(1).pow(2).sum(1)        sq_sum = (emb ** 2).sum(1).sum(1)        fm_cross = 0.5 * (sum_sq - sq_sum)        deep_in = x @ self.V        deep_out = self.mlp(deep_in).squeeze(-1)        return torch.sigmoid(linear + fm_cross + deep_out)  def main():    torch.manual_seed(42)    n, n_feat = 2000, 20    X = torch.randint(0, 2, (n, n_feat)).float()    y = ((X[:, 0] * X[:, 1] + X[:, 2] * X[:, 3] + X[:, :6].sum(1)) > 2.5).float()    model = DeepFM(n_feat)    opt = torch.optim.Adam(model.parameters(), lr=0.02)    loss_fn = nn.BCELoss()    for epoch in range(30):        perm = torch.randperm(n)        total = 0.0        for i in range(0, n, 128):            idx = perm[i:i + 128]            xb, yb = X[idx], y[idx]            opt.zero_grad()            loss = loss_fn(model(xb), yb)            loss.backward()            opt.step()            total += loss.item() * len(idx)        if epoch % 10 == 0:            print(f"epoch {epoch}: loss = {total / n:.4f}")  if __name__ == "__main__":    main()
目的:用 PyTorch 从零实现一个极简 DeepFM,在随机生成的特征交叉数据集上演示端到端训练过程。
  1. self.V = nn.Parameter(torch.randn(n_features, n_factors) * 0.01)定义共享嵌入矩阵,FM 和 Deep 两条路都复用它
  2. emb = x.unsqueeze(-1) * self.V将每个特征值与其嵌入向量逐维相乘,得到带权嵌入
  3. fm_cross = 0.5 * (sum_sq - sq_sum)FM 二阶交叉的线性时间等价写法:“和的平方”减“平方和”
  4. deep_in = x @ self.VDeep 部分复用同一嵌入矩阵,保证两路语义一致
  5. return torch.sigmoid(linear + fm_cross + deep_out)双路得分相加后过 sigmoid,输出点击概率
  6. y = ((X[:, 0] * X[:, 1] + X[:, 2] * X[:, 3] + X[:, :6].sum(1)) > 2.5).float()构造包含特征交叉关系的模拟标签
  7. loss.backward()端到端反向传播,同时更新 FM 与 Deep 的所有参数
  8. opt.step()用 Adam 优化器更新一次梯度

常见误区

误区以为 DeepFM 就是把一个 FM 和一个 DNN 的输出简单拼在一起,两个模块各训各的,互不相干。

正解实际上 FM 和 Deep 共享底层嵌入向量 $\mathbf{V}$,并且整个模型端到端联合训练。共享嵌入保证了两个模块对特征的理解一致——就像美食家和创意大厨共用同一本食材手账,不会出现同一道食材两套说法的乌龙。

为何常见:DeepFM 这个名字看起来就是"FM + Deep",看结构图时也容易把两条路径理解成两个独立模型,忽略了底层的共享嵌入层。

误区既然 DeepFM 自动学习特征交叉,那原始数据是不是可以直接塞进去?连清洗都不用做。

正解模型确实免去了“人工构造交叉特征”,但基础的特征清洗、缺失值填充、类别特征编码(如映射为 ID 或哈希分桶)仍然必须做。嵌入层学习的是“编码后的特征”之间的关系,而不是原始日志文本。垃圾进,垃圾出,这个原则在 DeepFM 里同样成立。

为何常见:“无需人工特征工程”这句宣传语被过度解读为“数据什么都不用做”,实际上它特指不需要人工设计交叉组合。

误区两者都是“宽 + 深”结构,结构图看上去很像,很多人认为只是换了个名字。

正解Wide&Deep 的 Wide 侧需要人工构造交叉特征 $\phi(\mathbf{x})$,且 Wide 与 Deep 的嵌入不共享;DeepFM 用 FM 自动做二阶交叉,并让 FM 与 Deep 共享同一嵌入矩阵。这是“人工 vs 自动”和“共享 vs 不共享”两个本质区别。

为何常见:结构图确实相似(一条浅路 + 一条深路),初学时容易只看到外形,忽略内部“谁提供交叉特征、嵌入是否共享”这两个关键差异。

误区认为 $\mathbf{v}_i$ 是像“口味标签”一样由人预先定义好的向量,比如“深夜=0.8, 火锅=0.9”。

正解隐向量是通过训练数据用梯度下降学出来的,不是人写的。它的“口味标签”含义是训练结束后回头解释出来的,而不是设计时指定进去的。模型只负责让预测更准,标签解释是人类的事后解读。

为何常见:FM 的数学形式看起来像“给每个特征分配一个向量”,容易让人误以为是人为初始化好的静态表,忽略了它是在训练中不断更新的参数。

误区Deep 部分层数越多、神经元越多,高阶交互就学得越好,所以拼命加深网络。

正解网络加深会增加参数量,在训练数据不足时容易过拟合——大厨创意太多、菜品太飘,反而偏离顾客真实口味。实践中 DeepFM 的隐藏层一般 2-3 层足够,还要配合 dropout、$L_2$ 正则等手段。层数不是越多越好,而是“够用就好”。

为何常见:“深度学习 = 越深越好”的朴素认知,加上对过拟合风险缺乏直观感受,导致盲目堆层数。

面试题

Q1. DeepFM 中 FM 因子分解机部分的核心职责是?

单选题 · easy

  • A.学习低阶特征交叉← 正确答案
  • B.学习高阶特征交互
  • C.生成图像特征数据
  • D.压缩模型网络参数

答案:A。FM 用隐向量内积计算两两特征交叉,属于低阶(二阶)交互,对应“美食家熟记两两搭配”;高阶交互由 Deep 部分负责,所以 B 错,C、D 与 FM 的职责无关。

Q2. DeepFM 中深度网络部分主要负责?

单选题 · easy

  • A.线性加权求和
  • B.学习高阶特征交互← 正确答案
  • C.人工构造交叉特征
  • D.降低特征维度

答案:B。Deep 部分通过多层非线性变换建模多特征组合,即高阶交互,相当于创意大厨的融合菜。A 是 FM 线性部分的活,C 是 Wide&Deep 的 Wide 侧做法,D 不是深度网络的主要职责。

Q3. 与 Wide&Deep 相比,DeepFM 的最大优势是?

单选题 · mid

  • A.无需人工构造交叉特征← 正确答案
  • B.参数量显著少于所有模型
  • C.只使用浅层线性模型结构
  • D.不支持稀疏离散型特征

答案:A。Wide&Deep 的 Wide 侧依赖人工设计交叉特征 $\phi(\mathbf{x})$;DeepFM 用 FM 自动完成二阶交叉,省去人工。B、C 与事实不符,D 恰好说反——DeepFM 非常擅长处理稀疏离散特征。

Q4. FM 部分计算二阶特征交叉时使用什么方式?

单选题 · mid

  • A.隐向量两两内积← 正确答案
  • B.深度网络自动提取
  • C.人工规则手动组合
  • D.余弦相似度聚类

答案:A。FM 把每个特征映射成隐向量,用两个隐向量的内积 $\langle \mathbf{v}_i, \mathbf{v}_j \rangle$ 表示搭配强度。实现时可用“平方和减和平方”优化,把复杂度从 $O(n^2k)$ 降到 $O(nk)$。

Q5. DeepFM 中 FM 与 Deep 两部分的共同点有哪些?

多选题 · mid

  • A.共享输入嵌入向量← 正确答案
  • B.输出单一的标量值← 正确答案
  • C.需要人工交叉特征
  • D.结果相加后再预测← 正确答案

答案:ABD。FM 与 Deep 共享同一嵌入矩阵 $\mathbf{V}$,各自输出一个标量,相加后过 sigmoid 得到预测。C 是 Wide&Deep 的 Wide 侧特征,DeepFM 完全不需要人工交叉特征。

Q6. 关于 FM 二阶交叉项的高效计算,下列说法正确的有?

多选题 · hard

  • A.平方和减去和平方← 正确答案
  • B.复杂度降为 O(nk)← 正确答案
  • C.单纯增加网络层数
  • D.应用独热编码特征

答案:AB。$\sum_{i<j}\langle\mathbf{v}_i,\mathbf{v}_j\rangle x_i x_j = \frac{1}{2}\sum_{f=1}^{k}\left[(\sum_{i=1}^{n}v_{i,f}x_i)^2 - \sum_{i=1}^{n}v_{i,f}^2 x_i^2\right]$,从 $O(n^2k)$ 降为 $O(nk)$。C 与 FM 计算无关,D 是输入预处理方式而非高效计算技巧。

Q7. CTR 预估任务本质上是一个?

单选题 · easy

  • A.二分类问题← 正确答案
  • B.回归问题
  • C.聚类问题
  • D.生成问题

答案:A。CTR 预测用户是否点击,标签 $y \in \{0,1\}$,输出点击概率,是标准二分类。回归预测连续值,聚类是无监督学习,生成问题输出新样本,都不符合点击率预估的任务定义。

Q8. 关于 DeepFM 的训练过程,下列说法正确的有?

多选题 · hard

  • A.交叉熵作为损失函数← 正确答案
  • B.FM 与 Deep 联合训练← 正确答案
  • C.反向传播端到端更新← 正确答案
  • D.依赖人工构造交叉特征

答案:ABC。DeepFM 使用二分类交叉熵损失,整个模型端到端联合训练,梯度同时更新 FM 与 Deep 的参数。D 是 Wide&Deep 的做法,DeepFM 用 FM 自动完成交叉,不依赖人工。

Q9. DeepFM 中 Deep 部分的输入来自?

单选题 · mid

  • A.特征嵌入向量拼接← 正确答案
  • B.直接输入稀疏向量
  • C.FM 的二阶交叉输出
  • D.人工规则生成特征

答案:A。稀疏特征先过嵌入层得到稠密向量,拼接后送入 MLP。B 直接喂稀疏向量会维度爆炸,C 是分支输出而非输入,D 是 Wide 侧的做法。

Q10. 若将 DeepFM 的共享嵌入改为 FM 与 Deep 各自独立学习,最可能出现的问题是?

单选题 · extreme

  • A.两路特征语义不一致← 正确答案
  • B.模型参数大幅减少
  • C.训练速度必然加快
  • D.不再需要类别特征

答案:A。共享嵌入保证两个模块对同一特征理解一致;独立学习会导致同一特征在两条路径上学出不同语义,削弱融合效果,最终伤害预测精度。B、C 都不成立——独立学习反而增加参数量和训练开销,D 与嵌入是否共享无关。