Advertisement

【人工智能】Python与强化学习:从零实现多臂老虎机(Multi-Armed Bandit)问题

阅读量:

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!

强化学习是一种模仿生物行为的学习方法,在不确定环境中寻找最优策略。多臂老虎机(Multi-Armed Bandit, MAB)是强化学习的经典问题之一,模拟了在多个选择中如何平衡探索和利用,以获取最大的长期回报。本篇文章将详细讲解多臂老虎机问题的理论背景、数学模型,以及如何用Python实现常见的强化学习策略(如 ε-贪婪算法、UCB 和汤普森采样)。文章包含大量代码示例与中文注释,帮助读者深入理解强化学习的核心思想,并掌握在多臂老虎机问题中的应用。


目录

  1. 什么是多臂老虎机?

    • 背景与定义
    • 应用场景
  2. 强化学习与多臂老虎机的理论基础

    • 奖励函数
    • 探索与利用
  3. Python实现多臂老虎机模拟环境

  4. ε-贪婪算法

    • 理论分析
    • Python实现与实验
  5. 上置信界(UCB)算法

    • 理论分析
    • Python实现与实验
  6. 汤普森采样(Thompson Sampling)算法

    • 理论分析
    • Python实现与实验
  7. 策略比较与性能评估

  8. 总结与扩展


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)**之间的权衡:

  • 探索 :尝试未被充分选择的老虎机,以了解其奖励分布。
  • 利用 :选择当前已知最优的老虎机,以最大化即时奖励。

解决这一权衡需要设计策略,常见的策略包括:

  1. ε-贪婪算法 :在大多数情况下选择当前最优动作,但偶尔随机探索。
  2. 上置信界(UCB)算法 :使用奖励的置信区间来指导选择。
  3. 汤普森采样(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 和汤普森采样三个策略,展示了强化学习在决策问题中的核心思想。未来可以结合深度强化学习或复杂环境扩展本问题的研究。

全部评论 (0)

还没有任何评论哟~