Обсуждение статьи "Использование самоорганизующихся карт Кохонена в трейдинге"

 

Опубликована статья Использование самоорганизующихся карт Кохонена в трейдинге:

Важной особенностью самоорганизующихся карт Кохонена (Kohonen Self-Organizing Maps) является их способность отображать многомерные пространства признаков на плоскость. Представление данных в виде двумерной карты значительно упрощает кластеризацию и корреляционный анализ данных. В этой статье мы разберем несколько простых примеров практического использования карт Кохонена.


Автор: MetaQuotes

 

Полно и главное красиво.

Такой вопрос Евгению - вы один и тот же класс (с небольшими изменениями) копировали во все файлы SOM_exN ?  

и второй вопрос - правильно ли я понял, что у вас функции отображение карт и сами расчеты карт объединены в один класс?

 
sergeev:

Такой вопрос Евгению - вы один и тот же класс (с небольшими изменениями) копировали во все файлы SOM_exN ?  

и второй вопрос - правильно ли я понял, что у вас функции отображение карт и сами расчеты карт объединены в один класс?

Да, Вы правы, класс один и тот же. Незначительные изменения обусловлены спецификой решаемых задач (размерностью данных и способами отображения RGB,CMYK). Функции отображения карт и расчеты объединены в один класс.

Общая структура такова:

//--- загружаем обучающее множество в массив m_training_sets_array[]
 KohonenMap.LoadData()
//--- обучение сети - модификация значений весов узлов m_som_nodes[]
 KohonenMap.Train();
//--- формирование картинки с картой - "проектирование" состояния узлов в экземпляр класса cIntBMP
 KohonenMap.Render();
//--- показываем подписи на карте к каждому из элементов обучающего множества 
//т.е. добавляем на рисунок идентификаторы каждого из элементов обучающего множества
 KohonenMap.ShowTrainPatterns();
//--- показываем картинку на графике
 KohonenMap.ShowBMP();

расчет производится в методе Train (для некоторых случаев внутри него вызываются Render и ShowBMP для показа процесса обучения), затем результаты "переносятся" на bmp-картинку, которая отображается в методе ShowBMP.

Для отрисовки и отображения использовался класс cIntBMP.

 
Quantum:

Да, Вы правы, класс один и тот же. Незначительные изменения обусловлены спецификой решаемых задач (размерностью данных и способами отображения RGB,CMYK). Функции отображения карт и расчеты объединены в один класс.

может тогда для удобства работы с классами переделать в иерархию ?  уверен это уменьшит код и упростит знакомство с ним

особенно что касается одних и тех же функций одинаковых во всех файлах.


 
sergeev:

может тогда для удобства работы с классами переделать в иерархию ?  уверен это уменьшит код и упростит знакомство с ним

особенно что касается одних и тех же функций одинаковых во всех файлах.

задумка была в том, чтобы показать практические аспекты использования сетей Кохонена.

В методическом плане оказалось удобнее рассмотреть все задачи отдельно. небольшая иерархия имеется, CSOM->CSomWeb, CSOM->CSomFood (все они трехмерные, как и первый пример). В 4-х мерном случае с ирисами Фишера наряду с CSOM пришлось менять также и CSomNode для работы с 4 компонентами. Потом появились компонентные плоскости, а m_bmp превратился в массив.

Далее после отказа от отображения фиксированных специфических 3-х (RGB) и 4-х мерных (CMYK) данных получился SOM.mq5, который позволяет работать с данными любой размерности, данные предыдущих примеров перенеслись в файлы определенного формата, а их анализ далее проводится на языке компонентных плоскостей.

По сути, нам нужен som.mq5 как инструмент, а все остальные примеры носят обучающих характер и являются лишь иллюстрацией особенностей сетей Кохонена.

 

в функции CSOM::ReadCSVData

строка какая-то неправильная

// инициализация сети, 10000 итераций, решетка CellsX*CellsY узлов, картинка ImageXSize x ImageYSize
int dimension=ArraySize(stringsarr)-1;
KohonenMap.InitParameters(dimension,10000,CellsX,CellsY,ImageXSize,ImageYSize);

 
sergeev:

в функции CSOM::ReadCSVData

строка какая-то неправильная

Если имеется ввиду строка:

int dimension=ArraySize(stringsarr)-1;

то здесь дело в специфике формата файла входных данных -  размерность предполагается равной кол-ву столбцов-1.

последний столбец - это строковое наименование обучающей выборки. Например в products.csv

Protein;Carbohydrate;Fat;Title
0.4;11.8;0.1;Apples

первая строка-заголовок, содержащая наименования компонент, они уйдут в массив m_som_titles[].

далее идут данные (в m_training_sets_array[]) и наименования (в m_train_titles[]).

 
нет, я ж выделил красным цветом
KohonenMap

у вас в самом классе присутствует объект этого класса.  вот.

-------------------------

В связи с этим с точки зрения дальнейшего использования класса CSOM автономно необходимо:

1. Разделить файлы с классами CSOMNode, CSOM и конкретные скрипты их использования

2. Убрать внешние input параметры из класса CSOM в конкретный скрипт.

3. Добавить в самом классе все эти параметры

public:
    ColorSchemes m_clrSchema; // градиентная схема
    int m_maxpict; // число картинок в ряду
    bool m_bHexCell; // шестигранные ячейки
    bool m_bShowBorder; // показывать границы
    bool m_bShowTitle; // показывать подписи

4.
В связи с этим функцию CSOM::Init расширить на 5 параметров для инициализации (можно удалить m_dimension, которая задаётся в ReadCSVData)
Init(int iter, int xc, int yc, int bmpw, int bmph, int maxpic, ColorSchemes clrSchema, bool bhex, bool bborder, bool btitle)

Это позволит вам вынести класс CSOM из файла эксперта и использовать его просто как include к нужным проектам

#property script_show_inputs

#include "SOM.mqh"

input string DataFileName="products.csv"; // Имя файла данных
input int CellsX=30; // Число узлов по X
input int CellsY=30; // Число узлов по Y
input int ImageW=250; // Ширина картинки
input int ImageH=250; // Высота картинки
input int MaxPictures=4; // макс. картинок в строке
input bool HexagonalCell=true; // Ячейки в виде шестиугольников
input bool ShowBorders=false; // показ границ ячеек
input bool ShowTitles=true; // показ наименований в координатных плоскостях
input ColorSchemes ColorScheme=Blue_Green_Red; // Цвета градиента

//------------------------------------------------------------------    OnStart
void OnStart()
{
  CSOM KohonenMap;
  MathSrand(200);
  // загружаем обучающее множество из файла
  if(!KohonenMap.LoadTrainDataFromFile(DataFileName)) { Print("Ошибка загрузки данных для обучения"); return; }
  KohonenMap.Init(10000, CellsX, CellsY, ImageW, ImageH, MaxPictures, ColorScheme, HexagonalCell, ShowBorders, ShowTitles); // инициализация сети
  KohonenMap.Train(); // обучение сети
  KohonenMap.Render(); // формирование картинки с картой
  KohonenMap.ShowTrainPatterns(); // показываем подписи на карте к каждому из элементов обучающего множества
  KohonenMap.ShowBMP(); // показываем картинку на графике
}

и еще одна доработка - функцию ReadCSVData на всякий случай сделать тоже bool.
и проверять несовпадение размерностей заголовка и считанной очередной строки данных

PS.

я уже произвел все эти манипуляции с классом, так скажем доработал мелочи.
Но всё равно ваш класс CSOM просто шикарный. Спасибо.
 
sergeev:

и еще одна доработка - функцию ReadCSVData на всякий случай сделать тоже bool.
и проверять несовпадение размерностей заголовка и считанной очередной строки данных

PS.

я уже произвел все эти манипуляции с классом, так скажем доработал мелочи.

Большое Вам спасибо за интерес и полезные рекомендации.

Про KohonenMap.InitParameters понял, тут явно ошибка.

Финальный класс конечно нужно поправить так как Вы предложили, будет гораздо красивее.

Приложите пожалуйста что у Вас получилось, заменим его в статье.

 

Одна из лучших статей на MQL5. И в практическом смысле особенно.

Спасибо!

 
Quantum:

Приложите пожалуйста что у Вас получилось, заменим его в статье.

прикладываю. список изменений:

1. небольшое изменение в функции cIntBMP::Show(int aX, int aY, string aBMPFileName, string aObjectName, bool aFromImages=true)

2. в основной скрипт добавлено

#import "shell32.dll"
   int ShellExecuteW(int hwnd, string oper, string prog, string param, string dir, int show);
#import

input bool OpenAfterAnaliz=true; // открытие папки с картами после завершения

Изменения в классе CSOM

1. Добавлена функция CSOM::HideChart - она гасит под цвет фона график, сетку и т.д.
2. Добавлены параметры m_chart, m_wnd, m_x0, m_y0 - указание на каком чарте и каком окне отображать карты.
+ префикс имен объектов m_sID.  Префикс автоматически берется по имени файла, иначе присваивается "SOM"
3. Карты пишутся в папку с именем m_sID
4. Имена файлов bmp даются по имени столца обучающего паттерна.
4. Изменена функция CSOM::ShowBMP - карты не копируются в папку Images, а остаются в Files (иначе очень затратно по времени получается)
5. Вместо функции CSOM::NetDeinit - появилась функция CSOM::HideBMP
7. Функция CSOM::ReadCSVData перенастроена на чтение файла, чтоб первый столбец - это столбец названий
6. В функцию CSOM::Train добавлен флаг показа промежуточных карт CSOM::Train(bool bShowProgress)
8. В функции CSOM::Train отображение промежуточных данных происходит через каждые 2 секунды, а не через итерации,
а также оповещение прогресса вынесено из журнала в Comment
9. Укорочены имена некоторых переменных и упорядочены функции по категориям.

отрисовка bmp очень тормозит процесс. Поэтому лучше без надобности не использовать.

В примере, карты построенные на данных оптимизации эксперта.
Файлы: