Ciência de Dados e Aprendizado de Máquina (Parte 19): Supercharge Seus Modelos de IA com AdaBoost
O que é Adaboost?
Adaboost, abreviação de adaptive boosting, é um modelo de aprendizado de máquina em conjunto que tenta construir um classificador forte a partir de classificadores fracos.Como funciona?
- O algoritmo atribui pesos às instâncias com base em sua classificação correta ou incorreta.
- Ele combina aprendizes fracos usando uma soma ponderada.
- O aprendiz forte final é uma combinação linear de aprendizes fracos com pesos determinados durante o processo de treinamento.

Por que alguém deveria se importar em usar Adaboost?
Adaboost oferece vários benefícios, incluindo:
- Melhoria na Precisão – O Boosting pode melhorar a precisão geral do modelo combinando várias previsões de modelos fracos. Média das previsões feitas por todos os modelos para regressão ou votação sobre elas para classificação para aumentar a precisão do modelo finalidade
- Robustez contra Overfitting – O Boosting pode reduzir o risco de overfitting atribuindo pesos às entradas classificadas incorretamente.
- Melhor manejo de dados desbalanceados – O Boosting pode lidar com dados desbalanceados focando mais nos pontos de dados que são classificados incorretamente.
- Melhor interpretabilidade – O Boosting pode aumentar a interpretabilidade do modelo dividindo o processo de decisão do modelo em vários processos.
O que é um Stump de Decisão?
Um Stump de Decisão é um modelo simples de aprendizado de máquina usado como um aprendiz fraco em métodos de conjunto como Adaboost. Ele é essencialmente um modelo de aprendizado de máquina simplificado para tomar decisões com base em uma única característica e um limiar. O objetivo de usar um stump de decisão como um aprendiz fraco é capturar um padrão básico nos dados que pode contribuir para melhorar o modelo de conjunto geral.
Abaixo está uma breve explicação da teoria por trás de um stump de decisão, usando o classificador Árvore de Decisão como exemplo:
1. Estrutura:
Um stump de decisão toma uma decisão binária com base em uma única característica e um limiar.
Ele divide os dados em dois grupos: aqueles com valores de característica abaixo do limiar e aqueles com valores acima.
Isso é comumente implementado no construtor da maioria dos nossos classificadores nesta Biblioteca:
CDecisionTreeClassifier(uint min_samples_split=2, uint max_depth=2, mode mode_=MODE_GINI); ~CDecisionTreeClassifier(void);
2. Treinamento:.
Durante o treinamento, o stump de decisão identifica a característica e o limiar que minimizam um determinado critério, muitas vezes o erro de classificação ponderado.
O erro de classificação é calculado para cada possível divisão, e a que possui o menor erro é escolhida.
- A função fit é onde todo o treinamento é realizado:
void fit(matrix &x, vector &y);
3. Predição:
Para a predição, um ponto de dados é classificado com base em se seu valor de característica está acima ou abaixo do limiar escolhido.
double predict(vector &x); vector predict(matrix &x);
Comumente, os aprendizes fracos usados em métodos de ensemble como o AdaBoost incluem:
1.Stumps de Decisão/Árvores de Decisão:
Conforme descrito acima, stumps de decisão ou árvores de decisão rasas são comumente usados devido à sua simplicidade.
2. Modelos Lineares:
Modelos lineares como regressão logística ou SVMs lineares podem ser usados como aprendizes fracos.
3. Modelos Polinomiais:
Modelos polinomiais de grau mais alto podem capturar relações mais complexas, e usar polinomiais de baixo grau pode atuar como aprendizes fracos.
4. Redes Neurais (Rasas):
Redes neurais rasas com um pequeno número de camadas e neurônios são às vezes usadas.
5. Modelos Gaussianos:
Modelos gaussianos, como o Naive Bayes Gaussiano, podem ser empregados como aprendizes fracos.
A escolha de um aprendiz fraco depende das características específicas dos dados e do problema em questão. Na prática, stumps de decisão são populares devido à sua simplicidade e eficiência em algoritmos de boosting. A abordagem de ensemble do AdaBoost melhora o desempenho ao combinar as previsões desses aprendizes fracos.
Como um stump de decisão é um modelo, precisamos dar ao construtor da classe Adaboost os argumentos dos parâmetros do nosso modelo fraco.
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); };
Este exemplo usa a árvore de decisão, mas qualquer modelo de aprendizado de máquina de classificação pode ser implementado.
Construindo a classe AdaBoost:
O termo número de estimadores refere-se ao número de aprendizes fracos (modelos base ou stumps de decisão) que são combinados para criar o aprendiz forte final em um algoritmo de aprendizado em conjunto. No contexto de algoritmos como AdaBoost ou gradient boosting, esse parâmetro é frequentemente denotado como 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 }
A partir da seção protegida da classe, você viu o vetor m_alphas , enquanto também ouviu o termo weights várias vezes neste artigo. Abaixo está a explicação:
Valores de Alph
Os valores de alpha representam a contribuição ou peso atribuído a cada aprendiz fraco no conjunto. Esses valores são calculados com base no desempenho de cada aprendiz fraco durante o treinamento.
Valores de alpha mais altos são atribuídos a aprendizes fracos que têm bom desempenho na redução de erros de treinamento.
A fórmula para calcular alpha é geralmente dada por:
![]()
onde:
é o erro ponderado do t-th aprendiz fraco.
Implementation:
double alpha = 0.5 * log((1-error) / (error + 1e-10));
Pesos:
Os vetores de pesos representam a importância de cada instância de treinamento em cada iteração.
Durante o treinamento, os pesos das instâncias classificadas incorretamente são aumentados para focar nos exemplos difíceis de classificar na próxima iteração.
A fórmula para atualizar os pesos das instâncias é geralmente dada por:
![]()
é o peso da instância i na iteração
é o peso atribuído ao t-th aprendiz fraco.
é o rótulo verdadeiro da instância
é a previsão do t-th aprendiz fraco na instância
é um fator de normalização para garantir que a soma dos pesos seja igual a 1.
Implementation:
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();
Treinando o modelo Adaboost:
Assim como outras técnicas de ensemble, n modelos (referidos como m_estimators na função abaixo) são usados para fazer previsões nos mesmos dados, o voto da maioria ou outras técnicas podem ser utilizadas para determinar o melhor resultado possível.
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); //fitting 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; } }
Assim como qualquer outra técnica de ensemble, bootstrapping é crucial também. Sem ele, todos os modelos e os dados são simplesmente os mesmos, o que poderia fazer com que o desempenho de todos os modelos se tornasse indistinguível um do outro. O bootstrapping precisa ser implementado:
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); //fitting 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; } }O construtor da classe também teve que ser alterado:
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 }
Obtendo as Previsões da Maioria
Usando os pesos treinados, o classificador Adaboost determina a classe com o máximo de votos, significando que ela tem mais probabilidade de aparecer do que as outras.
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 }
Agora vamos ver como podemos usar o modelo dentro de um Expert Advisor:
#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); }
Usando o dataset iris.csv apenas para construir o modelo e para fins de depuração. Isso resultou em:
2024.01.17 17:52:27.914 AdaBoost Test (EURUSD,H1) Adaboost acc = 0.960
Parece que nosso modelo está indo bem até agora, com valores de precisão em torno de 90%, depois que defini o random_state para -1, o que fará com que o GetTickCount seja usado como uma semente aleatória cada vez que o EA é executado, para que eu possa avaliar o modelo em um ambiente muito mais aleatório.
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
Os mesmos padrões e estruturas de codificação podem ser seguidos para outros weak learners presentes em nossa biblioteca. Veja quando a regressão logística foi usada como um weak learner:
A única diferença em toda a classe é encontrada na função fit, onde o tipo de modelo implementado como weak learner é Regressão Logística:
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); //fitting 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; } }
Modelos de IA com AdaBoost no Testador de Estratégias
Ao usar o indicador de banda de Bollinger aplicado ao preço de abertura, estamos tentando treinar nossos modelos para aprender a prever o próximo fechamento de candle, seja ele altista, baixista ou nenhum dos dois (MANTER).
Vamos construir um Expert Advisor para testar nossos modelos no ambiente de negociação, começando com o código para coletar os dados de treinamento:
Coletando os Dados de Treinamento:
//--- 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); }
Notou a mudança na criação da variável alvo? Como a árvore de decisão é versátil e pode lidar bem com múltiplas classes na variável alvo, ela tem a capacidade de classificar três padrões no mercado, COMPRAR, VENDER e MANTER. Ao contrário do modelo de regressão logística que tem a função sigmoide em seu núcleo e que classifica bem duas classes, 0 e 1, a melhor coisa é preparar a condição da variável alvo para ser COMPRAR ou VENDER.
Treinamento e Teste do Modelo Treinado:
Um Elefante na sala:
MatrixExtend::TrainTestSplitMatrices(dataset,train_x,train_y,test_x,test_y,0.7,_random_state); Esta função divide os dados em amostras de treinamento e teste, dado um estado aleatório para embaralhamento, 70% dos dados para a amostra de teste, enquanto os outros 30% para teste.
Mas antes que possamos usar os dados recém-coletados, A Normalização ainda é crucial para o desempenho do modelo.
//--- 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; }
Saídas:
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
Até agora, tudo bem! Vamos finalizar nosso Expert Advisor com as linhas de código capazes de executar negociações:
Obtendo os sinais de negociação:
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; } }
Lembre-se, 1 representa o sinal de compra para a árvore de decisão, 0 representa o sinal de compra para a regressão logística; 2 representa o sinal de venda para a árvore de decisão; 1 representa o sinal de venda para a regressão logística. Não nos importamos com o sinal 0 que representa manter para a árvore de decisão. Vamos unificar esses sinais para serem identificados como 0 e 1 para sinais de compra e venda, respectivamente.
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;
Uma estratégia simples feita a partir de nossos modelos:
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()); } }
Resultados no testador de estratégias | de janeiro de 2020 a fevereiro de 2023 | Intervalo de tempo de 1 HORA:
Árvore de Decisão Adaboost:

Regressão Logística Adaboost:

Ambos os desempenhos no INTERVALO DE TEMPO DE UMA HORA estão muito longe de serem bons. Uma das principais razões para isso é que nossa estratégia é baseada nas barras atuais. Em minha experiência, esse tipo de estratégia é mais adequado para intervalos de tempo maiores, pois uma única barra representa um movimento significativo, ao contrário das pequenas barras que ocorrem 24 vezes por dia. Vamos tentar o INTERVALO DE TEMPO DE 12 HORAS.
Todos os parâmetros foram mantidos os mesmos, exceto pelo train_bars, que foi reduzido de 1000 para 100, pois intervalos de tempo maiores não têm muitas barras para solicitar o histórico de preços no passado.
Árvore de Decisão Adaboost:

Regressão Logística Adaboost:

Em conclusão:
AdaBoost emerge como um algoritmo potente capaz de melhorar significativamente o desempenho dos modelos de IA discutidos ao longo desta série de artigos. Embora venha com um custo computacional, o investimento se mostra válido quando implementado de forma judiciosa. AdaBoost tem encontrado aplicações em diversos setores e indústrias, incluindo finanças, entretenimento, educação, entre outros.
Ao concluirmos nossa exploração, é essencial reconhecer a versatilidade do algoritmo e sua capacidade de abordar desafios complexos de classificação, aproveitando a força coletiva dos aprendizes fracos. As Perguntas Frequentes (FAQs) abaixo visam oferecer clareza e insight, abordando questões comuns que podem surgir durante sua exploração do AdaBoost.
Perguntas Frequentes (FAQs) sobre Adaboost:
Pergunta: Como o AdaBoost funciona?
Resposta: O AdaBoost funciona treinando iterativamente aprendizes fracos (geralmente modelos simples como tocos de decisão) no conjunto de dados, ajustando os pesos das instâncias classificadas incorretamente a cada iteração. O modelo final é uma soma ponderada dos aprendizes fracos, com pesos maiores dados aos mais precisos.
Pergunta: O que são aprendizes fracos no AdaBoost?
Resposta: Aprendizes fracos são modelos simples que têm um desempenho ligeiramente melhor que o acaso. Tocos de decisão (árvores de decisão rasas) são comumente usados como aprendizes fracos no AdaBoost, mas outros algoritmos também podem servir a esse propósito.
Pergunta: Qual é o papel dos pesos das instâncias no AdaBoost?
Resposta: Os pesos das instâncias no AdaBoost controlam a importância de cada instância de treinamento durante o processo de aprendizado. Inicialmente, todos os pesos são definidos igualmente, e são ajustados a cada iteração para focar mais nas instâncias classificadas incorretamente, melhorando a capacidade do modelo de generalizar.
Pergunta: Como o AdaBoost lida com erros cometidos por aprendizes fracos?
Resposta: O AdaBoost atribui pesos maiores às instâncias classificadas incorretamente, forçando os aprendizes fracos subsequentes a focar mais na correção desses erros. O modelo final dá mais peso aos aprendizes fracos com taxas de erro mais baixas.
Pergunta: O AdaBoost é sensível a ruídos e outliers?
Resposta: O AdaBoost pode ser sensível a ruídos e outliers, pois tenta corrigir as classificações incorretas. Outliers podem receber pesos maiores, influenciando o modelo final. Aprendizes fracos robustos ou técnicas de pré-processamento de dados podem ser aplicados para mitigar essa sensibilidade.
Pergunta: O AdaBoost sofre de sobreajuste?
Resposta: O AdaBoost pode estar sujeito ao sobreajuste se os aprendizes fracos forem muito complexos ou se o conjunto de dados contiver ruídos. Usar aprendizes fracos mais simples e aplicar técnicas como validação cruzada pode ajudar a prevenir o sobreajuste.
Pergunta: O AdaBoost pode ser usado para problemas de regressão?
Resposta: O AdaBoost é projetado principalmente para tarefas de classificação, mas pode ser adaptado para regressão modificando o algoritmo para prever valores contínuos. Técnicas como AdaBoost.R2 existem para problemas de regressão.
Pergunta: Existem alternativas ao AdaBoost?
Resposta: Sim, existem outros métodos de aprendizado em conjunto, como Random Forest, Gradient Boosting e XGBoost. Cada método tem seus pontos fortes e fracos, e a escolha depende das características específicas dos dados e do problema em questão.
Pergunta: Em quais situações o AdaBoost é particularmente eficaz?
Resposta: O AdaBoost é eficaz ao lidar com uma variedade de aprendizes fracos e em cenários onde há necessidade de combinar múltiplos classificadores para criar um modelo robusto. Ele é frequentemente usado em detecção de faces, classificação de textos e outras aplicações do mundo real.
Para se manter atualizado sobre o progresso do desenvolvimento e correções de bugs deste algoritmo, bem como de muitos outros, por favor visite o repositório GitHub em https://github.com/MegaJoctan/MALE5.
Até mais.
Anexos:
| Arquivo | Descrição|Uso |
|---|---|
| Adaboost.mqh | Contém classes de namespace Adaboost tanto para regressão logística quanto para a árvore de decisão. |
| Logistic Regression.mqh | Contém a classe principal de regressão logística |
| MatrixExtend.mqh | Contém funções adicionais de manipulação de matrizes |
| metrics.mqh | Uma biblioteca contendo código para medir o desempenho de modelos de aprendizado de máquina |
| preprocessing.mqh | Uma classe contendo funções para pré-processamento de dados para torná-los adequados para aprendizado de máquina |
| tree.mqh | Biblioteca de árvore de decisão pode ser encontrada neste arquivo |
| AdaBoost Test.mq5(EA) | O principal Expert Advisor de teste, todo o código explicado aqui é executado dentro deste arquivo |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/14034
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Inferência causal em problemas de classificação de séries temporais
Indicador Customizado: Traçar os Pontos de Entradas Parciais em contas Netting
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso