街角有家咖啡店,老板阿兴有个本事:老顾客一推门,他就知道对方想喝什么。加班晚归的小李,他递上一杯冰美式;周末带孩子的王姐,他提前备好少糖拿铁。阿兴不靠读心术,只靠两件事——记下每个人每一次的点单,再偷偷观察他今天的表情。这其实就是智能推荐系统在做的事:AI 通过分析用户的行为轨迹,一边记住“你一直喜欢什么”,一边捕捉“你此刻想要什么”,最终在上百万个商品里猜中你最想点的那一个。这篇文章会带你认识“用户兴趣建模”:从行为序列到注意力机制,从多兴趣胶囊到兴趣漂移应对,最后聊聊如何让模型在真实业务里经受离线评估与 A/B 测试的考验。

岗位关联

掌握用户兴趣建模,是推荐算法从业者从“调参工程师”走向“个性化架构师”的关键一步——它决定了用户看到的信息流是否真的懂他,也决定了平台的留存与成交天花板。

目录
  1. 可视化演示
  2. 兴趣建模基础
  3. 行为序列编码
  4. 注意力机制
  5. 多兴趣表征
  6. 兴趣漂移应对
  7. 离线评估体系
  8. A/B与产业落地
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示基于序列建模、注意力聚合与多兴趣胶囊的兴趣提取过程,可切换三种模式观察短期意图与长期偏好的动态捕捉。

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

序列建模捕捉兴趣 短期兴趣通过最近行为序列建模,RNN/LSTM逐步更新 输出代表当前意图的隐藏状态向量 GRU: h_t = f(h_{t-1}, x_t) 序列建模捕捉即时意图。

兴趣建模基础

阿兴曾经以为,记住顾客“爱喝什么”就够了。直到他发现,小李平时必点冷萃,可每次加班到晚上九点,进门却要一杯热拿铁——“平时喜欢的”和“此刻想要的”完全是两回事。他开始在点单卡上分两栏记录:一栏写口味习惯,一栏写今天的天气、时间和状态。这个直觉,正是推荐系统里最核心的拆分:长期偏好与短期意图。

在 AI 的世界里,早期做法是把用户压成一个固定向量,就像填一张“静态资料卡”:性别、年龄、品类偏好。可这张卡不会自己更新,用户上个季度爱露营,这个季度突然入了烘焙坑,卡上的字却纹丝不动。于是研究者转向一个更自然的视角:把用户的行为按时间排成一串,像阿兴那本越来越厚的点单卡,让模型从“连续发生的事”里理解人。

这种视角叫序列建模。它不再把用户看作静止的点,而是一段正在流动的河。兴趣状态随时间被新行为不断刷新:

阿兴恍然大悟:真正懂一个人,不是背下他的资料卡,而是记住他一路怎么走过来,并允许这份记忆每时每刻都在更新。用户兴趣建模,本质就是给 AI 装上一本会呼吸、会生长的“点单卡”。

ht=G(ht−1,xt)h_t = G\left(h_{t-1}, x_t\right)
这条公式是说:现在的兴趣状态,等于“过去的兴趣状态”和“刚刚发生的新行为”通过一个更新函数融合后的结果。就像阿兴对小李的了解,每完成一次点单就刷新一次。
  1. 历史状态 $h_{t-1}$记录着截止到上一时刻的用户兴趣,好比阿兴对小李“昨天之前”的全部印象。
    ht−1h_{t-1}
  2. 新行为 $x_t$用户此刻刚刚产生的交互,比如刚点了一杯热拿铁,这是一个新的信号输入。
    xtx_t
  3. 更新函数 $G$负责把旧印象和新信号融合的规则,可以是一个神经网络,也可以是一条加权公式,相当于阿兴“更新记忆”的方式。
    G(⋅)G(\cdot)
  4. 当前状态 $h_t$融合完成后的最新兴趣状态,是推荐系统此刻用来预测用户下一个行为的依据。
    hth_t

行为序列编码

阿兴的点单卡越记越厚,但他很快发现:光记没用,还得“好记”。如果他只写“第几次点了什么”,几百条记录挤在一起就像一团乱麻。于是他想了个办法——把每杯饮品翻译成一组“暗号”:拿铁=冰爽系,美式=清醒系,热巧=治愈系。这样一来,卡片上不再是零散的名字,而是一串有含义的记忆编码。AI 处理行为序列前,也需要做同样的翻译。

第一步是清洗。原始行为日志里有大量噪声:用户点开商品页面不到一秒就退出,可能是误触;凌晨三点反复刷新同一页面,可能是爬虫。这些“脏数据”会污染兴趣画像,需要按停留时长、点击深度、频次异常等规则过滤掉。第二步是切片:用户的历史可能有几千条,模型吞不下,于是按时间排序后只取最近 L 条,构成一个定长序列——就像阿兴只翻“最近这一页”来推测今天想喝什么。

第三步就是关键的“翻译”——嵌入表示。商品 ID 像人名,本身没有语义;模型通过一张嵌入矩阵,把每个高维稀疏的 ID 映射成一个稠密向量。语义相近的商品,训练后会在向量空间里相互靠近:

有了这套“暗号手册”,阿兴不用死记两百个名字,而是记两百组含义。模型也一样——把一本杂乱的点单流水账,变成了一条干净、稠密、可计算的行为序列。

et=E⋅onehot(xt)e_t = E \cdot \mathrm{onehot}(x_t)
公式里 $x_t$ 是某个商品 ID,$\mathrm{onehot}(x_t)$ 把它变成一个只亮一盏灯的开关数组,$E$ 是模型学出来的“字典”,两者相乘就得到商品对应的稠密向量 $e_t$。
  1. 商品 ID $x_t$行为序列里记录的原始商品编号,比如“商品编号 007”。
    xtx_t
  2. 独热向量 $\mathrm{onehot}(x_t)$把 ID 改写成一段只有对应位置为 1、其余全为 0 的向量。如果商品池有一百万个,这个向量就有一百万维,极其稀疏。
    onehot(xt)\mathrm{onehot}(x_t)
  3. 嵌入矩阵 $E$形状为“商品数 × 向量维度”的查找表,每一行就是一个商品的初始语义向量,等价于阿兴那本“翻译暗号手册”。
    EE
  4. 商品向量 $e_t$查表得到的稠密低维向量,比如 64 维,浓缩了商品的语义信息,后续模型就在这个空间里计算兴趣。
    ete_t

注意力机制

阿兴算账有个习惯:参考最近的点单最认真,三个月前的记忆会自然淡忘。但如果今天下大雨,他反而会想起顾客上次下雨天点的那杯姜茶。这种“选择性回忆”不是玄学,而是人类直觉里的注意力:该重视的记忆多给权重,无关的记忆轻轻带过。AI 想学这个本领,靠的就是注意力机制。

在序列模型里,自注意力让每个行为都和其他行为互相打分。具体来说,当前时刻的意图作为 Query(问句),历史每个行为作为 Key(标签),先计算“这个记忆跟当前问题有多相关”,再用 softmax 把相关度变成一堆加起来等于 1 的权重,最后按权重把 Value(内容)加权求和。这样,每次融合历史时,模型会自动突出那些真正重要的记忆。

这套操作写成公式就是深度学习里最常见的自注意力:

阿兴的“偏心”从此不再凭感觉——它变成了一套可解释的加权算法:重要的记忆自动放大,无关的细节自动隐退。注意力机制让模型学会在长长短短的行为序列里,精准找出“决定下一杯”的关键信号。

Attention(Q,K,V)=softmax(QK⊤d)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\left( \frac{Q K^{\top}}{\sqrt{d}} \right) V
通俗讲:用当前关心的问题去翻记忆档案,相关度高的档案被重点朗读,读出来的内容就是融合后的兴趣表示。除以 $\sqrt{d}$ 是为了防止打分数字过大,让注意力分布更温和。
  1. 查询向量 $Q$代表“我此刻最关心什么”,通常由序列当前状态生成,相当于阿兴心里默念“这家伙现在想喝什么”。
    QQ
  2. 键向量 $K$每个历史行为各自的“标签”,相当于档案袋上贴的便签,写着“这是冰的”“这是雨天点的”。
    KK
  3. 点积打分 $QK^\top$把问题与每个标签做匹配度计算,得到一组原始分数,分数越高表示这条记忆越值得参考。
    QK⊤QK^{\top}
  4. 缩放因子 $\sqrt{d}$向量维度 $d$ 越大、点积结果越大,除以 $\sqrt{d}$ 把分数拉回合理区间,防止送入 softmax 后直接饱和、注意力变成“只认一个”的极端状态。
    d\sqrt{d}
  5. 归一化 softmax把分数变成总和为 1 的权重,相当于把“哪些记忆更值得翻”的排序落成具体概率。
    softmax(⋅)\mathrm{softmax}(\cdot)
  6. 加权求和 $V$按权重把各位置的真实内容加到一起,得到融合后的兴趣向量,即模型对用户当前状态的浓缩理解。
    ∑iαivi\sum_i \alpha_i v_i

多兴趣表征

阿兴后来发现,小李身上住着好几个人格:工作日是冷萃重症患者,周末是手冲单品爱好者,约会时却会点最甜的焦糖摩卡。如果只给小李建一个“平均画像”——拿冷萃、手冲、摩卡三个口味取个平均——最后会得到一杯四不像的“灰色咖啡”。这个平均向量既不冷萃也不摩卡,什么都代表不了。单一向量描述一个复杂用户,注定会失真。

于是研究者提出多兴趣表征:不再用一个向量表示用户,而是用 $K$ 个向量,分别刻画用户在不同场景下的子兴趣。这些子兴趣怎么来?一种典型方案是胶囊网络:把用户行为里的低层特征(比如“冰”、“甜”、“气泡”)通过动态路由投递到不同的高层“兴趣胶囊”里,让模型自己决定哪些特征抱团组成一个兴趣。训练完成后,每个胶囊就是一个鲜明的偏好方向。

做召回时,$K$ 个兴趣向量各走一路,分别去商品库里捞自己的候选集,再合并排序。当用户产生新交互时,模型还要根据当前场景决定更依赖哪个兴趣胶囊。这一融合过程可以写成:

阿兴不再把小李定义成“某一种人”,而是给他准备了一抽屉人格卡片:工作、周末、约会各一张,看场合抽出对应那张。多兴趣表征的价值,正在于让推荐系统尊重人的复杂性,而不是粗暴地取一个平庸的均值。

ufinal=∑k=1Kβk uku_{\mathrm{final}} = \sum_{k=1}^{K} \beta_k \, u_k
意思是:最终的当前用户表示,是 $K$ 个兴趣向量按当前场景权重加权求和。每个 $u_k$ 代表一种“人格”,$\beta_k$ 代表此刻谁在主导。
  1. 兴趣向量 $u_k$第 $k$ 个兴趣胶囊的表示,比如小李的“冷萃人格”和“摩卡人格”各是一个向量。
    uku_k
  2. 场景权重 $\beta_k$当前时刻下对第 $k$ 个兴趣的关注程度,由最近的交互序列动态计算,相当于“今天是谁说了算”。
    βk\beta_k
  3. 加权求和 $\sum$把 $K$ 个兴趣向量按权重合并,得到一个综合的当前用户表示。
    ∑k=1K\sum_{k=1}^{K}
  4. 融合结果 $u_{\mathrm{final}}$最终用来和商品向量计算相似度、指导召回的向量。
    ufinalu_{\mathrm{final}}

兴趣漂移应对

咖啡圈的风向变得比天气还快:年初满城都在喝气泡美式,夏天全转去冰萃,秋天又流行起燕麦拿铁。更别提顾客自己也在变——老王最近开始戒糖,连最爱的焦糖玛奇朵都换成了美式。阿兴要是不更新记忆,就会在一次又一次的皱眉里发现猜错了。用户的兴趣从来不是一成不变,而是持续漂移的。

漂移的应对策略有三板斧。首先是漂移探测:定期监控兴趣向量的分布变化、品类热度迁移以及推荐指标的突然下滑,及时发现“口味在变”的信号。其次是时间衰减:给行为加上一个随年龄递减的权重,越久远的行为对当前兴趣的影响就越小,让模型天然地“喜新厌旧”但不至于“翻脸不认人”。最后是在线更新:模型不再每周离线训练一次,而是随着新交互产生不断做增量学习,让记忆跟上现实。

时间衰减的数学形式很简洁,一个指数函数:

阿兴给自己装了一块“记忆橡皮擦”,但不是糊涂地全忘:旧习惯保留三分,新趋势追七分。兴趣漂移应对,让推荐系统既能记住你是谁,又不会抱着你的过去不放。

w(Δt)=e−Δt/τw\left(\Delta t\right) = e^{-\Delta t / \tau}
这条公式是说:一条行为对当前兴趣的贡献权重,随着距离现在的时间 $\Delta t$ 增加而指数级衰减。$\tau$ 是“遗忘速度”旋钮——调大一点,老记忆退得慢;调小一点,模型立刻追新。
  1. 时间差 $\Delta t$行为发生到现在的间隔时长,比如“三个月前那条点单记录”的 $\Delta t$ 就很大。
    Δt\Delta t
  2. 衰减常数 $\tau$控制遗忘速率的超参数,$\tau$ 越大,同等时间差下旧行为保留的权重越多。
    τ\tau
  3. 指数函数 $e^{-\Delta t / \tau}$当 $\Delta t=0$ 时权重为 1,随着 $\Delta t$ 增大权重平滑趋向 0,形成一个自然的“记忆曲线”。
    e−Δt/τe^{-\Delta t / \tau}

离线评估体系

阿兴的秘方到底准不准?光靠自我感觉可不行。他搞了个“盲测”:把每位顾客的点单卡最后一页撕掉,只凭前面的记录猜他最后点了哪杯,猜中率就是实力的证明。推荐系统上线前,也需要这样一场严谨的“盲测”——这就是离线评估。

评估的第一步是数据划分。不能随机打乱后划分,而必须按时间切分:用户前 80% 的行为做训练,最后一条真实交互做测试。否则模型会“偷看未来”,戴上有色眼镜走向考场。第二步是选指标:HitRate@K 看“真实点击是否出现在模型推荐的 Top-K 里”,NDCG@K 更进一步——命中的商品排得越靠前,得分越高。第三步是找基线:新模型要和热门推荐、协同过滤、简单均值池化等对照,证明提升不是来自巧合。

其中 HitRate@K 是最直观的命中率指标:

盲测让阿兴的秘方第一次变得可量化:每次调整配方、每次升级记忆法,先自己刷一遍考卷再决定要不要见顾客。离线评估的意义,就是在真实世界付出代价之前,先用历史数据给模型一场公平的补考。

HR@K=Top-K 命中真实交互的样本数评测样本总数\mathrm{HR@K} = \frac{\text{Top-}K\ \text{命中真实交互的样本数}}{\text{评测样本总数}}
通俗理解:把所有用户当考卷,翻到最后一页之前先让模型写出 Top-K 个猜测,看看有多少张考卷的真实答案恰好被写在里面。
  1. 命中真实交互模型的 Top-K 推荐列表里,包含用户实际消费的那个商品,算一次命中。
    Top-K 命中\text{Top-}K \text{ 命中}
  2. 分子所有测试样本中命中的个数,相当于盲测猜对的考卷张数。
    命中真实交互的样本数\text{命中真实交互的样本数}
  3. 分母参与评测的样本总量,不管猜没猜中,每张考卷都算数。
    评测样本总数\text{评测样本总数}
  4. 比值命中数除以总数得到命中率,越接近 1 说明兴趣画像越敏锐。
    命中总数\frac{\text{命中}}{\text{总数}}

A/B与产业落地

阿兴觉得新秘方好使,但他没有直接全店换新——万一只是心理作用呢?他做了个决定:城南老店继续用旧配方,城北新店试用新配方,两边都用统一的顾客满意度评分,跑满两周后对比数据再下结论。这就是 A/B 测试在现实世界里的样子:小范围验证,用数据决策,而不是拍脑袋全量上线。

实验设计的第一步是明确假设和指标:比如“新兴趣模型能把首页点击率提升 3%”,主指标定为 CTR,辅指标看转化率和人均时长。第二步是分流机制:按用户 ID 哈希分流到实验组和对照组,保证两组画像大致一致;更规范的做法是引入实验层与流量层正交,让多个实验共享流量却互不污染。上线前还要做 AA 检验——把两组都分到旧模型,确认指标没有显著差异,证明分流是均匀的。第三步是算样本量:预期提升越小、数据波动越大,需要的样本量就越大,不能实验跑一小时就拍板。

看完实验数据后,业务上最关心的往往是一个百分比提升:

从一张点单卡到一套可复制的“记忆方法论”,阿兴的咖啡馆最终变成了一个数据驱动的实验场:每一项改动都先假设、再验证、后定论。A/B 测试与产业落地,就是让兴趣建模从论文里的公式,变成真实业务里那杯更懂顾客的咖啡。

lift=CTR实验−CTR对照CTR对照\mathrm{lift} = \frac{\mathrm{CTR}_{\text{实验}} - \mathrm{CTR}_{\text{对照}}}{\mathrm{CTR}_{\text{对照}}}
释义:实验组的点击率相对对照组提高了百分之多少。lift 为正且统计显著,说明新模型值得全量上线;lift 为负或波动剧烈,就该回到离线阶段继续调优。
  1. 实验组点击率 $\mathrm{CTR}_{\text{实验}}$使用新兴趣模型那部分用户群体的点击率。
    CTR实验\mathrm{CTR}_{\text{实验}}
  2. 对照组点击率 $\mathrm{CTR}_{\text{对照}}$沿用旧模型那部分用户群体的点击率,作为参照系。
    CTR对照\mathrm{CTR}_{\text{对照}}
  3. 差值相减算出新模型带来的绝对提升,比如 5.2% 减去 4.8% 等于 0.4 个百分点。
    CTR实验−CTR对照\mathrm{CTR}_{\text{实验}} - \mathrm{CTR}_{\text{对照}}
  4. 归一化相除把绝对差距换算成相对提升比例,方便在不同业务量级间横向比较。
    ΔCTR对照\frac{\Delta}{\mathrm{CTR}_{\text{对照}}}

AI 应用场景

电商首页“猜你喜欢”

阶段:召回与排序(兴趣建模生成用户向量,指导候选商品召回)

解决的问题:传统规则推荐只看品类热度,忽略了用户“正在进行的连续任务”。用户为了周末露营连续搜索帐篷、防潮垫、营地灯,如果只按历史标签推他买过的键盘,就错过了此刻最强烈的需求。

具体案例:用户在电商平台连续浏览露营装备,序列模型用最近 20 次行为计算注意力权重,发现“营地灯”与当前意图点积得分最高,于是把它顶到首页第一屏。点击率对比旧策略提升明显,随后通过 A/B 测试确认后全量上线。

短视频信息流的实时兴趣追踪

阶段:在线学习与兴趣漂移应对(增量更新用户兴趣向量)

解决的问题:短视频用户的兴趣以小时为单位漂移,可能昨晚沉迷健身,今早就狂刷 AI 绘画教程。静态画像跟不上“三天热度”,用户很快失去新鲜感。

具体案例:某短视频平台监测到用户近半小时的观看序列高度集中在 AI 绘画教程,在线更新模块立刻调高该类目的兴趣权重,同时按时间衰减平滑掉一周前的健身内容——但不是彻底雪藏,避免用户突然回切时失去推荐。

家庭视频平台的“一人多面”

阶段:多兴趣表征(多兴趣向量分别召回、分区展示)

解决的问题:一个家庭账号常常多人共用,孩子看动画、父母看悬疑剧;即便是单人用户,也可能同时爱着纪录片和偶像剧。单向量模型无法兼顾,推荐结果总有一半人不满意。

具体案例:视频平台为同一账号建了多个兴趣胶囊,首页按不同板块各自动用对应胶囊召回:少儿区由“动画胶囊”主导,深夜剧场由“悬疑胶囊”主导,各路人马互不干扰,账号的整体观看时长显著提升。

Python 演示

python53 行
import numpy as np def make_data(num_users=150, num_items=60, seq_len=8, seed=42):    # 模拟用户行为序列: 每条序列末尾对应一个待预测的目标商品    rng = np.random.default_rng(seed)    seqs = rng.integers(0, num_items, size=(num_users, seq_len))    targets = rng.integers(0, num_items, size=num_users)    return seqs, targets def init_embeddings(num_items, dim=16, seed=0):    # 随机初始化商品嵌入矩阵    rng = np.random.default_rng(seed)    return rng.normal(0, 0.1, size=(num_items, dim)) def attention_user_vector(seq, emb, tau=1.0):    # 简化自注意力: 用最近行为当查询, 历史行为按相关度加权    e = emb[seq]    query = e[-1]    scores = e @ query / np.sqrt(e.shape[1])    scores = scores / tau    w = np.exp(scores - scores.max())    w = w / w.sum()    return (e * w[:, None]).sum(axis=0) def mean_user_vector(seq, emb):    # 基线方法: 对行为序列做均值池化    return emb[seq].mean(axis=0) def hit_at_k(user_vec, emb, target, k=5):    sims = emb @ user_vec    topk = np.argsort(-sims)[:k]    return 1.0 if target in topk else 0.0 def evaluate(seqs, targets, emb, method, k=5):    hits = 0    for s, t in zip(seqs, targets):        if method == "attn":            u = attention_user_vector(s, emb)        else:            u = mean_user_vector(s, emb)        hits += hit_at_k(u, emb, t, k)    return hits / len(seqs) def main():    seqs, targets = make_data()    emb = init_embeddings(60)    hr_attn = evaluate(seqs, targets, emb, "attn")    hr_mean = evaluate(seqs, targets, emb, "mean")    print(f"mean-pooling baseline HR@5 = {hr_mean:.3f}")    print(f"attention interest  HR@5   = {hr_attn:.3f}") if __name__ == "__main__":    main()
目的:用 NumPy 实现一个微型“基于注意力的兴趣建模”,在模拟行为序列上预测下一个交互商品,并与均值池化基线对比 HitRate@5。
  1. e = emb[seq]把商品 ID 序列翻译成向量序列,相当于阿兴翻开点单卡。
  2. query = e[-1]拿最近一次行为当作“此刻的意图”,就像阿兴看顾客刚进门那一眼的状态。
  3. scores = e @ query / np.sqrt(e.shape[1])所有历史行为给当前意图打分,除以维度平方根防止分数过度饱和。
  4. w = np.exp(scores - scores.max())数值稳定化的 softmax 分子,把分数变成非负的“关注度”。
  5. w = w / w.sum()归一化成总和为 1 的注意力权重。
  6. return (e * w[:, None]).sum(axis=0)按注意力权重加权求和,得到融合历史后的兴趣向量。
  7. sims = emb @ user_vec计算所有候选商品与兴趣向量的相似度。
  8. topk = np.argsort(-sims)[:k]取相似度最高的前 K 个商品作为召回结果。

常见误区

误区很多初学者以为兴趣建模就是给用户打标签,“爱咖啡”“爱运动”“爱数码”,标签打上去就一劳永逸,后续只要查标签做推荐就行。上线后却发现用户很快不买账,于是怀疑模型出了问题。

正解兴趣的本质是流动的。用户上季度爱露营,这季度可能迷上烘焙;即便在同一天里,加班后的口味也和周末不同。所以兴趣建模必须用行为序列加时间衰减持续更新,像阿兴那样每次点单后都刷新对顾客的了解,而不是守着一张过期的资料卡。

为何常见:静态标签实现简单、结果直观,容易让人误以为“画像”是一张可以永久存档的身份证,忽略了人是会变的。

误区有人看到注意力权重分布很尖锐——最近一次行为几乎分走了全部权重——就认为模型很聪明,理由是“它懂得聚焦”。但换一批数据后效果反而剧烈下滑。

正解注意力权重过度集中于最近一次行为,意味着模型对短期噪声过拟合。用户可能误点了一个不感兴趣的链接,如果模型把这当成最重要的信号,整个兴趣画像都会被带偏。好的注意力应该像阿兴那样:近期记忆权重高,但长期偏好仍然占有一席之地,两者有节奏地平衡。

为何常见:直觉上“最近发生的最重要”,于是把尖锐的分布误当成模型强大的标志,忽略了长期偏好的稳定价值。

误区HR@K 或 AUC 在离线评测集上提升明显,开发者兴冲冲地全量上线,结果线上点击率反而下跌,复盘时才发现离线与在线差距巨大。

正解离线评估用的是历史数据,天然存在选择偏差——过去的行为是由旧推荐策略产生的;线上还存在反馈循环:推荐影响用户行为,行为又变成训练数据。离线高、在线低是常态。正确的流程是离线通过后,先做小流量 A/B 测试,用业务指标决定是否全量,就像阿兴先在城北试点两周再看数据。

为何常见:离线评测快、成本低、数字直观,容易让人产生“数据说话”的安全感,却忽略了它和真实世界的系统性偏差。

误区认为深度学习就是“数据越多越准”,于是把全部行为日志按时间顺序直接拼成序列喂给模型,甚至把三个月前的数据也原样保留,结果模型越训越迟钝。

正解行为日志里充斥着噪声:误触点击、爬虫刷量、广告位误曝光被记成“喜欢”。这些脏数据会污染兴趣向量,让模型把噪声当成偏好。建模之前必须做清洗,比如过滤停留时间过短的点击、识别异常高频访问;切片时也要按实际业务选择窗口长度。数据多不等于信息多,干净且有序的数据才有价值。

为何常见:“大模型靠大数据”的说法深入人心,但那是针对规模化语料;推荐行为日志的信噪比远低于文本,需要先做取舍。

面试题

Q1. 关于长期偏好与短期意图,下列哪项描述正确?

单选题 · easy

  • A.长期偏好稳定,短期意图多变← 正确答案
  • B.长期偏好多变,短期意图稳定
  • C.长期短期偏好均稳定不变
  • D.长期短期偏好均频繁变化

答案:A。长期偏好是用户相对稳定的口味基底,比如小李一直偏爱冷萃;短期意图则是当下场景驱动的临时需求,加班后想喝热拿铁。A 正确。B 把两者说反了,C 和 D 都否定了“长期稳、短期变”的基本结构,与兴趣建模的核心假设不符。

Q2. 自注意力公式中除以 $\sqrt{d}$ 的主要原因是?

单选题 · mid

  • A.防止点积过大进入 softmax 饱和区← 正确答案
  • B.让向量维度更小以降低计算开销
  • C.让每个词向量变成单位长度向量
  • D.使模型对不同序列长度更加鲁棒

答案:A。当向量维度 $d$ 增大时,点积 $QK^\top$ 的方差随之变大,数值可能很大,softmax 流入饱和区后梯度消失、注意力退化成“只盯一个位置”。除以 $\sqrt{d}$ 是让分数方差保持稳定,类似阿兴打分前先归一数字,避免某个记忆因数值过大而一票否决。

Q3. 行为序列编码中,Embedding 层的主要作用是什么?

单选题 · mid

  • A.为每个商品分配随机唯一编号
  • B.把稀疏高维 ID 转为稠密低维向量← 正确答案
  • C.直接输出预测的下一个商品 ID
  • D.对商品类别做人工规则编码

答案:B。商品 ID 是离散且高维的,独热向量动辄百万维,无法直接计算语义。Embedding 矩阵把每个 ID 映射成几十维的稠密向量,语义相近的商品在向量空间里互相靠近。A 只是编号没有语义,C 是输出层的事,D 是人工特征工程,都与嵌入表示不符。

Q4. 下列哪些方法可以有效缓解用户兴趣漂移问题?

多选题 · mid

  • A.对旧行为施加时间衰减权重← 正确答案
  • B.用滑动窗口截取最近行为← 正确答案
  • C.在线学习随新数据持续更新← 正确答案
  • D.扩大正样本采样比例

答案:ABC。时间衰减让老记忆权重递减,滑动窗口直接丢弃过时行为,在线增量训练让模型跟上新趋势,三者都是应对漂移的常规手段。D 是调整正负样本平衡的采样策略,和“兴趣随时间变化”没有直接关系。

Q5. 多兴趣表征主要解决什么问题?

单选题 · easy

  • A.一个用户同时有多种兴趣偏好← 正确答案
  • B.商品数量太多导致召回太慢
  • C.用户行为序列长度不够稳定
  • D.离线指标与在线效果不一致

答案:A。现实中的用户往往“一人多面”:工作日看职场剧、周末追动画、偶尔刷纪录片。单一向量把这些偏好揉成平均值,哪个都推荐不准。多兴趣用多个向量分别刻画不同子兴趣,让每种偏好都有机会被召回。B 是工程性能问题,C 是序列长度处理问题,D 是评估一致性问题。

Q6. 胶囊网络中动态路由的核心思想是什么?

单选题 · hard

  • A.低层特征向高层兴趣胶囊传递汇总投票← 正确答案
  • B.高层胶囊直接复制低层特征的加权平均
  • C.兴趣胶囊个数随训练动态增加减少
  • D.路由系数固定且只更新胶囊内容

答案:A。动态路由通过多轮迭代更新“底层特征属于哪个高层胶囊”的系数,让低层特征向合适的兴趣胶囊传递信息、逐个投票,最终让兴趣结构自己长出来。B 忽略迭代投票过程,C 的胶囊数量是预设超参数,D 把路由系数当作固定值,都不是动态路由的本质。

Q7. 下列哪些是推荐模型常用的离线评估指标?

多选题 · mid

  • A.HR@K 衡量真实交互是否进入前 K← 正确答案
  • B.NDCG@K 衡量命中位置是否靠前← 正确答案
  • C.AUC 衡量正负样本排序质量← 正确答案
  • D.PV 即页面浏览量指标

答案:ABC。HR@K 看命中与否,NDCG@K 还惩罚排位靠后的命中,AUC 衡量模型把正样本排在负样本前面的能力,三者都是经典离线指标。PV 是流量统计口径,不能衡量模型对用户兴趣的刻画质量。

Q8. 离线评估效果好但线上失败,可能的原因有哪些?

多选题 · hard

  • A.离线数据存在样本选择偏差← 正确答案
  • B.在线环境存在反馈循环放大← 正确答案
  • C.离线评测假设数据独立同分布← 正确答案
  • D.用户始终只喜欢推荐的物品

答案:ABC。离线数据由旧策略产生,行为分布是被策略“过滤”过的,天然有选择偏差;线上推荐在影响用户的同时又被用户行为影响,形成反馈循环;离线评估通常假设样本独立同分布,而线上分布实时变化。D 显然不成立,用户偏好本来就是动态的。

Q9. 时间衰减权重 $e^{-\Delta t/\tau}$ 中,$\tau$ 越大意味着什么?

单选题 · easy

  • A.τ 越大,旧行为保留权重越多← 正确答案
  • B.τ 越大,旧行为权重衰减越快
  • C.τ 越小,模型使用序列长度越长
  • D.τ 与兴趣漂移应对没有关系

答案:A。$\tau$ 是遗忘速率的“旋钮”。$\tau$ 越大,指数衰减越平缓,同等时间差下旧行为权重更高,模型更依赖长期记忆;$\tau$ 越小则越追新。B 说反了,C 中序列长度由窗口决定而非 $\tau$,D 直接否认了时间衰减在漂移应对中的作用。

Q10. 关于 A/B 测试分流机制,正确的做法包括哪些?

多选题 · extreme

  • A.实验层与流量层正交避免相互污染← 正确答案
  • B.上线前用 AA 检验验证分流均匀← 正确答案
  • C.样本量按最小提升与方差预估← 正确答案
  • D.实验跑一小时后立刻看结果下线

答案:ABC。多个实验同时进行时,实验层与流量层正交可以避免不同实验相互干扰;AA 检验把两组都放到旧策略上,确认指标无显著差异,才能证明分流均匀;样本量需要结合预期提升幅度和指标方差算清楚,否则实验功效不足。D 是典型的样本量不足,一小时的结论没有统计显著性。