01
60 秒回答模板
面试中可以这样回答:DSIN 的主干是先把用户历史行为按时间间隔切成多个 session,再把每个行为中的稀疏特征做 embedding,经过 session interest extractor 提取每个 session 的兴趣表示,再通过兴趣交互层建模 session 之间的演化,最后用目标商品对这些 session interest 做 activation,得到与当前候选 item 相关的用户兴趣表示。稠密特征一般不是替代这个流程,而是作为 side feature 加到对应层级:用户年龄、消费能力、历史统计等用户稠密特征放在 user/context tower;商品价格、销量、质量分等 item 稠密特征放在 item tower;时间差、行为强度、session 长度、session 内点击次数等行为或 session 级稠密特征可以归一化后拼到 behavior embedding 或 session representation 上。常见做法是先对 dense feature 做 log、clip、standardization、min-max、bucketing,再通过小 MLP 或线性投影映射到和 embedding 相近的维度,然后与 sparse embedding、target item embedding、context embedding、DSIN 产出的 session interest 向量 concat,后面接 feature crossing、attention activation 或最终 DNN 输出 CTR。
考点 DSIN 主干先解决序列兴趣建模
主线 Session 内抽取兴趣表示
易错点 把 DSIN 理解成普通 DNN 拼接模型,只回答 d…
02
深入解析
01 DSIN 主干先解决序列兴趣建模
DSIN 面向推荐和 CTR 预估,重点不是简单拼接用户历史行为,而是把用户行为序列按照时间窗口或行为间隔切成多个 session。每个 session 代表一段相对连续的兴趣片段。原始行为里的 item id、cate id、shop id、brand id 等通常是稀疏特征,会先进入 embedding 层,得到每个行为的低维向量表示。
02 Session 内抽取兴趣表示
在每个 session 内,DSIN 会用 self-attention 或类似的序列建模结构捕捉行为之间的相关性,再聚合成该 session 的 interest representation。这里的核心是让模型知道一个 session 内哪些行为共同表达了用户当时的兴趣,而不是把所有历史点击平均处理。
03 Session 间建模兴趣演化
多个 session 的兴趣向量会继续进入兴趣交互或演化建模层,常见思路是用序列结构建模 session 之间的先后关系。这样模型可以表达用户兴趣从一个主题迁移到另一个主题的过程,例如近期兴趣比很久以前的兴趣更接近当前购买意图。
04 目标商品激活相关兴趣
最终预测某个候选商品是否会被点击时,DSIN 通常会用 target item embedding 去激活历史 session interest,得到与当前候选商品最相关的兴趣表示。这一步类似目标感知的 attention:不是所有 session 都同等重要,而是和当前候选 item 更相关的 session 权重更高。
05 稠密特征分层进入表示
稠密特征可以按来源分层加入:用户侧 dense 特征如年龄、消费层级、历史点击率、近 7 天活跃天数;商品侧 dense 特征如价格、销量、评分、转化率统计;上下文 dense 特征如小时、距离上次行为时间、曝光频次;行为侧 dense 特征如停留时长、行为权重、时间衰减;session 侧 dense 特征如 session 长度、session 内点击次数、session 时间跨度。
06 数值特征需要映射
实际实现时,dense feature 一般不会直接以原值参与大 DNN。常用方式有三种:连续值经过缺失值填充、clip、log、标准化后直接 concat;连续值分桶后当作离散特征做 embedding;用小型 MLP 或线性层把 dense 向量投影到与 sparse embedding 相近的维度。对于长尾分布明显的特征,分桶 embedding 往往更稳。
07 最终融合通常发生在 DNN 输入层
DSIN 产出的目标感知 session interest 向量,会和用户画像 embedding、候选商品 embedding、上下文 embedding、处理后的 dense 表示拼接,再输入最终的 DNN。DNN 负责学习高阶特征组合,例如价格与消费能力、类目与时间段、近期 session 兴趣与候选商品属性之间的交叉关系。
03
易错点
- 把 DSIN 理解成普通 DNN 拼接模型,只回答 dense 特征 concat 到最后一层,没有说明行为 session 和兴趣演化。
- 把所有稠密特征都拼到每个行为 embedding 上,忽略用户级、商品级、上下文级、行为级、session 级特征的语义边界。
- 直接输入原始数值,不做缺失值处理、异常值截断、log、归一化、标准化或分桶,导致训练不稳定。
- 只讲 sparse embedding,不说明 dense feature 如何通过 MLP、线性投影或 bucket embedding 映射到可融合表示。
- 忽略 dense 特征与 target item、用户兴趣、上下文之间的交叉,导致回答停留在机械拼接层面。
- 没有提训练和线上一致性,尤其是统计类特征的时间窗口、延迟、穿越和归一化参数问题。
04
面试官追问
稠密特征可以直接拼到 DSIN 的 behavior embedding 吗?
可以,但要看特征是不是行为级语义。如果是单次行为的停留时长、行为类型权重、行为发生时间距当前的间隔、行为价格等,可以先归一化或投影后拼到每个 behavior embedding,再送入 session interest extractor。如果是用户年龄、总消费能力、候选商品价格这类非行为级特征,直接拼到每个历史行为上会引入语义噪声。
稠密特征到底该归一化还是分桶?
两者不冲突。连续、平滑、单调意义较强的特征适合归一化后直接输入,比如比例、打分、衰减因子。长尾、非线性、区间效应强的特征适合分桶 embedding,比如价格、历史点击次数、停留时长、距离上次点击时间。很多模型会同时保留连续归一化版本和分桶离散版本。
为什么不能把原始价格、次数、时长直接喂给模型?
因为这些特征的尺度差异很大,价格可能是几千,比例是 0 到 1,点击次数可能长尾到几百,时长可能受异常值影响。直接输入会导致梯度被大数值特征主导,优化器难以稳定更新 embedding 和 DNN 参数,也会让模型对异常值过度敏感。
dense feature 和 sparse embedding 拼接后维度不一致怎么办?
维度不一致不是问题,concat 本身允许不同来源的向量拼接。关键是数值尺度和表达能力要匹配。工程上通常会把 dense 向量通过 BatchNorm、LayerNorm、线性层或小 MLP 投影到合适维度,再与 sparse embedding、target item embedding、session interest 向量拼接。
加入 dense 特征后效果变差,常见原因是什么?
常见原因包括训练和线上特征口径不一致、统计特征发生数据穿越、缺失值没有统一处理、异常值没有截断、归一化参数用错时间范围、dense 特征数量过多导致噪声增加、与 sparse embedding 融合过早破坏 session 结构,以及最终 DNN 没有足够能力学习有效交叉。