强化学习基础(二):Q-Learning与SARSA算法原理

好,咱们接着聊。上一章我们把强化学习的核心概念捋了一遍,状态、动作、奖励、策略这些基本盘算是稳了。这一章,我们直接上硬菜——两种最经典的时序差分(TD)算法:Q-Learning 和 SARSA。

说实话,这两个算法是入门强化学习的“必过坎”。我当年刚接触时,也绕了不少弯路。今天我就用最直白的方式,把它们的原理、区别,以及在实际量化交易中怎么用,给你讲透。

一、从“猜数字”游戏理解TD思想

先别急着看公式。我们想一个问题:你玩一个猜数字游戏,每次猜完,系统只告诉你“高了”或“低了”。你怎么快速逼近正确答案?

你不会等猜完100次再总结,而是每猜一次,就根据反馈调整下一次的猜测。这就是时序差分(TD)的核心思想——用当前步的即时奖励 + 下一步的估计值,来更新当前步的估计值

用公式表达就是:

新估计值 = 旧估计值 + 学习率 × (即时奖励 + 折扣因子 × 下一步估计值 - 旧估计值)

这个括号里的差值,我们叫它TD误差。说白了,就是“我猜的”和“实际发生的”之间的差距。差距越大,调整幅度越大。

核心要点:TD算法不需要等到回合结束才更新,它可以在每一步都学习。这在交易场景中特别重要——你不可能等一年后再优化策略,对吧?

二、Q-Learning:离线学习的“激进派”

Q-Learning 是 Watkins 在1989年提出的。它的核心思想很直接:学习一个最优动作价值函数 Q(s,a),告诉你“在状态s下做动作a,未来能拿到多少累计奖励”。

更新公式长这样:

Q(s,a) ← Q(s,a) + α [ r + γ * max_a' Q(s',a') - Q(s,a) ]

注意看那个 max_a' Q(s',a')——它取的是下一个状态中所有动作里最大的那个Q值。这意味着什么?

意味着Q-Learning在更新时,假设自己下一步一定会选最优动作。它不管当前策略是什么,只管“理论上最好的结果”。

我举个例子。你在交易中,当前持仓是空仓(状态s),你有三个动作:买入、卖出、持有。Q-Learning在更新时,会直接看“如果我现在买入,未来最好的情况能赚多少”,而不是看“按我现在的策略,买入后下一步会怎么操作”。

我的经验:在量化回测中,Q-Learning往往收敛更快,因为它“胆子大”,直接朝着最优方向学。但风险是——如果市场环境突变,它可能会过度乐观。我曾经在2015年股灾回测中吃过这个亏,模型在暴跌前还拼命买入,因为历史数据里“买入”一直是好动作。

三、SARSA:在线学习的“稳健派”

SARSA 的名字来源于它的更新需要5个元素:State, Action, Reward, State', Action'。也就是当前状态、当前动作、奖励、下一个状态、下一个动作。

更新公式:

Q(s,a) ← Q(s,a) + α [ r + γ * Q(s',a') - Q(s,a) ]

和Q-Learning唯一的区别在于:它用的是 Q(s',a'),而不是 max_a' Q(s',a')。这里的 a'实际要执行的下一个动作,而不是理论上的最优动作。

这意味着什么?SARSA 在更新时,会考虑当前策略的“实际行为”。如果当前策略是ε-greedy(后面会讲),那它就会把“探索”带来的次优动作也考虑进去。

关键区别一句话总结:

  • Q-Learning:学的是“如果我一直选最优,结果会怎样”
  • SARSA:学的是“按我现在的策略走,结果会怎样”

四、探索与利用的权衡:ε-greedy策略

好,现在问题来了。无论是Q-Learning还是SARSA,都需要一个策略来生成动作。这个策略不能一直选已知的最优动作(利用),否则会错过更好的选择(探索)。

ε-greedy 是最简单也最常用的解决方案:

  • 以概率 ε 随机选择一个动作(探索)
  • 以概率 1-ε 选择当前Q值最大的动作(利用)

代码实现就几行:

import numpy as np

def epsilon_greedy(Q, state, epsilon, n_actions):
    if np.random.random() < epsilon:
        # 探索:随机选一个动作
        return np.random.randint(n_actions)
    else:
        # 利用:选Q值最大的动作
        return np.argmax(Q[state])

避坑指南:我曾经在实盘模拟中把ε设成固定值0.1,结果模型永远在探索,永远学不好。正确的做法是让ε随时间衰减——初期多探索,后期多利用。比如从0.9线性衰减到0.01。

五、在离散动作空间中的应用:以仓位管理为例

在量化交易中,离散动作空间最常见的场景就是仓位管理。假设我们只允许三种仓位:

  • 动作0:空仓(0%仓位)
  • 动作1:半仓(50%仓位)
  • 动作2:满仓(100%仓位)

状态可以定义为:过去N天的收益率、波动率、成交量变化等。奖励函数可以设为:每步的收益率 - 惩罚项(比如最大回撤惩罚)

下面是一个完整的Q-Learning训练循环框架:

import numpy as np

# 初始化Q表
n_states = 100  # 离散化后的状态数
n_actions = 3   # 空仓、半仓、满仓
Q = np.zeros((n_states, n_actions))

# 超参数
alpha = 0.1     # 学习率
gamma = 0.9     # 折扣因子
epsilon = 0.9   # 初始探索率
epsilon_min = 0.01
epsilon_decay = 0.995

# 训练循环
for episode in range(1000):
    state = env.reset()  # 获取初始状态
    done = False
    
    while not done:
        # 用ε-greedy选动作
        action = epsilon_greedy(Q, state, epsilon, n_actions)
        
        # 执行动作,获取下一个状态和奖励
        next_state, reward, done = env.step(action)
        
        # Q-Learning更新
        best_next_action = np.argmax(Q[next_state])
        td_target = reward + gamma * Q[next_state][best_next_action]
        td_error = td_target - Q[state][action]
        Q[state][action] += alpha * td_error
        
        state = next_state
    
    # 衰减探索率
    if epsilon > epsilon_min:
        epsilon *= epsilon_decay

我的习惯:在实际项目中,我不会直接用原始收益率作为奖励。我会用夏普比率或者卡玛比率的增量作为奖励,这样模型会更关注风险调整后的收益。你想想看,一个策略如果收益高但回撤大,你敢用吗?

六、Q-Learning vs SARSA:到底选哪个?

这个问题我经常被问到。直接给结论:

对比维度 Q-Learning SARSA
学习方式 离线学习(Off-policy) 在线学习(On-policy)
更新依据 理论最优动作 实际执行动作
收敛速度 通常更快 通常更慢
风险偏好 激进,可能高估 稳健,更贴近实际
适用场景 环境稳定,追求最优 环境波动大,求稳

我个人在量化交易中的经验是:先用Q-Learning快速找到大致方向,再用SARSA做精细调优。这样既保证了效率,又兼顾了稳健性。

七、本章知识体系图

下面这张图把本章的核心逻辑串起来了,建议你多看几遍:

强化学习基础(二):核心知识体系 时序差分(TD)学习 Q-Learning(离线) SARSA(在线) 更新用 max Q(s',a') 不考虑当前策略 收敛快,偏激进 更新用 Q(s',a') 考虑实际策略 收敛慢,偏稳健 探索与利用:ε-greedy策略 应用:离散仓位管理(空仓/半仓/满仓)

本章核心记忆点:

  • Q-Learning 用 max 更新,胆子大,学得快
  • SARSA 用实际动作更新,步子稳,更安全
  • ε-greedy 是探索和利用的“调节旋钮”
  • 离散动作空间最适合做仓位管理、买卖信号等

好了,这一章的内容就到这。下一章我们会把这些算法真正跑起来,用Python实现一个完整的交易智能体。到时候你会发现,这些理论其实离实战并不远。


公众号:蓝海数据掘金营,微信deep3321