![Aprendizaje automático y ciencia de datos (Parte 18): Potencie sus modelos de IA con AdaBoost](https://c.mql5.com/2/65/Data_Science_and_Machine_Learning_7Part_191_Supercharge_Your_AI_models_with_AdaBoost_600x314.jpg)
Aprendizaje automático y ciencia de datos (Parte 18): Potencie sus modelos de IA con AdaBoost
¿Qué es AdaBoost?
AdaBoost es un modelo de aprendizaje automático conjunto que intenta construir un clasificador fuerte a partir de clasificadores débiles.¿Cómo funciona?
- El algoritmo asigna pesos a las instancias en función de su clasificación correcta o incorrecta.
- Combina los aprendices débiles mediante una suma ponderada.
- El aprendiz fuerte final es una combinación lineal de aprendices débiles con pesos determinados durante el proceso de entrenamiento.
¿Por qué debería a alguien importarle usar Adaboost?
AdaBoost proporciona varios beneficios incluyendo:
- Precisión mejorada - El refuerzo puede mejorar la precisión general del modelo combinando varias predicciones de modelos débiles. Promediar las predicciones realizadas por todos los modelos para la regresión o votar sobre ellos para la clasificación con el fin de aumentar la precisión del modelo final.
- Robustez al sobreajuste - El refuerzo puede reducir el riesgo de sobreajuste asignando los pesos a las entradas mal clasificadas.
- Mejor manejo de datos desequilibrados - El refuerzo puede manejar los datos desequilibrados centrándose más en los puntos de datos que están mal clasificados.
- Mejor Interpretabilidad - El refuerzo puede aumentar la interpretabilidad del modelo al dividir el proceso de decisión del modelo en múltiples procesos.
¿Qué es un modelo de decisión simple?
Un modelo de decisión simple es un modelo de aprendizaje automático simple utilizado como un aprendiz débil en métodos de conjunto como AdaBoost. Es esencialmente un modelo de aprendizaje automático simplificado para tomar decisiones basadas en una sola característica y un umbral. El objetivo de usar un modelo de decisión simple como un aprendiz débil es capturar un patrón básico en los datos que pueda contribuir a mejorar el modelo de conjunto general.
A continuación se explica brevemente la teoría en la que se basa un modelo de decisión simple, utilizando como ejemplo el clasificador Árboles de decisión:
1. Estructura:
- Un modelo de decisión simple toma una decisión binaria basada en una única característica y un umbral.
- Divide los datos en dos grupos: los que tienen valores de características por debajo del umbral y los que tienen valores por encima.
- Esto se despliega comúnmente en el constructor de la mayoría de nuestros clasificadores en esta Biblioteca:
CDecisionTreeClassifier(uint min_samples_split=2, uint max_depth=2, mode mode_=MODE_GINI); ~CDecisionTreeClassifier(void);
2. Entrenamiento:
- Durante el entrenamiento, el modelo de decisión simple identifica la característica y el umbral que minimizan un determinado criterio, a menudo el error de clasificación errónea ponderado.
- Se calcula el error de clasificación para cada división posible y se elige la que tenga el error más bajo.
- La(s) función(es) de ajuste es donde se realiza todo el entrenamiento:
void fit(matrix &x, vector &y);
3. Predicción:
- Para la predicción, un punto de datos se clasifica en función de si su valor de característica está por encima o por debajo del umbral elegido.
double predict(vector &x); vector predict(matrix &x);
Los aprendices débiles comúnmente utilizados en métodos de conjunto como AdaBoost incluyen:
1.Modelo de decisión simple/Árboles de decisión:
- Como se ha descrito anteriormente, los árboles de decisión poco profundos se utilizan habitualmente debido a su simplicidad.
2. Modelos lineales:
- Los modelos lineales como la regresión logística o las SVM lineales pueden utilizarse como aprendices débiles.
3. Modelos polinómicos:
- Los modelos polinómicos de mayor grado pueden captar relaciones más complejas, y el uso de polinomios de bajo grado puede actuar como aprendices débiles.
4. Redes neuronales (poco profundas):
- A veces se utilizan redes neuronales poco profundas con un número reducido de capas y neuronas.
5. Modelos gaussianos:
- Los modelos gaussianos, como Gaussian Naive Bayes (GNB), que es un clasificador probabilístico basado en el teorema de Bayes y que asume que las características siguen una distribución normal (gaussiana), pueden ser empleados como aprendices débiles.
La elección de un aprendiz débil depende de las características específicas de los datos y del problema en cuestión. En la práctica, los modelos de decisión simple son populares por su sencillez y eficacia en los algoritmos de refuerzo. El enfoque de conjunto de AdaBoost mejora el rendimiento combinando las predicciones de estos aprendices débiles.
Dado que un modelo de decisión simple es un modelo, necesitamos proporcionar al constructor de la clase Adaboost los argumentos de los parámetros de nuestro modelo débil.
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); };
En este ejemplo se utiliza el Árbol de decisión, pero puede utilizarse cualquier modelo de aprendizaje automático de clasificación.
Construcción de la clase AdaBoost:
El término número de estimadores (n_estimators) se refiere al número de aprendices débiles (modelos base o de decisión simple) que se combinan para crear el aprendiz fuerte final en un algoritmo de aprendizaje ensemble. En el contexto de algoritmos como AdaBoost o 'Gradient boosting', este parámetro suele denominarse 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 }
Desde la sección protegida de la clase, has visto el vector m_alphas, y también has escuchado el término weights varias veces en este artículo. A continuación, se ofrece una aclaración:
Valores alfa:
Los valores alfa representan la contribución o el peso asignado a cada aprendiz débil en el conjunto, estos valores se calculan en función del rendimiento de cada aprendiz débil durante el entrenamiento.
Los valores alfa más altos se asignan a los alumnos débiles que consiguen reducir los errores de formación.
La fórmula para calcular alfa suele venir dada por:
Donde:
es el error ponderado del t-ésimo aprendiz débil.
Implementación:
double alpha = 0.5 * log((1-error) / (error + 1e-10));
Pesos:
Los vectores de pesos representan la importancia de cada instancia de entrenamiento en cada iteración.
Durante el entrenamiento, los pesos de las instancias mal clasificadas se incrementan para centrarse en los ejemplos difíciles de clasificar en la siguiente iteración.
La fórmula para actualizar los pesos de las instancias suele venir dada por:
es el peso de la instancia i en la iteración
es el peso asignado al t-ésimo aprendiz débil.
es la verdadera etiqueta de la instancia
es la predicción del t-ésimo aprendiz débil sobre la instancia
es un factor de normalización para garantizar que los pesos suman 1.
Implementación:
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();
Entrenamiento del modelo AdaBoost:
Al igual que otras técnicas de ensamble, se utilizan 'n' numero de modelos (referidos como m_estimators en la función a continuación) para hacer predicciones sobre los mismos datos. Se puede emplear la votación por mayoría u otras técnicas para determinar el mejor resultado posible.
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; } }
Al igual que cualquier otra técnica de ensamble, Bootstrapping es algo crucial también, sin él todos los modelos y los datos son simplemente iguales, y esto podría causar que el rendimiento de todos los modelos se vuelva indistinguible entre sí, es necesario desplegar el Bootstrapping:
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; } }También hubo que cambiar el constructor de la clase:
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 }
Obtener las predicciones mayoritarias
Utilizando las ponderaciones entrenadas, el clasificador AdaBoost determina la clase con el máximo de votos, lo que significa que es más probable que aparezca que las demás.
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 }
Ahora vamos a ver cómo podemos utilizar el modelo dentro de un Asesor Experto:
#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); }
Utilizando el conjunto de datos iris.csv sólo para la construcción del modelo y fines de depuración. Esto dio lugar a:
2024.01.17 17:52:27.914 AdaBoost Test (EURUSD,H1) Adaboost acc = 0.960
Parece que nuestro modelo está funcionando bien hasta ahora, con valores de precisión alrededor del 90 por ciento. Después configuré el random_state en -1, lo cual hará que GetTickCount se use como semilla aleatoria cada vez que se ejecute el EA, para que pueda evaluar el modelo en un entorno mucho más aleatorio.
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
Los mismos patrones de codificación y estructura pueden seguirse para otros aprendices débiles presentes en nuestra biblioteca, Véase cuando se utilizó la regresión logística como aprendiz débil:
La única diferencia en toda la clase se encuentra bajo la función fit el tipo de modelo desplegado como aprendiz débil es Regresión 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 con AdaBoost en el probador de estrategias.
Utilizando el indicador de las bandas de Bollinger aplicado al precio de apertura, estamos intentando entrenar a nuestros modelos para que aprendan a predecir la siguiente vela de cierre si es bullish, bearish o ninguna de las dos(HOLD).
Vamos a construir un Asesor Experto para probar nuestros modelos en el entorno de negociación, comenzando con el código para recoger los datos de entrenamiento:
Recopilación de los datos de entrenamiento:
//--- 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); }
¿Notas el cambio en la elaboración de la variable objetivo? Dado que el árbol de decisión es versátil y puede manejar bien múltiples clases en la variable objetivo, tiene la capacidad de clasificar tres patrones en el mercado, BUY, SELL, y HOLD. A diferencia del modelo de regresión logística que tiene la función sigmoidea en su núcleo que clasifica bien dos clases 0 y 1, lo mejor es preparar la condición de la variable objetivo para que sea BUY o SELL.
Entrenamiento y prueba del modelo entrenado:
Un elefante en la habitación:
MatrixExtend::TrainTestSplitMatrices(dataset,train_x,train_y,test_x,test_y,0.7,_random_state);
Esta función divide los datos en muestras de entrenamiento y de prueba dado un estado aleatorio para barajar, el 70% de los datos para la muestra de prueba mientras que el 30% restante para la prueba.
Pero antes de poder utilizar los datos recién recogidos, la normalización sigue siendo crucial para el rendimiento del 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; }
Salidas:
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
Hasta ahora, todo bien. Terminemos nuestro Asesor Experto con las líneas de código capaces de ejecutar operaciones:
Obtención de las señales de trading:
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; } }
Recuerde, 1 representa la señal de compra para el árbol de decisión, 0 representa la señal de compra para la regresión logística; 2 representa la señal de venta para el árbol de decisión; 1 representa la señal de venta para la regresión logística. No nos importa la señal 0 que representa mantener para el árbol de decisión. Unifiquemos estas señales para que se identifiquen como 0 y 1 para señales de compra y venta 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;
Una estrategia sencilla a partir de nuestros 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 en el probador de estrategias | de enero 2020 - febrero 2023 | Timeframe 1 HORA:
Árbol de decisión AdaBoost:
Regresión logística AdaBoost:
Ambas actuaciones con UN TIMEFRAME DE UNA HORA están muy lejos de ser buenas. Una razón importante para esto es que nuestra estrategia se basa en las barras actuales, En mi experiencia, este tipo de estrategias se adaptan sobre todo bien en marcos de tiempo más altos como una sola barra representa un movimiento significativo a diferencia de las pequeñas barras que se producen 24 en un día, vamos a intentar un TIMEFRAME DE 12 HORAS.
Todos los parámetros se dejaron igual excepto el train_bars que se redujo a 100 desde 1000, ya que los marcos de tiempo más altos no tienen muchas barras para solicitar el historial de precios en el pasado.
Árbol de decisión AdaBoost:
Regresión logística AdaBoost:
En conclusión:
AdaBoost emerge como un potente algoritmo capaz de mejorar significativamente el rendimiento de los modelos de IA analizados a lo largo de esta serie de artículos. Aunque conlleva un coste computacional, la inversión merece la pena si se aplica con sensatez. AdaBoost ha encontrado aplicaciones en diversos sectores e industrias, como las finanzas, el entretenimiento y la educación, entre otros.
Para concluir nuestra exploración, es esencial reconocer la versatilidad del algoritmo y su capacidad para abordar retos de clasificación complejos aprovechando la fuerza colectiva de los aprendices débiles. Las preguntas más frecuentes (FAQs) que se ofrecen a continuación pretenden ofrecer claridad y comprensión, abordando las dudas más comunes que puedan surgir durante la exploración de AdaBoost.
Preguntas frecuentes (FAQs) sobre AdaBoost:
Pregunta: ¿Cómo funciona AdaBoost?
Respuesta: AdaBoost funciona entrenando iterativamente aprendices débiles (normalmente modelos simples de decisión) en el conjunto de datos, ajustando los pesos de las instancias mal clasificadas en cada iteración. El modelo final es una suma ponderada de los aprendices débiles, dando mayor peso a los más precisos.
Pregunta: ¿Qué son los aprendices débiles en AdaBoost?
Respuesta: Los aprendices débiles son modelos simples que funcionan ligeramente mejor que el azar. Los modelos simples de decisión (árboles de decisión poco profundos) se suelen utilizar como aprendices débiles en AdaBoost, pero otros algoritmos también pueden servir para este propósito.
Pregunta: ¿Cuál es el papel de los pesos de instancia en AdaBoost?
Respuesta: Los pesos de instancia en AdaBoost controlan la importancia de cada instancia de entrenamiento durante el proceso de aprendizaje. Inicialmente, todas las ponderaciones se fijan por igual, y se ajustan en cada iteración para centrarse más en los casos mal clasificados, mejorando la capacidad de generalización del modelo.
Pregunta: ¿Cómo gestiona AdaBoost los errores cometidos por los aprendices débiles?
Respuesta: AdaBoost asigna pesos más altos a las instancias mal clasificadas, forzando a los aprendices débiles posteriores a centrarse más en corregir estos errores. El modelo final da más peso a los aprendices débiles con índices de error más bajos.
Pregunta: ¿Es AdaBoost sensible al ruido y a los valores atípicos?
Respuesta: AdaBoost puede ser sensible al ruido y a los valores atípicos, ya que intenta corregir las clasificaciones erróneas. Los valores atípicos podrían recibir ponderaciones más altas, influyendo en el modelo final. Para mitigar esta sensibilidad pueden aplicarse aprendices débiles robustos o técnicas de preprocesamiento de datos.
Pregunta: ¿Sufre AdaBoost de sobreajuste?
Respuesta: AdaBoost puede ser propenso al sobreajuste si los aprendices débiles son demasiado complejos o si el conjunto de datos contiene ruido. Utilizar aprendices débiles más sencillos y aplicar técnicas como la validación cruzada puede ayudar a evitar el sobreajuste.
Pregunta: ¿Se puede utilizar AdaBoost para problemas de regresión?
Respuesta: AdaBoost está diseñado principalmente para tareas de clasificación, pero puede adaptarse para regresión modificando el algoritmo para predecir valores continuos. Existen técnicas como AdaBoost.R2 para los problemas de regresión.
Pregunta: ¿Existen alternativas a AdaBoost?
Respuesta: Sí, existen otros métodos de aprendizaje en conjunto, como Random Forest, Gradient Boosting y XGBoost. Cada método tiene sus puntos fuertes y débiles, y la elección depende de las características específicas de los datos y del problema en cuestión.
Pregunta: ¿En qué situaciones es AdaBoost especialmente eficaz?
Respuesta: AdaBoost es eficaz cuando se trata con una variedad de aprendices débiles y en escenarios donde hay una necesidad de combinar múltiples clasificadores para crear un modelo robusto. Se utiliza a menudo en la detección de rostros, la clasificación de textos y otras aplicaciones del mundo real.
Para mantenerse al día sobre el progreso del desarrollo y las correcciones de errores de este algoritmo, así como de muchos otros, visite el repositorio de GitHub en https://github.com/MegaJoctan/MALE5.
Paz.
Archivos adjuntos:
Archivo | Descripción / Uso |
---|---|
Adaboost.mqh | Contiene clases del espacio de nombres AdaBoost tanto para la regresión logística como para el árbol de decisión. |
Logistic Regression.mqh | Contiene la clase principal de regresión logística. |
MatrixExtend.mqh | Contiene una función adicional de manipulación de matrices. |
metrics.mqh | Una biblioteca que contiene código para medir el rendimiento de los modelos de aprendizaje automático. |
preprocessing.mqh | Clase que contiene funciones de preprocesamiento de datos para adaptarlos al aprendizaje automático. |
tree.mqh | La biblioteca del árbol de decisiones se encuentra en este archivo. |
AdaBoost Test.mq5 (EA) | El Asesor Experto de prueba principal, todo el código explicado aquí se ejecuta dentro de este archivo. |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/14034
![Utilizando redes neuronales en MetaTrader](https://c.mql5.com/2/16/777_40.gif)
![Desarrollo de un sistema de repetición (Parte 55): Módulo de control](https://c.mql5.com/2/83/Desenvolvendo_um_sistema_de_Replay_Parte_55__LOGO.png)
![Particularidades del trabajo con números del tipo double en MQL4](https://c.mql5.com/2/16/762_31.png)
![Desarrollo de un sistema de repetición (Parte 54): El nacimiento del primer módulo](https://c.mql5.com/2/82/Desenvolvendo_um_sistema_de_Replay_Parte_54___LOGO2.png)
![MQL5 - Lenguaje de estrategias comerciales para el terminal de cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso