第八章:机器学习辅助:使用PCA降维曲面数据、聚类算法识别形态、LSTM预测曲面变化

各位,欢迎来到第八章。

前面几章我们聊了怎么手工识别曲面形态,怎么用参数化模型去拟合。但说实话,手工看曲面,一天看个几十次还行,要是做高频或者批量扫描几百个品种,眼睛就花了。我早年做CTA策略回测时,就吃过这个亏——人工标注了三千个曲面样本,结果脖子疼了一周,还漏掉了几次关键的结构转换信号。

所以这一章,我们聊聊怎么让机器帮我们干这活。核心思路就三步:降维、聚类、预测。说白了,就是把高维的曲面数据压缩成几个关键特征,然后让算法自己学会“这是什么形态”,最后用时序模型猜一猜“下一步会变成什么样”。

核心逻辑框架:原始曲面(10×10网格)→ PCA降维(3-5个主成分)→ K-Means聚类(识别牛陡、熊平、蝶式等形态)→ LSTM时序预测(预测未来曲面主成分)→ 生成交易信号。

原始曲面数据 10×10 波动率网格 PCA降维 100维 → 5维 K-Means聚类 识别4-6种形态 LSTM预测 预测未来主成分 滚动更新:新数据加入,重新降维与聚类 机器学习辅助曲面分析流程

8.1 为什么要降维?—— 曲面数据的“维度诅咒”

一个标准的波动率曲面,假设期限有10档,行权价有10档,那就是100个数据点。你想想看,100维的空间里做聚类,距离度量基本失效——所有点之间的距离都差不多,聚类结果毫无意义。这就是所谓的“维度诅咒”。

我2018年刚尝试用机器学习做曲面分类时,直接拿100维数据跑K-Means,结果分出来的类别完全随机,跟扔骰子差不多。后来才意识到,必须先降维。

我的经验:PCA降维后保留的主成分数量,我一般取能解释总方差95%以上的前几个。对于外汇期权曲面,通常是3-5个;对于股指期权,有时需要6-7个。你可以画个“碎石图”看看拐点在哪。

8.2 PCA降维实战:从100维到5维

PCA的原理不复杂,就是找数据方差最大的方向。具体到曲面数据,第一主成分通常对应“整体波动率水平”,第二主成分对应“期限结构的斜率”,第三主成分对应“微笑曲率”。

import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# 假设曲面数据 shape = (n_samples, 100)
# 每一行是一个展平的曲面(10期限 × 10行权价)
X = np.random.randn(5000, 100)  # 示例数据

# 标准化:PCA对尺度敏感
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 执行PCA,保留95%方差
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X_scaled)

print(f"原始维度: {X.shape[1]}")
print(f"降维后维度: {X_pca.shape[1]}")
print(f"各主成分解释方差比: {pca.explained_variance_ratio_}")

跑完这段代码,你会发现前3个主成分通常能解释70%-80%的方差,前5个能到95%以上。我习惯把前三个主成分分别命名为:水平因子斜率因子曲率因子。这样解释起来很直观。

注意:PCA假设数据是线性的。如果曲面形态存在明显的非线性结构(比如极端行权价处的“翘尾”),你可能需要尝试核PCA或t-SNE。不过对于大多数常规市场,线性PCA已经够用。

8.3 聚类算法识别形态:让机器自己学会分类

降维之后,我们就可以在低维空间里做聚类了。我推荐用K-Means,简单、快、可解释性强。但有个问题:K值怎么选?

我个人习惯用“肘部法则”加“业务理解”双重验证。比如你先跑K=2到K=10,看每个K对应的SSE(簇内平方和),找到拐点。然后看看每个簇的中心点对应的曲面长什么样——如果K=4时,四个中心分别对应“牛陡”、“熊平”、“蝶式正”、“蝶式负”,那就很完美。

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# 用肘部法则选K
sse = []
for k in range(2, 11):
    kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
    kmeans.fit(X_pca)
    sse.append(kmeans.inertia_)

# 画图看拐点
plt.plot(range(2, 11), sse, marker='o')
plt.xlabel('K')
plt.ylabel('SSE')
plt.title('肘部法则确定最佳K值')
plt.show()

# 假设拐点在K=5
kmeans = KMeans(n_clusters=5, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_pca)

# 每个簇的中心点(在主成分空间)
centers_pca = kmeans.cluster_centers_
# 反变换回原始曲面空间,看看每个形态长什么样
centers_original = pca.inverse_transform(centers_pca)

我曾经用这个方法在欧元兑美元期权上跑过一次。聚类结果很有意思:K=5时,五个簇分别对应“平稳市”、“陡峭牛”、“平坦熊”、“左偏微笑”、“右偏微笑”。而且我发现,当市场从“平稳市”切换到“左偏微笑”时,往往预示着尾部风险在积聚——这个信号后来帮我躲过了一次闪崩。

避坑指南:聚类结果不是一成不变的。我建议每周重新训练一次模型,或者用滚动窗口的方式更新聚类中心。市场结构会变,去年的“牛陡”和今年的“牛陡”可能不是一回事。

8.4 LSTM预测曲面变化:从分类到预测

聚类只能告诉我们“现在是什么形态”,但交易需要知道“接下来会变成什么”。这时候就需要时序模型了。

LSTM(长短期记忆网络)特别适合处理这种序列数据。我们的输入是过去N个时间步的PCA主成分,输出是未来M个时间步的主成分。然后我们可以把预测出的主成分反变换回曲面,看看未来曲面长什么样。

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout

# 构造序列数据:用过去20个时间步预测未来5个时间步
def create_sequences(data, seq_length=20, pred_length=5):
    X, y = [], []
    for i in range(len(data) - seq_length - pred_length + 1):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length:i+seq_length+pred_length])
    return np.array(X), np.array(y)

# 假设X_pca是降维后的数据,shape=(n_samples, n_components)
X_seq, y_seq = create_sequences(X_pca, seq_length=20, pred_length=5)

# 划分训练集和测试集
split = int(0.8 * len(X_seq))
X_train, X_test = X_seq[:split], X_seq[split:]
y_train, y_test = y_seq[:split], y_seq[split:]

# 构建LSTM模型
model = Sequential([
    LSTM(64, activation='tanh', return_sequences=True, input_shape=(20, X_pca.shape[1])),
    Dropout(0.2),
    LSTM(32, activation='tanh', return_sequences=False),
    Dropout(0.2),
    Dense(5 * X_pca.shape[1]),  # 预测5个时间步 × n_components
    tf.keras.layers.Reshape((5, X_pca.shape[1]))
])

model.compile(optimizer='adam', loss='mse')
model.summary()

# 训练
history = model.fit(X_train, y_train, epochs=50, batch_size=32, 
                    validation_data=(X_test, y_test), verbose=1)

训练完成后,我们就可以用最新的20个时间步数据,预测未来5个时间步的曲面主成分。然后反变换回原始曲面空间,看看未来曲面长什么样。

我的小技巧:LSTM预测的曲面不要直接用于交易。我通常会把预测结果和当前曲面做个对比,计算“预测变化量”。如果预测显示未来曲面会从“牛陡”变成“熊平”,而且变化幅度超过历史90分位数,我才会考虑入场。说白了,预测是辅助,不是圣杯。

8.5 完整流程:从数据到信号

把上面三步串起来,就是一个完整的机器学习辅助交易系统:

  1. 数据准备:获取实时曲面数据,展平成100维向量,标准化。
  2. PCA降维:用预训练的PCA模型,将100维降到5维主成分。
  3. 形态识别:用预训练的K-Means模型,给当前主成分打上形态标签。
  4. 趋势预测:用LSTM模型,基于过去20个时间步的主成分,预测未来5步。
  5. 信号生成:结合当前形态标签和预测变化,生成交易信号。
当前形态 预测变化 交易信号
牛陡 → 熊平 做空短期波动率,做多长期波动率
蝶式正 → 蝶式负 卖出蝶式价差,买入反向蝶式
平稳市 → 左偏微笑 买入虚值看跌期权对冲尾部风险

重要提醒:机器学习模型在市场结构发生剧烈变化时(比如2020年3月、2008年金融危机)会失效。因为这些极端行情在训练数据中很少出现。我建议设置一个“模型置信度”阈值——当预测结果和历史分布偏差超过3个标准差时,自动切换到规则交易模式。

好了,这一章的内容就到这里。PCA降维、K-Means聚类、LSTM预测,这三板斧用好了,能帮你从海量曲面数据中快速提取交易信号。但记住,机器是辅助,最终决策还是要靠你对市场的理解。


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