LSTM时序预测的“特征工程”血泪史——从43%到RMSE下降31%
花了一周搭好LSTM模型,一测准确率43%,跟抛硬币差不多。那一刻我深刻体会到了什么叫“模型在嘲笑你”。
坑1:只有一个特征,模型等于“盲猜”
第一版LSTM,我只用了收盘价做预测。训练完测试,准确率只有43%——比随机猜测的50%还低。
根本原因:
LSTM虽然能捕捉时间序列的依赖关系,但它只能基于你给的数据做模式识别。只给收盘价,它看到的只是价格曲线,根本不知道当前是贵还是便宜。就像让一个分析师只看股价不看估值,他判断不准是正常的。
解决方案:
引入估值特征——PE分位、PB分位。PE/PB分位告诉模型当前价格在历史区间的位置,模型就能判断“目前处于高估还是低估区间”。
| 版本 | 特征 | RMSE | 变化 |
|---|---|---|---|
| V1.0 | 仅收盘价 | 基线 | — |
| V1.1 | 收盘价 + 涨跌幅 + 成交量 | 小幅下降 | — |
| V1.2 | 收盘价 + 涨跌幅 + 成交量 + PE分位 + PB分位 | RMSE下降31% | ✅ 关键突破 |
坑2:加了新特征,RMSE从3.39飙升到11.22
看到V1.2效果好,我信心满满地加了更多技术指标——RSI、布林带、MACD。结果RMSE从3.39直接飙到11.22,模型完全崩溃。
根本原因:
新增的特征和原有特征在量纲上差异太大。PE/PB分位在0-1之间,RSI在0-100之间,布林带是价格绝对值,三者混在一起,模型根本不知道怎么权衡。
解决方案:
回退到V1.2,只用那些经过验证的特征。然后逐个新增特征做A/B测试,新增的特征必须通过单独的效果验证才会合入主版本。
代码示意:特征筛选逻辑
# 特征组合测试
feature_sets = {
'v1.2': ['close', 'pct_change', 'volume', 'pe_percentile', 'pb_percentile'],
'v1.3': ['close', 'pct_change', 'volume', 'pe_percentile', 'pb_percentile', 'rsi'],
'v1.4': ['close', 'pct_change', 'volume', 'pe_percentile', 'pb_percentile', 'bollinger']
}
for version, features in feature_sets.items():
rmse = train_and_evaluate(features)
print(f"{version}: RMSE={rmse}")
if rmse <= best_rmse * 1.05: # 允许5%的容忍度
print(f"✅ {version} 通过验证,可合入")
else:
print(f"❌ {version} 效果回退,暂不合入")
踩坑总结:
-
特征不是越多越好。量纲差异大的特征混在一起,模型会“精神分裂”。
-
每次只加一个新特征,验证有效再合入,不要一次性加一堆。
-
回退机制是底线。发现效果回退,立刻回滚到上一个稳定版本,不要恋战。

浙公网安备 33010602011771号