Алгоритм выбора признаков с использованием энергетического обучения на чистом MQL5
Введение
Широкое использование машинного обучения в алгоритмической торговле привело к внедрению методов интеллектуального анализа данных для выявления скрытых закономерностей в финансовых данных. Исследователи часто сталкиваются с проблемой сортировки многочисленных переменных при определении тех из них, которые с наибольшей вероятностью окажутся полезными для достижения конкретных целей или решения конкретных проблем. В этой статье мы рассмотрим реализацию алгоритма выбора признаков, направленного на оценку релевантности набора потенциальных переменных для задачи прогнозирования.
Юн Ли, Дженни Си, Гоцзин Чжоу, Шаша Хуан и Сонгкан Чен стали соавторами исследовательской работы под названием "FREL: Стабильный алгоритм выбора признаков" (FREL: A Stable Feature Selection Algorithm). В работе представлен алгоритм под названием "Взвешивание признаков как регуляризованное обучение на основе энергии" (Feature Weighting as Regularized Energy-Based Learning, FREL), который служит в качестве метода отбора признаков или взвешивания, призванного обеспечить как точность, так и стабильность. Мы дадим обзор теоретических основ регуляризованного обучения на основе энергии и взвешивания признаков. Кроме того, мы проиллюстрируем эффективность предлагаемого подхода, реализовав пример MQL5-программы, созданной в виде скрипта, чтобы подчеркнуть потенциал метода как инструмента для выбора признаков.
Взвешенная классификация метода ближайших соседей
Концепция FREL черпает вдохновение из метода, известного как взвешенная классификация ближайших соседей (weighted nearest-neighbour classification), который использует расстояния между точками в наборе данных для составления прогнозов. Определяя соответствующие веса для каждого признака, метод повышает точность прогнозирования. Взвешенная классификация ближайших соседей представляет собой разновидность алгоритма k ближайшего соседа (k-NN) - широко используемого подхода в машинном обучении для задач классификации. В стандартной классификации k-NN алгоритм проверяет k ближайших точек данных в обучающем наборе при классификации новой точки данных, в конечном итоге присваивая новой точке данных класс большинства среди этих соседей.
Однако при взвешенной классификации ближайших соседей вместо простого подсчета голосов ближайших соседей голос каждого соседа взвешивается в соответствии с его расстоянием от новой точки данных. Обоснование заключается в том, что более близкие соседи должны оказывать более сильное влияние на решение о классификации, чем более далекие. Процесс взвешивания включает в себя расчет расстояния между новой точкой данных и каждой точкой в обучающем наборе. Обычно используемые метрики расстояния включают евклидово расстояние, манхэттенское расстояние или косинусный коэффициент, выбранные на основе характеристик данных. В этом контексте мы используем манхэттенское расстояние, также называемое расстоянием между городскими кварталами, между точками данных. Формула расчета расстояния приведена ниже. Здесь w - это веса, а testcase - это тестовый случай, который оценивается относительно других обучающих данных, заданных как обучающий случай (trainingcase)
Энергетические модели
Энергетическое моделирование в машинном обучении применима как к обучению с учителем, так и к обучению без учителя. Принцип его работы основан на присвоении энергетических значений различным конфигурациям данных и обучении модели, способной различать желательные и нежелательные конфигурации. Это достигается за счет минимизации энергии наблюдаемых данных и максимизации энергии ненаблюдаемых или нежелательных конфигураций данных.
В основе энергетических моделей лежит определение энергетической функции, обозначаемой как E(). Эта функция принимает в качестве входных данных конфигурацию входных переменных или предикторов, а также набор параметров модели. Выходные данные энергетической функции дают представление о релевантности конфигурации входных переменных. Например, в контексте оценки регрессионной модели энергетическая функция может быть представлена как среднеквадратическая ошибка. Когда в уравнение среднеквадратической ошибки вводятся соответствующие предикторы, выходное значение, как правило, меньше, что отражает более высокую релевантность. И наоборот, плохие предикторы приводят к большим значениям среднеквадратической ошибки. Энергетическая функция присваивает скалярное значение каждой возможной конфигурации переменных.
Цель обучения энергетической модели — изучить параметры энергетической функции таким образом, чтобы она присваивала низкие значения энергии релевантным входным переменным, а высокие значения — нерелевантным. Это влечет за собой определение целевой функции, которая штрафует высокие значения энергии при правильных переменных и низкие значения - при неправильных. Для достижения этой цели необходимо определить конфигурацию неверных переменных, которая обеспечивает наименьшую энергию, представляя собой выборку, которая с большой вероятностью может привести к ошибочным прогнозам модели. Функция ниже представляет энергию конфигурации входных параметров, x, и параметра модели, w, который выводит ошибочное значение, y, чтобы отличить их от конфигураций входных переменных, которые дают точные прогнозы.
В конечном итоге целевая функция стремится максимизировать расхождение между неправильной конфигурацией с наименьшей энергией и ближайшей правильной конфигурацией переменных. Энергия такой конфигурации приведена ниже.
Целевая функция, известная как функционал потерь (loss functional), представляет собой усредненную по выборке функцию потерь. Ниже приведен логарифм потерь.
В качестве функции потерь для каждой выборки могут использоваться различные критерии потерь, такие как кусочно-линейная функция потерь (hinge loss), логарифмические потери, квадратичные потери и квадратно-экспоненциальные потери, выбор которых зависит от области применения.
Это основные концепции, лежащие в основе FREL. В следующем разделе подробно рассматриваются особенности самого алгоритма.
Алгоритм FREL
Для эффективного применения алгоритма FREL необходимо соблюдать некоторые фундаментальные условия. Во-первых, крайне важно тщательно оценить данные обучения. FREL идеально подходит для наборов данных, которые сопоставляют набор потенциальных переменных с одной целью. Не менее важно обеспечить схожесть масштабов переменных. Воздействие FREL на потенциальных предикторов с непоследовательным масштабированием может существенно исказить конечные результаты.
Во-вторых, учитывая, что FREL представляет собой процедуру обучения на основе энергии, необходимо определить энергетическую функцию, включающую весовые параметры. Поэтому используемая модель должна быть настроена на прием набора возможных переменных вместе с соответствующими весовыми коэффициентами. Например, если рассматривать среднеквадратичную ошибку как энергетическую функцию с регрессионной моделью, включение весовых параметров становится относительно простым делом. Каждый вес будет сопоставлен с потенциальным предиктором.
Наконец, необходимо выбрать функцию потерь для каждого образца, чтобы определить функционал потерь. Функционал потерь, включающий весовые параметры модели, представляет собой функцию (или функции), минимизированную для получения оптимальных весов.
Основные этапы алгоритма FREL следующие:
- Начнем с обучающего набора данных, включающего n наблюдений с d потенциальными предикторами, соответствующими n целевым значениям. Цель состоит в том, чтобы выявить наиболее релевантные предикторы из набора d кандидатов для определения целевых значений. Это приводит к присвоению весов каждому из d-предикторов, что указывает на важность переменной по отношению к другим. Больший вес означает большую значимость при определении целевого значения.
- Первоначально присвоим всем весам значение 1.
- Применим классификацию взвешенных ближайших соседей к каждому наблюдению в обучающих данных, чтобы определить конфигурацию неверных переменных, дающую самую низкую энергию, и ближайшую конфигурацию правильных переменных с высокой энергией. Применим эти значения энергии для расчета потерь на образец с использованием выбранной функции потерь.
- Наконец, минимизируйте функцию потерь (опционально с помощью регуляризации), используя необходимую процедуру оптимизации. Это основа алгоритма FREL.
Реализация FREL на MQL5
Реализация FREL, представленная в этом тексте, использует метод оптимизации Пауэлла. Хотя конкретный используемый метод оптимизации не имеет решающего значения, результаты должны быть относительно единообразными при использовании разных методов. В этой реализации метод Пауэлла представлен как класс PowellsMethod, определенный в Powells.mqh. Алгоритм FREL инкапсулирован в классе FREL, потомке PowellsMethod, указанном в frel.mqh.
//+------------------------------------------------------------------+ //| constructor | //+------------------------------------------------------------------+ FREL(matrix &in_data,int numboot=1, int bootsize=0) { m_data = in_data; m_num_boot=(numboot>0)?numboot:1; m_bootsize=(bootsize>2 && bootsize<=int(m_data.Rows()) && m_num_boot>1)?bootsize:int(m_data.Rows()); if(ArrayResize(m_indices, int(m_data.Rows()))!=int(m_data.Rows()) || ArrayResize(m_target_bin, int(m_data.Rows()))!=int(m_data.Rows()) || ArrayResize(m_trial_weights, int(m_data.Cols()-1))!=int(m_data.Cols()-1) || ArrayResize(m_work_weights, int(m_data.Cols()-1))!=int(m_data.Cols()-1) ) { Print(__FUNCTION__, " error ", GetLastError()); m_memory_allocated = false; } else m_memory_allocated = true; }
Рассмотрим параметрический конструктор. Он вызывается как минимум с одним параметром: матрицей обучающих данных. Важно отметить, как должны быть структурированы обучающие данные в матрице. Каждая строка представляет собой наблюдение или отдельный образец, а столбцы представляют собой потенциальные переменные или предикторы, подлежащие оценке. Ожидается, что цель будет находиться в последнем столбце матрицы. Дополнительные параметры конструктора более подробно описаны в таблице ниже.
Название параметра | Тип данных | Значение по умолчанию | Описание |
---|---|---|---|
numboot | целое число | 1 | numboot устанавливает количество проводимых самозагрузок (bootstraps) |
bootsize | целое число | 0 | bootsize определяет размер каждой самозагрузки. Будьте внимательны при настройке этого параметра. Если используется значение, превышающее количество наблюдений в матрице, numboot автоматически возвращается к 1, а bootsize — к количеству наблюдений. |
Для использования класса FREL пользователям необходимо ознакомиться только с одним методом: WeighVars().
//+-----------------------------------------------------------------------+ //| Find the most relevant variables from a dataset of candidate variables| //+-----------------------------------------------------------------------+ bool WeighVars(int num_bins_target, double reg_factor,int &index[],double &weights[]) { if(!m_memory_allocated) { Print(" INTERNAL ERROR "); return false; } if(num_bins_target<=1 || num_bins_target>int(m_data.Rows())) { Print(__FUNCTION__, " invalid function parameter: num_bins_target. Parameter should be >=2 "); return false; } int ret=0; double target[], target_thresholds[] ; double sum ; int n_cases = int(m_data.Rows()); m_reg_factor = MathAbs(reg_factor); m_loss = 0.0; if(ArrayResize(index,int(m_data.Cols()-1))!=int(m_data.Cols()-1) || !np::vecAsArray(m_data.Col(m_data.Cols()-1),target) ) { Print(__FUNCTION__, " error ", GetLastError()); return false; } int k = num_bins_target ; if(!bin_array(target, k, target_thresholds, m_target_bin)) return false; if(k<num_bins_target) { Print("error bins of target vector ", num_bins_target," : ", k); return false; } for(int i=0 ; i<n_cases ; i++) { if(m_target_bin[i] >= num_bins_target) { Print("error m_target_bin array at index ", i, " is ",m_target_bin[i], " should be less than ", num_bins_target); return false; } } ret = calc_wt(num_bins_target,m_loss,weights); if(ret<0) return false; sum = 0.0 ; for(ulong var=0 ; var<m_data.Cols()-1 ; var++) { weights[var] = m_data.Col(var).Std() * exp(weights[var]); sum += weights[var] ; } for(ulong var=0 ; var<m_data.Cols()-1 ; var++) { weights[var] *= 100.0 / sum ; index[var] = int(var) ; } MathQuickSortDescending(weights,index,0,int(weights.Size()-1)) ; return true; }
Этот метод оценивает обучающие данные, указанные в конструкторе. Возвращает логическое значение, где false указывает на то, что процедура не была завершена. Параметры этого метода следующие:
- num_bins_target - целое число, определяющее количество ячеек, на которые будут разделены целевые значения. Параметр должен быть установлен на любое целое число >= 2, но <= количество наблюдений в обучающих данных.
- reg_factor - положительное значение double, контролирующее степень регуляризации. Значение 0 отключает регуляризацию.
- index[] - целочисленный массив, в который будет записана часть результатов операции. Он содержит исходные индексы столбцов, предоставленные конструктору, расположенные в порядке убывания релевантности цели.
- weights[] - массив double, содержащий оптимальные веса, упорядоченные в порядке убывания.
При вызове WeighVars() целевые значения извлекаются из матрицы и помещаются в массив для подготовки к вызову закрытого метода bin_array(). Этот метод сегментирует массив на приблизительно равные по размеру категории, выводя два массива после успешного завершения. upperbound_thresholds[] — это массив верхних порогов для каждого сегмента, тогда как целочисленный массив categories[] содержит значения индекса, представляющие сегмент, к которому принадлежит каждое соответствующее целевое значение. Каждое из этих значений проверяется, чтобы убедиться, что все целевые значения были правильно распределены.
//+------------------------------------------------------------------+ //| calculates the optimal weights of candidate variables | //+------------------------------------------------------------------+ int calc_wt(int num_bins_target,double &loss_value, double &w[]) { int ret,rand_error, class_count[] ; ret = 0; if(ArrayResize(class_count,num_bins_target)!=num_bins_target || (w.Size()!=uint(m_data.Cols()-1) && ArrayResize(w,int(m_data.Cols()-1))!=int(m_data.Cols()-1))) { Print(__FUNCTION__, " error ", GetLastError()); return -1; } ArrayInitialize(w,0.0); loss_value = 0.0 ; for(ulong i=0 ; i<m_data.Rows() ; i++) m_indices[i] = int(i) ; for(int ibootstrap=0 ; ibootstrap<m_num_boot; ibootstrap++) { Comment(" Bootstrap iteration ", ibootstrap+1); ArrayInitialize(class_count,0); int ii, j, k, m; ii = int (m_data.Rows()) ; while(ii > 1) { m = int (m_data.Rows()) - ii ; if(m >= m_bootsize) break ; j = (int)(MathRandomUniform(0.0,1.0,rand_error) * ii) ; if(j >= ii) j = ii - 1 ; k = m_indices[m] ; m_indices[m] = m_indices[m+j] ; m_indices[m+j] = k ; --ii ; ++class_count[m_target_bin[m_indices[m]]] ; } for(int i=0 ; i<num_bins_target ; i++) { if(class_count[i] < 2) Print(__FUNCTION__, " class at ", i, " has less than 2 members. Consider adjusting Frel parameters. (number of partitions or bootstrap sample size)"); } ArrayInitialize(m_trial_weights,0.0); ret += Optimize(m_trial_weights); loss_value += PowellsMethod::GetFret() ; for(ulong i=0 ; i<m_data.Cols()-1 ; i++) w[i] += m_trial_weights[i] ; } for(ulong i=0 ; i<m_data.Cols()-1; i++) w[i] /= double(m_num_boot) ; return ret ; }
Оценка веса начинается с вызова calc_wt(). Здесь выполняется бутстреп-выборка, перемешивающая данные перед оптимизацией начальных весов. Оптимизация выполняется методом родительского класса Optimize(). Оптимальные веса для каждого бутстрапа суммируются в w[] для усреднения перед выходом из calc_wt().
//+------------------------------------------------------------------+ //| function minimized by Powells optimization method | //+------------------------------------------------------------------+ virtual double func(const double& p[]) { double pen = 0.0 ; for(ulong i=0 ; i<m_data.Cols()-1 ; i++) { if(p[i] > 4.0) { m_work_weights[i] = exp(4.0) + p[i] - 4.0 ; pen += (p[i] - 4.0) * (p[i] - 4.0) ; } else if(p[i] < -3.0) { m_work_weights[i] = exp(-3.0) + p[i] + 3.0 ; pen += (p[i] + 3.0) * (p[i] + 3.0) ; } else m_work_weights[i] = exp(p[i]) ; } return (loss(m_work_weights) + pen) ; }
Помните, что минимизируемая функция — это функционал потерь, представленный переопределенным методом родительского класса под названием func().
//+------------------------------------------------------------------+ //| calculates the loss function | //+------------------------------------------------------------------+ double loss(double &w[]) { double totaloss = total_loss(w); totaloss/=double(m_data.Rows()); if(m_reg_factor>0.0) { for(ulong i=0; i<m_data.Cols()-1;i++) totaloss+=m_reg_factor*pow(w[i],2.0); } return totaloss; }
В func() задействован метод loss(), запускающий вычисление функции потерь для каждой выборки, реализованной как закрытый метод total_loss().
//+------------------------------------------------------------------+ //| loss over all data | //+------------------------------------------------------------------+ double total_loss(double &w[]) { int category,first, other ; double distance, top, bottom, loss ; loss = 0.0 ; for(int i=0; i<m_bootsize; i++) { other = m_indices[i] ; category = m_target_bin[other] ; top = bottom = DBL_MAX ; for(int iother=0 ; iother<m_bootsize; iother++) { first = m_indices[iother] ; if(first == other) continue ; distance = 0.0 ; for(ulong v=0 ; v<m_data.Cols()-1; v++) { distance += w[v] * fabs(m_data[other][v] - m_data[first][v]) ; } if(m_target_bin[first] == category) { if(distance < top) top = distance ; } else { if(distance < bottom) bottom = distance ; } } distance = top - bottom ; if(distance > 30.0) loss += distance ; else loss += log(1.0 + exp(distance)); } return loss ; }
После завершения всех бутстрапов усредненные оптимальные веса записываются в предоставленный пользователем массив weights[]. Перед сортировкой по убыванию веса преобразуются таким образом, чтобы их общая сумма составляла 100, что повышает интерпретируемость.
Пример выбора признаков с использованием FREL
Для демонстрации алгоритма FREL мы предоставляем скрипт FrelExample.mq5. Этот скрипт использует FREL для анализа случайно сгенерированного набора данных, включающего в себя кандидаты в переменные и цель для выявления наилучших предикторов. Пользователи могут настраивать все параметры алгоритма FREL и определенные характеристики синтетического набора данных. Сюда входит общее количество наблюдений ( num_observations ) и количество кандидатов-предикторов ( num_candidate_predictors ). Ниже приведен фрагмент, иллюстрирующий настраиваемые пользователем входные данные скрипта:
//---user adjustable input parameters input int number_of_partitions = 8; //Number of partitions input double regularization_factor = 0.0; //Regularization factor input int number_of_bootstraps = 1; input int bootstrap_size = 0; input ulong num_observations = 2000;// Sample size of random dataset input ulong num_candidate_predictors = 10;// Maximum number of candidate predictors in dataset
Скрипт генерирует матрицу случайных чисел с num_observations строк и num_candidate_predictors + 1 столбцов. Последний столбец перезаписывается суммой столбцов с индексами 1, 3, 5 и 7, которая служит целевой переменной набора данных.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { srand(126); //---check user input parameters if(number_of_partitions<2 || num_observations<10 || num_candidate_predictors<8) { Print("Invalid input parameters"); return; } //---the data matrix dataset; //---initialize size of random dataset dataset.Init(num_observations,num_candidate_predictors+1); //---fill dataset with random data dataset.Random(1.0,10.0); //---set the target variable in the last column if(!dataset.Col(dataset.Col(1) + dataset.Col(3) + dataset.Col(5) + dataset.Col(7),num_candidate_predictors)) { Print("error ", GetLastError()); return; } //---initialize Frel object FREL frel(dataset,number_of_bootstraps,bootstrap_size); //---declare containers to recieve output from Frel operation double optimal_weights[]; int index[]; //--- ulong timeIT = GetTickCount64(); //---find the most relevant predictors if(!frel.WeighVars(number_of_partitions,regularization_factor,index,optimal_weights)) return; //---calculate runtime Print("Runtime of FREL ", GetTickCount64() - timeIT, " ms"); //---display results for(uint i = 0; i<optimal_weights.Size(); i++) Print("Predictor at Column index ", index[i], " weight ", optimal_weights[i]); } //+------------------------------------------------------------------+
Цель состоит в том, чтобы увидеть, может ли FREL надлежащим образом взвесить переменные, обозначив столбцы 1, 3, 5 и 7 как имеющие наиболее сильную связь с целью. Первоначально мы запускаем скрипт с параметрами по умолчанию, отметив, что регуляризация отключена и указана только одна самозагрузка.
Результаты.
ON 0 18:12:30.906 FrelExample (BTCUSD,D1) Runtime of FREL 273375 ms GD 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 24.46987538756267 IH 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 24.22319404776024 EL 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 22.26820806768701 LP 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 22.13748732798876 DD 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 1.162036446785271 KK 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 1.1532145209345603 RO 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 1.1496286906955606 RS 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 1.1472521997561425 NG 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 1.14561384476096 DK 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 1.14348946606884
Далее мы исследуем влияние регуляризации на оценочные веса, проводя тестирование со степенями регуляризации 0,1 и 1,0.
Результаты.
MQ 0 18:19:03.951 FrelExample (BTCUSD,D1) Runtime of FREL 331296 ms QD 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 19.63442784832085 PK 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 19.009699240770477 GO 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 18.823288529399388 GQ 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 18.18026689510982 NE 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 4.106428447842871 KI 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 4.075425288243113 OM 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 4.070169243578418 MQ 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 4.051103060690134 FE 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 4.025271426001863 FJ 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 4.0239200200430805
Результаты.
HP 0 18:25:43.421 FrelExample (BTCUSD,D1) Runtime of FREL 362984 ms FF 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 10.353013480731704 JJ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 10.227015183302557 IM 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 10.213781888319609 KQ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 10.079770794877978 PF 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 9.948300319843046 QJ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 9.938367489770178 KN 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 9.897336276433514 DQ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 9.79559491756489 EF 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 9.774541742551756 CI 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 9.77227790660475
Результаты тестов регуляризации показывают, что веса распределяются по другим переменным, отклоняясь от правильных переменных. Вероятно, что указание большей степени регуляризации приведет к менее четким весам, что затруднит дифференциацию полезных переменных от нерелевантных.
При изучении результатов наших тестов становится очевидным, что FREL работает относительно медленно. Узкое место, скорее всего, связано с функцией total_loss(), которая должна многократно проходить по всему набору данных во время работы оптимизатора. Для повышения эффективности выполнения мы проводим многочисленные самозагрузки с меньшим размером выборки. Следующие результаты получены в результате прогона со 100 самозагрузками из 40 выборок.
Результаты.
IN 0 18:30:55.441 FrelExample (BTCUSD,D1) Runtime of FREL 22985 ms OK 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 18.706272752181135 OL 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 18.32079620338284 RS 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 18.194009676469012 HG 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 16.298306686632337 MI 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 5.838867272535404 LM 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 5.249285089162589 FQ 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 4.791606631149278 DE 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 4.770223641360407 KI 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 3.974977300216029 KM 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 3.855654746910961
Заключение
В статье представлена реализация взвешивания признаков на языке MQL5 с использованием регуляризованного энергетического моделирования. Также приведен краткий обзор теоретической основы алгоритма и продемонстрирована его эффективность на синтетическом наборе данных. Хотя результаты оказались многообещающими, что алгоритм требует значительных вычислительных затрат, что приводит к замедлению анализа. Для решения этой проблемы предложено использовать множественные самозагрузки с меньшими размерами выборки, что значительно повысило общую скорость выполнения алгоритма. Однако наша реализация все равно может значительно выиграть от многопоточности или графического ускорения. Тем не менее, лицам, заинтересованным в этом методе, предлагается настроить код в соответствии со своими потребностями. Приложения к статье содержит весь обсуждаемый код. Каждый исходный файл подробно описан в таблице ниже.
Исходный файл | Описание |
---|---|
Mql5\include\np.mqh | Заголовочный файл различных инструментов для работы с векторами и матрицами |
Mql5\include\Powells.mqh | Определение класса PowellsMethod, реализующего метод минимизации функции Пауэллса |
Mql5\include\frel.mqh | Определение класса FREL, представляющего взвешивание признаков как регуляризованный алгоритм обучения на основе энергии |
Mql5\script\FrelExample.mq5 | Скрипт, демонстрирующий использование класса FREL |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/14865
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования