18. 机器学习在曲面预测中的应用:LSTM、随机森林
各位,聊到波动率曲面预测,传统的时间序列模型(ARIMA、GARCH)其实也能做。但说实话,做跨品种套利的时候,曲面形态变化太快,非线性关系太复杂。传统模型往往力不从心。
这时候,机器学习就派上用场了。我个人习惯把机器学习方法分成两类:一类是树模型(随机森林、XGBoost),适合捕捉特征间的交互;另一类是深度学习(LSTM),专门处理时序依赖。今天咱们就重点聊聊这两个。
18.1 为什么传统方法不够用?
先说说痛点。我记得刚入行那会儿,用GARCH模型预测波动率曲面。结果呢?遇到市场异动,模型直接崩了。为什么?
- 非线性关系:波动率曲面与标的资产价格、时间、行权价之间,不是简单的线性关系
- 多因子影响:除了价格,还有成交量、持仓量、市场情绪、宏观数据……传统模型塞不下这么多变量
- 曲面结构约束:无套利条件、期限结构、微笑形态,这些约束传统模型很难同时满足
说白了,传统模型就像一把螺丝刀,拧拧螺丝还行。但波动率曲面预测,需要的是瑞士军刀。
18.2 随机森林:特征工程的利器
随机森林,我愿称之为「特征工程的懒人福音」。你不需要太担心特征之间的多重共线性,也不用做太多数据预处理。树模型自己会做特征选择。
18.2.1 特征怎么构造?
我在项目中遇到过一个问题:直接用原始波动率数据训练,效果很差。后来发现,需要构造一些衍生特征:
- 时间特征:剩余到期天数、是否临近到期、是否周末/节假日
- 曲面形态特征:偏度(skew)、峰度(kurtosis)、期限结构斜率
- 市场状态特征:隐含波动率与历史波动率的比值、VIX指数、成交量变化率
- 跨品种特征:相关品种的波动率曲面差异、价差变化
核心思路:随机森林擅长处理高维特征,但前提是特征要有「信息量」。别一股脑把所有数据都扔进去,先做一轮特征筛选。
18.2.2 代码示例:随机森林预测曲面点
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
# 假设我们有一个DataFrame,包含特征和波动率标签
# 特征:delta, tau, skew, vix, volume_change ...
# 标签:implied_vol
X = df[['delta', 'tau', 'skew', 'vix', 'volume_change']]
y = df['implied_vol']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练随机森林
rf = RandomForestRegressor(
n_estimators=200,
max_depth=10,
min_samples_leaf=5,
random_state=42
)
rf.fit(X_train, y_train)
# 预测
y_pred = rf.predict(X_test)
# 特征重要性
importance = pd.DataFrame({
'feature': X.columns,
'importance': rf.feature_importances_
}).sort_values('importance', ascending=False)
print(importance)
我的经验:随机森林的n_estimators设到200-500就够了,再大收益递减。max_depth控制在10以内,防止过拟合。你想想看,波动率曲面本身就有噪声,树太深容易把噪声也学进去。
18.3 LSTM:捕捉时序依赖
随机森林有个硬伤:它把每个时间点的数据当成独立样本。但波动率曲面是时序数据,今天的曲面形态和昨天、前天是高度相关的。
LSTM(长短期记忆网络)就是干这个的。它能记住过去N个时间步的信息,用来预测下一个时间步的曲面。
18.3.1 数据重构:从截面到时序
用LSTM之前,需要把数据重构成「样本-时间步-特征」的三维结构。举个例子:
- 假设我们有过去30天的曲面数据
- 每个时间点有20个特征(delta、tau、skew等)
- 那么每个样本的形状就是 (30, 20)
- 预测目标:未来1天的曲面点
注意:LSTM对数据尺度敏感。一定要做归一化或标准化。我曾经因为忘了归一化,模型训练了三天都不收敛……嗯,从那以后我每次都会检查数据预处理。
18.3.2 代码示例:LSTM预测曲面
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from sklearn.preprocessing import MinMaxScaler
# 假设 data 是形状为 (样本数, 时间步, 特征数) 的三维数组
# 例如:data.shape = (10000, 30, 20)
# 归一化
scaler = MinMaxScaler()
# 注意:需要按特征维度做归一化,不能把不同特征混在一起
data_scaled = scaler.fit_transform(data.reshape(-1, data.shape[-1]))
data_scaled = data_scaled.reshape(data.shape)
# 构建LSTM模型
model = Sequential([
LSTM(64, return_sequences=True, input_shape=(30, 20)),
Dropout(0.2),
LSTM(32, return_sequences=False),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(1) # 预测单个曲面点
])
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.summary()
# 训练
history = model.fit(
X_train, y_train,
validation_data=(X_val, y_val),
epochs=50,
batch_size=64,
verbose=1
)
18.4 两种方法的对比与选择
你可能会问:到底用随机森林还是LSTM?我的建议是:看数据量。
| 维度 | 随机森林 | LSTM |
|---|---|---|
| 数据量要求 | 几千条就能出效果 | 至少几万条,最好十万+ |
| 时序依赖 | 不支持(需手动构造滞后特征) | 天然支持 |
| 特征交互 | 优秀(树模型自动捕捉) | 一般(需要大量数据学习) |
| 可解释性 | 高(特征重要性、SHAP值) | 低(黑盒) |
| 训练速度 | 快(几分钟到几十分钟) | 慢(几小时到几天) |
| 过拟合风险 | 中等(调参可控制) | 高(需要正则化、早停) |
实战建议:
- 数据量小于1万条 → 用随机森林
- 数据量大于10万条,且时序依赖明显 → 用LSTM
- 中间地带 → 两个都试试,选验证集误差小的
18.5 避坑指南
做机器学习预测曲面,有几个坑我踩过,分享给大家:
- 数据泄露:千万别用未来数据构造特征。比如用t+1天的VIX来预测t天的波动率,这属于作弊。我见过有人犯这个错,回测曲线漂亮得不行,实盘直接亏哭。
- 曲面一致性:预测出来的曲面点,要检查是否满足无套利条件。机器学习模型可不懂这些金融约束。我通常会在预测后加一个「曲面校正」步骤,用样条插值或优化方法把曲面拉平。
- 滚动预测:别一次性预测未来30天的曲面。LSTM的预测误差会随时间步累积。我习惯用「滚动预测」:每次只预测未来1天,然后把预测值作为输入,再预测下一天。
- 特征漂移:市场结构会变。去年有效的特征,今年可能就失效了。我建议每个月重新训练一次模型,或者用在线学习的方法增量更新。
18.6 知识体系图
下面这张图,是我自己总结的机器学习预测曲面的完整流程。你可以把它当成一个checklist:
最后说一句:机器学习不是银弹。它只是工具,帮你从历史数据中挖掘规律。但市场会变,规律会失效。我见过太多人迷信模型,结果市场风格切换时亏得底朝天。记住:模型是辅助,风控是底线。
公众号:蓝海资料掘金营,微信deep3321