城市巷口有一家老王面馆,卤肉面是镇店招牌,天天卖断货。可老板老王最近很愁:店门口的「今日推荐」只有一块黑板,永远写卤肉面,固然稳赚,但顾客总有吃腻的一天;换成新研发的藤椒面,万一没人点,今晚的流水就亏了。更麻烦的是,藤椒面刚上桌时,谁也不知道它会不会变成下一个爆款。这个两难,就是推荐系统里的「探索与利用」问题:平台每天能给出的推荐位(流量)就那么多,是把位置给已知受欢迎的「老内容」吃干饭(利用),还是留一部分给「新内容」试错(探索)?解决这个问题的算法家族叫 Bandit(多臂老虎机):epsilon-greedy 像「每十桌留一桌随便点」,UCB 像给每道菜画一张「潜力上限」的记账本,Thompson 采样则像在脑内模拟一千位顾客的口味曲线。读完这篇文章,你会像老王一样,学会在「吃老本」和「押新品」之间找到长期收益最大的平衡点。
理解探索与利用,是推荐系统从「短期点击率」走向「长期生态收益」的分水岭。掌握 Bandit 三件套(epsilon-greedy、UCB、Thompson 采样),你就能在工业推荐落地中设计出既保老内容收益、又给新内容机会的流量策略,这是内容生态与广告增长方向算法工程师的核心技能。
可视化演示
动态演示推荐中的探索与利用的核心机制,通过总览/传输/转换/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
推荐中的探索与利用:探索与利 探索与利用问题的本质与挑战 Epsilon-Greedy贪 核心机制可视化 推荐中的探索与利用整体架构与关键组件
问题定义
老王面馆每晚只有二十桌客人,每桌最多推一道「今日推荐」。卤肉面天天卖爆,但老王心里清楚:卤肉面总有一天会让人吃腻,而菜单上新加的藤椒面,可能一文不值,也可能是下一个招牌。把推荐位永远给卤肉面,是稳赚不赔的短期选择;分出一部分推荐位给藤椒面,是在为明天下注。这就是「探索与利用」的两难。
推荐系统每天面对同样的局面:热门老内容就像卤肉面,点击率高、风险低;新发布的内容就像藤椒面,没有数据、前途未知。如果把推荐位全给老内容,短期指标好看,长期却会让内容生态僵化。科学家把这个困境抽象成一个经典模型——多臂老虎机。
多臂老虎机比喻一台有多个拉杆的老虎机,每个拉杆对应一个未知的中奖概率。你每拉一次杆,要么赢要么输,目标是有限次数内累计收益最大。推荐场景里,物品是拉杆,用户点击或下单就是中奖。于是问题变成:已知每个物品「试吃好评率」的估计值,如何分配推荐次数让总收益最大。
老王每天打烊后看流水,流水就是他这一天二十次推荐决策的总收益。这个公式提醒他:别只盯某一桌赚了多少,要看一整晚、一整年赚了多少。长期收益,才是 EE 问题真正的裁判。
- 累计收益 G_T从第 1 次到第 T 次推荐,把所有单次收益依次相加得到的总和。
- 单次收益 r_t第 t 次推荐得到的回报,用户点击或购买记 1,否则记 0。
- 累加范围下标的 1 到 T 表示从第一次决策一直加到第 T 次决策,T 越大越能看出策略的真实水平。
Epsilon贪心
老王的第一招很朴素:每天晚上,九成顾客照旧推荐好评榜单第一的菜,剩下一成顾客不做任何判断,随机从菜单里挑一道,哪怕是最没人气的新品。他管这叫「每十桌留一桌随便点」。
这就是 epsilon-greedy(ε-贪心)的核心思想:以概率 ε 随机探索,以概率 1−ε 选择当前估计最优。ε 就是那个「乱点」的比例,通常取 0.1 到 0.2。它最大的优点是简单:只需要维护每个物品的平均好评率,不需要置信区间或贝叶斯计算。
缺点是探索是「盲目」的——随机选菜时完全不管哪道菜更有潜力,把精力平均撒在所有菜上。如果某道菜明显难吃,它依然会时不时被随机翻牌,白白浪费宝贵的桌位。
老王很快发现,一成随机虽然偶尔带来惊喜,但很多次随机都点到确定没人爱的菜,浪费了珍贵桌位。他决定换一个更聪明的试菜办法——把精力花在「最值得怀疑」的菜上。
- 当前最优者先算出好评率最高的那道菜,作为「利用」的候选。
- 探索概率 ε以概率 ε 放弃最优者,进入随机环节。
- 均匀随机挑选探索时每道菜被选中的概率相等,都是 1/N。
UCB算法
老王改进策略:不再盲目随机。他在小本本上记下每道菜被尝试的次数。卤肉面试了 100 次,好评率 80%;藤椒面只试了 2 次,好评率 50%。凭均值,藤椒面远不如卤肉面。可老王想:藤椒面才试 2 次,这个 50% 太不可靠了——它也许其实有 90% 的潜力呢?
UCB(Upper Confidence Bound,上置信界)算法把这个直觉量化成公式:每道菜的得分 = 平均好评率 + 一个「补偿项」。补偿项随尝试次数变少而增大。也就是说,越是被冷落的菜,越会得到额外加分,直到它被充分尝试、真相大白。
补偿项里,T 是到目前为止的总推荐次数,N 是该菜被尝试的次数。当 N 很小时,补偿项很大,即使均值不高也能冲上推荐位;随着 N 增大,补偿项变小,得分逐渐回归真实均值。于是系统自动把探索流量导向「信息量最大」的菜。
老王的小本本法则很奏效:卤肉面依然常驻推荐位,但藤椒面每隔几桌就能上一次,逐渐攒够数据。UCB 的优雅之处在于,探索不再是撒胡椒面,而是精准地优先试探「最值得怀疑」的菜。
- 平均收益该菜累计好评数除以上次数,代表已经知道的实力。
- 不确定性补偿尝试次数 N_a 越小,补偿项越大,给「陌生菜」加分。
- 总分均值加补偿,作为本轮推荐位的打分依据。
汤普森采样
再后来,老王学到更高级的一招:他不再只记一个平均分,而是在脑子里为每道菜画一条「口味猜测曲线」。卤肉面的曲线又高又窄——集中在 80% 附近;藤椒面的曲线又矮又宽——从 30% 到 90% 都有可能。
这就是贝叶斯思想:用 Beta 分布描述对每道菜好评率的信念。每得到一次好评,曲线往右挪一点;每得到一次差评,曲线往左挪一点。曲线越窄,代表越有把握。
每次做推荐前,老王从每条曲线里「抽签」:卤肉面大概率抽到 0.8 左右,藤椒面有时抽到 0.9、有时抽到 0.3。谁抽到的值最大,谁就上推荐位。宽曲线意味着它经常能抽到很高的值,于是新菜得到不少机会;一旦数据变多、曲线变窄,它就必须凭真实实力说话。
老王发现,这种「脑内模拟顾客口味」的方法,在长期收益上比固定比例的盲目探索更稳,也比 UCB 更抗噪声。它不再需要一个显式的探索率,因为不确定性已经天然融入采样过程。
- Beta 分布参数 α 是好评数加一,β 是差评数加一,两者共同决定曲线的形状。
- 随机采样为每道菜从自己的分布中抽一个代表口味值。
- 选出最高比较所有采样值,取最大者上推荐位。
Bandit框架
一个季度结束,老王想复盘:如果每次都推「隐藏的最佳菜」,理想流水是多少?拿理想流水减去实际流水,就是「后悔度」。后悔度越低,说明他这一季度的决策越接近神仙视角。
Bandit 框架将所有 EE 策略统一进这一套评价体系:策略的目标不是单次点击率,而是把累计后悔度最小化。epsilon-greedy、UCB、汤普森采样都是框架内的具体策略,谁后悔得少,谁就是更好的老板。
后悔度的计算很直观:每个时刻都有唯一的最佳菜 μ\,理想收益是 T 乘以 μ\;而实际第 t 次推荐如果推了菜 a_t,它的真实好评率是 μ_{a_t},两者之差累加起来就是累计后悔。注意这里用的是「真实好评率」,而不是算法估计值——后悔度衡量的是策略本身离全知有多远。
老王看着后悔度曲线若有所思:盲目随机会让后悔度线性飙升,而好的策略能让它只按对数速度增长。评判一个 EE 策略好不好,不看单次运气,而看它长期离「全知老板」有多远。
- 理想收益上限每个时刻都推真正最优的菜,T 次累计的理论最大值。
- 实际收益每次实际推荐的菜的真实好评率之和,反映策略的真实水平。
- 后悔差值两者相减,得到策略离「全知老板」的距离。
冷启动结合
藤椒面刚上架那天是最棘手的:一道菜没有任何试吃记录,UCB 的补偿分无从算起,Thompson 的曲线还是平的,平均分更是为零。老王干脆定了个死规矩:任何新菜上架头几天,必须占满一定比例的推荐位,哪怕它大概率难吃。
这在工业界叫「冷启动结合」。新内容没有交互数据,无法参与纯数据驱动的打分。常见做法是分层探索:全局按一定比例把流量划给新内容池,池内再均匀或按简单规则分配;老内容池里则用 UCB 或汤普森采样精细运营。
数学上常写成加权混合:最终展示概率等于「带权 bandit 得分」加「新奇补偿」。λ 是探索权重,新内容上架越久、数据越多,λ 越小,策略逐渐从「无脑给曝光」过渡到「凭实力竞争」。这样既保证新菜有最低曝光,又不至于无限烧钱。
老王把「新菜必占推荐位」写成店里铁律,同时规定:上了三天还是没人点的菜自动下架。既给了新人机会,又防止了机会被浪费。冷启动与 EE 的结合,就是「有节奏地给机会,再按实力排座次」。
- 组合概率最终展示概率由 bandit 得分和新奇补偿加权合成。
- 探索权重 λλ 越大越偏向给新内容曝光,随数据积累逐渐调小。
- 新奇补偿数据越少权重越高,保证新菜有最低曝光下限。
系统落地
光有算法还不够。老王学乖了:新策略先只在两张桌子上实验,收集顾客反馈,和常规策略对比流水,效果好再全店铺开,效果差就立刻回滚。这套流程,就是上线前的灰度验证。
工业界落地 EE 策略,通常分三步:流量切分、效果评估、迭代调参。先把少量真实流量分给新策略(比如 5%),跑一两周,计算提升率;确认正向收益后逐步放大流量,并持续观察点击率之外的长期指标,如用户留存与内容生态健康度。
评估离不开基线对比。提升率公式把新策略的收益和老策略做相对比较,避免绝对指标受季节、大盘波动干扰。参数也要跟着调:ε 从 0.1 起步,UCB 的探索力度、冷启动的 λ 大小,都要看实验数据说话,而不是拍脑袋定死。
老王把「先在两张桌上试水」写进店规,再也没有因为头脑发热一次性全店换菜单。推荐系统的 EE 落地同理:小步快跑、数据说话,让探索服务于长期收益,而不是为了探索而探索。
- 基线收益老策略在相同流量下的单用户收益。
- 新策略收益EE 策略在相同流量下的单用户收益。
- 相对提升率两者差值除以基线,得到可跨时段、跨场景比较的比率。
AI 应用场景
短视频信息流的新内容冷启动
阶段:召回与排序阶段的候选生成
解决的问题:新发布视频没有播放数据,很难进入推荐池,热门视频霸屏导致创作者流失。传统做法是等新内容自然积累数据,效率极低;用分层 EE 给新内容固定探索流量,并随数据积累逐步过渡到 UCB 精细打分,相当于给每道新菜一张「潜力上限」的记账本。
具体案例:某信息流 App 将 8% 流量划入新内容池,新视频在池内按 UCB 竞争曝光位。上线三个月后,新内容人均消费时长提升 12%,创作者活跃度提升 20%,「老内容吃干饭」的局面明显改善。
广告素材流量分配
阶段:广告投放策略层
解决的问题:广告主持续上新素材,老素材吃光预算,新素材没有曝光就难以验证效果。传统 A/B 测试只能等分流量、浪费机会;用 epsilon-greedy 以 15% 比例随机上新素材,配合汤普森采样对不确定素材加权,像老王「每十桌留一桌随便点」。
具体案例:某信息流广告平台用多臂老虎机管理 5000 个素材创意,素材点击率提升 8%,上新效率翻倍,广告主的预算分配从「凭经验」变成「凭数据」。
电商新品打爆
阶段:商品冷启动与流量放大
解决的问题:新品没有销量与评价,在搜索和推荐排名里天然吃亏。传统做法是付费买量硬推,成本高且效果不可控;用汤普森采样在推荐流中给新品「试吃机会」,快速估计爆款概率,好菜多上桌、差菜早下架。
具体案例:某电商平台的「新品实验室」把新品曝光按 Beta 分布采样分配,比纯随机曝光的新品转化率提升 15%,还提前一周发现两个潜在爆款。
Python 演示
import mathimport random class Restaurant: """模拟一道菜(一个拉杆)""" def __init__(self, true_rate): self.true_rate = true_rate # 真实好评率,对算法隐藏 self.n = 0 # 被推荐次数 self.good = 0 # 获得好评次数 self.alpha = 1 # Beta分布参数 self.beta = 1 def mean(self): return self.good / self.n if self.n else 0.0 def reward(self): return 1 if random.random() < self.true_rate else 0 def play(dishes, idx): d = dishes[idx] win = d.reward() d.n += 1 d.good += win d.alpha += win d.beta += 1 - win return win def run_epsilon_greedy(dishes, pulls=2000, eps=0.1): total = 0 for _ in range(pulls): if random.random() < eps: idx = random.randrange(len(dishes)) else: idx = max(range(len(dishes)), key=lambda i: dishes[i].mean()) total += play(dishes, idx) return total def run_ucb(dishes, pulls=2000): total = 0 for t in range(pulls): scores = [] for d in dishes: if d.n == 0: scores.append(float("inf")) else: scores.append(d.mean() + math.sqrt(2 * math.log(t + 1) / d.n)) idx = scores.index(max(scores)) total += play(dishes, idx) return total def run_thompson(dishes, pulls=2000): total = 0 for _ in range(pulls): scores = [random.betavariate(d.alpha, d.beta) for d in dishes] idx = scores.index(max(scores)) total += play(dishes, idx) return total def build_dishes(): return [Restaurant(0.30), Restaurant(0.55), Restaurant(0.42)] if __name__ == "__main__": print("epsilon-greedy:", run_epsilon_greedy(build_dishes())) print("UCB :", run_ucb(build_dishes())) print("Thompson :", run_thompson(build_dishes()))
python 运行即可看到胜负。idx = random.randrange(len(dishes))以 ε 概率随机选菜,这就是「每十桌留一桌随便点」。idx = max(range(len(dishes)), key=lambda i: dishes[i].mean())其余时候选当前平均好评率最高的菜,对应「利用」。if d.n == 0: scores.append(float("inf"))没试过的菜优先探索,避免 UCB 除零。scores.append(d.mean() + math.sqrt(2 * math.log(t + 1) / d.n))UCB 核心:均值加不确定性补偿分。scores = [random.betavariate(d.alpha, d.beta) for d in dishes]从每道菜的 Beta 曲线抽签,实现汤普森采样。d.alpha += win; d.beta += 1 - win用真实反馈更新贝叶斯信念,曲线越抽越准。
常见误区
误区我只要每天随机给一部分用户推新内容,就算在探索了。探索不需要动脑子,随机就是最公平的。
正解随机探索只是 epsilon-greedy 的做法,它是「盲目的」:把试错机会平均分给所有物品,经常浪费在注定没人爱的菜上。UCB 和汤普森采样会把探索机会优先给「不确定性最大」的物品——同样的流量,前者像撒胡椒面,后者像精准探矿。
为何常见:epsilon-greedy 是最先被科普的算法,很多人以为探索只有「随机」一种形态,忽略了信息量的差别。
误区探索比例设得越高,新内容机会越多,长期肯定赚。干脆把 epsilon 设成 0.5,一半流量都给新菜。
正解探索是拿短期收益换长期信息,比例过大会导致大量推荐位被无效尝试占据,用户频繁看到烂内容还会流失。工业界通常从 0.05 到 0.2 起步,且常用衰减策略:前期多探索、后期少探索。
为何常见:新手容易只盯着「探索覆盖面」,忽略了每张桌子都有机会成本——探索的机会也是稀缺资源。
误区探索与利用只在冷启动阶段给新内容加曝光,召回做完就没它的事了。
正解EE 适用于任何「资源有限、收益未知」的分配问题:广告预算分配、素材优选、动态定价、甚至 A/B 测试的流量分配都能用 Bandit 框架建模。老王学会了 UCB,不只用来试新菜,还能决定哪道菜配给大份。
为何常见:冷启动是 EE 最直观的应用场景,容易让人误以为它的边界止步于此。
误区新策略上线后 CTR 涨了 3 个点,说明探索很成功,赶紧全量铺开。
正解CTR 是平均指标,EE 优化的是长期累计收益。把推荐位全给老内容 CTR 往往更高,但内容生态会僵化。真正要看的是累计收益、留存、生态健康度——UB 类策略甚至会有意「牺牲」部分短期点击率去换取长期信息。
为何常见:平均点击率最简单粗暴、人人会看,但它看不见长期的机会成本。
误区新内容没有数据,那就在首页疯狂推它,推的人多了自然就有数据了。
正解无差别狂推会严重破坏用户体验。正确做法是分层探索:给新内容一个受控的探索流量池,池内再按均匀随机或汤普森采样竞争,同时设定展示上限,表现差就降权,λ 权重也随时间衰减。
为何常见:「给机会」被理解成「给流量核弹」,忽略了机会成本与体验损失之间的平衡。
面试题
Q1. 老王面馆每天只能推一道今日推荐,他应该怎么决策才最合理?
- A.永远推荐卖得最好的卤肉面
- B.完全不看数据随机推荐一道菜
- C.大部分推荐好评菜偶尔试新菜← 正确答案
- D.只推荐还没有人点过的新菜品
答案:C。C 兼顾了「利用」和「探索」:推荐好评菜保证短期收益,偶尔试新菜积累长期信息。A 会错过潜在爆款,B 浪费已有好评数据,D 则完全放弃已知收益。这四种做法对应了 EE 光谱上的不同极端位置。
Q2. epsilon-greedy 算法中的 ε 表示什么?
- A.推荐结果排序时加的分数
- B.用户点击某件商品的概率
- C.随机探索一道新菜的概率← 正确答案
- D.老菜品口碑打分的权重
答案:C。ε 是探索率,表示以多大概率放弃当前最优、改为随机尝试。它控制的是「探索」和「利用」的分流比例,与排序分数、点击概率、口碑权重无关,所以选 C。
Q3. UCB 打分公式里 sqrt(2ln T/N) 这一项起什么作用?
- A.给尝试次数少的菜额外加分← 正确答案
- B.给尝试次数少的菜额外减分
- C.给尝试次数多的菜额外加分
- D.让点击率高的菜逐渐衰减
答案:A。N 越小,补偿项越大,所以它是在给「试得少的菜」加分,鼓励系统优先验证不确定性大的物品。N 增大后补偿项变小,得分回归真实均值,因此 B、C、D 都与公式逻辑相反。
Q4. 汤普森采样用哪个概率分布刻画对好评率的信念?
- A.正态分布
- B.指数分布
- C.泊松分布
- D.Beta分布← 正确答案
答案:D。汤普森采样用 Beta(α, β) 描述对每个物品成功率的信念,α 与 β 随好评/差评更新。Beta 分布天然定义在 0 到 1 之间,适合刻画概率,而正态可越界、指数和泊松适用于时间或计数场景。
Q5. 下列哪种做法最符合「探索」的含义?
- A.把点击率最高的内容顶到首位
- B.给新内容留出固定比例的曝光← 正确答案
- C.完全按用户历史偏好做推荐
- D.把低点击率内容从池中删除
答案:B。探索的本质是「试错」,给新内容固定曝光就是在收集未知信息。A 和 C 都是在利用已有数据,D 直接消灭了未来的可能性。注意探索不等于盲目,固定比例只是最简单的形态。
Q6. 后悔度(Regret)衡量的是什么?
- A.用户不满意关掉页面的次数
- B.算法实际收益与最优策略的差距← 正确答案
- C.推荐系统接口响应的延迟时间
- D.新内容被展示出来的频率
答案:B。Regret 用「理想最优收益 - 实际收益」的累计差来衡量策略水平,越大说明决策越差。它跟用户情绪、系统延迟、展示频率都不直接相关,是 Bandit 框架里评价策略的标尺。
Q7. 新上架的商品没有任何点击数据,最适合先怎么做?
- A.直接下架避免浪费推荐位
- B.完全参照老商品的历史数据
- C.分给它一部分探索曝光试水← 正确答案
- D.只投放到流量最少的时段
答案:C。冷启动的核心是先给探索机会、再凭实力竞争。完全没有数据时无法判断好坏,下架、照搬老品或藏进低流量时段都会让新品永无翻身之日,只有受控的探索曝光能快速攒出真实反馈。
Q8. UCB 在探索早期为什么倾向选择尝试次数为 0 的物品?
- A.因为零点击的物品算分一定会最高
- B.因为不确定性补偿项会变得无穷大← 正确答案
- C.因为该物品的均值和方差都足够大
- D.因为该物品被系统赋予了绝对偏袒
答案:B。UCB 的补偿项分母是 N,N=0 时分母为零,补偿趋于无穷。工程实现中通常直接对 N=0 的物品赋予最高优先级,强制先试一轮。这不代表它分数一定最高,也不代表系统偏袒,只是公式推出来的必然结果。
Q9. 以下哪些属于常见的 EE 策略?
- A.Epsilon 贪心算法← 正确答案
- B.上置信界 UCB 算法← 正确答案
- C.汤普森采样算法← 正确答案
- D.协同过滤推荐算法
答案:ABC。A、B、C 是三大经典 Bandit 策略:贪心靠概率分流、UCB 靠补偿项、汤普森靠贝叶斯采样。协同过滤是利用用户历史行为的相似度做推荐,属于「纯利用」范式,不含显式的探索机制,因此不选。
Q10. 关于 epsilon-greedy 与汤普森采样的对比,下列说法正确的有?
- A.前者的随机探索无视物品间的信息差异← 正确答案
- B.后者会根据不确定性大小调整探索概率← 正确答案
- C.前者需要记录尝试次数来估计均值和最优← 正确答案
- D.后者完全不需要维护任何统计量
答案:ABC。epsilon-greedy 的随机部分把所有物品一视同仁,确实无视信息差异,但它仍需记录尝试次数与累计收益才能找到当前最优,所以 A、C 正确。汤普森采样通过 Beta 分布天然体现不确定性,探索概率由分布宽度自动决定,B 正确;但它要维护 α 和 β 统计量,D 错误。