![Машинное обучение и Data Science (Часть 19): Совершенствуем AI-модели с помощью AdaBoost](https://c.mql5.com/2/65/Data_Science_and_Machine_Learning_7Part_191_Supercharge_Your_AI_models_with_AdaBoost_600x314.jpg)
Машинное обучение и Data Science (Часть 19): Совершенствуем AI-модели с помощью AdaBoost
Что такое AdaBoost?
AdaBoost (сокращение от Adaptive Boosting - адаптивный бустинг) представляет собой модель ансамблевого машинного обучения, которая пытается создать сильный классификатор из слабых классификаторов.
Как он работает?
- Алгоритм присваивает веса экземплярам на основе их правильной или неправильной классификации.
- Он объединяет слабые экземпляры с помощью взвешенной суммы.
- Последняя сильная модель представляет собой линейную комбинацию слабых, веса которых определяются в процессе обучения.
Для чего использовать методику Adaboost?
Adaboost предоставляет ряд преимуществ, в том числе:
- Улучшение точности — бустинг может повысить общую точность модели за счет объединения нескольких слабых прогнозов модели, усреднения прогнозов, сделанных всеми моделями регрессии, или голосования по ним для классификации. Все это повышает точность итоговой модели.
- Устойчивость к переобучению — бустинг может снизить риск переобучения за счет присвоения весов неправильно классифицированным входным данным.
- Улучшенная обработка несбалансированных данных — бустинг позволяет справиться с несбалансированными данными, уделяя больше внимания точкам данных, которые неправильно классифицированы.
- Лучшая интерпретируемость — бустинг может повысить интерпретируемость модели за счет разбиения процесса принятия решения модели на несколько процессов.
Что такое "пень решений"?
"Пень решений" (Decision Stump) — это простая модель машинного обучения, используемая в качестве слабого ученика в ансамблевых методах, таких как Adaboost. По сути, это модель машинного обучения, упрощенная для принятия решений на основе одной функции и порогового значения. Цель использования такого пня в качестве слабого ученика — уловить базовую закономерность в данных, которая может способствовать улучшению общей модели ансамбля.
Ниже приводится краткое объяснение теории, лежащей в основе пня решений, с использованием классификатора Древа решений в качестве примера:
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 }
В защищенном разделе класса находится вектор 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 }
Теперь давайте посмотрим, как эту модель можно использовать в советнике:
#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. Тогда при каждом запуске советника в качестве случайного начального числа будет использоваться 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; } }
Adaboosted AI-модели в тестере стратегий.
Мы используем индикатор Bollinger Bands к ценам открытия и попытаемся научить наши модели прогнозировать следующую свечу закрытия, независимо от того, будет ли это бычья, медвежья свеча или ни та, ни другая (удерживаем HOLD).
Создадим советник для тестирования наших моделей в торговой среде. Начнем со сбора обучающих данных:
Сбор данных для обучения:
//--- 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); }
Обратили внимание на изменение в создании целевой переменной? Поскольку дерево решений является универсальным и может хорошо обрабатывать множество классов целевой переменной, оно позволяет классифицировать три модели рынка: BUY, SELL и HOLD. В основе модели логистической регрессии лежит сигмовидная функция, хорошо классифицирующая два класса 0 и 1. Для нас лучше сделать так, чтобы условием целевой переменной было либо BUY, либо SELL.
Обучение и тестирование обученной модели
Слон в комнате:
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
Пока все идет хорошо. Дополним наш советник кодом для совершения сделок:
Получение торговых сигналов:
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 г. по февраль 2023 г. на часовом таймфрейме:
Дерево решений Adaboost:
Логистическая регрессия Adaboost:
Результаты обеих моделей на часовом таймфрейме очень далеки от приемлемых. Основная причина заключается в том, что наша стратегия основана на текущих барах. По моему опыту, стратегии такого типа в основном хорошо подходят для старших таймфреймов, поскольку один бар представляет собой значительное движение в отличие от маленьких баров, которые происходят 24 в день. Попробуем 12-часовой таймфрейм.
Все параметры остались прежними, кроме train_bars, значение которого теперь 100 вместо 1000, поскольку на старших таймфреймах не так много баров для запроса истории цен.
Дерево решений Adaboost:
Логистическая регрессия Adaboost:
Заключение
AdaBoost представляет собой мощный алгоритм, способный значительно повысить производительность ИИ-моделей, обсуждаемых в этой серии статей. Хотя он требует вычислительных затрат, инвестиции окупаются при разумной реализации. Метод AdaBoost нашел применение в различных секторах и отраслях, включая финансы, развлечения, образование и многое другое.
В завершении нашего исследования можно отметить универсальность алгоритма и его способность решать сложные задачи классификации, используя коллективную силу слабых учеников. Ниже представлены часто задаваемые вопросы (FAQ) приз, в них покрыты общие вопросы, которые могут возникнуть во время изучения AdaBoost.
FAQ, или часто задаваемые вопросы об AdaBoost:
Вопрос: Как работает алгоритм 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 | Библиотеку деревьев решений можно найти в этом файле |
AdaBoost Test.mq5(EA) | Основной тестовый советник, весь описанный здесь код, выполняется внутри этого файла. |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/14034
![Как просматривать сделки прямо на графике и не утонуть в торговой истории](https://c.mql5.com/2/80/How_to_avoid_drowning_in_trading_history_and_easily_glide_right_along_the_chart____LOGO.png)
![Элементы корреляционного анализа в MQL5: Критерий независимости хи-квадрат Пирсона и корреляционное отношение](https://c.mql5.com/2/80/Pearson_chi-square_independence_test_and_correlation_ratio____LOGO.png)
![Нейросети — это просто (Часть 94): Оптимизация последовательности исходных данных](https://c.mql5.com/2/80/Neural_networks_are_easy_Part_94____LOGO.png)
![Наиболее известные модификации алгоритма искусственного кооперативного поиска (Artificial Cooperative Search, ACSm)](https://c.mql5.com/2/80/Popular_Artificial_Cooperative_Search____LOGO.png)
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования