目录
2.3 Thompson sampling(汤普森采样)算法
2.4 UCB算法(Upper Confidence Bound)
1、推荐系统中的EE问题
Exploration and Exploitation(EE问题,探索与开发)是计算广告和推荐系统里常见的一个问题,为什么会有EE问题?简单来说,是为了平衡推荐系统的准确性和多样性。
EE问题中的Exploitation就是:对用户比较确定的兴趣,当然要利用开采迎合,好比说已经挣到的钱,当然要花;而exploration就是:光对着用户已知的兴趣使用,用户很快会腻,所以要不断探索用户新的兴趣才行,这就好比虽然有一点钱可以花了,但是还得继续搬砖挣钱,不然花完了就得喝西北风。
2:相关算法
2.1:Bandit算法简介
Bandit算法是解决EE问题的一种有效算法,我们先来了解一下Bandit算法的起源。
Bandit算法来源于历史悠久的赌博学,它要解决的问题是这样的:一个赌徒,要去摇老虎机,走进赌场一看,一排老虎机,外表一模一样,但是每个老虎机吐钱的概率可不一样,他不知道每个老虎机吐钱的概率分布是什么,那么每次该选择哪个老虎机可以做到最大化收益呢?这就是多臂赌博机问题(Multi-armed bandit problem, K-armed bandit problem, MAB)。
![]() |
怎么解决这个问题呢?最好的办法是去试一试,不是盲目地试,而是有策略地快速试一试,这些策略就是Bandit算法。
Bandit算法如何同推荐系统中的EE问题联系起来呢?假设我们已经经过一些试验,得到了当前每个老虎机的吐钱的概率,如果想要获得最大的收益,我们会一直摇哪个吐钱概率最高的老虎机,这就是Exploitation。但是,当前获得的信息并不是老虎机吐钱的真实概率,可能还有更好的老虎机吐钱概率更高,因此还需要进一步探索,这就是Exploration问题。
2.2:朴素Bandit算法
先随机试若干次,计算每个臂的平均收益,一直选均值最大那个臂。对应到推荐系统中就是每物料的ctr
2.3 Thompson sampling(汤普森采样)算法
- 假设每个臂是否产生收益,其背后有一个概率分布,产生收益的概率为 p。
- 我们不断地试验,去估计出一个置信度较高的 “概率 p 的概率分布” 就能近似解决这个问题了。
- 怎么能估计 “概率 p 的概率分布” 呢? 答案是假设概率 p 的概率分布符合 beta(wins, lose)分布,它有两个参数: wins, lose。
- 每个臂都维护一个 beta 分布的参数。每次试验后,选中一个臂,摇一下,有收益则该臂的 wins 增加 1,否则该臂的 lose 增加 1。
- 每次选择臂的方式是:用每个臂现有的 beta 分布产生一个随机数 b,选择所有臂产生的随机数中最大的那个臂去摇。
用一行pyhton代码实现
import numpy as np
import pymc
N = 100
i = 0
win = [0 ,1, 3, 6, 10, 100]
trials = [0, 2, 5, 30, 21, 205]
while i<100:
choice = np.argmax(pymc.rbeta(1 + wins, 1 + trials - wins))
wins[choice] += 1
trials[choice] += 1
i += 1
这个算法中重要点的理解:
- 对rbeta,也就是选臂的过程,其实本质就是选赢率最高的,也可以理解点击率最高的ctr=clickshowctr=clickshow
- 当新来一条物料,会优先进行explor,因为根据公式,新来物料ctr = 1
- 当然beta分布中的两个参数可以根据先验知识去设置,比如物料平均点击率3%, 那么我可以设置beta分布参数α=3,β=97,这样更贴近真实情况,可能更有效。这里的参数设置知识可以参照下面Beta分布相关知识。
2.4:UCB算法(Upper Confidence Bound)
- 初始化:先对每一个臂都试一遍
- 按照如下公式计算每个臂的分数,然后选择分数最大的臂作为选择:
- 观察选择结果,更新tt和TjtTjt。其中加号前面是这个臂到目前的收益均值,后面的叫做 bonus,本质上是均值的标准差,t 是目前的试验次数,Tj,t是这个臂被试次数
![]() |
这个算法中重要点的理解:
- 首先公式前面一项是收益均值,可以理解为前面算法说的点击率
- 核心是第二项,我们知道当x取值大于1时ln函数的作用是平滑,如果实验次数很多,那么后一项就会趋近很小,从而收敛到前一项收益均值,如果是一个新物料或者explore次数很少,那么后一项很大甚至大于1从而优先进行explore,支持探索到这个臂到达置信的次数。
- UCB就解决了前面汤普森采样人工先验设置参数以及探索到多少更置信的问题。
import numpy as np
T = 1000 # T轮试验
N = 10 # N个老虎机
true_rewards = np.random.uniform(low=0, high=1, size=N) # 每个老虎机真实的吐钱概率
estimated_rewards = np.zeros(N) # 每个老虎机吐钱的观测概率,初始都为0
chosen_count = np.zeros(N) # 每个老虎机当前已经探索的次数,初始都为0
total_reward = 0
# 计算delta
def calculate_delta(T, item):
if chosen_count[item] == 0:
return 1
else:
return np.sqrt(2 * np.log(T) / chosen_count[item])
# 计算每个老虎机的p+delta,同时做出选择
def UCB(t, N):
upper_bound_probs = [estimated_rewards[item] + calculate_delta(t, item) for item in range(N)]
item = np.argmax(upper_bound_probs)
reward = np.random.binomial(n=1, p=true_rewards[item])
return item, reward
for t in range(1, T): # 依次进行T次试验
# 选择一个老虎机,并得到是否吐钱的结果
item, reward = UCB(t, N)
total_reward += reward # 一共有多少客人接受了推荐
# 更新每个老虎机的吐钱概率
estimated_rewards[item] = ((t - 1) * estimated_rewards[item] + reward) / t
chosen_count[item] += 1
3: Beta分布知识
帖子:https://www.zhihu.com/question/30269898