3. 策略热力图分析:动作概率分布的可视化解读

说实话,做强化学习量化模型最头疼的问题是什么?

不是模型不赚钱,而是模型不解释

你辛辛苦苦训练了一个智能体,它在回测里跑得风生水起,但一到实盘你就慌了——它到底为什么在那个时刻选择买入?为什么在另一个时刻选择空仓?

我当年第一次遇到这个问题时,盯着回测曲线看了整整三天,愣是没想明白。后来我意识到:我们需要一个工具,把智能体的「大脑」可视化出来。策略热力图,就是干这个的。

3.1 什么是策略热力图?

说白了,策略热力图就是一张二维表格。

横轴是时间(或者市场状态),纵轴是动作空间(买入、卖出、持有、空仓等)。每个格子里的颜色深浅,代表智能体在那个状态下选择某个动作的概率。

举个例子:

市场状态 买入概率 持有概率 卖出概率 空仓概率
高波动+上涨 0.72 0.18 0.06 0.04
低波动+下跌 0.05 0.12 0.08 0.75
震荡+缩量 0.30 0.55 0.10 0.05

你看,当市场处于「高波动+上涨」时,智能体买入概率高达0.72;而到了「低波动+下跌」,空仓概率直接飙到0.75。这就是策略热力图的价值——一眼看出智能体的交易偏好

3.2 为什么要做热力图分析?

我遇到过不少团队,模型收益曲线很漂亮,但一问到「模型在什么情况下会亏钱」,没人答得上来。

这就是黑箱的代价。

策略热力图能帮你回答三个核心问题:

  • 智能体在哪些市场状态下最自信?(概率接近1或0)
  • 智能体在哪些状态下犹豫不决?(概率均匀分布)
  • 智能体的交易逻辑是否符合你的预期?(比如,下跌时是否真的在空仓)

核心观点:热力图不是用来「看热闹」的,它是用来诊断模型行为的。如果智能体在上涨行情中大量卖出,在下跌行情中频繁买入——那你的模型大概率学歪了。

3.3 如何生成策略热力图?

嗯,这里要注意:生成热力图需要两个关键数据——状态序列动作概率序列

具体步骤如下:

  1. 收集数据:让智能体在回测环境中运行,记录每一步的观测状态和动作概率分布。
  2. 状态离散化:将连续的市场状态(如波动率、收益率)映射到有限的类别中。
  3. 聚合统计:对每个状态类别,计算所有动作的平均概率。
  4. 绘制热力图:用颜色编码展示概率值。

我给你们看一段代码,这是我实际项目中用过的简化版:

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

def plot_policy_heatmap(states, action_probs, state_labels, action_labels):
    """
    states: 离散化后的状态索引数组 (T,)
    action_probs: 动作概率数组 (T, num_actions)
    state_labels: 状态名称列表
    action_labels: 动作名称列表
    """
    num_states = len(state_labels)
    num_actions = len(action_labels)
    
    # 初始化聚合矩阵
    prob_matrix = np.zeros((num_states, num_actions))
    count_matrix = np.zeros(num_states)
    
    # 聚合统计
    for s, probs in zip(states, action_probs):
        prob_matrix[s] += probs
        count_matrix[s] += 1
    
    # 计算平均概率
    for s in range(num_states):
        if count_matrix[s] > 0:
            prob_matrix[s] /= count_matrix[s]
    
    # 绘制热力图
    plt.figure(figsize=(10, 6))
    sns.heatmap(prob_matrix, 
                xticklabels=action_labels,
                yticklabels=state_labels,
                annot=True, fmt='.2f',
                cmap='RdYlGn', vmin=0, vmax=1)
    plt.title('策略动作概率热力图')
    plt.xlabel('动作')
    plt.ylabel('市场状态')
    plt.tight_layout()
    plt.show()

# 示例用法
states = np.random.randint(0, 4, 1000)  # 4种状态
action_probs = np.random.dirichlet(np.ones(3), 1000)  # 3个动作
state_labels = ['高波动上涨', '低波动下跌', '震荡缩量', '放量突破']
action_labels = ['买入', '持有', '卖出']

plot_policy_heatmap(states, action_probs, state_labels, action_labels)

小技巧:我习惯在热力图旁边加一个「置信度柱状图」,展示每个状态下最大概率的值。这样能快速定位智能体「最确定」和「最不确定」的状态。

3.4 实战案例:诊断一个「异常」智能体

我曾经接手过一个项目,智能体在回测中收益很高,但实盘表现很差。

我第一件事就是画策略热力图。

结果发现了一个诡异的现象:

  • 在「大幅下跌」状态下,智能体买入概率高达0.65
  • 在「大幅上涨」状态下,智能体卖出概率高达0.70

这明显是逆势交易策略。但问题是——回测数据里,这种逆势操作恰好碰上了几次V型反转,所以收益曲线很好看。可实盘中,V型反转哪有那么多?

避坑指南:我曾经以为热力图只是锦上添花的可视化工具,直到那次踩坑才明白——热力图是模型行为审计的第一道防线。如果发现智能体的交易逻辑与你的先验知识严重不符,一定要深挖原因,不要盲目相信回测收益。

3.5 知识体系:策略热力图分析的核心逻辑

下面这张图是我自己总结的,把整个分析流程串起来了:

策略热力图分析核心流程 ① 数据采集 状态 + 动作概率 ② 状态离散化 连续 → 离散类别 ③ 聚合统计 平均概率计算 ④ 热力图绘制 颜色编码展示 ⑤ 行为诊断 识别异常模式 ⑥ 策略优化 调整奖励/网络 迭代优化循环 核心目标:将智能体的「黑箱决策」转化为可解释的「交易偏好图谱」

3.6 常见问题与应对

在实际使用中,你可能会遇到几个坑:

  • 状态离散化太粗:比如只分「涨」和「跌」两种状态,信息损失太大。我建议至少分4-6个状态。
  • 样本不均衡:某些状态出现次数极少,统计出的概率不可靠。可以设置最小样本数阈值。
  • 概率值过于集中:如果所有状态下的概率都接近0.5,说明智能体还没收敛,需要继续训练。

我的习惯:每次训练完一个新模型,我都会先跑一遍热力图。如果发现「买入」和「卖出」的概率在大多数状态下都差不多,我会直接判定这个模型「没学会」,然后回去调奖励函数。

你想想看,如果连你自己都看不懂模型在干什么,你怎么敢把它放到实盘上去?

策略热力图,就是帮你把模型的「内心戏」翻译成人话的工具。用好了,它能帮你省下无数个「盯着回测曲线发呆」的夜晚。


公众号:蓝海资料掘金营,微信deep3321