【人工智能】Python与强化学习:从零实现多臂老虎机(Multi-Armed Bandit)问题
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!
强化学习是一种模仿生物行为的学习方法,在不确定环境中寻找最优策略。多臂老虎机(Multi-Armed Bandit, MAB)是强化学习的经典问题之一,模拟了在多个选择中如何平衡探索和利用,以获取最大的长期回报。本篇文章将详细讲解多臂老虎机问题的理论背景、数学模型,以及如何用Python实现常见的强化学习策略(如 ε-贪婪算法、UCB 和汤普森采样)。文章包含大量代码示例与中文注释,帮助读者深入理解强化学习的核心思想,并掌握在多臂老虎机问题中的应用。
目录
-
什么是多臂老虎机?
- 背景与定义
- 应用场景
-
强化学习与多臂老虎机的理论基础
- 奖励函数
- 探索与利用
-
Python实现多臂老虎机模拟环境
-
ε-贪婪算法
- 理论分析
- Python实现与实验
-
上置信界(UCB)算法
- 理论分析
- Python实现与实验
-
汤普森采样(Thompson Sampling)算法
- 理论分析
- Python实现与实验
-
策略比较与性能评估
-
总结与扩展
1. 什么是多臂老虎机?
1.1 背景与定义
多臂老虎机问题是一种决策优化问题,源于赌场中的老虎机场景:
假设有 ( k ) 台老虎机,每台老虎机的奖励分布未知。玩家的目标是在有限的尝试次数内选择拉动哪台老虎机的手柄,以最大化累积奖励。
数学上,多臂老虎机问题可以描述为:
- ( k ) 个老虎机对应 ( k ) 个概率分布 ( P_1, P_2, \ldots, P_k )。
- 每次选择老虎机 ( i ) 会产生一个奖励 ( r \sim P_i )。
- 玩家希望找到一个策略 ( \pi ),使得累计奖励最大化。
1.2 应用场景
多臂老虎机问题的应用场景包括:
- 广告推荐 :选择显示哪种广告,以最大化点击率。
- 医疗试验 :选择最佳治疗方法以提高疗效。
- Web实验 :优化网站布局以提升用户体验。
2. 强化学习与多臂老虎机的理论基础
2.1 奖励函数
在多臂老虎机问题中,奖励函数定义为:
R = \sum_{t=1}^T r_t
其中:
- ( r_t ) 是在第 ( t ) 次尝试中的奖励。
- ( T ) 是尝试的总次数。
2.2 探索与利用
多臂老虎机问题的核心挑战是**探索(Exploration)与 利用(Exploitation)**之间的权衡:
- 探索 :尝试未被充分选择的老虎机,以了解其奖励分布。
- 利用 :选择当前已知最优的老虎机,以最大化即时奖励。
解决这一权衡需要设计策略,常见的策略包括:
- ε-贪婪算法 :在大多数情况下选择当前最优动作,但偶尔随机探索。
- 上置信界(UCB)算法 :使用奖励的置信区间来指导选择。
- 汤普森采样(Thompson Sampling) :基于贝叶斯更新概率分布进行采样。
3. Python实现多臂老虎机模拟环境
首先,我们实现一个多臂老虎机的模拟环境,用于生成奖励。
import numpy as np
class MultiArmedBandit:
"""
多臂老虎机模拟环境
"""
def __init__(self, arms):
"""
初始化
:param arms: 每个老虎机的中奖概率列表
"""
self.arms = arms
self.k = len(arms)
def pull(self, arm):
"""
拉动指定老虎机的手柄
:param arm: 选择的老虎机编号(0 <= arm < k)
:return: 奖励(0 或 1)
"""
if arm < 0 or arm >= self.k:
raise ValueError("无效的老虎机编号")
return 1 if np.random.rand() < self.arms[arm] else 0
测试老虎机环境
# 定义每个老虎机的中奖概率
arm_probabilities = [0.1, 0.5, 0.8]
# 创建老虎机环境
env = MultiArmedBandit(arm_probabilities)
# 测试拉动手柄
for i in range(len(arm_probabilities)):
reward = env.pull(i)
print(f"拉动第{i}个老虎机,奖励: {reward}")
4. ε-贪婪算法
4.1 理论分析
ε-贪婪算法 在每次选择时:
- 以 ( 1 - \epsilon ) 的概率选择当前平均奖励最高的老虎机(利用)。
- 以 ( \epsilon ) 的概率随机选择一个老虎机(探索)。
4.2 Python实现
class EpsilonGreedy:
"""
ε-贪婪算法实现
"""
def __init__(self, k, epsilon=0.1):
"""
初始化
:param k: 老虎机数量
:param epsilon: 探索概率
"""
self.k = k
self.epsilon = epsilon
self.counts = np.zeros(k) # 每个老虎机的选择次数
self.values = np.zeros(k) # 每个老虎机的平均奖励
def select_arm(self):
"""
选择一个老虎机
:return: 选择的老虎机编号
"""
if np.random.rand() < self.epsilon:
return np.random.randint(self.k) # 探索
return np.argmax(self.values) # 利用
def update(self, arm, reward):
"""
更新指定老虎机的奖励信息
:param arm: 老虎机编号
:param reward: 奖励值
"""
self.counts[arm] += 1
n = self.counts[arm]
self.values[arm] += (reward - self.values[arm]) / n
4.3 实验
# 参数设置
episodes = 1000
env = MultiArmedBandit([0.2, 0.5, 0.75])
agent = EpsilonGreedy(k=3, epsilon=0.1)
# 训练
rewards = []
for _ in range(episodes):
arm = agent.select_arm()
reward = env.pull(arm)
agent.update(arm, reward)
rewards.append(reward)
print(f"累计奖励: {sum(rewards)}")
5. 上置信界(UCB)算法
5.1 理论分析
UCB 算法在选择时计算每个老虎机的置信上界:
\text{UCB}_i = \hat{\mu}_i + \sqrt{\frac{2 \ln t}{n_i}}
其中:
- ( \hat{\mu}_i ) 是第 ( i ) 个老虎机的平均奖励。
- ( t ) 是总选择次数。
- ( n_i ) 是第 ( i ) 个老虎机被选择的次数。
5.2 Python实现
class UCB:
"""
上置信界算法实现
"""
def __init__(self, k):
self.k = k
self.counts = np.zeros(k)
self.values = np.zeros(k)
def select_arm(self, t):
ucb_values = self.values + np.sqrt(2 * np.log(t + 1) / (self.counts + 1e-5))
return np.argmax(ucb_values)
def update(self, arm, reward):
self.counts[arm] += 1
n = self.counts[arm]
self.values[arm] += (reward - self.values[arm]) / n
5.3 实验
agent = UCB(k=3)
rewards = []
for t in range(episodes):
arm = agent.select_arm(t)
reward = env.pull(arm)
agent.update(arm, reward)
rewards.append(reward)
print(f"UCB累计奖励: {sum(rewards)}")
6. 汤普森采样(Thompson Sampling)算法
6.1 理论分析
汤普森采样使用贝叶斯思想更新奖励分布,根据采样值选择老虎机。
6.2 Python实现
class ThompsonSampling:
def __init__(self, k):
self.k = k
self.alpha = np.ones(k)
# 胜利次数
self.beta = np.ones(k) # 失败次数
def select_arm(self):
sampled_theta = np.random.beta(self.alpha, self.beta)
return np.argmax(sampled_theta)
def update(self, arm, reward):
if reward == 1:
self.alpha[arm] += 1
else:
self.beta[arm] += 1
6.3 实验
agent = ThompsonSampling(k=3)
rewards = []
for _ in range(episodes):
arm = agent.select_arm()
reward = env.pull(arm)
agent.update(arm, reward)
rewards.append(reward)
print(f"汤普森采样累计奖励: {sum(rewards)}")
7. 策略比较与性能评估
7.1 比较不同策略
绘制累计奖励曲线。
import matplotlib.pyplot as plt
plt.plot(rewards_epsilon, label="Epsilon-Greedy")
plt.plot(rewards_ucb, label="UCB")
plt.plot(rewards_ts, label="Thompson Sampling")
plt.legend()
plt.show()
8. 总结与扩展
本文从理论和实现两个层面详细讲解了多臂老虎机问题,并通过 ε-贪婪算法、UCB 和汤普森采样三个策略,展示了强化学习在决策问题中的核心思想。未来可以结合深度强化学习或复杂环境扩展本问题的研究。
