生长型神经气 GNG:MQL5 中的聚类与可视化
一、GNG(生长型神经气)是什么
GNG 是一种自组织神经网络,用“神经元(顶点)+ 边(连接)”来逼近输入数据的分布。它从 2 个神经元开始,训练过程中不断在误差最大的区域插入新顶点、删除过老的边,最终长成贴合数据密度的拓扑结构。文章用它把 RSI 的二维特征点聚类,区分不同市场状态。
二、相比 K-means / SOFM 的优势
- 无需预设簇数:从 2 个神经元起步,自动决定需要多少个。
- 自适应拓扑:神经元布置由数据决定,不像 SOFM 固定网格。
- 能学流形:边老化+删除使拓扑接近 Delaunay 三角剖分,可覆盖输入空间密度。
- 在难分类空间比 RBF 网络更高效(监督版 S-GNG)。
三、MQL5 实现:类结构与关键函数
用标准库 CList/CObject 组织动态顶点与边(链表比数组更适合反复增删)。CGNGNeuron 含权重向量、局部误差 E、唯一 ID;CGNGConnection 含 uid1/uid2/age;CGNGAlgorithm 是主类,ProcessVector 即原文的训练步进。
- lambda:插入新顶点的迭代间隔。
- age_max:连接最大年龄,超过则删边。
- alpha:插入新节点时 u,v 误差衰减系数(如 0.5)。
- beta:每步所有神经元误差衰减分数(如 0.0005)。
- eps_w / eps_n:赢家/近邻的权重适应率。
- max_nodes:网络规模上限。
四、训练一步在做什么
每输入一个向量:找最近(赢家)和次近(次优)两个神经元;赢家局部误差累加、向输入平移 eps_w,近邻平移 eps_w 的小比例;赢家所有连接 age++,赢家与次优若已连则 age 归零否则建连;age>age_max 删边、无连边的孤立神经元删除;每 lambda 步在误差最大的 u,v 中间插新顶点 r,用 u-r、v-r 替换 u-v;最后所有神经元误差乘 (1-beta) 衰减。
五、输入数据与可视化
文章取当前柱与前一柱的 RSI 配对成二维特征(隔 3 柱取样降低关联),用 CopyBuffer 取 RSI 值、归一化到 0~100,样本数约 1000。可视化用 OBJ_ARROW 画神经元(赢家 Lime、次优 Green、其他 Red)、OBJ_TREND 黄虚线画边、OBJ_LABEL 显示样本数与神经元数,每步 ChartRedraw 刷新。
六、坑与局限
七、最小可运行骨架
下面是文章 CGNGNeuron / CGNGAlgorithm 的精简骨架,展示“顶点-边”结构与一步训练在做什么。真实工程用 CList 管理动态增删:
class CGNGNeuron
{
public: double w[]; double E; int uid;
double ProcessVector(double &in[], int dim)
{ double e=0; for(int i=0;i<dim;i++) e+=(in[i]-w[i])*(in[i]-w[i]); return(e); }
void Adapt(double &in[], double eps, int dim)
{ for(int i=0;i<dim;i++) w[i]+=eps*(in[i]-w[i]); }
};
// 一步训练(ProcessVector 精简)
void Step(double &in[], int dim)
{
// 1) 找最近(winner)与次近(second)
// 2) winner.E += winner.error; winner.Adapt(in, eps_w); second.Adapt(in, eps_n);
// 3) 赢家所有边 age++;赢家-次近若已连 age=0 否则建连
// 4) age>age_max 删边,无连边顶点删除
// 5) 每 lambda 步在最大误差的 u,v 中间插新顶点 r
// 6) 所有顶点 E *= (1-beta)
}
八、落地到交易的两种姿势
姿势一:状态监测。把近期 RSI(或价格斜率)打成二维点喂给网络,网络自适应覆盖密度;某个区域没有神经元覆盖,说明市场处于罕见状态,可作为异常预警。姿势二:作为特征工程前端,把“当前点最近的神经元 ID / 到它的距离”当作新特征,喂给后续分类或信号逻辑,比原始价格序列更平滑、信息更浓缩。
九、GNG 算法步骤
生长型神经气(GNG)是一种自适应聚类:随机投点、按最近节点隶属性调整、按「被引用频率」插入新节点、删除太久没用的节点、用边年龄控制拓扑。它不需预设簇数,能随数据长出合适的聚类结构。
相比 K-means 要你先定 K、且对初值敏感,GNG 自动决定簇数、对初值更鲁棒;相比 SOFM(自组织映射)它不强制规则网格、拓扑更灵活,适合非线性分布的数据。
十、在交易中的应用:聚类行情状态
把每段行情的若干特征(波动率、趋势强度、成交量变化)作为向量喂给 GNG,它能把行情自动分成几类「状态」(如高波动趋势、低波动震荡、拐点区)。EA 据此切换策略,比用固定阈值判断更贴合数据分布。
关键在于特征选择:喂垃圾特征就聚出垃圾状态。常用波动率加收益率斜率加成交量偏离,并先做标准化(不同量纲要归一),否则某个量纲会主导距离计算。
十一、MQL5 实现坑:距离度量与学习率
实现时两点最易错:一是距离度量要用标准化后的特征,且权重合理;二是学习率与插入频率要衰减,否则节点乱长、拓扑不稳。GNG 的「边年龄」超参也需调,太大拓扑松散、太小过度紧凑。
double Dist(const double &a[], const double &b[])
{
double s = 0;
for(int i=0; i<ArraySize(a); i++)
s += (a[i]-b[i])*(a[i]-b[i]); // 欧氏距离平方
return sqrt(s);
}