数据科学和机器学习(第 18 部分):掌握市场复杂性博弈,截断型 SVD 对比 NMF(基础篇)
📘

数据科学和机器学习(第 18 部分):掌握市场复杂性博弈,截断型 SVD 对比 NMF(基础篇)

第 1/3 篇

◍ 高维行情里的维度诅咒与两条降维路径

在 MT5 上做特征工程时,很多人直接把几十个指标一股脑喂给模型,却忽略了「维度诅咒」:当特征维度升高,样本在特征空间里变得极度稀疏,距离度量失效,过拟合概率显著上升。外汇与贵金属波动本身高风险,样本量相对有限,硬堆维度往往换来更脆的泛化。 截断型 SVD(Truncated SVD)把原始矩阵分解为左奇异、奇异值、右奇异三部分,只保留前 k 个最大奇异值对应的成分,用可释方差函数决定 k。它能处理负值特征,适合把相关性高的指标群压缩成少数正交因子。 NMF(非负矩阵分解)则要求原矩阵与分解结果均非负,逼出局部加性结构——对只取正向动能、波动率这类非负量的场景更贴合直觉。两者都能把高维特征降到 2~10 维,但截断型 SVD 可能因负值组合丢失物理可解释性,NMF 则对初值与稀疏度敏感。 开 MT5 接 Python 环境跑一遍:先用 1444 根 H1 美日 K 线提取 30 个技术指标,分别用截断型 SVD 与 NMF 降到 5 维,看重建误差与后续轻量模型 AUC 的差异,比空谈理论来得直接。

「高维数据为什么必须压成低维」

降维本质是把样本从高维空间投射到低维空间,同时尽量保住原始数据里那些有区分度的属性,理想状态是逼近数据自身的固有维度。在 MT5 里如果直接拿几十个指标维度去跑模型,样本会迅速变得稀疏,运算量也失控。 维基百科给出的定义很直接:降维是高维转低维且保留有意义属性的过程。外汇与贵金属市场多周期、多品种叠加后维度爆炸,稀疏样本会让策略过拟合概率显著上升,这类市场本身高风险,维度越多越难证伪。 信号处理、语音识别这些领域早就在用降维,原因就一个——高维空间里数据又稀又难算。做价格行为分析时,把 15 个特征压到 3 个主成分,回测速度可能快 5 到 10 倍,但保留的是哪部分信息必须自己验证。

MT5内置指标堆出的高维陷阱

现实里多数机器学习建模用的数据集,特征维度远超肉眼可盯的范围。维度一高,计算开销、过拟合概率和可视化难度会同步抬头,这不是靠拍脑袋能绕开的。 您在EA里常用5个自变量做判断,这离AI算法交易的实战体量差得太远。若把MT5全部38个内置指标的缓冲区都收进来,最终会得到56个缓冲区的数据流——这个数据集已经相当庞大,普通笔记本跑回测都可能卡顿。 高维不等于高胜率,外汇与贵金属市场本身高风险,维度泛滥反而容易让模型记住噪声。开MT5用iIndicatorsTotal测一下你当前品种的缓冲区总数,先看清自己喂给了模型多少维。

◍ 高相关特征把模型带进沟里

做线性回归预测 EURUSD H1 收盘价时,若直接塞进去 10 个趋势类指标(CSV 前 13 列本就都是趋势跟踪量,彼此高度相关),训练集 R² 能冲到 92.2%,测试集也有 87.5%。数字好看,但测试比训练掉了约 5 个点,说明模型大概率把训练样本里的噪声和特定形态当规律记了。 这就是高维里典型的维度诅咒:特征高度共线会让 ML 模型过拟合,稀疏分布加上算力消耗只是附赠的麻烦。用 PCA 把 10 列压到更低维后再跑同一套回归,训练准确率变成 88.98%、测试 89.991%,泛化落差几乎消失。 降维后绝对精度低了,但样本外存活能力明显更强——对做外汇/贵金属量化的人来说,这种模型才值得接实盘验证。高杠杆品种里过拟合模型崩起来很快,别被训练分数晃了眼。 下面这段是训练/预测的核心调用,注意 TrainTestSplit 先切样本,fit 里用 NORM_MIN_MAX_SCALER 做归一,predict 拿训练集回测算 R²: matrix_utils.TrainTestSplitMatrices(data, train_x, train_y, test_x, test_y); lr.fit(train_x, train_y, NORM_MIN_MAX_SCALER); vector preds = lr.predict(train_x); Print("Train acc = ",metrics.r_squared(train_y, preds)); 日志里打出 Train acc = 0.9222314640780123,就是 10 趋势指标未降维时的成绩。

MQL5 / C++
matrix_utils.TrainTestSplitMatrices(data, train_x, train_y, test_x, test_y);
lr.fit(train_x, train_y, NORM_MIN_MAX_SCALER);
vector preds = lr.predict(train_x);
Print("Train acc = ",metrics.r_squared(train_y, preds));

「PCA 降维后 EURUSD 的泛化表现」

在 EURUSD H1 上抓取了 70 个指标快照(如 07:10:55 那笔 GetAllIndicators 日志,数值跨度从 1.09148 到 1.10082),直接喂分类器容易过拟合。用 PCA 压到 8 维后再看,测试集准确率从降维前的 0.8759 提升到 0.8992,训练集 0.8899,说明信息损失可控且泛化反而更稳。 代码里先 new CPCA(8) 把特征列锁死为 8 列,fit_transform 做标准化投影,再用 extract_components 按 Scree Plot 准则提取主成分。外汇与贵金属属高风险品种,这类降维准确率仅代表历史样本内概率,实盘可能随波动结构漂移而失效。 想验证就开 MT5 跑同周期指标池,把维度从 8 调到 12 对比 Test acc,通常 H1 欧元在 8~10 维之间拐点最明显。

MQL5 / C++
pca = new CPCA(class="num">8); class=class="str">"cmt">//Reduce the dimensions of the data to class="num">8 columns
data = pca.fit_transform(data);
pca.extract_components(data, CRITERION_SCREE_PLOT);

为什么非要给特征降维

把特征维度压下来,最先见效的是算力账。维度少了,机器学习模型在 MT5 里训练和推理的耗时都会明显缩短,尤其当你拿分钟级外汇 tick 数据跑集成模型时,维度砍掉一半可能训练时间直接少三成以上。 普适度是另一层动机。降维相当于强制模型丢掉冗余噪声,对新行情的泛化能力会好一些,这点我们在前面线性回归示例里已经看到过:高维过拟合的曲线在样本外立刻塌房,降维后反而贴住真实分布。 还有个务实理由——人要看得懂。把几十维特征投到二维或三维空间,贵金属跨品种联动这类结构肉眼就能扫出来,比盯一堆相关系数表直观得多。外汇和贵金属杠杆高、跳空频繁,任何可视化辅助都只是降低认知负荷,不替代风控。

常见问题

高相关指标提供冗余信息,特征维度高会放大噪声;建议先用降维把强相关指标合并,再喂给模型。
20 维里大量重叠信号,PCA 提主成分后去噪,样本外误差倾向更低;可自己取不同维数对比曲线。
小布可对接你的品种页,用 AIGC 跑特征相关性诊断,直接标出高冗余指标并给保留建议。
SVD 允许负值适合作差类特征,NMF 只出非负逼近更适合量价强度;先弄懂 SVD 再碰 NMF 更稳。
贵金属跳空多、特征耦合强,高维让优化面畸变;降维后参数鲁棒性会明显提升,但仍有高风险。