想象一家老社区图书馆。图书管理员老陈最近很头疼:馆里藏书越来越多,已经超过一百万本,但书架隔间是固定的。以前他的办法很「笨」——每本书都单独占一整间阅览室,书架上只放这一本书,找起来确实方便,但馆里很快就塞不下了。更麻烦的是,每天还有新书到馆,根本不知道往哪儿放。后来老陈想出了两个办法:第一,给每本书写一张「内容摘要卡」,相似的书摘要风格相近,大家只查卡片、不占整间房,这就是 Embedding(嵌入);第二,准备一排固定数量的「编号储物柜」,任何新书来了,用查字典的方式迅速算出该进哪个柜子,柜子满了就稍微挤一挤,这就是 哈希技巧。再往后,老陈还总结出「荐书三口诀」:单本书本身好不好(一阶特征)、两本书搭不搭(二阶交叉)、整套书背后的品味脉络(高阶特征),以及老读者最近反复借的那几本才是重点(注意力机制)。这套思路,正是深度学习推荐系统 DeepFM 与 DIN 模型的灵魂。

岗位关联

推荐场景下特征动辄千万上亿,掌握 Embedding 与哈希技巧,意味着你能把「装不下的书架」变成「永远够用的储物柜」,这是推荐算法工程师的核心基本功。

目录
  1. 可视化演示
  2. 特征编码困境
  3. Embedding本质
  4. 哈希映射技巧
  5. 碰撞与多哈希
  6. DeepFM架构
  7. DIN兴趣网络
  8. 工程性能调优
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示离散特征到稠密向量的Embedding映射、哈希技巧降维与碰撞、DeepFM共享Embedding层架构,切换模式查看推荐系统核心技术。

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

特征Embedding映射 离散类别特征通过Embedding矩阵映射为连续稠密向量,维度d决定表达能力 E: {1,...,N} → R^d Embedding是可学习的参数表,通过梯度下降优化

特征编码困境

老陈最初的做法,是给每本书单独准备一整间阅览室——书架上只放一本书,找起来一目了然,这就是 One-Hot 编码(独热编码) 的直觉:每个特征取值都拥有一个独立维度,这个维度为 1,其余全部为 0。可图书馆藏书超过一百万本时,馆内根本盖不起这么多房间。推荐系统里,用户 ID、商品 ID、类目、品牌这些特征加起来常常有几千万甚至上亿个取值,One-Hot 后的向量长达千万维,其中 99.99% 的位置都是 0。这种「高维稀疏」向量存起来费内存、算起来费算力,喂给神经网络时绝大多数乘法都在和 0 做无用功。

更棘手的是 信息孤岛 问题:One-Hot 把所有特征当作彼此无关的独立维度,「手机」和「数码」两个类目在向量空间里就像两颗离得很远的星星,模型学不到它们的相似性。而推荐系统恰恰依赖这种相似性——看过华为手机的用户,大概率也会对小米手机感兴趣。如果特征之间不能共享信息,模型的泛化能力会大打折扣。

图书馆的启示很清楚:房间再多也有上限。Feature(特征)的数量是动态增长的,而书架(存储和算力)是有限的。老陈意识到,必须在「保存信息」和「控制空间」之间找一条新路。

x=[x1,x2,…,xV]⊤,xi∈{0,1},∑i=1Vxi=1x = [x_1, x_2, \dots, x_V]^\top, \quad x_i \in \{0, 1\}, \quad \sum_{i=1}^{V} x_i = 1
One-Hot 把「第几个取值」翻译成一长串 0 和 1,V 是取值总数,向量只有一个位置是 1。
  1. 向量空间声明x 是一个长度为 V 的列向量,V 等于该字段全部可能取值的总数,比如商品 ID 有 1000 万个,V 就是 1000 万。
    x∈{0,1}Vx \in \{0, 1\}^{V}
  2. 取 0/1 约束每一维只能取 0 或 1,表示「这个取值是否存在」,不取连续的数值。
    xi∈{0,1}x_i \in \{0, 1\}
  3. 归一约束(恰一位为 1)所有维度求和等于 1,意味着此刻只有当前取值对应的那一维被点亮,其余全是暗的。
    ∑i=1Vxi=1\sum_{i=1}^{V} x_i = 1

Embedding本质

老陈的新方案是给每本书写一张「内容摘要卡」:不存放整本书,只保存几百字的关键信息。更妙的是,内容相似的书,摘要风格也相近——《三体》和《球状闪电》的卡片上都写着「科幻、刘慈欣、宇宙」。《内容摘要卡》就是 Embedding:把高维稀疏的 One-Hot 向量,压缩成低维稠密的实数向量。原来的 1000 万维只剩下 8 到 128 维,但每一维都有实数值,承载着压缩后的语义信息。

Embedding 的本质是一张 查表字典:模型训练时,每个特征值对应表格里的「一行」向量。这张表不是人工写的,而是在训练过程中通过反向传播自动学习的。学习的目标是让「语义相近」的特征在向量空间里距离更近:看过「华为 Mate60」的用户行为,会带动「小米 14」和「iPhone 15」的向量向相似方向聚拢,因为它们常在同一批用户的历史中出现。这正是 Embedding「端到端可学习」的强大之处——不需要人工设计相似度规则,数据自己就会把相似的东西摆在一起。

摘要卡片解决了「一间房一本书」的空间浪费,但老陈又遇到了新问题:书还在源源不断地进馆,每来一本新书都得重新编号、重新安排位置。有没有一种办法,不管什么书来了都能立刻找到它的卡片?

ef=E[xf],E∈RV×d,d≪Ve_f = E[x_f], \quad E \in \mathbb{R}^{V \times d}, \quad d \ll V
Embedding 就是查表:输入特征索引,输出一行稠密向量。V 是特征总数,d 是目标维度。
  1. 查表字典 EE 是一个 V 行 d 列的可学习矩阵,每一行是某个特征值的 d 维向量表示,相当于摘要卡片的存放位置。
    E∈RV×dE \in \mathbb{R}^{V \times d}
  2. 按索引取值x_f 是特征 f 的索引(One-Hot 中 1 的位置),查表取出对应那一行向量。
    xf=argmax(x)x_f = \mathrm{argmax}(x)
  3. 维度压缩d 远小于 V,高维稀疏的 One-Hot 被压缩成低维稠密向量,语义信息被浓缩进每个实数维度。
    d≪Vd \ll V

哈希映射技巧

老陈的第二个妙招,是准备一排固定数量的储物柜,再立一条铁规矩:任何新书到馆,不用找人登记,而是用一本「字典」当场算出它该进哪个柜门。这本字典就是 哈希函数:输入特征名或 ID,输出一个整数。再对这个整数取模,就得到 0 到 L-1 之间的槽位编号。这个编号直接作为 Embedding 表的行索引——老陈只需维护一张 L×d 的小表,就能承接无限增长的特征。

哈希技巧解决了两大痛点。第一是 OOV(新特征)问题:传统方式遇到训练时没见过的特征 ID 会直接崩溃或忽略,而哈希函数对任何输入都能算出槽位,新特征永远有位置可去。第二是 内存固定:表长 L 是预先定好的,无论特征总数涨到 1000 万还是 1 亿,Embedding 表的参数量始终是 L×d,不会跟着特征数膨胀。这正是推荐系统能支撑海量用户的工程基石。此外,哈希映射在分布式环境下天然一致——同一特征在任何机器上算出的索引都相同,训练和推理的查表结果不会错位。

老陈的储物柜法立竿见影,但他很快发现另一个问题:书的数量多了,难免有两本书被字典算出同一个柜门。柜子只有一个,书却要挤在一起——这在哈希世界里叫「碰撞」。

if=hash(f) mod L,L≪Vi_f = \mathrm{hash}(f) \bmod L, \quad L \ll V
哈希技巧的核心:用哈希函数加取模,把任意特征映射到固定长度 L 的表里。
  1. 哈希函数hash(f) 把特征名或 ID 变成一个整数,像字典给书编的临时号码。
    h=hash(f)h = \mathrm{hash}(f)
  2. 取模收缩对 L 取模,把整数压进 [0, L-1] 区间,对应固定长度的 Embedding 表槽位。
    if=h mod Li_f = h \bmod L
  3. 空间压缩比L 远小于原始特征总数 V,内存从 V×d 降到 L×d,换来的是不同特征可能映射到同一槽位。
    L≪VL \ll V

碰撞与多哈希

碰撞的本质是:两个不同的特征 f1 和 f2,经过哈希取模后落到同一个槽位,被迫共享同一个 Embedding 向量。老陈的储物柜里,两本毫不相干的书挤在一个格子里,取 A 书时看到的摘要其实是两本书的混合体。碰撞会稀释特征的个性化表达:如果「茅台」和「纸尿裤」撞到同一槽,模型对这两个特征的区分度就会下降。

碰撞概率可以由「生日悖论」估算:n 个特征随机落入 L 个槽位,至少一对碰撞的概率约为 1 - e^{-n²/(2L)}。工程上用 多哈希 来缓解:同时用两个独立的哈希函数,把两个结果组合后取模,相当于把原本「一条路进柜」变成「两条路交叉验证」,分布更均匀。此外还有 特征分桶 和 频率分层:高频特征(如热门商品)单独建表,保证它们的表达不被挤压;低频长尾特征(如小众商品)共享哈希表,因为它们的样本量本来就少,即使偶尔碰撞,对模型整体影响也可控。

挤一挤并不可怕,可怕的是挤爆。多哈希和分桶就像给储物柜加了隔板:同一个柜门里放几个小抽屉,重要书籍单独占一格。碰撞解决了,老陈开始琢磨更深层的问题——怎么从一堆摘要卡片里,真正读懂一位读者的口味。

P≈1−e−n2/(2L),if=(h1(f)+h2(f)) mod LP \approx 1 - e^{-n^2 / (2L)}, \quad i_f = \big(h_1(f) + h_2(f)\big) \bmod L
碰撞概率随特征数平方增长;多哈希把两次独立映射组合起来,让分布更均匀。
  1. 生日悖论碰撞概率n 个特征落入 L 个槽位时,至少一对碰撞的概率约 1-e^{-n²/(2L)},n 越大概率越高。
    P≈1−e−n2/(2L)P \approx 1 - e^{-n^2 / (2L)}
  2. 双哈希组合两个独立哈希结果相加再取模,把单一映射打散,降低特定模式下的碰撞聚集。
    if=(h1(f)+h2(f)) mod Li_f = (h_1(f) + h_2(f)) \bmod L

DeepFM架构

老陈给自己定了个「荐书三口诀」。第一句是 单本评价:这本书本身好不好看?对应模型中的一阶项,每个特征独立打分。第二句是 搭配评价:这两本书凑在一起妙不妙?比如「悬疑 + 东野圭吾」比「悬疑 + 菜谱」合理得多,这对应 FM(因子分解机)的二阶交叉项——用两个特征向量的内积衡量它们的搭配强度。第三句是 品味脉络:整本书背后的深层逻辑、跨多个维度的复杂关联,比如「30 岁男性 + 程序员 + 深夜 + 科幻电影 + 咖啡」共同暗示了什么,这需要深层网络(DNN)来捕捉。

DeepFM 把三句口诀合在一起:一阶项(w0 + Σwixi)负责单独打分,FM 二阶项负责两两交叉,DNN 负责高阶非线性交互,最后联合训练、一起优化。与纯 FM 相比,DeepFM 多了深度网络的表征能力;与纯 DNN 相比,它多了显式的二阶交叉,让模型在数据稀疏时也能学得稳。这也是它成为工业界 CTR 预估标配的原因——既能快速捕捉低阶规律,又能深度挖掘高阶模式。

三句口诀让老陈像个合格的荐书员了,但还不够贴心。一位老读者明明只看科幻,为什么系统总是推荐言情?因为模型没有抓住「最近反复借的那几本」才是兴趣的关键。

y^=w0+∑iwixi+∑i<j⟨vi,vj⟩xixj+DNN(x)\hat{y} = w_0 + \sum_{i} w_i x_i + \sum_{i<j} \langle v_i, v_j \rangle x_i x_j + \mathrm{DNN}(x)
DeepFM = 一阶线性 + 二阶 FM 交叉 + 深层网络,把「单本、搭配、脉络」三股力量合流。
  1. 全局偏置与一阶项w0 是全局偏置(默认倾向),第二项对每个特征单独打分,对应「单本书自己的价值」。
    w0+∑iwixiw_0 + \sum_i w_i x_i
  2. 二阶交叉项对任意两两特征计算嵌入向量的内积,捕捉「书与书的搭配效应」。
    ∑i<j⟨vi,vj⟩xixj\sum_{i<j} \langle v_i, v_j \rangle x_i x_j
  3. 高阶项把特征 embedding 拼接或池化后送入深度网络,学习跨越多维的高阶非线性交互。
    DNN(x)\mathrm{DNN}(x)

DIN兴趣网络

老陈发现,给老读者荐书时,不能把他十年来的借阅记录一视同仁。他上个月借了七本《三体》相关书籍,最近又借了两本《流浪地球》——当推荐新科幻书时,这些近期记录应该被「重点盯住」;而他五年前借的一本言情小说,此时完全可以忽略。这种「盯着关键历史行为」的能力,就是 注意力机制,也是 DIN(深度兴趣网络) 的核心思想。

DIN 具体怎么做?把候选商品(比如《球状闪电》)当作「探照灯」,逐一扫描用户历史行为中的每个商品(《三体》《流浪地球》《甄嬛传》……)。探照灯的光束强度由打分函数 g 计算——候选与历史行为越相关,得分越高。得分经过 softmax 归一化成权重 α,再对历史商品的 Embedding 做 加权求和,得到用户的 兴趣向量。这个兴趣向量是动态的:换一个候选商品,探照灯的角度变了,兴趣向量也跟着变。这正是 DIN 胜过「把所有历史行为平均一下」的关键——平均是「一碗水端平」,注意力是「重点关照」。

老陈的推荐越来越准了,但图书馆的经费有限。摘要卡片该写多长?储物柜该准备几排?机器学习的「钱」——内存和算力,必须花在刀刃上。

vU=∑i=1nαivi,αi=exp⁡(g(vi,vA))∑jexp⁡(g(vj,vA))v_U = \sum_{i=1}^{n} \alpha_i v_i, \quad \alpha_i = \frac{\exp\big(g(v_i, v_A)\big)}{\sum_{j} \exp\big(g(v_j, v_A)\big)}
DIN 用注意力给历史行为加权:候选商品越相关的历史行为,权重越大,最终加权求和得到用户兴趣向量。
  1. 注意力打分g(v_i, v_A) 计算候选商品与历史行为第 i 个商品的相关度,常用内积或小网络作为打分函数。
    si=g(vi,vA)s_i = g(v_i, v_A)
  2. softmax 归一化对打分做指数归一,得到和为 1 的权重,表示「这个历史行为有多值得参考」。
    αi=esi∑jesj\alpha_i = \frac{e^{s_i}}{\sum_j e^{s_j}}
  3. 加权求和各历史行为向量按权重融合成用户兴趣向量,关键行为主导最终表达。
    vU=∑iαiviv_U = \sum_i \alpha_i v_i

工程性能调优

最后一个问题是资源配比。第一,Embedding 维度 d:卡片写得太短(如 2 维),信息装不下;写得太长(如 1024 维),柜子占地方、训练也慢。推荐场景的经验区间是 8 到 128 维,特征基数越大、样本量越足,可以适当取高。第二,哈希表长 L:表越大碰撞越少,但内存线性增长。工程经验是取原始特征总数的 1% 到 10%,并把碰撞率控制在 5% 以内——超过这个阈值再考虑加表或加分桶。参数与内存可以精确估算:参数量 = L × d,每个 float32 参数占 4 字节。

第三,分布式训练分片:亿级特征的哈希表不可能塞进单机内存,要按哈希索引切分到多台机器上。分片时要注意热点特征均衡——把「双十一爆款」这类超高访问特征分散到不同节点,避免单机成为瓶颈,同时减少跨机通信。第四,线上部署优化:推理时 Embedding 查表要走缓存(如 Redis 或本地 hashmap),哈希计算本身是 O(1) 的,要把算力留给 DNN 的矩阵运算。这些调优手段,最终目标都是让推荐系统在有限的资源下跑得更快、更准。

至此,老陈的图书馆体系完整了:One-Hot 是旧时代的单间,Embedding 是摘要卡,哈希技巧是储物柜,DeepFM 是荐书三口诀,DIN 是探照灯。理解了这套逻辑,你就掌握了工业级推荐系统的核心骨架。

Params=L×d,Memory≈4×L×d bytes\mathrm{Params} = L \times d, \quad \mathrm{Memory} \approx 4 \times L \times d \ \mathrm{bytes}
哈希 Embedding 的参数量由表长乘以维度决定,与特征总数解耦;每参数占 4 字节可估算内存。
  1. 参数量哈希表大小为槽位数乘以维度,与原始特征数 V 完全解耦,这是哈希技巧降低内存的理论依据。
    Params=L×d\mathrm{Params} = L \times d
  2. 内存估算每个 float32 占 4 字节,可快速估算模型嵌入层占用,方便在资源受限时做取舍。
    Memory≈4Ld bytes\mathrm{Memory} \approx 4 L d \ \mathrm{bytes}
  3. 调优指导经验上 d 取 8-128,L 取 V 的 1%-10%,碰撞率控制在 5% 以内,超限时加桶或加分哈希。
    L≈0.01V∼0.1VL \approx 0.01V \sim 0.1V

AI 应用场景

电商推荐:用户兴趣动态建模

阶段:召回与排序阶段的用户表征

解决的问题:传统模型把用户所有历史行为一视同仁地平均,导致「最近刚买过手机的用户」仍被推荐手机配件,缺乏对瞬时兴趣的捕捉。DIN 的注意力机制让模型动态聚焦与候选商品最相关的历史行为,显著提升点击率。

具体案例:淘宝商品流推荐中,用户历史点击「AirPods、iPhone 保护壳、华为充电器」,当候选商品是「小米手机」时,DIN 会给「华为充电器」等数码配件更高的注意力权重,从而生成更贴合当前购买意愿的兴趣向量,排序结果更精准。

广告 CTR 预估:海量特征的内存治理

阶段:特征工程与模型训练

解决的问题:广告场景特征维度动辄数十亿,完整的 Embedding 表需要数百 GB 内存,且每天都有新广告 ID 涌入。哈希技巧把特征压缩到固定大小的表中,同时天然支持 OOV 新特征,让模型可以持续在线更新。

具体案例:某信息流广告平台将 20 亿维的用户与广告特征通过双哈希映射到 1 亿槽位的 Embedding 表,配合高频特征单独建桶,内存占用下降 95%,CTR 预估 AUC 仅损失 0.3%,却换来了每天千万级新特征的实时接入能力。

视频推荐:DeepFM 多路特征融合

阶段:精排阶段的特征交叉建模

解决的问题:视频推荐特征包含用户画像、视频内容标签、上下文环境等复杂维度,单一线性模型学不好「深夜 + 科幻 + 男性用户」这类高阶组合。DeepFM 的一阶、二阶、高阶三路特征交叉显式互补,兼顾了低阶记忆与高阶泛化。

具体案例:抖音极速版将「年龄、性别、视频类目、完播率分桶」等特征输入 DeepFM,正样本的 FM 二阶交叉项捕捉到「年轻人×搞笑类目」的强搭配,DNN 分支则捕捉「深夜×影视解说×高完播」的深层模式,整体播放时长提升 6.8%。

Python 演示

python55 行
"""特征Embedding与哈希技巧演示: 哈希Embedding + 极简DeepFM前向传播"""import numpy as np  class HashEmbedding:    """用哈希技巧把大规模稀疏特征压缩到固定尺寸的Embedding表"""     def __init__(self, table_size, dim):        self.table_size = table_size        self.dim = dim        # 哈希表: table_size x dim 的稠密矩阵        self.table = np.random.randn(table_size, dim) * 0.1        self.free_lists = {}        self.gc_count = 0     def _hash(self, key):        return hash(key) % self.table_size     def lookup(self, key):        return self.table[self._hash(key)]     def group_lookup(self, keys):        return np.vstack([self.lookup(k) for k in keys])  class DeepFM:    """极简DeepFM: 一阶线性 + 二阶FM交叉 + 单层DNN高阶"""     def __init__(self, table_size, dim):        self.emb = HashEmbedding(table_size, dim)        self.w0 = 0.0        self.w1 = np.random.randn(dim) * 0.1        self.W_dnn = np.random.randn(dim, 8) * 0.1     def forward(self, keys):        vecs = self.emb.group_lookup(keys)          # N x d        # 一阶项: 对每个特征向量做加权求和 (简化)        linear = float(np.sum(vecs))        # 二阶FM: 两两内积交叉        fm = 0.0        for i in range(len(keys)):            for j in range(i + 1, len(keys)):                fm += float(np.dot(vecs[i], vecs[j]))        # DNN高阶: 均值池化后过一层非线性        pooled = vecs.mean(axis=0)        high = float(np.tanh(np.dot(pooled, self.W_dnn).sum()))        return self.w0 + linear + fm + high  if __name__ == "__main__":    model = DeepFM(table_size=64, dim=16)    features = ["user:10001", "item:8899", "cate:手机", "brand:华为"]    score = model.forward(features)    print("CTR预估分:", round(score, 4))    print("哈希表参数量:", model.emb.table.size, "(远小于原始特征数x维度)")
目的:用 60 行代码演示「哈希 Embedding 查表 + DeepFM 三路前向传播」,直观看到任意特征(包括从未见过的 OOV 特征)都能通过哈希映射查到向量,并完成一阶、二阶、高阶的分数融合。
  1. self.table = np.random.randn(table_size, dim) * 0.1初始化一张固定大小的哈希 Embedding 表,全部参数可学习。
  2. return hash(key) % self.table_size核心哈希技巧:对任意特征名取模,映射到固定槽位。
  3. def group_lookup(self, keys)把多个特征一次查表并堆叠成矩阵,模拟真实模型中的批量特征嵌入。
  4. fm += float(np.dot(vecs[i], vecs[j]))FM 二阶交叉项:所有特征两两内积求和,衡量搭配强度。
  5. high = float(np.tanh(np.dot(pooled, self.W_dnn).sum()))DNN 高阶项:均值池化后过一层带 tanh 激活的线性变换。
  6. features = ["user:10001", "item:8899", "cate:手机", "brand:华为"]真实推荐特征的简化形式:字段名加冒号拼 ID,哈希函数直接作用于字符串。

常见误区

误区总以为 Embedding 维度设得越大,模型表达能力越强,效果一定越好,于是直接上 512 维甚至 1024 维。

正解维度大意味着参数量大,训练数据不足时极易过拟合,且推理变慢。就像摘要卡片写得太长反而抓不住重点。推荐场景经验值是 8 到 128 维,特征基数大、样本充足才逐步上调。

为何常见:把「神经网络层越宽越强」的直觉迁移到 Embedding 上,忽略了维度、数据量与泛化能力三者的平衡。

误区觉得哈希碰撞让不同特征共享一个向量,信息一定丢失得很厉害,模型效果肯定会崩。

正解哈希技巧本质是「用小表 + 均匀分布近似原始分布」。表长取特征总数的 1% 到 10% 时,碰撞率很低;再加上多哈希、频率分层,效果可以接近完整 Embedding 表。相比之下,内存爆炸和 OOV 特征无法处理才是真正的致命伤。

为何常见:把数学上的「信息无损」误解为工程上的唯一标准,忽略了长尾特征本身样本稀疏,共享向量带来的损失远小于拿不到向量的问题。

误区以为推荐系统里的「哈希技巧」和机器学习课上讲的「特征哈希」是同一个东西,拿哈希值直接当特征值。

正解两者都用到哈希函数,但服务环节不同。特征哈希是把特征直接变成稀疏的二值/计数值,省去维护特征字典;哈希技巧是给 Embedding 分配固定行索引,Embedding 本身仍是可学习的稠密向量。一个替代输入编码,一个替代查表索引。

为何常见:名字都带「哈希」,网上资料容易混用术语,初学者没厘清「哈希用在哪个环节」。

误区以为 DeepFM 有了 FM 的二阶交叉项,就能表达所有特征组合,DNN 只是可有可无的装饰。

正解FM 只显式建模两两交互,类似「只考虑两本书搭配」,而真实兴趣往往是「30 岁 + 程序员 + 深夜 + 科幻」这种跨多特征的复杂模式,必须靠 DNN 隐式拟合。两者互补、联合训练才是 DeepFM 的完整形态。

为何常见:只盯着公式里醒目的二阶项,忽略了 DNN(x) 这一项在模型容量上的决定性作用。

误区以为注意力权重是根据业务经验手工配置的,比如「最近 7 天的行为权重高,更早的权重低」。

正解DIN 的注意力打分函数是一个可学习的网络,通过梯度下降自动学会「什么历史行为对当前候选更重要」。人工只设计网络结构(打分函数怎么组合、候选如何融合),不决定具体权重值。

为何常见:「注意力」这个比喻太形象,让人联想到人的主观关注,误以为是人写死在代码里的规则。

面试题

Q1. 关于 One-Hot 编码的「维度爆炸」问题,哪种说法正确?

单选题 · easy

  • A.把所有特征转为低维稠密向量
  • B.每个取值独占一个独立维度← 正确答案
  • C.用哈希函数压缩特征维度
  • D.编码后输出稠密浮点数组

答案:B。One-Hot 的核心定义就是每个特征取值占据一个独立维度,取值越多向量越长,导致维度爆炸。A 是 Embedding 的功能,C 是哈希技巧的功能,D 与 One-Hot 的稀疏 0/1 特性相反。

Q2. Embedding 本质上在做什么?

单选题 · easy

  • A.压缩高维稀疏到低维稠密← 正确答案
  • B.统计特征出现频率大小
  • C.对特征做排序和筛选
  • D.把离散值转换成连续值

答案:A。Embedding 通过查表把高维稀疏的 One-Hot 向量映射为低维稠密实数向量,且语义相近的特征在向量空间中距离更近。B、C、D 描述的分别是统计频次、特征选择与数值归一化,都不是 Embedding 的本质。

Q3. 哈希技巧解决的核心问题是什么?

单选题 · easy

  • A.提升模型推理响应速度
  • B.解决特征表无限膨胀的压力← 正确答案
  • C.消除所有哈希碰撞问题
  • D.替代神经网络训练过程

答案:B。哈希技巧将任意特征映射到固定长度的表,内存不再随特征总数增长,同时天然支持新特征。碰撞只能用多哈希等方案缓解,无法彻底消除,因此 C 不是核心目标。

Q4. 哈希碰撞在工程中最直接的后果是什么?

单选题 · mid

  • A.多个特征共享同一向量← 正确答案
  • B.模型完全无法训练
  • C.特征顺序被打乱
  • D.预测概率变成负数

答案:A。碰撞意味着两个不同特征落入同一槽位,被迫共享同一个 Embedding 向量,特征的个性化表达被稀释。它不会让训练崩溃,也不会改变特征顺序,预测值通常是正数,因此 B、C、D 均不成立。

Q5. 缓解哈希碰撞的常见方案有哪些?

多选题 · mid

  • A.使用多个独立哈希函数← 正确答案
  • B.增加哈希表的总长度← 正确答案
  • C.对高频特征单独建表← 正确答案
  • D.直接移除全部低频特征

答案:ABC。多哈希把两个独立映射组合起来使分布更均匀,加长表直接降低碰撞概率,高频特征单独建表防止热门特征被挤压。移除低频特征会损失长尾信息,不是缓解碰撞的正道。

Q6. DeepFM 中 FM 部分的核心能力是什么?

单选题 · mid

  • A.仅建模单个特征权重
  • B.建模两两特征交互← 正确答案
  • C.生成全部用户向量
  • D.做特征注意力加权

答案:B。FM 的二阶交叉项对任意两个特征做内积,捕捉「搭配效应」。一阶项才负责单特征权重,DIN 负责注意力加权,用户向量是模型的产出而非 FM 的能力。

Q7. DIN 的注意力权重是通过什么方式得到的?

单选题 · mid

  • A.人工经验设定的固定权重
  • B.打分后softmax归一化← 正确答案
  • C.随机初始化后不再更新
  • D.各候选商品平均分配

答案:B。DIN 先由一个可学习的打分函数计算候选与每个历史行为的相关度,再经 softmax 归一得到权重,权重随训练自动更新。人工不直接指定权重,平均分配则是没有注意力的做法。

Q8. 关于 Embedding 维度的选择,哪些说法正确?

多选题 · mid

  • A.维度越大信息越丰富← 正确答案
  • B.推荐常用八到一百二十八维← 正确答案
  • C.维度越大效果一定最好
  • D.维度太大易导致过拟合← 正确答案

答案:ABD。更大的维度承载更多信息,但参数量同步增长,数据不足时容易过拟合,所以「一定最好」不成立。推荐场景经验上取 8 到 128 维,在信息容量与泛化之间取平衡。

Q9. 多哈希组合 (h1+h2) mod L 相比单哈希的主要优势是什么?

单选题 · extreme

  • A.让哈希运行速度成倍提升
  • B.进一步降低碰撞发生概率← 正确答案
  • C.能够彻底消除全部碰撞
  • D.无需再维护哈希索引表

答案:B。两个独立哈希组合能把特定模式下的碰撞打散,使特征分布更均匀,从而降低碰撞率。它不会消除全部碰撞(表长有限,生日悖论依然存在),反而多了一次哈希计算,速度不会更快。

Q10. 分布式训练中 Embedding 表的分片策略需要考虑哪些因素?

多选题 · hard

  • A.热点特征分散到不同机器← 正确答案
  • B.降低节点间通信开销← 正确答案
  • C.所有参数保持一份副本
  • D.哈希索引保证映射一致← 正确答案

答案:ABD。热点特征要分散到多节点避免单机瓶颈,分片要尽量减少跨机通信,哈希索引的全局一致性保证各节点查到同一个槽位。所有参数在各节点各存一份既浪费内存又会造成更新不一致,不是合理策略。