English Deutsch
preview
データサイエンスと機械学習(第19回):AdaBoostでAIモデルをパワーアップ

データサイエンスと機械学習(第19回):AdaBoostでAIモデルをパワーアップ

MetaTrader 5トレーディング | 23 4月 2024, 17:01
86 0
Omega J Msigwa
Omega J Msigwa

AdaBoostについて

AdaBoostとは、Adaptive Boostingの略で、弱い分類器から強い分類器を構築しようとするアンサンブル機械学習モデルです。

仕組み

  • アルゴリズムは、分類の正誤に基づいてインスタンスに重みを割り当てます。
  • 加重和を使用して弱い学習機を組み合わせます。
  • 最終的な強い学習機は、学習過程で決定された重みを持つ弱い学習機の線形結合です。

mql5のAdaBoost


AdaBoostを使用する理由

AdaBoostには、以下のような利点があります。

  • 精度の向上:ブースティングは、いくつかの弱いモデルの予測を組み合わせることで、モデルの全体的な精度を向上させることができます。回帰の場合はすべてのモデルによっておこなわれた予測を平均化し、分類の場合は最終モデルの精度を向上させるためにそれらを投票します。 
  • 過剰適合に対する頑健性:ブースティングは、誤分類された入力に重みを割り当てることで、過剰適合のリスクを減らすことができます。
  • 不均衡なデータへのより良い対応:ブースティングは、誤分類されたデータポイントに焦点を当てることで、不均衡なデータを処理することができます。
  • より良い解釈可能性:ブースティングは、モデルの決定プロセスを複数のプロセスに分割することで、モデルの解釈可能性を高めることができます。 


決定株とは

決定株は、AdaBoostのようなアンサンブル手法の弱い学習機として使用される単純な機械学習モデルです。これは基本的に、単一の特徴と閾値に基づいて決定を下すように単純化された機械学習モデルです。弱い学習機として決定株を使用する目的は、アンサンブルモデル全体の改善に貢献できるデータの基本的なパターンを捉えることです。

以下、決定木分類器を例に、決定株の理論を簡単に説明します。

1.構造

-決定株は、1つの特徴と閾値に基づいて 二分決定をおこないます。

-特徴量が閾値を下回るグループと、閾値を上回るグループに分けます。

-これはこのライブラリのほとんどの分類器のコンストラクタに共通して導入されています。

 CDecisionTreeClassifier(uint min_samples_split=2, uint max_depth=2, mode mode_=MODE_GINI);
~CDecisionTreeClassifier(void);

2.訓練

-訓練中、決定株は、ある基準(多くの場合、重み付き誤分類誤差)を最小化する特徴と閾値を特定します。

-可能性のある分割ごとに誤分類誤差が計算され、最も誤差の少ないものが選択されます。

-すべての訓練はfit関数でおこなわれます。

void fit(matrix &x, vector &y);

3.予想

-予測では、データ点はその特徴値が選択された閾値を上回るか下回るかに基づいて分類されます。

double predict(vector &x);
vector predict(matrix &x);

AdaBoostのようなアンサンブル手法でよく使用される弱い学習機には、以下のようなものがあります。


1. 決定株/決定木

-上述したように、決定株や浅い決定木は、その単純さから一般的に使用されています。

2.線形モデル

-ロジスティック回帰や線形SVMのような線形モデルは、弱い学習機として使用することができます。

3.多項式モデル

-高次の多項式モデルはより複雑な関係を捉えることができ、低次の多項式を用いれば弱い学習機として機能します。

4.ニューラルネットワーク(浅い)

-層とニューロンの数が少ない浅いニューラルネットワークが使用されることもあります。

5.ガウスモデル

-ガウス単純ベイズなどのガウスモデルは、弱い学習機として採用することができます。

弱い学習機の選択は、データの特定の特性と手元の問題に依存します。実際には、ブースティングアルゴリズムがシンプルで効率的であることから、決定株がよく使用されています。AdaBoostのアンサンブルアプローチは、これらの弱い学習機の予測を組み合わせることで、パフォーマンスを向上させます。

決定株はモデルなので、AdaBoostクラスのコンストラクタに弱いモデルパラメータの引数を与える必要があります。

class AdaBoost
  {
  
protected:
                     vector m_alphas;
                     vector classes_in_data;
                     uint m_min_split, m_max_depth;
                     
                     CDecisionTreeClassifier *weak_learners[]; //store weak_learner pointers for memory allocation tracking
                     CDecisionTreeClassifier *weak_learner;
                     
                     uint m_estimators;
                     
public:
                     AdaBoost(uint min_split, uint max_depth, uint n_estimators=50);
                    ~AdaBoost(void);
                    
                    void fit(matrix &x, vector &y);
                    int predict(vector &x);
                    vector predict(matrix &x);
  };

この例では決定木を使用していますが、あらゆる分類機械学習モデルを導入することができます。


AdaBoostクラスの構築

推定器の数とは、アンサンブル学習アルゴリズムにおいて、最終的な強い学習機を作成するために結合される弱い学習機(基本モデルまたは決定株)の数を指します。AdaBoostや勾配ブースティングのようなアルゴリズムでは、このパラメータはしばしばn_estimatorsと表記されます。

AdaBoost::AdaBoost(uint min_split, uint max_depth, uint n_estimators=50)
:m_estimators(n_estimators),
 m_min_split(min_split),
 m_max_depth(max_depth)
 {
   ArrayResize(weak_learners, n_estimators);   //Resizing the array to retain the number of base weak_learners
 }

クラスのprotectedセクションから、ベクトルm_alphasを見ましたが、この記事では重みという用語も何度か聞いてきました。以下に説明します。


アルファ値

アルファ値は、アンサンブル内の各弱学習機に割り当てられた貢献度または重みを表し、これらの値は訓練中の各弱学習機のパフォーマンスに基づいて計算されます。

アルファ値が高い学習機は、学習ミスを減らすのに有効な弱い学習機に割り当てられます。

アルファ値の計算式は、しばしば次のように示されます。

アルファ式AdaBoost

ここで

t番目の弱い学習機の重み付き誤差です。

実装

double alpha = 0.5 * log((1-error) / (error + 1e-10));


重み

重みベクトルは、各反復における各訓練インスタンスの重要度を表します。

訓練中、誤分類されたインスタンスの重みは、次の反復で分類が困難な事例に焦点を当てるために増やされます。

インスタンスの重みを更新する式は、しばしば次のように与えられます。

重みAdaBoost

:反復におけるインスタンスiの重み 

t番目の弱い学習機に割り当てられた重み

:インスタンスの真のラベル 

:インスタンスのt番目の弱い学習機 

:重みの合計が1になるようにするための正規化係数

実装

 for (ulong j=0; j<m; j++)
    misclassified[j] = (preds[j] != y[j]);
 
 error = (misclassified * weights).Sum() / (double)weights.Sum();
 
//--- Calculate the weight of a weak learner in the final model

double alpha = 0.5 * log((1-error) / (error + 1e-10));

//--- Update instance weights

weights *= exp(-alpha * y * preds);
weights /= weights.Sum();


AdaBoostモデルの訓練

他のアンサンブル手法と同様に、n個のモデル(以下の関数ではm_estimatorsと呼ば)れるを使用して同じデータを予測し、多数決や他の手法で最良の結果を決定することができます。

void AdaBoost::fit(matrix &x,vector &y)
 {
   m_alphas.Resize(m_estimators);  
   classes_in_data = MatrixExtend::Unique(y); //Find the target variables in the class
      
   ulong m = x.Rows(), n = x.Cols();
   vector weights(m); weights = weights.Fill(1.0) / m; //Initialize instance weights
   vector preds(m);
   vector misclassified(m);
   

   double error = 0;
   
   for (uint i=0; i<m_estimators; i++)
    {      

//---
      
      weak_learner = new CDecisionTreeClassifier(this.m_min_split, m_max_depth);             
              
      weak_learner.fit(x, y); //fiting the randomized data to the i-th weak_learner
      preds = weak_learner.predict(x); //making predictions for the i-th weak_learner
      
             
       for (ulong j=0; j<m; j++)
          misclassified[j] = (preds[j] != y[j]);
       
       error = (misclassified * weights).Sum() / (double)weights.Sum();
       
      //--- Calculate the weight of a weak learner in the final weak_learner
      
      double alpha = 0.5 * log((1-error) / (error + 1e-10));
      
      //--- Update instance weights
      
      weights *= exp(-alpha * y* preds);
      weights /= weights.Sum();
      
      //--- save a weak learner and its weight
      
      this.m_alphas[i] = alpha;
      this.weak_learners[i] = weak_learner;
    }
 }

他のアンサンブル手法と同じように、ブートストラップも重要です。ブートストラッピングをおこなわないと、すべてのモデルとデータが単純に同じになってしまい、すべてのモデルのパフォーマンスが互いに区別できなくなってしまう可能性があるため、ブートストラッピングを導入する必要があります。

void AdaBoost::fit(matrix &x,vector &y)
 {
   m_alphas.Resize(m_estimators);  
   classes_in_data = MatrixExtend::Unique(y); //Find the target variables in the class
      
   ulong m = x.Rows(), n = x.Cols();
   vector weights(m); weights = weights.Fill(1.0) / m; //Initialize instance weights
   vector preds(m);
   vector misclassified(m);
   
//---

   matrix data = MatrixExtend::concatenate(x, y);
   matrix temp_data;
   
   matrix x_subset;
   vector y_subset;

   double error = 0;
   
   for (uint i=0; i<m_estimators; i++)
    {      
      
      temp_data = data;
      MatrixExtend::Randomize(temp_data, this.m_random_state, this.m_boostrapping);
      
       if (!MatrixExtend::XandYSplitMatrices(temp_data, x_subset, y_subset)) //Get randomized subsets
         {  
            ArrayRemove(weak_learners,i,1); //Delete the invalid weak_learner
            printf("%s %d Failed to split data",__FUNCTION__,__LINE__);
            continue;
         }

//---
      
      weak_learner = new CDecisionTreeClassifier(this.m_min_split, m_max_depth);             
              
      weak_learner.fit(x_subset, y_subset); //fiting the randomized data to the i-th weak_learner
      preds = weak_learner.predict(x_subset); //making predictions for the i-th weak_learner
      
      //printf("[%d] Accuracy %.3f ",i,Metrics::accuracy_score(y_subset, preds));
             
       for (ulong j=0; j<m; j++)
          misclassified[j] = (preds[j] != y_subset[j]);
       
       error = (misclassified * weights).Sum() / (double)weights.Sum();
       
      //--- Calculate the weight of a weak learner in the final weak_learner
      
      double alpha = 0.5 * log((1-error) / (error + 1e-10));
      
      //--- Update instance weights
      
      weights *= exp(-alpha * y_subset * preds);
      weights /= weights.Sum();
      
      //--- save a weak learner and its weight
      
      this.m_alphas[i] = alpha;
      this.weak_learners[i] = weak_learner;
    }
 }
クラスのコンストラクタも変更しなければなりませんでした。
class AdaBoost
  {
  
protected:
                     vector m_alphas;
                     vector classes_in_data;
                     int m_random_state;
                     bool m_boostrapping;
                     uint m_min_split, m_max_depth;
                     
                     CDecisionTreeClassifier *weak_learners[]; //store weak_learner pointers for memory allocation tracking
                     CDecisionTreeClassifier *weak_learner;
                     
                     uint m_estimators;
                     
public:
                     AdaBoost(uint min_split, uint max_depth, uint n_estimators=50, int random_state=42, bool bootstrapping=true);
                    ~AdaBoost(void);
                    
                    void fit(matrix &x, vector &y);
                    int predict(vector &x);
                    vector predict(matrix &x);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
AdaBoost::AdaBoost(uint min_split, uint max_depth, uint n_estimators=50, int random_state=42, bool bootstrapping=true)
:m_estimators(n_estimators),
 m_random_state(random_state),
 m_boostrapping(bootstrapping),
 m_min_split(min_split),
 m_max_depth(max_depth)
 {
   ArrayResize(weak_learners, n_estimators);   //Resizing the array to retain the number of base weak_learners
 }

多数派の予測を得る

学習された重みを使用して、AdaBoost分類器は最大得票数のクラスを決定します。これは、他のものよりも出現する可能性が高いことを意味します。

int AdaBoost::predict(vector &x)
 {
   // Combine weak learners using weighted sum   
   
   vector weak_preds(m_estimators), 
          final_preds(m_estimators);
          
   for (uint i=0; i<this.m_estimators; i++)
     weak_preds[i] = this.weak_learners[i].predict(x);
  
  return (int)weak_preds[(this.m_alphas*weak_preds).ArgMax()]; //Majority decision class
 }

このモデルをEAの中でどのように使用するかを見てみましょう。

#include <MALE5\Ensemble\AdaBoost.mqh>

DecisionTree::AdaBoost *ada_boost_tree;
LogisticRegression::AdaBoost *ada_boost_logit;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
  
   string headers;
   matrix data = MatrixExtend::ReadCsv("iris.csv",headers);
   
   matrix x; vector y;
   MatrixExtend::XandYSplitMatrices(data,x,y);
   
   ada_boost_tree = new DecisionTree::AdaBoost(2,1,10,42);
   ada_boost_tree.fit(x,y);
   
   vector predictions = ada_boost_tree.predict(x);
   
   printf("Adaboost acc = %.3f",Metrics::accuracy_score(y, predictions));
 
//---
   return(INIT_SUCCEEDED);
  }

モデル構築とデバッグのためだけにiris.csvデータセットを使用したところ、次のようになりました。

2024.01.17 17:52:27.914 AdaBoost Test (EURUSD,H1)       Adaboost acc = 0.960

モデルはこれまでのところうまくいっているようで、精度値は約90%です。random_stateを-1に設定すると、EAが実行されるたびにGetTickCountがランダムシードとして使用され、よりランダムな環境でモデルを評価できるようになります。

QK      0       17:52:27.914    AdaBoost Test (EURUSD,H1)       Adaboost acc = 0.960
LL      0       17:52:35.436    AdaBoost Test (EURUSD,H1)       Adaboost acc = 0.947
JD      0       17:52:42.806    AdaBoost Test (EURUSD,H1)       Adaboost acc = 0.960
IL      0       17:52:50.071    AdaBoost Test (EURUSD,H1)       Adaboost acc = 0.933
MD      0       17:52:57.822    AdaBoost Test (EURUSD,H1)       Adaboost acc = 0.967

私たちのライブラリに存在する他の弱学習機についても、同じコーディングパターンと構造に従うことができます。ロジスティック回帰が弱学習機としていつ使用されたかを見てください。

クラス全体における唯一の違いは、fit関数の下で弱学習機として導入されたモデルのタイプがロジスティック回帰であることです。

void AdaBoost::fit(matrix &x,vector &y)
 {
   m_alphas.Resize(m_estimators);  
   classes_in_data = MatrixExtend::Unique(y); //Find the target variables in the class
      
   ulong m = x.Rows(), n = x.Cols();
   vector weights(m); weights = weights.Fill(1.0) / m; //Initialize instance weights
   vector preds(m);
   vector misclassified(m);
   
//---

   matrix data = MatrixExtend::concatenate(x, y);
   matrix temp_data;
   
   matrix x_subset;
   vector y_subset;

   double error = 0;
   
   for (uint i=0; i<m_estimators; i++)
    {      
      
      temp_data = data;
      MatrixExtend::Randomize(temp_data, this.m_random_state, this.m_boostrapping);
      
       if (!MatrixExtend::XandYSplitMatrices(temp_data, x_subset, y_subset)) //Get randomized subsets
         {  
            ArrayRemove(weak_learners,i,1); //Delete the invalid weak_learner
            printf("%s %d Failed to split data",__FUNCTION__,__LINE__);
            continue;
         }

//---
      
      weak_learner = new CLogisticRegression();             
              
      weak_learner.fit(x_subset, y_subset); //fiting the randomized data to the i-th weak_learner
      preds = weak_learner.predict(x_subset); //making predictions for the i-th weak_learner
             
       for (ulong j=0; j<m; j++)
          misclassified[j] = (preds[j] != y_subset[j]);
       
       error = (misclassified * weights).Sum() / (double)weights.Sum();
       
      //--- Calculate the weight of a weak learner in the final weak_learner
      
      double alpha = 0.5 * log((1-error) / (error + 1e-10));
      
      //--- Update instance weights
      
      weights *= exp(-alpha * y_subset * preds);
      weights /= weights.Sum();
      
      //--- save a weak learner and its weight
      
      this.m_alphas[i] = alpha;
      this.weak_learners[i] = weak_learner;
    }
 }


ストラテジーテスターにおけるAdaBoostAIモデル

ボリンジャーバンドの指標を始値に適用することで、次の終値が強気弱気、またはそのいずれでもない(HOLD)ローソク足を予測できるようにモデルを学習させようとしています。

訓練データを収集するコードから始めて、取引環境でモデルをテストするエキスパートアドバイザー(EA)を構築してみましょう。

訓練データの収集

//--- Data Collection for training the model

//--- x variables Bollinger band only
   
   matrix dataset;
   
   indicator_v.CopyIndicatorBuffer(bb_handle,0,0,train_bars); //Main LINE
   dataset = MatrixExtend::concatenate(dataset, indicator_v);
   
   indicator_v.CopyIndicatorBuffer(bb_handle,1,0,train_bars); //UPPER BB
   dataset = MatrixExtend::concatenate(dataset, indicator_v);
   
   indicator_v.CopyIndicatorBuffer(bb_handle,2,0,train_bars); //LOWER BB
   dataset = MatrixExtend::concatenate(dataset, indicator_v);
   
//--- Target Variable
   
   int size = CopyRates(Symbol(),PERIOD_CURRENT,0,train_bars,rates);
   vector y(size);
   
   switch(model)
     {
      case  DECISION_TREE:
         {
            for (ulong i=0; i<y.Size(); i++)
              {
                 if (rates[i].close > rates[i].open)
                   y[i] = 1; //buy signal
                 else if (rates[i].close < rates[i].open)
                   y[i] = 2; //sell signal 
                 else
                   y[i] = 0; //Hold signal
              }
         }
        break;
      case LOGISTIC_REGRESSION:
            for (ulong i=0; i<indicator_v.Size(); i++)
              {
                 y[i] = (rates[i].close > rates[i].open); //if close > open buy else sell
              }
        break;
     }
   
   dataset = MatrixExtend::concatenate(dataset, y); //Add the target variable to the dataset
   
   if (MQLInfoInteger(MQL_DEBUG))
    {
       Print("Data Head");
       MatrixExtend::PrintShort(dataset);
    }

目標変数の作り方が変わっていることにお気づきでしょうか。決定木は汎用性があり、対象変数の複数のクラスをうまく扱うことができるため、市場の3つのパターンである買い売りHOLDを分類する能力があります。0と1の2つのクラスをうまく分類するシグモイド関数を中核とするロジスティック回帰モデルとは異なり、最適なのは、目標変数の条件を買い売りかのいずれかに準備することです。

訓練されたモデルの訓練とテスト

部屋の中の象 

MatrixExtend::TrainTestSplitMatrices(dataset,train_x,train_y,test_x,test_y,0.7,_random_state); 

この関数は、シャッフルのためにランダムな状態で、データの70%をテスト標本に、残りの30%をテスト用に、データを訓練標本とテスト標本に分割します。

しかし、新しく収集したデータを使用する前に、正規化はモデルのパフォーマンスにとって非常に重要です。

//--- Training and testing the trained model
   
   matrix train_x, test_x;
   vector train_y, test_y;
   
   MatrixExtend::TrainTestSplitMatrices(dataset,train_x,train_y,test_x,test_y,0.7,_random_state); //Train test split data | This function splits the data into training and testing sample given a random state and 70% of data to test while the rest 30% for testing
   
   train_x = scaler.fit_transform(train_x); //Standardize the training data
   test_x = scaler.transform(test_x); //Do the same for the test data
   
   Print("-----> ",EnumToString(model));
   
   vector preds;
   switch(model)
     {
      case  DECISION_TREE:
         ada_boost_tree = new DecisionTree::AdaBoost(tree_min_split, tree_max_depth, _n_estimators, -1, _bootstrapping);  //Building the 
        
        //--- Training 
         
         ada_boost_tree.fit(train_x, train_y);
        
         preds = ada_boost_tree.predict(train_x);
         printf("Train Accuracy %.3f",Metrics::accuracy_score(train_y, preds));
         
        //--- Testing
        
         preds = ada_boost_tree.predict(test_x);
         printf("Test Accuracy %.3f",Metrics::accuracy_score(test_y, preds));
         
        break;
      case LOGISTIC_REGRESSION:
         ada_boost_logit = new LogisticRegression::AdaBoost(_n_estimators,-1, _bootstrapping);
         
        //--- Training 
        
         ada_boost_logit.fit(train_x, train_y);
        
         preds = ada_boost_logit.predict(train_x);
         printf("Train Accuracy %.3f",Metrics::accuracy_score(train_y, preds));
         
        //--- Testing
        
         preds = ada_boost_logit.predict(test_x);
         printf("Test Accuracy %.3f",Metrics::accuracy_score(test_y, preds));
         
        break;
     }

出力

PO      0       22:59:11.807    AdaBoost Test (EURUSD,H1)       -----> DECISION_TREE
CI      0       22:59:20.204    AdaBoost Test (EURUSD,H1)       Building Estimator [1/10] Accuracy Score 0.561
OD      0       22:59:27.883    AdaBoost Test (EURUSD,H1)       Building Estimator [2/10] Accuracy Score 0.601
NP      0       22:59:38.316    AdaBoost Test (EURUSD,H1)       Building Estimator [3/10] Accuracy Score 0.541
LO      0       22:59:48.327    AdaBoost Test (EURUSD,H1)       Building Estimator [4/10] Accuracy Score 0.549
LK      0       22:59:56.813    AdaBoost Test (EURUSD,H1)       Building Estimator [5/10] Accuracy Score 0.570
OF      0       23:00:09.552    AdaBoost Test (EURUSD,H1)       Building Estimator [6/10] Accuracy Score 0.517
GR      0       23:00:18.322    AdaBoost Test (EURUSD,H1)       Building Estimator [7/10] Accuracy Score 0.571
GI      0       23:00:29.254    AdaBoost Test (EURUSD,H1)       Building Estimator [8/10] Accuracy Score 0.556
HE      0       23:00:37.632    AdaBoost Test (EURUSD,H1)       Building Estimator [9/10] Accuracy Score 0.599
DS      0       23:00:47.522    AdaBoost Test (EURUSD,H1)       Building Estimator [10/10] Accuracy Score 0.567
OP      0       23:00:47.524    AdaBoost Test (EURUSD,H1)       Train Accuracy 0.590
OG      0       23:00:47.525    AdaBoost Test (EURUSD,H1)       Test Accuracy 0.513
MK      0       23:24:06.573    AdaBoost Test (EURUSD,H1)       Building Estimator [1/10] Accuracy Score 0.491
HK      0       23:24:06.575    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.43700
QO      0       23:24:06.575    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.43432
KP      0       23:24:06.576    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.43168
MD      0       23:24:06.577    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.42909
FI      0       23:24:06.578    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.42652
QJ      0       23:24:06.579    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.42400
IN      0       23:24:06.580    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.42151
NS      0       23:24:06.581    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.41906
GD      0       23:24:06.582    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.41664
DK      0       23:24:06.582    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.41425
IQ      0       23:24:06.585    AdaBoost Test (EURUSD,H1)       Building Estimator [2/10] Accuracy Score 0.477
JP      0       23:24:06.586    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.43700
DE      0       23:24:06.587    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.43432
RF      0       23:24:06.588    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.43168
KJ      0       23:24:06.588    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.42909
FO      0       23:24:06.589    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.42652
NP      0       23:24:06.590    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.42400
CD      0       23:24:06.591    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.42151
KI      0       23:24:06.591    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.41906
NM      0       23:24:06.592    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.41664
EM      0       23:24:06.592    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.41425
EO      0       23:24:06.593    AdaBoost Test (EURUSD,H1)       Building Estimator [3/10] Accuracy Score 0.477
KF      0       23:24:06.594    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.41931
HK      0       23:24:06.594    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.41690
RL      0       23:24:06.595    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.41452
IP      0       23:24:06.596    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.41217
KE      0       23:24:06.596    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.40985
DI      0       23:24:06.597    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.40757
IJ      0       23:24:06.597    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.40533
MO      0       23:24:06.598    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.40311
PS      0       23:24:06.599    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.40093
CG      0       23:24:06.600    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.39877
NE      0       23:24:06.601    AdaBoost Test (EURUSD,H1)       Building Estimator [4/10] Accuracy Score 0.499
EL      0       23:24:06.602    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.41931
MQ      0       23:24:06.603    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.41690
PE      0       23:24:06.603    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.41452
OF      0       23:24:06.604    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.41217
JK      0       23:24:06.605    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.40985
KO      0       23:24:06.606    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.40757
FP      0       23:24:06.606    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.40533
PE      0       23:24:06.607    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.40311
CI      0       23:24:06.608    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.40093
NI      0       23:24:06.609    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.39877
KS      0       23:24:06.610    AdaBoost Test (EURUSD,H1)       Building Estimator [5/10] Accuracy Score 0.499
QR      0       23:24:06.611    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.42037
MG      0       23:24:06.611    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.41794
LK      0       23:24:06.612    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.41555
ML      0       23:24:06.613    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.41318
PQ      0       23:24:06.614    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.41085
FE      0       23:24:06.614    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.40856
FF      0       23:24:06.615    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.40630
FJ      0       23:24:06.616    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.40407
KO      0       23:24:06.617    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.40187
NS      0       23:24:06.618    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.39970
EH      0       23:24:06.619    AdaBoost Test (EURUSD,H1)       Building Estimator [6/10] Accuracy Score 0.497
FH      0       23:24:06.620    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.41565
LM      0       23:24:06.621    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.41329
IQ      0       23:24:06.622    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.41096
KR      0       23:24:06.622    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.40867
LF      0       23:24:06.623    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.40640
NK      0       23:24:06.624    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.40417
OL      0       23:24:06.625    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.40197
RP      0       23:24:06.627    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.39980
OE      0       23:24:06.628    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.39767
EE      0       23:24:06.628    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.39556
QF      0       23:24:06.629    AdaBoost Test (EURUSD,H1)       Building Estimator [7/10] Accuracy Score 0.503
CN      0       23:24:06.630    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.41565
IR      0       23:24:06.631    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.41329
HG      0       23:24:06.632    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.41096
RH      0       23:24:06.632    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.40867
ML      0       23:24:06.633    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.40640
FQ      0       23:24:06.633    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.40417
QR      0       23:24:06.634    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.40197
NF      0       23:24:06.634    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.39980
EK      0       23:24:06.635    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.39767
CL      0       23:24:06.635    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.39556
LL      0       23:24:06.636    AdaBoost Test (EURUSD,H1)       Building Estimator [8/10] Accuracy Score 0.503
HD      0       23:24:06.637    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.44403
IH      0       23:24:06.638    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.44125
CM      0       23:24:06.638    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.43851
DN      0       23:24:06.639    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.43580
DR      0       23:24:06.639    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.43314
CG      0       23:24:06.640    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.43051
EK      0       23:24:06.640    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.42792
JL      0       23:24:06.641    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.42537
EQ      0       23:24:06.641    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.42285
OF      0       23:24:06.642    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.42037
GJ      0       23:24:06.642    AdaBoost Test (EURUSD,H1)       Building Estimator [9/10] Accuracy Score 0.469
GJ      0       23:24:06.643    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [1/10] mse 0.44403
ON      0       23:24:06.643    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [2/10] mse 0.44125
LS      0       23:24:06.644    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [3/10] mse 0.43851
HG      0       23:24:06.644    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [4/10] mse 0.43580
KH      0       23:24:06.645    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [5/10] mse 0.43314
FM      0       23:24:06.645    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [6/10] mse 0.43051
IQ      0       23:24:06.646    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [7/10] mse 0.42792
QR      0       23:24:06.646    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [8/10] mse 0.42537
IG      0       23:24:06.647    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [9/10] mse 0.42285
RH      0       23:24:06.647    AdaBoost Test (EURUSD,H1)       ---> Logistic regression build epoch [10/10] mse 0.42037
KS      0       23:24:06.648    AdaBoost Test (EURUSD,H1)       Building Estimator [10/10] Accuracy Score 0.469
NP      0       23:24:06.652    AdaBoost Test (EURUSD,H1)       Train Accuracy 0.491
GG      0       23:24:06.654    AdaBoost Test (EURUSD,H1)       Test Accuracy 0.447

ここまでは順調です。それでは、取引を実行できるコード行でEAを完成させましょう。

取引シグナルの取得

void OnTick()
  {
//--- x variables Bollinger band only | The current buffer only this time

   indicator_v.CopyIndicatorBuffer(bb_handle,0,0,1); //Main LINE
   x_inputs[0] = indicator_v[0];
   indicator_v.CopyIndicatorBuffer(bb_handle,1,0,1); //UPPER BB
   x_inputs[1] = indicator_v[0];
   indicator_v.CopyIndicatorBuffer(bb_handle,2,0,1); //LOWER BB
   x_inputs[2] = indicator_v[0];
   
//---
   
   int signal = INT_MAX;
   switch(model)
     {
      case  DECISION_TREE:
        x_inputs = scaler.transform(x_inputs); //New inputs data must be normalized the same way
        signal = ada_boost_tree.predict(x_inputs);   
        break;
      case LOGISTIC_REGRESSION:
         x_inputs = scaler.transform(x_inputs); //New inputs data must be normalized the same way
         signal = ada_boost_logit.predict(x_inputs);
        break;
     }
  }

1決定木買いシグナル0ロジスティック回帰買いシグナルを示します。2決定木の売りシグナル1ロジスティック回帰売りシグナルを示します。決定木のホールドを表す0シグナルについては気にしません。  これらのシグナルを、それぞれ買いシグナルを0、売りシグナルを1と識別するように統一しましょう。

case  DECISION_TREE:
  
  x_inputs = scaler.transform(x_inputs); //New inputs data must be normalized the same way
  signal = ada_boost_tree.predict(x_inputs);   
  
   if (signal == 1) //buy signal for decision tree
     signal = 0;
   else if (signal == 2)
     signal = 1;
   else
     signal = INT_MAX; //UNKNOWN NUMBER FOR HOLD
  break;

モデルから作られたシンプルな戦略

 SymbolInfoTick(Symbol(), ticks);
 
 if (isnewBar(PERIOD_CURRENT))
  {        
   if (signal == 0) //buy signal
     {
        if (!PosExists(MAGIC_NUMBER, POSITION_TYPE_BUY)) 
          m_trade.Buy(lot_size, Symbol(), ticks.ask, ticks.ask-stop_loss*Point(), ticks.ask+take_profit*Point());
     }
     
   if (signal == 1)
     {
       if (!PosExists(MAGIC_NUMBER, POSITION_TYPE_SELL)) 
         m_trade.Sell(lot_size, Symbol(), ticks.bid, ticks.bid+stop_loss*Point(), ticks.bid-take_profit*Point());
     }
  }

ストラテジーテスターの結果|2020年1月~2023年2月|時間枠1時間:

決定木AdaBoost:

決定木AdaBoost

ロジスティック回帰AdaBoost:

ロジスティック回帰AdaBoost1時間tf

1H時間枠でのパフォーマンスはどちらも良好とは程遠いものです。その主な理由は、戦略が現在のバーに基づいているということです。私の経験では、この種の戦略は、1日に24本発生する小さなバーとは異なり、1本のバーが重要な動きを表すため、より長い時間枠によく適しています。12H時間枠を試してみましょう。

train_bars1000から100に減らした以外は、すべてのパラメータを同じにしました。より長い時間枠には、過去の価格履歴をリクエストするためのバーがあまりないためです。

決定木AdaBoost:

決定木AdaBoost

ロジスティック回帰AdaBoost:

ロジスティック回帰AdaBoost12H TF


結論

本連載で取り上げたAIモデルのパフォーマンスを大幅に向上させることができる強力なアルゴリズムとして、AdaBoostが登場しました。計算コストがかかるとはいえ、慎重に実施すれば投資に見合うだけの価値はあります。AdaBoostは、金融、エンターテインメント、教育など、さまざまな分野や産業で応用されています。

探索を終えるにあたり、このアルゴリズムの多用途性と、弱い学習機の総合力を活用することで複雑な分類の課題に対処できる能力を認めることが不可欠です。以下の「よくある質問(FAQ)」は、AdaBoostの使用中に発生する可能性のある一般的な質問について、わかりやすく説明することを目的としています。


AdaBoostに関するよくある質問(FAQ)


質問:AdaBoostはどのように機能するのですか?

回答:AdaBoostは、弱い学習機(通常は決定株のような単純なモデル)をデータセットで繰り返し訓練し、各反復で誤分類されたインスタンスの重みを調整することで機能します。最終的なモデルは、弱い学習機の重み付き総和であり、より正確な学習機ほど高い重みが与えられます。


質問:AdaBoostの弱い学習機とは?

回答:弱い学習機は、ランダムな偶然よりもわずかに良い結果を出す単純なモデルです。決定株(浅い決定木)は、AdaBoostの弱い学習機としてよく使用されますが、他のアルゴリズムでもこの目的を果たすことができます。


質問:AdaBoostにおけるインスタンスの重みの役割は何ですか?

回答:AdaBoostでのインスタンスの重みは、学習プロセスにおける各訓練インスタンスの重要度を制御します。最初はすべての重みが等しく設定され、各反復で調整され、誤分類されたインスタンスにより焦点を当て、モデルの汎化能力を向上させます。


質問:AdaBoostは弱い学習機による誤差をどのように処理しますか?

回答:AdaBoostは、誤分類されたインスタンスにより高い重みを割り当てるため、後続の弱い学習機は、これらの誤差を修正することに集中せざるを得なくなります。最終的なモデルは、誤差率の低い弱い学習機をより重視します。


質問:AdaBoostはノイズや外れ値に敏感ですか?

回答:AdaBoostは誤分類を修正しようとするため、ノイズや外れ値の影響を受けやすいです。外れ値はより高い重み付けを受け、最終モデルに影響を与えるかもしれません。この感度を緩和するために、頑健な弱学習機やデータの前処理技術を適用することができます。


質問:AdaBoostは過剰適合に悩まされるのか?

回答:AdaBoostは、弱い学習機が複雑すぎたり、データセットにノイズが含まれていたりすると、過剰適合を起こしやすいです。より単純な弱い学習機を使い、交差検証のようなテクニックを適用することで、過剰適合を防ぐことができます。


質問:AdaBoostは回帰問題に使用できますか?

回答:AdaBoostは主に分類タスクのために設計されていますが、連続値を予測するようにアルゴリズムを修正することで、回帰に適応させることができます。回帰問題にはAdaBoost.R2のようなテクニックがあります。


質問:AdaBoostに代わるものはありますか?

回答:はい。ランダムフォレスト勾配ブースティングXGBoostなどのアンサンブル学習法があります。各手法には長所と短所があり、その選択はデータの具体的な特性と手元の問題によって決まります。


質問:AdaBoostはどのような場面で特に効果的ですか?

回答:AdaBoostは、様々な弱い学習機を扱うときや、頑健なモデルを作成するために複数の分類器を組み合わせる必要があるシナリオで効果的です。顔検出、テキスト分類、その他の実世界でのアプリケーションでよく使用されます。


このアルゴリズムやその他多くのアルゴリズムの開発進捗状況やバグ修正の最新情報は、GitHubリポジトリ(https://github.com/MegaJoctan/MALE5)をご覧ください。


平和を祈ります。

添付ファイル:

ファイル 説明|使用
AdaBoost.mqh ロジスティック回帰と決定木の両方のAdaBoost名前空間クラス
Logistic Regression .mqh 主なロジスティック回帰クラス
MatrixExtend.mqh 行列操作関数
metrics.mqh 機械学習モデルのパフォーマンスを測定するコードを含むライブラリ
preprocessing.mqh データを機械学習に適するように前処理する関数を含むクラス
tree.mqh 決定木ライブラリ
AdaBoostTest.mq5(EA) メインテストEA(ここで説明したすべてのコードは、このファイルの中で実行される)

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/14034

添付されたファイル |
データサイエンスと機械学習(第20回):アルゴリズム取引の洞察、MQL5でのLDAとPCAの対決 データサイエンスと機械学習(第20回):アルゴリズム取引の洞察、MQL5でのLDAとPCAの対決
MQL5取引環境での適用を解剖しながら、これらの強力な次元削減テクニックに隠された秘密を解き明かしていきます。線形判別分析(LDA)と主成分分析(PCA)のニュアンスを深く理解し、戦略開発と市場分析への影響を深く理解します。
MQL5入門(第4部):構造体、クラス、時間関数をマスターする MQL5入門(第4部):構造体、クラス、時間関数をマスターする
最新記事でMQL5プログラミングの秘密を解き明かしましょう。構造体、クラス、時間関数の本質に迫り、コーディングの旅に力を与えます。初心者から経験豊富な開発者まで、個のガイドは、MQL5をマスターするための貴重な洞察を提供し、複雑な概念を簡素化します。プログラミングのスキルを高め、アルゴリズム取引の世界で一歩先を行きましょう。
時系列マイニングのためのデータラベル(第5回):ソケットを使用したEAへの応用とテスト 時系列マイニングのためのデータラベル(第5回):ソケットを使用したEAへの応用とテスト
この連載では、ほとんどの人工知能モデルに適合するデータを作成できる、時系列のラベル付け方法をいくつかご紹介します。ニーズに応じて的を絞ったデータのラベル付けをおこなうことで、訓練済みの人工知能モデルをより期待通りの設計に近づけ、モデルの精度を向上させ、さらにはモデルの質的飛躍を助けることができます。
MQL5入門(第3部):MQL5のコア要素をマスターする MQL5入門(第3部):MQL5のコア要素をマスターする
この初心者向けの記事では、MQL5プログラミングの基本を解説します。配列、カスタム関数、プリプロセッサ、イベント処理など、すべてのコードをわかりやすく説明し、すべての行にアクセスできるようにします。すべてのステップで理解を深める独自のアプローチで、MQL5のパワーを引き出しましょう。この記事はMQL5をマスターするための基礎となるもので、各コード行の説明に重点を置き、明確で充実した学習体験を提供します。