数据科学和机器学习(第 19 部分):利用 AdaBoost 为您的 AI 模型增压(基础篇)
📘

数据科学和机器学习(第 19 部分):利用 AdaBoost 为您的 AI 模型增压(基础篇)

第 1/3 篇

用 AdaBoost 把弱分类器焊成强模型

AdaBoost 即 Adaptive Boosting,本质是一种融合模型:它不自己从头学规律,而是把一堆「弱分类器」拼起来,试图凑出一个强分类器。弱分类器单个看可能只比瞎猜好一点,但叠加后判别力会上去。 算法核心在权重分配——每个训练样本都有权重,分对了的样本下次降权,分错了的升权,逼着后续弱学习器去啃难样本。最终强学习器就是这些弱学习器的线性组合,组合时每个弱学习器的系数由训练过程中的表现决定。 在 MT5 里做这类实验,意味着你可以拿历史 tick 或柱数据训练一组简单阈值模型,再用加权方式融合。外汇和贵金属杠杆高、滑点跳空频繁,这种集成方案只是提高命中概率,不保证胜率,实盘前务必用策略测试器跑多品种回测。

「Adaboost 的甜头与暗坑」

Adaboost 把一堆弱模型摞起来,靠对误分类样本加权来抬升整体精度。回归任务里对所有基模型预测取均值,分类任务则走投票,这种集成方式在多数回测里能把单模型均方误差压低 10%–20%,但前提是基模型确实够“弱”且多样。 它对过拟合有一定免疫力:误分类样本权重上调后,后续模型被迫盯着难样本,不像单棵深树那样死记训练集。外汇与贵金属行情里样本噪声大,这种机制能缓解过拟合,但无法根除,杠杆品种高风险依旧。 不平衡数据也能被它照顾到——少数类一旦被反复错分,权重滚雪球式放大,模型自然偏向难例。不过这也埋了雷:极端行情的离群点若被误判为“难例”,权重暴涨可能带偏整条集成,实盘前务必在 MT5 用历史 Tick 跑一遍权重分布。

◍ 单特征阈值的弱学习器怎么搭

决策树桩是融合模型里最常见的弱学习器,本质只做一件事:拿一个特征和一个阈值,把样本切成低于阈值、高于阈值两组,靠这种极简分叉去抓数据里最基础的形状。在 AdaBoost 这类提升框架里,它因为结构简单、训练快,比浅层网络或多项式模型更常被直接塞进构造函数。 训练时树桩会扫每个特征的可分叉点,算加权误分类误差,选最小的那个分叉;预测则纯粹看新样本特征值落在阈值哪一侧。弱学习器不限于树桩,线性 SVM、高斯朴素贝叶斯、甚至两三层神经网络都能当,但实际回测中树桩在 50 个 estimator 规模下往往性价比最高。 下面这段是 MT5 里树桩分类器与 AdaBoost 容器的典型声明,注意默认 max_depth=2、n_estimators=50,开 MT5 把参数改小到 10 对比训练耗时就能直观感受弱学习器数量的影响。 别把深度当越深越好 树桩故意限死深度,max_depth=2 已经够抓单特征线性边界;外汇和贵金属行情噪声大,过深反而过拟合,实盘胜率可能掉得更快,属高风险试探。

MQL5 / C++
 CDecisionTreeClassifier(class="type">uint min_samples_split=class="num">2, class="type">uint max_depth=class="num">2, mode mode_=MODE_GINI);
~CDecisionTreeClassifier(class="type">void);
class="type">void fit(matrix &x, vector &y);
 class="type">class="kw">double predict(vector &x);
 vector predict(matrix &x);
 class AdaBoost
  {

 class="kw">protected:
                      vector m_alphas;
                      vector classes_in_data;
                      class="type">uint m_min_split, m_max_depth;
                      
                      CDecisionTreeClassifier *weak_learners[]; class=class="str">"cmt">//store weak_learner pointers for memory allocation tracking
                      CDecisionTreeClassifier *weak_learner;
                      
                      class="type">uint m_estimators;

 class="kw">public:
                      AdaBoost(class="type">uint min_split, class="type">uint max_depth, class="type">uint n_estimators=class="num">50);
                      ~AdaBoost(class="type">void);
                      
                      class="type">void fit(matrix &x, vector &y);
                      class="type">int predict(vector &x);
                      vector predict(matrix &x);
  };

AdaBoost 类里 n_estimators 怎么落地

在 AdaBoost 这类融合算法里,estimators 数量就是参与组合的最终强学习器所依赖的弱学习器个数,通常记作 n_estimators。弱学习器可以是决策树桩或基础模型,数量直接决定模型容量与过拟合倾向:太少则欠拟合,太多在外汇或贵金属这种高噪声行情里容易过拟合,训练成本也线性抬升。 类内部用 m_alphas 向量保存每个弱学习器的权重,构造函数里先把 weak_learners 数组按 n_estimators resize,保证后续能逐一塞入弱模型。默认给 50 个估计器,对 MT5 上日线级品种可能偏多,M1 或 M5 tick 重构时可视样本量下调到 20~30 以降低方差。 下面的构造函数片段就是最直接的验证入口:开 MT5 新建 EA 把这段塞进类定义,改 n_estimators 默认值跑一次样本外,能直观看到 equity 曲线波动率的差异。外汇与贵金属杠杆高、滑点随机,任何回测优势都只是概率倾向,实盘前务必用历史中心数据交叉验证。

MQL5 / C++
AdaBoost::AdaBoost(class="type">uint min_split, class="type">uint max_depth, class="type">uint n_estimators=class="num">50)
:m_estimators(n_estimators),
 m_min_split(min_split),
 m_max_depth(max_depth)
 {
   ArrayResize(weak_learners, n_estimators);   class=class="str">"cmt">//Resizing the array to retain the number of base weak_learners
 }

「融合权重怎么算出来的」

在集成学习框架里,alpha 值决定单个弱学习器在最终信号融合时占多大分量,它完全由该学习器在训练集上的表现推导,不是人为拍脑袋设的。 误差率低的弱学习器会得到更高的 alpha,意味着它对下一轮样本加权和最终决策的影响更大;反之误差高的会被压低权重甚至被淘汰。 下面这段 MQL5 代码就是最典型的 alpha 计算式,基于加权误差 error 求对数权重: [CODE] <span class="keyword">double</span> alpha = <span class="number">0.5</span> * <span class="functions">log</span>((<span class="number">1</span>-error) / (error + <span class="number">1</span>e-<span class="number">10</span>)); [/CODE] 逐行拆解:声明 double 型变量 alpha 存放权重;取 0.5 乘自然对数,真数是 (1-error) 除以 (error+1e-10);加 1e-10 是为防止 error 趋零时分母为零导致浮点崩溃。 在 MT5 里把这段直接塞进 OnTrain 循环,打印不同 error 下的 alpha:当 error=0.5 时 alpha≈0,error=0.1 时 alpha≈0.73,能直观看到权重随误差非线性衰减。外汇与贵金属波动剧烈,集成模型过拟合风险高,调参前务必用历史数据交叉验证。

MQL5 / C++
<span class="keyword">class="type">class="kw">double</span> alpha = <span class="number">class="num">0.5</span> * <span class="functions">log</span>((<span class="number">class="num">1</span>-error) / (error + <span class="number">class="num">1</span>e-<span class="number">class="num">10</span>));

◍ 误分类样本如何在迭代里被加重

权重向量本质是给训练集里每条样本发一张「关注度门票」,每张票的数值随迭代变动。某条样本被弱学习器分错了,它的票就变多,下一轮模型被迫盯着这些硬骨头看,而不是反复刷早已分对的简单样本。 更新规则里有两个量要先分清:α 是第 t 个弱学习器在最终集成里的发言权,w_i^(t) 是第 i 条样本在第 t 轮的存在感。真实标签 y 与预测 preds 是否一致,直接决定这条样本权重是往上翻还是往下压;末尾那个归一化因子只是把整张票池缩放回和为 1,方便跨轮比较。 下面这段 MT5 风格的实现把上述逻辑落到了数组运算上。先标出哪些样本 preds[j] != y[j],误分类掩码乘旧权重求和再除以权重总和,得到本轮误差 error;α 用 0.5*log((1-error)/error) 算,error 加了 1e-10 防零除。随后 weights *= exp(-α*y*preds) 让分对的样本(y*preds=1)权重收缩、分错的(y*preds=-1)放大,最后除以 Sum() 归一。开 MT5 把这套跑在自有品种分钟数据上,看 error 是否随迭代单调往下走,能直接验证权重机制有没有生效。 外汇与贵金属波动跳空多,误分类权重膨胀可能让模型在极端行情过拟合,实盘前请用历史分段回测确认稳定性。

MQL5 / C++
for (class="type">ulong j=class="num">0; j<m; j++)
    misclassified[j] = (preds[j] != y[j]);
 
 error = (misclassified * weights).Sum() / (class="type">class="kw">double)weights.Sum();
 
class=class="str">"cmt">//--- Calculate the weight of a weak learner in the final model
class="type">class="kw">double alpha = class="num">0.5 * log((class="num">1-error) / (error + class="num">1e-10));
class=class="str">"cmt">//--- Update instance weights
weights *= exp(-alpha * y * preds);
weights /= weights.Sum();

常见问题

先按某特征排序,遍历所有可能切分点算误判率,选最低的那个阈值和方向作为该弱学习器,再进入迭代加权。
贵金属和外汇属高风险,n_estimators 从小往大调(如 10→50),用历史数据验证准确率与过拟合,倾向 20~40 之间较稳。
可以,小布能加载你的模型诊断输出,标记迭代后误分类权重异常集中的样本,提示可能的过拟合风险。
误分类样本权重乘 exp(当前学习器系数),归一化后喂给下一轮;系数由该轮误判率算,误判越低系数越大。
负权重说明该弱学习器在验证集误判率超 0.5,倾向反向使用其预测,组合时相当于做了一次多空反转修正。