📑 本页目录(点开跳转)
13 · 冷启动与探索利用
⏱ 20 分钟 | ⭐ 核心
🎯 一句话
冷启动 = 「没数据怎么推」;探索利用 = 「要不要冒险试试新东西」。 两者是同一枚硬币的两面:你不探索,就永远没数据。
❄️ 三种冷启动
- 难度:★★★☆☆ 解法相对成熟
- 难度:★★★★★ 最难,也最关键 ⭐
- 每天有海量新内容,处理不好整个内容生态就崩了
- 难度:★★★★☆ 靠冷启动期的运营和外部数据
① 用户冷启动:五步阶梯
按「拿到的信息量」递进,工业界通常几种叠加使用:
🔧 实战关键:新用户前 20 次刷的体验,直接决定次日留存。 很多公司有专门的新用户推荐链路,模型、策略、指标都和老用户不同。
② 物品冷启动:最难的那个 ⭐
为什么难 —— 死亡螺旋
新物品没有交互数据
↓
模型给它低分
↓
得不到曝光
↓
永远没有交互数据 ←──┘ 💀 无限循环
这个循环必须靠「外力」打破——这就是冷启动策略存在的原因。
解法一:内容特征(最根本)⭐
思路:新物品虽然没有行为,但有内容。
新视频
├─ 标题文本 → 文本 Embedding (BERT / 多语言模型)
├─ 封面图 → 图像 Embedding (CLIP / ViT)
├─ 视频内容 → 视频 Embedding
├─ 音频 → 音频 Embedding
└─ 元数据 → 类目、标签、作者、时长
↓ 全部拼起来
内容向量 → 在向量空间里找相似的老物品
↓
继承它们的用户群 / 统计特征作为先验
双塔模型的一个巨大好处:物品塔的输入可以完全不含 item_id,只用内容特征。 这样任何新物品一发布就有向量,可以立刻参与召回。
📌 这叫 ID-free / Content-based Tower,是解决物品冷启动最优雅的方案。 折中做法:
item_emb = ID_embedding + content_embedding,新物品 ID 部分为 0,靠内容部分工作。
解法二:强制曝光配额(Explore Pool)
def allocate_slots(candidates, n_slots=10, explore_ratio=0.1):
"""每 10 个位置留 1 个给冷启动物品"""
n_explore = max(1, int(n_slots * explore_ratio))
cold = [c for c in candidates if c.impressions < 1000]
warm = [c for c in candidates if c.impressions >= 1000]
result = warm[:n_slots - n_explore]
result += sorted(cold, key=lambda c: c.content_score)[:n_explore]
return result
分级流量池(工业界常用设计):
新物品发布
↓
【池 1】给 500 次曝光 → CTR 达标?──否──→ 淘汰
↓ 是
【池 2】给 5000 次曝光 → CTR 达标?──否──→ 淘汰
↓ 是
【池 3】给 5万次曝光 → 完播率达标?──否─→ 淘汰
↓ 是
进入正常推荐池(爆款诞生)
⚠️ 注意统计陷阱:500 次曝光的 CTR 波动巨大,不能直接用来判定。 ✅ 用置信区间下界或贝叶斯平滑后的估计(见第 7 节),否则会误杀好内容。
解法三:作者/店铺继承
新物品先继承作者的历史表现作为先验。 「这个作者过去 10 个视频平均完播率 60%」→ 新视频的初始预估也高一些。
解法四:跨域迁移
在其他场景已有数据的物品(如搜索里被搜过),迁移到推荐场景。
🎰 探索与利用(Explore & Exploit)
用老虎机讲清楚
你面前有 5 台老虎机,不知道哪台中奖率高。
有 1000 次机会,怎么赢最多钱?
策略 A:全部投同一台(纯利用 Exploit)
→ 万一选错了,白白亏 1000 次
策略 B:每台平均投 200 次(纯探索 Explore)
→ 知道了哪台好,但已经没机会了
策略 C:先试探,逐渐把钱压到表现好的那台 ✅
→ 这就是 E&E 要解决的问题
映射到推荐: - 利用(Exploit):推模型认为你最喜欢的 → 短期收益高 - 探索(Explore):推不确定的内容 → 短期可能亏,但换来信息
三个经典算法(从简单到实用)
① ε-greedy —— 最简单
import random
def epsilon_greedy(candidates, model_scores, epsilon=0.1):
if random.random() < epsilon:
return random.choice(candidates) # 10% 随机探索
return candidates[int(np.argmax(model_scores))] # 90% 选最优
✅ 一行就能实现 ❌ 探索是盲目的,不区分「已经很确定很差」和「还不确定」
② UCB —— 给不确定性加奖励
$$\text{UCB}_i = \underbrace{\bar{x}_i}_{\text{当前估计的收益}} + \underbrace{c\sqrt{\frac{2\ln N}{n_i}}}_{\text{不确定性奖励}}$$
💡 人话:「这个东西看起来一般,但我只试过 3 次,说不定其实很好——给它加点分让它再露个脸。」
def ucb_score(mean_reward, n_pulls, total_pulls, c=2.0):
if n_pulls == 0:
return float('inf') # 没试过的必须先试
return mean_reward + c * np.sqrt(2 * np.log(total_pulls) / n_pulls)
③ Thompson Sampling —— 工业界最爱 ⭐
思想:给每个物品维护一个「CTR 的概率分布」,每次从分布里采样,按采样值排序。
物品A:曝光 10000 次,点击 500 次
→ 分布很窄,几乎确定 CTR ≈ 5%
╱▔▔╲
────╱────╲──────
物品B:曝光 10 次,点击 1 次
→ 分布很宽,CTR 可能 1% 也可能 30%
╱▔▔▔▔▔▔▔▔╲
──╱──────────╲──
每次从各自分布里抽一个数 → B 有机会抽到高值 → 得到曝光机会
B 曝光多了,分布自然收窄 → 探索自动减少 ✅
import numpy as np
class ThompsonSampling:
"""Beta-Bernoulli Thompson Sampling —— 30 行的工业级 E&E"""
def __init__(self, n_items, prior_a=1.0, prior_b=1.0):
# Beta 分布的两个参数:alpha ≈ 点击数, beta ≈ 未点击数
self.a = np.full(n_items, prior_a)
self.b = np.full(n_items, prior_b)
def select(self, candidates, k=10):
"""从每个候选的 Beta 分布采样,取采样值最高的 k 个"""
samples = np.random.beta(self.a[candidates], self.b[candidates])
top = np.argsort(-samples)[:k]
return [candidates[i] for i in top]
def update(self, item, clicked):
if clicked: self.a[item] += 1
else: self.b[item] += 1
def set_prior_from_content(self, item, predicted_ctr, strength=20):
"""⭐ 用内容模型的预估当先验,冷启动更快"""
self.a[item] = predicted_ctr * strength
self.b[item] = (1 - predicted_ctr) * strength
为什么 Thompson Sampling 在工业界最受欢迎: - 探索量自适应(不确定就多探索,确定了自动少探索) - 天然支持并行/批量推荐(每个位置独立采样) - 实现简单,效果通常优于 UCB 和 ε-greedy - 容易接入先验(用内容模型的预估初始化)
🚀 更进一步:Contextual Bandit
上面的 bandit 对所有用户一视同仁。Contextual Bandit 考虑用户特征:
「这个视频对科技爱好者的 CTR 是多少?」而不是「这个视频的 CTR 是多少?」
代表算法:LinUCB、Neural Bandit。 本质是:用一个模型预测收益 + 用模型的不确定性做探索。
🕸️ 反馈循环:探索的深层价值
所以探索的价值不只是「找到新爆款」,更是: 1. 收集无偏训练数据(用于正确评估模型,见第 12 节) 2. 防止模型退化到局部最优 3. 维持内容生态健康(新作者有出头机会) 4. 打破用户的信息茧房
🔧 工业界的标配:留 1–5% 的流量做完全随机曝光。 这部分流量的短期指标一定是负的,但它产生的无偏数据集是整个系统的「校准基准」。 说服老板保留这部分流量,是算法负责人的重要工作。
🎚️ 探索强度怎么定
| 场景 | 探索比例 | 理由 |
|---|---|---|
| 新用户前 20 刷 | 高(20–30%) | 快速定位兴趣 |
| 成熟用户 | 低(5–10%) | 已经很了解,探索成本高 |
| 内容更新极快(新闻/短视频) | 高 | 物品生命周期短,必须持续探索 |
| 内容稳定(电影/图书) | 低 | 老物品的估计已经很准 |
| 高风险决策(贷款/医疗) | 极低或不探索 | 探索的代价是真实伤害 ⚠️ |
🔗 这一章连到哪里
| 去哪 | 为什么 |
|---|---|
| 强化学习 07 | ε-greedy / UCB / Thompson Sampling 的原理与后悔界:UCB 那个 √(2lnN/n) 是怎么推出来的 |
| 强化学习 01 | 多臂老虎机是 RL 的最小形态;「纯利用一定次优」这件事在这里被讲清楚 |
| 数学原理 02 | Thompson 的 Beta(a,b) 就是先验伪计数——用内容模型预估当先验,正是贝叶斯的 MAP 视角 |
✅ 检查点
- 三种冷启动分别是什么?哪个最难?
- 物品冷启动的「死亡螺旋」是什么?怎么打破?
- 双塔模型怎么帮助物品冷启动?(ID-free 塔是什么意思)
- ε-greedy、UCB、Thompson Sampling 的核心区别?
- Thompson Sampling 为什么在工业界最受欢迎?
- 为什么要留 1-5% 流量做随机曝光?(说出两个理由)
👀 答案
1. 用户冷启动、物品冷启动、系统冷启动。物品冷启动最难,因为新内容持续大量产生,且处理不好会伤害整个内容生态。 2. 没数据→模型低分→没曝光→还是没数据。必须靠外力打破:内容特征、强制曝光配额、分级流量池。 3. 物品塔的输入可以只用内容特征不含 item_id,这样新物品一发布就有向量,能立刻参与召回。 4. ε-greedy 固定概率盲目随机;UCB 给「试得少」的物品加确定性奖励;Thompson Sampling 给每个物品维护收益的概率分布,每次采样后排序,探索量自适应。 5. 探索量自适应(不确定就多探索,确定后自动减少)、天然支持批量推荐、实现简单、效果通常最好、容易接入内容模型作为先验。 6. ① 收集无偏训练/评估数据,用来正确评估模型(对抗曝光偏差);② 打破反馈循环,防止模型退化到局部最优、维持内容生态和用户兴趣的广度。🛑 可以停在这里
⚡ 走神救援
冷启动三种:用户(五步阶梯:兜底→画像→选兴趣→bandit→正常)、物品(最难,死亡螺旋,靠内容特征 + ID-free 双塔 + 分级流量池)、系统。E&E 三算法:ε-greedy(盲目)、UCB(给不确定性加奖励)、Thompson Sampling(采样,探索自适应,工业最爱)。留 1-5% 随机流量收集无偏数据 + 打破反馈循环。⭐ 死亡螺旋的闭环长这样:新物品没数据 → 模型不敢推 → 拿不到曝光 → 永远没数据。ID-free 双塔是最优雅的破法:物品塔只吃内容特征、不含 item_id,新物品一发布就有向量;折中写法是
item_emb = ID_emb + content_emb,新品 ID 部分为 0,先靠内容工作。⭐ 分级流量池(500 → 5000 → 5 万曝光,逐级看 CTR/完播率晋级或淘汰)是工业界的标配。⚠️ 但这里有个统计陷阱:500 次曝光算出的 CTR 波动极大,绝不能直接拿来判生死,要用置信区间下界或贝叶斯平滑后的估计,否则会误杀好内容。⭐ Thompson 的杀手锏是 先验可以从内容模型灌进去(a=预估CTR×strength, b=(1-预估CTR)×strength),冷启动和 E&E 在这里合成了一件事。⭐ 再往前一步是 Contextual Bandit(LinUCB / Neural Bandit):问的不再是「这个视频 CTR 多少」,而是「这个视频对科技爱好者的 CTR 多少」。⚠️ 探索强度要分场景:新用户前 20 刷可以 20–30%,成熟用户 5–10%,而贷款、医疗这类高风险决策几乎不该探索——那里探索的代价是真实伤害。
下一节 👉 14-生成式推荐-2026前沿.md
🔨 想把这一节变成肌肉记忆? 挑战项目B·信息流模拟器 会让你亲眼看到反馈循环怎么毁掉一个推荐系统,再用本节的 Thompson Sampling 把它救回来。