2. 价值函数可视化:如何可视化Q值表与状态价值函数,理解智能体的决策偏好

说实话,很多同学学强化学习,卡就卡在「看不见」智能体在想什么。

你写了个Q-learning,它跑起来了,收敛了。然后呢?它为什么选这个动作?它觉得哪个状态更值钱?

我刚开始做量化交易策略时,就吃过这个亏。模型跑得挺好,回测曲线漂亮,但一上实盘就崩。后来我把Q值表拉出来一看——好家伙,智能体在极端行情下根本分不清「抄底」和「接飞刀」,因为它的价值函数没学好。

所以今天咱们就聊聊,怎么把价值函数「画」出来。你想想看,能看见的东西,你才能信任它。

2.1 为什么要可视化价值函数?

价值函数,说白了就是智能体的「世界观」。它告诉智能体:站在某个状态,未来能赚多少。

Q值表更细一点:站在某个状态,做某个动作,未来能赚多少。

可视化这些值,能帮你回答三个核心问题:

  • 智能体有没有学会? —— 价值函数是否收敛,是否合理
  • 智能体偏好什么? —— 在相似状态下,它选A不选B,为什么
  • 有没有bug? —— 比如某个状态的价值异常高,可能是探索不够

核心观点: 价值函数可视化,是调试强化学习模型的第一把钥匙。我个人的习惯是,模型还没跑完就开始画图,边跑边看,比等训练结束再分析高效得多。

2.2 可视化Q值表:离散动作空间的利器

如果你的动作空间是离散的(比如买、卖、持有),Q值表就是一张二维矩阵。行是状态,列是动作,值是Q值。

2.2.1 热力图:一眼看出偏好

我最常用的方法是热力图。横轴是动作,纵轴是状态,颜色深浅代表Q值大小。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 假设我们有一个训练好的Q表,10个状态,3个动作
q_table = np.random.rand(10, 3)  # 实际中请用你训练好的Q表

plt.figure(figsize=(8, 6))
sns.heatmap(q_table, annot=True, fmt='.2f', 
            xticklabels=['买入', '卖出', '持有'],
            yticklabels=[f'状态{s}' for s in range(10)],
            cmap='RdYlGn', center=0)
plt.title('Q值表热力图')
plt.xlabel('动作')
plt.ylabel('状态')
plt.show()

嗯,这里要注意:center=0 这个参数很关键。它让正负值用不同颜色区分,一眼就能看出哪些动作是「赚钱」的,哪些是「亏钱」的。

我在项目中遇到过一个问题:某个状态的所有Q值都特别高。后来发现,是因为那个状态出现的频率太低,智能体根本没探索够。热力图上那一行颜色特别亮,就是个危险信号。

2.2.2 柱状图:对比动作差异

有时候你想看某个具体状态下,各个动作的Q值差异。柱状图更直观。

state_idx = 5  # 想看第5个状态
actions = ['买入', '卖出', '持有']
q_values = q_table[state_idx]

plt.figure(figsize=(6, 4))
plt.bar(actions, q_values, color=['green', 'red', 'blue'])
plt.axhline(y=0, color='black', linestyle='--', linewidth=0.8)
plt.title(f'状态{state_idx}下各动作的Q值')
plt.ylabel('Q值')
plt.show()

你看,如果某个动作的柱子明显高于其他,智能体就会偏向它。如果三个柱子差不多高,说明智能体在这个状态下很犹豫——这往往是策略需要优化的地方。

小技巧: 我习惯在柱状图上标注「最优动作」和「次优动作」的差值。如果差值小于0.1,我会认为这个状态下的决策不够稳定,需要增加探索或调整学习率。

2.3 可视化状态价值函数:连续状态的挑战

现实中的量化交易,状态空间往往是连续的(比如价格、波动率、持仓比例)。这时候没有Q值表,只有函数近似器(比如神经网络)。

状态价值函数 V(s) 告诉你:当前这个状态,未来能赚多少。可视化它,能帮你理解智能体对市场环境的「整体判断」。

2.3.1 二维投影:降维观察

假设你的状态是二维的(比如价格和持仓比例),可以直接画等高线图或3D曲面。

# 假设状态是二维的:价格(0-100) 和 持仓比例(0-1)
price = np.linspace(0, 100, 50)
holding = np.linspace(0, 1, 50)
P, H = np.meshgrid(price, holding)

# 模拟一个训练好的价值函数(实际中请用你的模型预测)
V = np.sin(P/20) * np.cos(H*5) + 0.5

plt.figure(figsize=(10, 8))
contour = plt.contourf(P, H, V, levels=20, cmap='viridis')
plt.colorbar(contour, label='状态价值 V(s)')
plt.xlabel('价格')
plt.ylabel('持仓比例')
plt.title('状态价值函数等高线图')
plt.show()

为什么会这样?你看,等高线密集的地方,说明价值对状态变化很敏感。智能体在这些区域会特别谨慎——因为稍微动一下,价值就大变。

我曾经在回测中发现,智能体在持仓比例0.3-0.5的区域,价值函数特别平坦。这意味着它觉得「拿三成还是五成仓位,差别不大」。但实盘中,这个区间恰恰是风险最大的。后来我调整了奖励函数,让价值函数在这个区域产生明显梯度,模型才学会精细控制仓位。

2.3.2 时序曲线:看价值如何演化

在交易场景中,我们更关心价值函数随时间的变化。把每个时间步的状态价值画成曲线,能看出智能体对市场走势的「信心」。

# 模拟一段交易过程的状态价值
timesteps = np.arange(100)
state_values = 0.5 + 0.3 * np.sin(timesteps/10) + np.random.normal(0, 0.05, 100)

plt.figure(figsize=(12, 4))
plt.plot(timesteps, state_values, linewidth=2)
plt.axhline(y=0.5, color='red', linestyle='--', label='基准线')
plt.fill_between(timesteps, 0.5, state_values, 
                 where=(state_values > 0.5), color='green', alpha=0.3, label='乐观区间')
plt.fill_between(timesteps, 0.5, state_values, 
                 where=(state_values < 0.5), color='red', alpha=0.3, label='悲观区间')
plt.xlabel('时间步')
plt.ylabel('状态价值 V(s)')
plt.title('交易过程中状态价值的变化')
plt.legend()
plt.show()

你看,价值高于基准线时,智能体「乐观」;低于基准线时,它「悲观」。如果价值曲线频繁穿越基准线,说明智能体对市场判断不稳定——这可能是状态特征不够好,或者模型过拟合了。

避坑指南: 我曾经在可视化时发现价值曲线突然跳变。查了半天,原来是状态归一化出了问题——某个特征的数值范围变了,导致价值函数剧烈波动。所以,画时序曲线时,一定要同时检查输入状态的分布是否稳定。

2.4 决策偏好分析:从价值到动作

可视化价值函数只是第一步。我们真正想知道的,是智能体「为什么选这个动作」。

这里我常用一个方法:优势函数可视化。优势函数 A(s,a) = Q(s,a) - V(s),它告诉你「做这个动作比平均水平好多少」。

# 假设我们有Q值和V值
q_values = np.array([0.2, 0.5, 0.3])  # 三个动作的Q值
v_value = 0.33  # 状态价值
advantages = q_values - v_value

actions = ['买入', '卖出', '持有']
plt.figure(figsize=(8, 4))
colors = ['green' if a > 0 else 'red' for a in advantages]
plt.bar(actions, advantages, color=colors)
plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
plt.title('优势函数:各动作相对平均水平的优劣')
plt.ylabel('优势值 A(s,a)')
plt.show()

嗯,这里要注意:优势值为正,说明这个动作比平均水平好;为负,说明不如平均水平。如果所有优势值都接近0,说明智能体在这个状态下「无所谓」——这往往是策略需要改进的地方。

2.5 实战:一个完整的可视化流程

我建议你按这个流程来:

  1. 先看整体:画Q值表热力图或V值等高线图,了解全局
  2. 再看局部:挑几个关键状态,画柱状图看动作偏好
  3. 最后看时序:画价值曲线,看智能体对市场环境的判断是否稳定

这个流程我用了好几年,每次都能快速定位问题。说白了,可视化不是炫技,是帮你和智能体「对话」的工具。

总结一下: 价值函数可视化,让你从「黑盒调参」变成「白盒调试」。你能看见智能体的偏好、犹豫、甚至错误。下次模型表现不好,别急着调学习率——先画张图看看。

价值函数可视化知识体系 价值函数可视化 Q值表可视化 状态价值函数可视化 决策偏好分析 热力图 柱状图对比 等高线/3D图 时序曲线 优势函数 目标:从黑盒调参 → 白盒调试 理解智能体决策偏好,快速定位问题

我的习惯: 每次训练完模型,我会把上面三张图(热力图、等高线图、优势函数图)存成一个报告。下次调参时直接对比,效率翻倍。

专注资料整理