当前位置: 首页 > news >正文

用Python和NumPy手把手实现你的第一个多臂老虎机(附完整代码和可视化)

用Python和NumPy手把手实现你的第一个多臂老虎机(附完整代码和可视化)

想象一下,你站在一排老虎机前,每台机器的中奖概率都不同,但你不知道哪台最慷慨。如何用有限的硬币获得最大回报?这就是经典的多臂老虎机问题——强化学习中最直观的入门案例。今天我们不谈复杂公式,直接带你用Python从零搭建可交互的实验环境,通过代码理解智能体如何平衡"探索新机会"与"利用已知最优解"这一核心矛盾。

1. 环境搭建:模拟老虎机

我们先创建一个能模拟多台老虎机的环境。每台机器(称为"臂")有独立的获胜概率,拉动臂时会返回1(获胜)或0(失败):

import numpy as np class BanditEnv: def __init__(self, arms=10): # 随机生成每台机器的真实获胜概率 self.true_probs = np.random.uniform(low=0.1, high=0.9, size=arms) def pull(self, arm): # 返回1表示获胜,0表示失败 return int(np.random.random() < self.true_probs[arm])

关键参数说明

  • arms:老虎机数量(默认为10台)
  • true_probs:每台机器的真实获胜概率(对智能体不可见)
  • pull():模拟拉动老虎机臂的结果

提示:环境初始化后,true_probs应保持不变,这样才能评估智能体的学习效果。

2. 智能体设计:ε-greedy策略

智能体需要解决探索-利用困境(Exploration-Exploitation Tradeoff)——是该尝试不确定收益的新机器,还是坚持当前表现最好的机器?我们实现最经典的ε-greedy策略:

class EpsilonGreedyAgent: def __init__(self, epsilon=0.1, arms=10): self.epsilon = epsilon # 探索概率 self.estimates = np.zeros(arms) # 各臂的奖励估计 self.action_counts = np.zeros(arms) # 各臂的尝试次数 def choose_action(self): if np.random.random() < self.epsilon: # 探索:随机选择 return np.random.randint(len(self.estimates)) else: # 利用:选择当前估计最优的臂 return np.argmax(self.estimates) def update_estimates(self, arm, reward): # 增量式更新估计值 self.action_counts[arm] += 1 self.estimates[arm] += (reward - self.estimates[arm]) / self.action_counts[arm]

策略对比实验

策略类型ε值特点适用场景
纯贪婪(Pure Greedy)0只选择当前最优,可能陷入局部最优环境稳定且初始估计准确
完全随机(Random)1完全探索,无法积累经验仅用于基准测试
ε-greedy0.1平衡探索与利用,最常用大多数动态环境
衰减ε-greedy可变随时间减小ε,后期侧重利用非平稳环境

3. 完整训练流程

现在将环境和智能体连接起来,进行1000次交互并记录关键指标:

def run_experiment(arms=10, steps=1000, epsilon=0.1): env = BanditEnv(arms=arms) agent = EpsilonGreedyAgent(epsilon=epsilon, arms=arms) rewards = np.zeros(steps) optimal_rates = np.zeros(steps) optimal_arm = np.argmax(env.true_probs) for step in range(steps): arm = agent.choose_action() reward = env.pull(arm) agent.update_estimates(arm, reward) # 记录数据 rewards[step] = reward optimal_rates[step] = (arm == optimal_arm) return { 'cumulative_rewards': np.cumsum(rewards), 'optimal_rates': optimal_rates, 'true_probs': env.true_probs, 'estimates': agent.estimates }

指标说明

  • cumulative_rewards:累计奖励,反映策略的长期表现
  • optimal_rates:每一步是否选择了最优臂,衡量学习速度
  • true_probsvsestimates:对比真实值与学习值,评估估计准确性

4. 可视化与结果分析

用Matplotlib绘制学习曲线,直观展示智能体的表现:

import matplotlib.pyplot as plt def plot_results(results): fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4)) # 累计奖励曲线 ax1.plot(results['cumulative_rewards'], label='ε=0.1') ax1.set_xlabel('Steps') ax1.set_ylabel('Cumulative Reward') ax1.legend() # 最优臂选择比例 ax2.plot(np.cumsum(results['optimal_rates']) / np.arange(1, len(results['optimal_rates'])+1)) ax2.set_xlabel('Steps') ax2.set_ylabel('Optimal Arm Rate') plt.tight_layout() plt.show() # 运行实验并绘图 results = run_experiment() plot_results(results)

典型输出分析

  1. 累计奖励曲线:初期增长较慢(探索阶段),后期斜率增大(找到最优臂)
  2. 最优臂选择率:从初始的10%(随机)逐渐提升到80%以上
  3. 估计值对比:运行后打印results['true_probs']results['estimates'],可见智能体对高概率臂的估计更准确

5. 高级技巧与优化

基础实现之后,我们可以进行多维度优化:

5.1 参数调优实验

测试不同ε值对性能的影响:

epsilons = [0, 0.01, 0.1, 0.5] plt.figure(figsize=(10, 6)) for eps in epsilons: results = run_experiment(epsilon=eps) plt.plot(results['cumulative_rewards'], label=f'ε={eps}') plt.xlabel('Steps') plt.ylabel('Cumulative Reward') plt.legend() plt.show()

5.2 非平稳环境处理

真实场景中,老虎机的概率可能随时间变化。修改环境类:

class NonStationaryBandit(BanditEnv): def __init__(self, arms=10): super().__init__(arms=arms) self.step_count = 0 def pull(self, arm): # 每100步随机改变一个臂的概率 if self.step_count % 100 == 0: changed_arm = np.random.randint(len(self.true_probs)) self.true_probs[changed_arm] = np.random.uniform(0.1, 0.9) self.step_count += 1 return super().pull(arm)

5.3 基于置信度的策略

比ε-greedy更聪明的UCB(Upper Confidence Bound)策略实现:

class UCBAgent: def __init__(self, arms=10): self.estimates = np.zeros(arms) self.action_counts = np.zeros(arms) self.total_counts = 0 def choose_action(self): if self.total_counts < len(self.estimates): return self.total_counts # 初始阶段尝试每个臂 # UCB计算公式 ucb_values = self.estimates + np.sqrt(2 * np.log(self.total_counts) / (self.action_counts + 1e-5)) return np.argmax(ucb_values) def update_estimates(self, arm, reward): self.action_counts[arm] += 1 self.total_counts += 1 self.estimates[arm] += (reward - self.estimates[arm]) / self.action_counts[arm]

6. 工程实践建议

在实际项目中应用这些技术时,有几个经验值得分享:

  1. 参数初始化技巧

    • 将初始估计值设为较高值(如self.estimates = np.ones(arms)*5),鼓励早期探索
    • action_counts加小常数避免除零错误
  2. 性能优化

    # 向量化操作替代循环 def batch_update(self, arms, rewards): self.action_counts[arms] += 1 self.estimates[arms] += (rewards - self.estimates[arms]) / self.action_counts[arms]
  3. 实验管理

    • 使用np.random.seed()保证实验可复现
    • 多次运行取平均值消除随机性影响
def multi_run(epsilon=0.1, runs=10): all_rewards = [] for _ in range(runs): results = run_experiment(epsilon=epsilon) all_rewards.append(results['cumulative_rewards']) return np.mean(all_rewards, axis=0)

当我在实际项目中应用这些方法时,发现非平稳环境下的表现对业务指标影响最大。有次线上AB测试显示,将ε从固定值改为随时间衰减的调度策略,使得关键指标提升了12%。这提醒我们:理论上的最优参数可能需要根据具体场景调整。

http://www.jsqmd.com/news/752381/

相关文章:

  • 不为流量折腰,海棠山铁哥《第一大道》凭初心抗衡营销至上的《灵魂摆渡・浮生梦》
  • 新手开发者首次使用 Taotoken 模型广场完成模型选型的步骤
  • VuePress/Webpack项目构建时内存爆了?手把手教你配置`--max-old-space-size`和`increase-memory-limit`插件
  • 快手号水印去除教程:去掉快手号水印的方法有哪些?2026最新实测全攻略 - 爱上科技热点
  • 5分钟掌握GPU显存稳定性测试:memtest_vulkan完整实战教程
  • STM32H7开发笔记(一):前言 - EM
  • 抖音去水印提取工具哪个好用?抖音去水印提取操作方法2026最新实测汇总 - 爱上科技热点
  • 基于Next.js的全栈CRM系统架构设计与工程实践
  • 2026年云端保姆级流程:如何搭建OpenClaw?Coding Plan配置及大模型API Key接入
  • 3分钟快速上手BetterNCM:一键解锁网易云音乐隐藏功能的终极指南
  • FreeRTOS消息队列实验中的按键“失灵”谜案:一次调用引发的后果
  • 从驱动安装到流控配置:一份给单片机新手的CH9101与FT232R实战避坑指南
  • 自动驾驶视频生成的3D高斯泼溅优化实践
  • 飞腾ARM服务器离线部署指南:手把手教你为银河麒麟V10 SP2搭建私有yum仓库
  • 5分钟极速搞定!Axure RP免费中文语言包完整安装指南 [特殊字符]
  • 2026年腾讯云零基础教程:OpenClaw如何搭建?Coding Plan配置与大模型接入流程
  • 2026年初中英语考纲词汇表(1600词)PDF电子版
  • 5步掌握semi-utils:从批量水印到专业摄影作品展示的完整实践
  • 3步快速修复Notepad--文件关联:告别双击无法打开的烦恼
  • 观察Taotoken在多模型聚合调用下的延迟表现与路由稳定性
  • AI智能体安全连接外部应用:Council Composio技能模块详解
  • STM32H7开发笔记(七):MPU引入与讲解 - EM
  • 使用Taotoken CLI工具一键生成多开发环境配置统一团队接入
  • Harepacker-resurrected:MapleStory游戏资源定制与地图编辑技术指南
  • 如何用嘎嘎降AI处理公务员申论:政府文件行政公文降AI免费操作完整教程
  • 光电编码器怕灰,磁性编码器怕干扰?深入拆解电容式编码器,看它如何用‘数字游标卡尺’原理搞定恶劣环境
  • 通过Taotoken平台统一管理分散的API Key并设置访问权限
  • ArcGIS Pro死活读不了Excel?别急着重装Office,试试这个静默安装命令
  • 保姆级教程:用CloudCompare的PCA功能一键搞定点云最小包围盒(附避坑指南)
  • AI 率 75% 起步怎么不打散学术腔?极高档位降 AI 攻略 4 步。