
データサイエンスと機械学習(第19回):AdaBoostでAIモデルをパワーアップ
AdaBoostについて
AdaBoostとは、Adaptive Boostingの略で、弱い分類器から強い分類器を構築しようとするアンサンブル機械学習モデルです。仕組み
- アルゴリズムは、分類の正誤に基づいてインスタンスに重みを割り当てます。
- 加重和を使用して弱い学習機を組み合わせます。
- 最終的な強い学習機は、学習過程で決定された重みを持つ弱い学習機の線形結合です。
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を見ましたが、この記事では重みという用語も何度か聞いてきました。以下に説明します。
アルファ値
アルファ値は、アンサンブル内の各弱学習機に割り当てられた貢献度または重みを表し、これらの値は訓練中の各弱学習機のパフォーマンスに基づいて計算されます。
アルファ値が高い学習機は、学習ミスを減らすのに有効な弱い学習機に割り当てられます。
アルファ値の計算式は、しばしば次のように示されます。
ここで
はt番目の弱い学習機の重み付き誤差です。
実装
double alpha = 0.5 * log((1-error) / (error + 1e-10));
重み
重みベクトルは、各反復における各訓練インスタンスの重要度を表します。
訓練中、誤分類されたインスタンスの重みは、次の反復で分類が困難な事例に焦点を当てるために増やされます。
インスタンスの重みを更新する式は、しばしば次のように与えられます。
:反復におけるインスタンス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:
1H時間枠でのパフォーマンスはどちらも良好とは程遠いものです。その主な理由は、戦略が現在のバーに基づいているということです。私の経験では、この種の戦略は、1日に24本発生する小さなバーとは異なり、1本のバーが重要な動きを表すため、より長い時間枠によく適しています。12H時間枠を試してみましょう。
train_barsを1000から100に減らした以外は、すべてのパラメータを同じにしました。より長い時間枠には、過去の価格履歴をリクエストするためのバーがあまりないためです。
決定木AdaBoost:
ロジスティック回帰AdaBoost:
結論
本連載で取り上げた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





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索