![MetaTrader 5에서 자동 정리 기능 맵 (코호넨 맵) 이용하기](https://c.mql5.com/i/articles/overlay.png)
MetaTrader 5에서 자동 정리 기능 맵 (코호넨 맵) 이용하기
들어가며
-자체 구성 기능 맵 (Self Organizing Feature Map, SOM) 은 맵 라고 불리는 훈련 샘플의 입력 공간에 대한 2차원 이산 표현을 생성하기 위해 감독되지 않은 학습을 사용하여 훈련되는 인공 신경 네트워크의 한 종류입니다.
이러한 맵은 다차원 스케일링과 유사한 고차원 데이터의 저차원 보기를 분류하고 시각화하는 데 유용합니다. 이 모델은 핀란드 교수인튜보 코호넨( Teuvo Kohonen)에 의해 인공신경망으로 처음 도입되었고 때로는 코호넨 맵이라고도 불린다.
이용가능한 알고리즘은 여럿 있지만 우리는 http://www.ai-junkie.com에서 제공된 코드를 활용할 것입니다. MetaTrader 5 클라이언트 터미널에서 데이터를 시각화하기 위하여 우린 BMP 이미지 생성용 라이브러리인 cIntBMP 를 사용할 것입니다. 이 기사에서는 코호넨 지도의 몇 가지 간단한 응용 프로그램을 살펴보겠습니다.
1. 자체 구성 기능 맵
자체 구성 기능 맵은 Teuvo Kohonen가 1982년에 처음 제창했습니다. 많은 신경망과 달리 입력 및 대상 출력 데이터 간의 일대일 대응이 필요하지 않습니다. 이 신경망은 비지도형 기계 학습을 사용하여 훈련됩니다.
SOM은 공식적으로 일반 저차원 어레이 요소에 대한 고차원 입력 데이터의 비선형, 순서, 매끄러운 매핑으로 설명할 수 있습니다. 기본적인 형태로 입력 데이터의 유사성 그래프를 생성합니다.
SOM은 고차원 데이터 간의 비선형 통계 관계를 노드의 정규 2차원 그리드에서 영상 포인트의 단순한 기하학적 관계로 변환합니다. SOM 맵은 고차원 데이터의 분류 및 시각화에 사용할 수 있습니다.
1.1. 네트워크 아키텍쳐
16개 노드의 그리드로 된 간단한 코호넨 맵(각 노드 4x4는 3차원 입력 벡터로 연결됨)이 1번 그림에 나타나있습니다.
1번 그림. 간단 코호넨 맵 (16 노드)
각 노드는 (x,y) 좌표를 가지고 있으며, 입력 벡터에 기초하여 정의된 구성 요소를 포함한 가중치의 벡터입니다.
1.2. 학습 알고리즘
다른 많은 종류의 신경망과 달리, SOM은 목표 출력을 지정할 필요가 없습니다. 대신 노드 가중치가 입력 벡터와 일치하는 경우, 격자 영역은 입력 벡터가 속한 클래스의 데이터와 더 가깝게 최적화됩니다.
무작위 가중치의 초기 분포로부터 그리고 여러 번 반복하여, SOM은 결국 안정 구역의 지도에 안착합니다. 각 영역은 실질적으로는 기능 분류기이므로 그래픽 출력을 입력 공간의 기능 맵 유형으로 생각할 수 있습니다.
학습은 여러 단계로 진행되며 여러 번 반복됩니다:
- 각 노드의 가중치는 무작위 값으로 초기화됩니다.
- 벡터는 학습 데이터 집합에서 무작위로 선택됩니다.
- 모든 노드가 입력 벡터와 가장 유사한 가중치를 계산하기 위해 검사됩니다. 우승 노드는 일반적으로 BMU(Best Matching Unit)로 알려져 있습니다.
- BMU 주변의 반경이 계산됩니다. 처음에는 이 값이 격자의 반지름으로 설정되지만 각 단계마다 희미해집니다.
- BMU 반경 내에서 발견되는 노드의 경우, 노드의 가중치는 입력 벡터처럼 되도록 조정됩니다. 노드가 BMU에 가까울수록 더 많은 노드에 경보가 울립니다.
- N 회 동안 2단계를 반복합니다.
상세에 대해선 http://www.ai-junkie.com에서 찾아보실 수 있습니다.
2. 케이스 분석
2.1. 예시 1 SOM에서의 "Hello World!"
코호넨 지도의 전형적인 예는 색상 클러스터링 문제입니다.
8가지 색상 세트가 있다고 가정하면, 각각은 RGB 색상 모델에서 3차원 벡터로 표현됩니다. .
-
빨강: (255,0,0);
녹색: (0,128,0);
파랑: (0,0,255);
암록색: (0,100,0);
군청색: (0,0,139);
노랑: (255,255,0);
주황색: (255,165,0);
보라색: (128,0,128).
MQL5 language로 코호넨 맵을 다룰 때, 우리는 객체 지향 패러다임을 따릅니다.
일반 그리드의 노드에 대한 CSOMNode 클래스와 신경망 클래스인 CSOM, 이렇게 두 가지 클래스가 필요합니다.
//+------------------------------------------------------------------+ //| CSOMNode class | //+------------------------------------------------------------------+ class CSOMNode { protected: int m_x1; int m_y1; int m_x2; int m_y2; double m_x; double m_y; double m_weights[]; public: //--- class constructor CSOMNode(); //--- class destructor ~CSOMNode(); //--- node initialization void InitNode(int x1,int y1,int x2,int y2); //--- return coordinates of the node's center double X() const { return(m_x);} double Y() const { return(m_y);} //--- returns the node coordinates void GetCoordinates(int &x1,int &y1,int &x2,int &y2); //--- returns the value of weight_index component of weight's vector double GetWeight(int weight_index); //--- returns the squared distance between the node weights and specified vector double CalculateDistance(double &vector[]); //--- adjust weights of the node void AdjustWeights(double &vector[],double learning_rate,double influence); };
이 클래스 메소드 구현은 som_ex1.mq5에서찾아보실 수 있습니다. 코드 안에 주석이 상당히 많습니다, 그 아이디어에 집중할겁니다.
CSOM 클래스는 이하와 같습니다:
//+------------------------------------------------------------------+ //| CSOM class | //+------------------------------------------------------------------+ class CSOM { protected: //--- class for using of bmp images cIntBMP m_bmp; //--- grid mode int m_gridmode; //--- bmp image size int m_xsize; int m_ysize; //--- number of nodes int m_xcells; int m_ycells; //--- array with nodes CSOMNode m_som_nodes[]; //--- total items in training set int m_total_training_sets; //--- training set array double m_training_sets_array[]; protected: //--- radius of the neighbourhood (used for training) double m_map_radius; //--- time constant (used for training) double m_time_constant; //--- initial learning rate (used for training) double m_initial_learning_rate; //--- iterations (used for training) int m_iterations; public: //--- class constructor CSOM(); //--- class destructor ~CSOM(); //--- net initialization void InitParameters(int iterations,int xcells,int ycells,int bmpwidth,int bmpheight); //--- finds the best matching node, closest to the specified vector int BestMatchingNode(double &vector[]); //--- train method void Train(); //--- render method void Render(); //--- shows the bmp image on the chart void ShowBMP(bool back); //--- adds a vector to training set void AddVectorToTrainingSet(double &vector[]); //--- shows the pattern title void ShowPattern(double c1,double c2,double c3,string name); //--- adds a pattern to training set void AddTrainPattern(double c1,double c2,double c3); //--- returns the RGB components of the color void ColToRGB(int col,int &r,int &g,int &b); //--- returns the color by RGB components int RGB256(int r,int g,int b) const {return(r+256*g+65536*b); } //--- deletes image from the chart void NetDeinit(); };
CSOM 클래스 용법은 간단합니다:
CSOM KohonenMap; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ void OnInit() { MathSrand(200); //--- initialize net, 10000 iterations will be used for training //--- the net contains 15x20 nodes, bmp image size 400x400 KohonenMap.InitParameters(10000,15,20,400,400); //-- add RGB-components of each color from training set KohonenMap.AddTrainPattern(255, 0, 0); // Red KohonenMap.AddTrainPattern( 0,128, 0); // Green KohonenMap.AddTrainPattern( 0, 0,255); // Blue KohonenMap.AddTrainPattern( 0,100, 0); // Dark green KohonenMap.AddTrainPattern( 0, 0,139); // Dark blue KohonenMap.AddTrainPattern(255,255, 0); // Yellow KohonenMap.AddTrainPattern(255,165, 0); // Orange KohonenMap.AddTrainPattern(128, 0,128); // Purple //--- train net KohonenMap.Train(); //--- render map to bmp KohonenMap.Render(); //--- show patterns and titles for each color KohonenMap.ShowPattern(255, 0, 0,"Red"); KohonenMap.ShowPattern( 0,128, 0,"Green"); KohonenMap.ShowPattern( 0, 0,255,"Blue"); KohonenMap.ShowPattern( 0,100, 0,"Dark green"); KohonenMap.ShowPattern( 0, 0,139,"Dark blue"); KohonenMap.ShowPattern(255,255, 0,"Yellow"); KohonenMap.ShowPattern(255,165, 0,"Orange"); KohonenMap.ShowPattern(128, 0,128,"Purple"); //--- show bmp image on the chart KohonenMap.ShowBMP(false); //--- }
결과를 2번 그림에서 볼 수 있습니다.
2번 그림. SOM_ex1.mq5 Expert Advisor의 결과
코호넨 맵 학습의 역학은 그림 3에 제시되어 있습니다(이미지 아래의 단계 참조).
3번 그림. 코호넨 맵 학습 역학
3번 그림에서 볼 수 있는 코호넨 맵은 2400 단계 후에 완성된 것입니다.
300개 노드의 그리드를 생성하고 이미지 크기를 400x400으로 지정하는 경우:
//--- lattice of 15x20 nodes, image size 400x400 KohonenMap.InitParameters(10000,15,20,400,400);
4번 그림에 획득한 이미지가 있습니다:
4번 그림. 300 노드 코호넨 맵, 이미지 사이즈 400x400
Guido Deboeck와 Teuvo Kohonen이 쓴 Visual Explorations in Finance: with Self-Organizing Maps을 읽어보셨다면 격자 노드는 육각형 셀로도 표현될 수 있다는 것을 알 수 있을 것입니다. Expert Advisor의 코드를 수정하여 다른 시각화를 구현할 수 있습니다.
SOM-ex1-hex.mq5 의 결과물은 5번 그림에 나타나 있습니다:
5번 그림. 300개의 노드가 있는 코호넨 맵, 이미지 크기 400x400, 노드는 육각 셀로 표시됩니다.
이 버전에서는 입력 패러미터를 사용하여 셀 테두리 표시를 정의할 수 있습니다.
// input parameter, used to show hexagonal cells input bool HexagonalCell=true; // input parameter, used to show borders input bool ShowBorders=true;
만약 셀 테두리를 표시할 필요가 없을 경우, ShowBounders=false로 지정하고 다음의 이미지를 얻을 수 있게 됩니다 (그림 6 참조):
6번 그림. 300개의 노드로 된 코호넨 맵, 이미지 400x400, 육각 셀로 표시된 노드, 셀 테두리 비활성화
첫 번째 예에서는 지정된 색상 구성 요소를 가진 학습 세트에 8가지 색상을 사용했습니다. CSOM 클래스에 두 가지 메소드를 추가하여 교육 세트를 확장하고 색상 구성요소 지정을 단순화할 수 있습니다.
이 경우 색상 공간에 구분된 색상이 거의 없기 때문에 코호넨 맵이 단순합니다. 결과적으로 로컬화된 클러스터를 얻게됩니다.
더 가까운 색상 구성 요소와 더 많은 색상을 고려하면 문제가 나타납니다.
2.2. 예시 2 학습 샘플로 웹 색상 이용하기
MQL5 언어에서 웹 색상은 사전 정의된 상수입니다.
7번 그림. 웹 색상
코호넨 알고리즘을 유사한 구성 요소를 가진 벡터 집합에 적용하면 어떨까요?
CSOM 클래스에서 파생된 CSOMWeb 클래스를 생성할 수 있습니다.
//+------------------------------------------------------------------+ //| CSOMWeb class | //+------------------------------------------------------------------+ class CSOMWeb : public CSOM { public: //--- adds a color to training set (used for colors, instead of AddTrainPattern) void AddTrainColor(int col); //--- method of showing of title of the pattern (used for colors, instead of ShowPattern) void ShowColor(int col,string name); };
보시다시피 컬러로 작업을 단순화하기 위해 두 가지 새로운 방법을 추가했습니다. 컬러 구성요소를 명시적으로 지정할 필요가 없습니다.
클래스 방법의 구현은 다음과 같습니다:
//+------------------------------------------------------------------+ //| Adds a color to training set | //| (used for colors, instead of AddTrainPattern) | //+------------------------------------------------------------------+ void CSOMWeb::AddTrainColor(int col) { double vector[]; ArrayResize(vector,3); int r=0; int g=0; int b=0; ColToRGB(col,r,g,b); vector[0]=r; vector[1]=g; vector[2]=b; AddVectorToTrainingSet(vector); ArrayResize(vector,0); } //+------------------------------------------------------------------+ //| Method of showing of title of the pattern | //| (used for colors, instead of ShowPattern) | //+------------------------------------------------------------------+ void CSOMWeb::ShowColor(int col,string name) { int r=0; int g=0; int b=0; ColToRGB(col,r,g,b); ShowPattern(r,g,b,name); }
모든 웹 색상은 web_colors[] 어레이에 합쳐질 수 있습니다:
//--- web colors array color web_colors[132]= { clrBlack, clrDarkGreen, clrDarkSlateGray, clrOlive, clrGreen, clrTeal, clrNavy, clrPurple, clrMaroon, clrIndigo, clrMidnightBlue, clrDarkBlue, clrDarkOliveGreen, clrSaddleBrown, clrForestGreen, clrOliveDrab, clrSeaGreen, clrDarkGoldenrod, clrDarkSlateBlue, clrSienna, clrMediumBlue, clrBrown, clrDarkTurquoise, clrDimGray, clrLightSeaGreen, clrDarkViolet, clrFireBrick, clrMediumVioletRed, clrMediumSeaGreen, clrChocolate, clrCrimson, clrSteelBlue, clrGoldenrod, clrMediumSpringGreen, clrLawnGreen, clrCadetBlue, clrDarkOrchid, clrYellowGreen, clrLimeGreen, clrOrangeRed, clrDarkOrange, clrOrange, clrGold, clrYellow, clrChartreuse, clrLime, clrSpringGreen, clrAqua, clrDeepSkyBlue, clrBlue, clrMagenta, clrRed, clrGray, clrSlateGray, clrPeru, clrBlueViolet, clrLightSlateGray, clrDeepPink, clrMediumTurquoise, clrDodgerBlue, clrTurquoise, clrRoyalBlue, clrSlateBlue, clrDarkKhaki, clrIndianRed, clrMediumOrchid, clrGreenYellow, clrMediumAquamarine, clrDarkSeaGreen, clrTomato, clrRosyBrown, clrOrchid, clrMediumPurple, clrPaleVioletRed, clrCoral, clrCornflowerBlue, clrDarkGray, clrSandyBrown, clrMediumSlateBlue, clrTan, clrDarkSalmon, clrBurlyWood, clrHotPink, clrSalmon, clrViolet, clrLightCoral, clrSkyBlue, clrLightSalmon, clrPlum, clrKhaki, clrLightGreen, clrAquamarine, clrSilver, clrLightSkyBlue, clrLightSteelBlue, clrLightBlue, clrPaleGreen, clrThistle, clrPowderBlue, clrPaleGoldenrod, clrPaleTurquoise, clrLightGray, clrWheat, clrNavajoWhite, clrMoccasin, clrLightPink, clrGainsboro, clrPeachPuff, clrPink, clrBisque, clrLightGoldenrod, clrBlanchedAlmond, clrLemonChiffon, clrBeige, clrAntiqueWhite, clrPapayaWhip, clrCornsilk, clrLightYellow, clrLightCyan, clrLinen, clrLavender, clrMistyRose, clrOldLace, clrWhiteSmoke, clrSeashell, clrIvory, clrHoneydew, clrAliceBlue, clrLavenderBlush, clrMintCream, clrSnow, clrWhite };
OnInit() 함수는 간단한 형태로 되어있습니다:
CSOMWeb KohonenMap; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ void OnInit() { MathSrand(200); int total_web_colors=ArraySize(web_colors); //--- initialize net, 10000 iterations will be used for training //--- the net contains 15x20 nodes, bmp image size 400x400 KohonenMap.InitParameters(10000,50,50,500,500); //-- add all web colors to training set for(int i=0; i<total_web_colors; i++) { KohonenMap.AddTrainColor(web_colors[i]); } //--- train net KohonenMap.Train(); //--- render map to bmp KohonenMap.Render(); //--- show patterns and titles for each color for(int i=0; i<total_web_colors; i++) { KohonenMap.ShowColor(web_colors[i],ColorToString(web_colors[i],true)); } //--- show bmp image on the chart KohonenMap.ShowBMP(false); }
som-ex2-hex.mq5를 실행하면 그림 8에 표시된 그림을 볼 수 있게 됩니다.
8번 그림. 웹 색상의 코호넨 맵
보시는 것처럼 클러스터가 일부 있지만 일부 색상(예: xxxBlue)은 서로 다른 지역에 있습니다.
그 이유는 학습 세트의 구조 때문입니다. 구성 요소가 밀접한 벡터가 많습니다.
2.3. 예시 3 상품 클러스터링
지금부터 우리는 25개의 음식을 3개 패러미터 단백질, 탄수화물 그리고 지방의 유사도에 따라 영역에 몰아넣을 것입니다. .
음식 | 단백질 | 탄수화물 | 지방 | |
---|---|---|---|---|
1 | 사과 | 0.4 | 11.8 | 0.1 |
2 | 아보카도 | 1.9 | 1.9 | 19.5 |
3 | 바나나 | 1.2 | 23.2 | 0.3 |
4 | 소고기 스테이크 | 20.9 | 0 | 7.9 |
5 | 빅 맥 | 13 | 19 | 11 |
6 | 브라질 너츠 | 15.5 | 2.9 | 68.3 |
7 | 빵 | 10.5 | 37 | 3.2 |
8 | 버터 | 1 | 0 | 81 |
9 | 치즈 | 25 | 0.1 | 34.4 |
10 | 치즈케잌 | 6.4 | 28.2 | 22.7 |
11 | 쿠키 | 5.7 | 58.7 | 29.3 |
12 | 콘플레이크 | 7 | 84 | 0.9 |
13 | 달걀 | 12.5 | 0 | 10.8 |
14 | 후라이드 치킨 | 17 | 7 | 20 |
15 | Fries | 3 | 36 | 13 |
16 | 핫 초코 | 3.8 | 19.4 | 10.2 |
17 | 페퍼로니 | 20.9 | 5.1 | 38.3 |
18 | 피자 | 12.5 | 30 | 11 |
19 | 돼지고기 파이 | 10.1 | 27.3 | 24.2 |
20 | 감자 | 1.7 | 16.1 | 0.3 |
21 | Rice | 6.9 | 74 | 2.8 |
22 | 통닭 | 26.1 | 0.3 | 5.8 |
23 | 설탕 | 0 | 95.1 | 0 |
24 | 참치 스테이크 | 25.6 | 0 | 0.5 |
25 | 물 | 0 | 0 | 0 |
테이블 1. 25개 음식의 단백질, 탄수화물, 지방
이 문제는 입력 벡터의 값이 다르고 구성 요소마다 값 범위가 다르기 때문에 흥미롭습니다. RGB 색상 모델을 0부터 255까지 다양하게 사용하므로 시각화에 매우 중요합니다.
다행히 이 경우 입력 벡터 또한 3차원이며 코호넨 맵 시각화를 위해 RGB 색상 모델을 사용할 수 있습니다.
//+------------------------------------------------------------------+ //| CSOMFood class | //+------------------------------------------------------------------+ class CSOMFood : public CSOM { protected: double m_max_values[]; double m_min_values[]; public: void Train(); void Render(); void ShowPattern(double c1,double c2,double c3,string name); };
보시다시피 교육 세트의 최대값과 최소값 저장을 위해 m_max_values[], m_min_values[] 어레이를 추가하였으며, RGB 컬러 모델 시각화를 위해서는 "스케일링"이 필요하므로 Train(), Render(), ShowPattern() 메소드를 오버로드하였습니다.
최대값과 최소값의 검색은 Train() 메소드로 구현됩니다.
//--- find minimal and maximal values of the training set ArrayResize(m_max_values,3); ArrayResize(m_min_values,3); for(int j=0; j<3; j++) { double maxv=m_training_sets_array[3+j]; double minv=m_training_sets_array[3+j]; for(int i=1; i<m_total_training_sets; i++) { double v=m_training_sets_array[3*i+j]; if(v>maxv) {maxv=v;} if(v<minv) {minv=v;} } m_max_values[j]=maxv; m_min_values[j]=minv; Print(j,"m_min_value=",m_min_values[j],"m_max_value=",m_max_values[j]); }
RGB 색상 모델에서 구성 요소를 표시하려면 Render() 메소드를 수정해야 합니다.
// int r = int(m_som_nodes[ind].GetWeight(0)); // int g = int(m_som_nodes[ind].GetWeight(1)); // int b = int(m_som_nodes[ind].GetWeight(2)); int r=int ((255*(m_som_nodes[ind].GetWeight(0)-m_min_values[0])/(m_max_values[0]-m_min_values[0]))); int g=int ((255*(m_som_nodes[ind].GetWeight(1)-m_min_values[1])/(m_max_values[1]-m_min_values[1]))); int b=int ((255*(m_som_nodes[ind].GetWeight(2)-m_min_values[2])/(m_max_values[2]-m_min_values[2])));
9번 그림에서 나타난 som_ex3.mq5의 결과물
9번 그림. 음식 맵, 유사도에 따른 영역 그룹, 단백질 탄수화물 지방 기준
구성 요소 분석 지도에서 설탕, 쌀, 그리고 콘플레이크가 탄수화물 (2번째 구성요소) 때문에 녹색으로 표시되어 있다는 것을 알 수 있습니다. 버터는 지방 (3번째 구성요소)가 많아 녹색 영역에 있습니다. 비프 스테이크, 로스트 치킨, 참치 스테이크에는 단백질 (1번째 구성 요소) 이 듬뿍 들어 있습니다.
식품 구성 테이블 (대체 테이블)에서 새 음식을 받아추가하는 것으로 학습 세트를 늘릴 수 있습니다.
보시다시피 문제는 "순수하게" R, G, B 방향으로 해결되었습니다. 몇 가지 동일한 구성 요소를 가진 다른 음식들은 어떨까요? 컴포넌트 평면는 특히 입력 벡터의 치수가 3보다 큰 경우에 매우 유용합니다.
2.4. 예시 4 4차원 케이스 피셔의 아이리스 데이터셋 CMYK
3차원 벡터의 경우 시각화에 문제가 없습니다. 결과는 색상 구성요소를 시각화하는 데 사용되는 RGB 색상 모델 때문에 명확합니다.
고차원 데이터로 작업할 때는 시각화할 수 있는 방법을 찾아야 합니다. 간단한 해결책은 벡터 길이에 비례하여 색상을 사용하여 그라데이션 맵(예: 블랙/화이트)을 플롯하는 것입니다. 다른 방법은 다른 색상 공간을 사용하는 것입니다. 이 예시에서 우리는 피셔의 아이리스 데이터 셋에 대해CMYK색상 모델을 이용해볼 것입니다. 더 나은 해결책이 있습니다. 고려해 볼 필요도 없습니다.
아이리스 꽃 데이터 세트 또는 피셔의 아이리스 데이터 세트는 R. 피셔가 1936년에 소개한 판별 분석의 예시입니다. 이 데이터셋은 아이리스 꽃 3개종으로부터 각각 50 샘플씩 추출한 데이터가 담겨있습니다 (Iris setosa, Iris virginica 및 Iris versicolor).
각 샘플에서 꽃받침의 너비와 길이, 꽃잎의 너비와 길이 도합 4개 요소가 측정되었습니다.
10번 그림. 아이리스 꽃
각 샘플엔 4개의 특징이 있습니다:
- 꽃받침 길이;
- 꽃받침 너비;
- 꽃잎 길이;
- 꽃잎 너비.
아이리스 꽃 데이터 셋은 SOM_ex4.mq5에서 찾아볼 수 있습니다.
이 예에서는 중간 CMYK 색상 공간을 플로팅에 사용합니다. 즉, 노드의 가중치를 CMYK 공간의 벡터로 간주합니다. 결과를 시각화하기 위해 CMYK->RGB 변환이 사용됩니다. 새 메소드 int CSOM::CMYK2Col(uchar c,uchar m,uchar y,uchar k)가 CSOM 클래스에 추가되었으며, CSOM::Render() 메소드에서 활용됩니다. 또한 4차원 벡터를 지원하도록 클래스를 수정해야 합니다.
결과를 11번 그림에서 볼 수 있습니다.
11번 그림. CMYK 컬러 모델으로 표시된 아이리스 꽃 데이터 셋용 코호넨 맵
무엇이 보이십니까? 문제의 특징 때문에 완전한 클러스터링은 없지만, iris setosa의 선형 분리는 확인할 수 있습니다.
setosa가 선형으로 분리되는 이유는 CMYK 공간에 큰 "마젠타" 구성 요소 (2번째) 때문입니다.
2.6. 구성 요소 평면 분석
이전의 예(음식 및 홍채 데이터 클러스터링)에서 데이터 시각화에 문제가 있음을 알 수 있습니다.
예를 들어, 음식 문제를 위해, 우리는 특정 색(빨간색, 녹색, 파란색)에 대한 정보를 사용하여 코호넨 맵을 분석했습니다. 기본적인 클러스터 외에도, 몇 가지 구성 요소가 있는 음식들이 있었습니다. 또한, 구성 요소가 대부분 같으면 분석이 어려워집니다.
구성 요소 평면은 각 식품에 대한 상대적인 강도를 볼 수 있는 기회를 제공합니다..
우리는 CIntBMP 클래스 인스턴스 (m_bmp[] 어레이를) CSOM 클래스에 추가하고 이에 대응되는 렌더 메소드를 수정할 필요가 있습니다. 또한 각 구성 요소의 강도를 시각화할 수 있는 그라데이션 맵이 필요합니다(낮은 값은 파란색, 높은 값은 빨간색).
12번 그림. 그라디언트 파레트
Palette[768] 어레이, GetPalColor() 및 Blend() 메소드를 추가했습니다. RenderCell() 메소드에 노드 그림이 추가되었습니다.
아이리스 꽃 데이터 셋
som-ex4-cpr.mq5의 결과는 13번 그림에 나타나있습니다.
13번 그림. 아이리스 꽃 데이터 셋의 구성요소 평면 표현
이 경우 이미지 크기가 300x300인 30x30 노드가 있는 그리드를 사용합니다.
구성 요소 평면은 상관 관계 검출에 중요한 역할을 합니다. 이러한 평면을 비교함으로써 부분적으로 상관 관계가 있는 변수도 육안 검사를 통해 검출될 수 있습니다. 상관 관계가 있는 평면이 서로 가까이 오도록 구성 요소 평면을 재구성하는 경우 이 작업이 더 쉽습니다. 이렇게 하면 추가 조사를 위해 흥미로운 구성 요소 조합을 쉽게 선택할 수 있습니다.
구성 요소 평면을 고려해봅시다 (14번 그림).
최대 및 최소 구성 요소의 값이 그라데이션 표에 표시됩니다.
14번 그림. 아이리스 꽃 데이터 셋 구성 요소 평면
CMYK 색상 모델에 표시된 모든 구성 요소 평면은 그림 15에 나와 있습니다.
15번 그림. 아이리스 꽃 데이터 셋 CMYK 색상 모델로 된 코호넨 맵
아이리스 타입 setosa 를 다시 떠올려 봅시다. 구성요소 평면 분석(그림 14)을 사용하여 첫 번째(Sepal Length), 세 번째(Petal Length), 네 번째(Petal Width) 구성요소 평면에서 최소값을 가지는 것을 알 수 있습니다.
CMYK 컬러 모델과 동일한 결과인 두 번째 구성 요소 평면(꽃받침 너비)에서 최대값을 보인다는 점이 주목할 만합니다(Magenta 구성 요소t, 그림 15).
음식 클러스터링
이제 성분 평면 분석(som-ex3-cpr.mq5)을 사용한 식품 클러스터링 문제를 고려해 봅시다.
결과는 16번 그림 (30x30 노드, 이미지 크기 300x300, 테두리가 없는 육각 셀)에 나와 있습니다.
16번 그림. 식품 코호넨 맵, 구성 요소 평면 표현
CSOM 클래스의 ShowPattern() 메소드에 타이틀 표시 옵션을 추가하였습니다(입력 패러미터 ShowTitles=true).
구성 요소 평면(단백질, 탄수화물, 지방)은 다음과 같습니다.
17번 그림. 음식의 코호넨 맵 구성 요소평면과 RGB 색상 모델
17번 그림에 나타난 구성 요소 평면은 식품 구성 요소의 구조에 대한 새로운 관점을 열어줍니다. 또한 9번 그림에 나온 RGB 색상 모델에서는 볼 수 없는 추가 정보를 제공합니다.
예를 들어, 이제 첫 번째 성분 평면(단백질)에 치즈를 볼 수 있습니다. RGB 색상 모델에서는 지방(두 번째 성분)으로 인해 마젠타에 가까운 색으로 표시됩니다.
2.5. 임의의 차원에 대한 구성 요소 평면 구현
우리가 고려한 예는 몇 가지 특정한 특징을 가지고 있으며, 치수는 고정되어 있고 시각화 알고리즘은 표현마다 다릅니다(RGB 및 CMYK 색상 모델).
이제 임의 치수에 대한 알고리즘을 일반화할 수 있지만 이 경우에는 구성 요소 평면만 시각화합니다. 프로그램이 CSV 파일에서 임의 데이터를 로드할 수 있어야 합니다.
예를 들어 food.csv의 모양은 다음과 같습니다.
Protein;Carbohydrate;Fat;Title 0.4;11.8;0.1;Apples 1.9;1.9;19.5;Avocado 1.2;23.2;0.3;Bananas 20.9;0.0;7.9;Beef Steak 13.0;19.0;11.0;Big Mac 15.5;2.9;68.3;Brazil Nuts 10.5;37.0;3.2;Bread 1.0;0.0;81.0;Butter 25.0;0.1;34.4;Cheese 6.4;28.2;22.7;Cheesecake 5.7;58.7;29.3;Cookies 7.0;84.0;0.9;Cornflakes 12.5;0.0;10.8;Eggs 17.0;7.0;20.0;Fried Chicken 3.0;36.0;13.0;Fries 3.8;19.4;10.2;Hot Chocolate 20.9;5.1;38.3;Pepperoni 12.5;30.0;11.0;Pizza 10.1;27.3;24.2;Pork Pie 1.7;16.1;0.3;Potatoes 6.9;74.0;2.8;Rice 26.1;0.3;5.8;Roast Chicken 0.0;95.1;0.0;Sugar 25.6;0.0;0.5;Tuna Steak 0.0;0.0;0.0;Water
파일의 첫 번째 줄에는 입력 데이터 벡터의 이름(제목)이 포함됩니다. 구성 요소 평면을 구분하려면 제목이 필요합니다. 그래서 그라데이션 패널에 이름을 넣을 것입니다.
패턴의 이름은 마지막 열에 있고, 저희 경우에는 음식의 이름입니다.
SOM.mq5 (OnInit 함수)의 코드가 간략화되었습니다:
CSOM KohonenMap; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { MathSrand(200); //--- load patterns from file if(!KohonenMap.LoadTrainDataFromFile(DataFileName)) { Print("Error in loading data for training."); return(1); } //--- train net KohonenMap.Train(); //--- render map KohonenMap.Render(); //--- show patterns from training set KohonenMap.ShowTrainPatterns(); //--- show bmp on the chart KohonenMap.ShowBMP(false); return(0); }
학습 패턴이 담긴 파일의 이름은 DataFileName 입력 패러미터(예: "food.csv")에 지정되어 있습니다.
결과가 18번 그림에 나타납니다.
18번 그림. 음식의 흑백 그라디언트 색상 스케마 코호넨 맵
또한 그라데이션 방식을 선택하기 위해 Color Scheme 입력 패러미터를 추가했습니다.
현재 4가지 색상표(Color Scheme=0,1,2,4=흑-백, 남색-파랑-녹색-노랑-빨강, 빨강-검정-녹색, 빨강-하양-녹색)를 사용할 수 있습니다.
CSOM::InitParameters() 메소드에 그라디언트을 추가하면 자신만의 스케마를 쉽게 추가할 수 있습니다.
색상 스케마는 Expert Adviso의 입력 패러미터에서 선택할 수 있습니다:
마찬가지로 아이리스 꽃 데이터 셋(Iris-fisher.csv)도 같은 방식으로 처리할 수 있습니다.
Sepal length;Sepal width;Petal length;Petal width;Title 5.1;3.5;1.4;0.2;setosa 4.9;3.0;1.4;0.2;setosa 4.7;3.2;1.3;0.2;setosa 4.6;3.1;1.5;0.2;setosa 5.0;3.6;1.4;0.2;setosa 5.4;3.9;1.7;0.4;setosa 4.6;3.4;1.4;0.3;setosa 5.0;3.4;1.5;0.2;setosa 4.4;2.9;1.4;0.2;setosa 4.9;3.1;1.5;0.1;setosa 5.4;3.7;1.5;0.2;setosa 4.8;3.4;1.6;0.2;setosa 4.8;3.0;1.4;0.1;setosa 4.3;3.0;1.1;0.1;setosa 5.8;4.0;1.2;0.2;setosa 5.7;4.4;1.5;0.4;setosa 5.4;3.9;1.3;0.4;setosa 5.1;3.5;1.4;0.3;setosa 5.7;3.8;1.7;0.3;setosa 5.1;3.8;1.5;0.3;setosa 5.4;3.4;1.7;0.2;setosa 5.1;3.7;1.5;0.4;setosa 4.6;3.6;1.0;0.2;setosa 5.1;3.3;1.7;0.5;setosa 4.8;3.4;1.9;0.2;setosa 5.0;3.0;1.6;0.2;setosa 5.0;3.4;1.6;0.4;setosa 5.2;3.5;1.5;0.2;setosa 5.2;3.4;1.4;0.2;setosa 4.7;3.2;1.6;0.2;setosa 4.8;3.1;1.6;0.2;setosa 5.4;3.4;1.5;0.4;setosa 5.2;4.1;1.5;0.1;setosa 5.5;4.2;1.4;0.2;setosa 4.9;3.1;1.5;0.2;setosa 5.0;3.2;1.2;0.2;setosa 5.5;3.5;1.3;0.2;setosa 4.9;3.6;1.4;0.1;setosa 4.4;3.0;1.3;0.2;setosa 5.1;3.4;1.5;0.2;setosa 5.0;3.5;1.3;0.3;setosa 4.5;2.3;1.3;0.3;setosa 4.4;3.2;1.3;0.2;setosa 5.0;3.5;1.6;0.6;setosa 5.1;3.8;1.9;0.4;setosa 4.8;3.0;1.4;0.3;setosa 5.1;3.8;1.6;0.2;setosa 4.6;3.2;1.4;0.2;setosa 5.3;3.7;1.5;0.2;setosa 5.0;3.3;1.4;0.2;setosa 7.0;3.2;4.7;1.4;versicolor 6.4;3.2;4.5;1.5;versicolor 6.9;3.1;4.9;1.5;versicolor 5.5;2.3;4.0;1.3;versicolor 6.5;2.8;4.6;1.5;versicolor 5.7;2.8;4.5;1.3;versicolor 6.3;3.3;4.7;1.6;versicolor 4.9;2.4;3.3;1.0;versicolor 6.6;2.9;4.6;1.3;versicolor 5.2;2.7;3.9;1.4;versicolor 5.0;2.0;3.5;1.0;versicolor 5.9;3.0;4.2;1.5;versicolor 6.0;2.2;4.0;1.0;versicolor 6.1;2.9;4.7;1.4;versicolor 5.6;2.9;3.6;1.3;versicolor 6.7;3.1;4.4;1.4;versicolor 5.6;3.0;4.5;1.5;versicolor 5.8;2.7;4.1;1.0;versicolor 6.2;2.2;4.5;1.5;versicolor 5.6;2.5;3.9;1.1;versicolor 5.9;3.2;4.8;1.8;versicolor 6.1;2.8;4.0;1.3;versicolor 6.3;2.5;4.9;1.5;versicolor 6.1;2.8;4.7;1.2;versicolor 6.4;2.9;4.3;1.3;versicolor 6.6;3.0;4.4;1.4;versicolor 6.8;2.8;4.8;1.4;versicolor 6.7;3.0;5.0;1.7;versicolor 6.0;2.9;4.5;1.5;versicolor 5.7;2.6;3.5;1.0;versicolor 5.5;2.4;3.8;1.1;versicolor 5.5;2.4;3.7;1.0;versicolor 5.8;2.7;3.9;1.2;versicolor 6.0;2.7;5.1;1.6;versicolor 5.4;3.0;4.5;1.5;versicolor 6.0;3.4;4.5;1.6;versicolor 6.7;3.1;4.7;1.5;versicolor 6.3;2.3;4.4;1.3;versicolor 5.6;3.0;4.1;1.3;versicolor 5.5;2.5;4.0;1.3;versicolor 5.5;2.6;4.4;1.2;versicolor 6.1;3.0;4.6;1.4;versicolor 5.8;2.6;4.0;1.2;versicolor 5.0;2.3;3.3;1.0;versicolor 5.6;2.7;4.2;1.3;versicolor 5.7;3.0;4.2;1.2;versicolor 5.7;2.9;4.2;1.3;versicolor 6.2;2.9;4.3;1.3;versicolor 5.1;2.5;3.0;1.1;versicolor 5.7;2.8;4.1;1.3;versicolor 6.3;3.3;6.0;2.5;virginica 5.8;2.7;5.1;1.9;virginica 7.1;3.0;5.9;2.1;virginica 6.3;2.9;5.6;1.8;virginica 6.5;3.0;5.8;2.2;virginica 7.6;3.0;6.6;2.1;virginica 4.9;2.5;4.5;1.7;virginica 7.3;2.9;6.3;1.8;virginica 6.7;2.5;5.8;1.8;virginica 7.2;3.6;6.1;2.5;virginica 6.5;3.2;5.1;2.0;virginica 6.4;2.7;5.3;1.9;virginica 6.8;3.0;5.5;2.1;virginica 5.7;2.5;5.0;2.0;virginica 5.8;2.8;5.1;2.4;virginica 6.4;3.2;5.3;2.3;virginica 6.5;3.0;5.5;1.8;virginica 7.7;3.8;6.7;2.2;virginica 7.7;2.6;6.9;2.3;virginica 6.0;2.2;5.0;1.5;virginica 6.9;3.2;5.7;2.3;virginica 5.6;2.8;4.9;2.0;virginica 7.7;2.8;6.7;2.0;virginica 6.3;2.7;4.9;1.8;virginica 6.7;3.3;5.7;2.1;virginica 7.2;3.2;6.0;1.8;virginica 6.2;2.8;4.8;1.8;virginica 6.1;3.0;4.9;1.8;virginica 6.4;2.8;5.6;2.1;virginica 7.2;3.0;5.8;1.6;virginica 7.4;2.8;6.1;1.9;virginica 7.9;3.8;6.4;2.0;virginica 6.4;2.8;5.6;2.2;virginica 6.3;2.8;5.1;1.5;virginica 6.1;2.6;5.6;1.4;virginica 7.7;3.0;6.1;2.3;virginica 6.3;3.4;5.6;2.4;virginica 6.4;3.1;5.5;1.8;virginica 6.0;3.0;4.8;1.8;virginica 6.9;3.1;5.4;2.1;virginica 6.7;3.1;5.6;2.4;virginica 6.9;3.1;5.1;2.3;virginica 5.8;2.7;5.1;1.9;virginica 6.8;3.2;5.9;2.3;virginica 6.7;3.3;5.7;2.5;virginica 6.7;3.0;5.2;2.3;virginica 6.3;2.5;5.0;1.9;virginica 6.5;3.0;5.2;2.0;virginica 6.2;3.4;5.4;2.3;virginica 5.9;3.0;5.1;1.8;virginica
그 결과는 그림 19에서 볼 수 있습니다.
19번 그림. 아이리스 꽃 데이터 셋 빨강-검정-녹색 색상 스케마 구성 요소 평면 (ColorScheme=2, iris-fisher.csv)
이제 실전 응용을 위한 준비가 끝났습니다.
2.6. 예시 5 시장 히트 맵
자체 구성 기능 맵은 시장 추이 맵에도 사용할 수 있습니다. 때때로 시장의 전 세계적인 모습이 필요하며, 시장 히트맵는 매우 유용한 도구입니다. 그 주식은 경제 분야에 따라 합쳐집니다.
현재 주식 색상은 현재 성장률(%)에 따라 달라집니다.
20번 그림. S&P500 주식 종목 시장 히트 맵
S&P (http://finviz.com)의 주간 시장 히트 맵은 20번 그림에서 볼 수 있습니다. 색상은 성장률(%)에 따라 달라집니다.
주식 사각형의 크기는 시가총액에 따라 달라집니다. MetaTrader 5 클라이언트 단말에서도 코호넨 맵을 이용하여 동일한 분석이 가능합니다.
이 아이디어는 여러 기간 동안 성장률(%)을 사용하는 것입니다. 코호넨 맵을 사용하는 툴이 있으므로 데이터를 .csv 파일에 저장하는 스크립트만 있으면 됩니다.
미국 주식시장 CFD 매매가 (#AA, #AIG, #AXP, #BA, #BAC, #C, #CAT, #CVX, #DD, #DIS, #EK, #GE, #HD, #HON, #HPQ, #IBM, #INTC, #IP, #JNJ, #JPM, #KFT, #KO, #MCD, #MMM, #MO, #MRK, #MSFT, #PFE, #PG, #T, #TRV, #UTX, #VZ, #WMT и #XOM) 는 MetaQuotes Demo 서버에서 찾을 수 있습니다.
dj.csv file를 생성하는 스크립트는 몹시 간단합니다:
//+------------------------------------------------------------------+ //| DJ.mq5 | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" string s_cfd[35]= { "#AA","#AIG","#AXP","#BA","#BAC","#C","#CAT","#CVX","#DD","#DIS","#EK","#GE", "#HD","#HON","#HPQ","#IBM","#INTC","#IP","#JNJ","#JPM","#KFT","#KO","#MCD","#MMM", "#MO","#MRK","#MSFT","#PFE","#PG","#T","#TRV","#UTX","#VZ","#WMT","#XOM" }; //+------------------------------------------------------------------+ //| Returns price change in percents | //+------------------------------------------------------------------+ double PercentChange(double Open,double Close) { return(100.0*(Close-Open)/Close); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ResetLastError(); int filehandle=FileOpen("dj.csv",FILE_WRITE|FILE_ANSI); if(filehandle==INVALID_HANDLE) { Alert("Error opening file"); return; } //--- MqlRates MyRates[]; ArraySetAsSeries(MyRates,true); string t="M30;M60;M90;M120;M150;M180;M210;M240;Title"; FileWrite(filehandle,t); Print(t); int total_symbols=ArraySize(s_cfd); for(int i=0; i<total_symbols; i++) { string cursymbol=s_cfd[i]; int copied1=CopyRates(cursymbol,PERIOD_M30,0,8,MyRates); if(copied1>0) { string s=""; s=s+DoubleToString(PercentChange(MyRates[1].open,MyRates[0].close),3)+";"; s=s+DoubleToString(PercentChange(MyRates[2].open,MyRates[0].close),3)+";"; s=s+DoubleToString(PercentChange(MyRates[3].open,MyRates[0].close),3)+";"; s=s+DoubleToString(PercentChange(MyRates[4].open,MyRates[0].close),3)+";"; s=s+DoubleToString(PercentChange(MyRates[5].open,MyRates[0].close),3)+";"; s=s+DoubleToString(PercentChange(MyRates[6].open,MyRates[0].close),3)+";"; s=s+DoubleToString(PercentChange(MyRates[7].open,MyRates[0].close),3)+";"; s=s+cursymbol; Print(s); FileWrite(filehandle,s); } else { Print("Error in request of historical data on symbol ",cursymbol); return; } } Alert("OK"); FileClose(filehandle); } //+------------------------------------------------------------------+
과거 데이터를 다운받아야하는데, 이는 DownloadHistory 스크립트를 통해 자동으로 처리할 수 있습니다.
dj.mq5 스크립트의 결과물로 dj.csv 와 이하의 데이터를 얻게됩니다:
M30;M60;M90;M120;M150;M180;M210;M240;Title 0.063;-0.564;-0.188;0.376;0.251;0.313;0.627;0.439;#AA -0.033;0.033;0.067;-0.033;0.067;-0.133;0.266;0.533;#AIG -0.176;0.039;0.039;0.274;0.196;0.215;0.430;0.646;#AXP -0.052;-0.328;-0.118;0.315;0.223;0.367;0.288;0.328;#BA -0.263;-0.351;-0.263;0.000;-0.088;0.088;0.000;-0.088;#BAC -0.224;-0.274;-0.374;-0.100;-0.274;-0.224;-0.324;-0.598;#C -0.069;-0.550;-0.079;0.766;0.727;0.638;0.736;0.589;#CAT -0.049;-0.168;0.099;0.247;0.187;0.049;0.355;0.266;#CVX 0.019;-0.058;0.058;0.446;0.174;0.349;0.136;-0.329;#DD -0.073;-0.219;-0.146;0.267;0.170;0.292;0.170;0.267;#DIS -1.099;-1.923;-1.099;0.275;0.275;0.275;-0.549;-1.374;#EK -0.052;-0.310;-0.103;0.362;0.258;0.362;0.465;0.258;#GE -0.081;-0.244;-0.326;-0.136;0.081;0.326;0.489;0.489;#HD -0.137;-0.427;-0.171;0.427;0.445;0.342;0.325;0.359;#HON -0.335;-0.363;-0.112;0.112;0.168;0.307;0.475;0.251;#HPQ 0.030;-0.095;0.065;0.190;0.071;0.214;0.279;0.327;#IBM 0.000;-0.131;-0.044;-0.088;-0.044;0.000;0.000;0.044;#INTC -0.100;-0.200;-0.166;0.100;-0.067;0.033;-0.532;-0.798;#IP -0.076;0.076;0.259;0.473;0.427;0.336;0.336;-0.076;#JNJ -0.376;-0.353;-0.494;-0.259;-0.423;-0.329;-0.259;-0.541;#JPM -0.057;-0.086;-0.029;0.086;0.114;0.057;0.257;-0.114;#KFT 0.059;-0.030;0.119;0.282;0.119;0.193;0.208;-0.119;#KO -0.109;-0.182;0.206;0.352;0.279;0.473;0.521;0.194;#MCD -0.043;-0.195;-0.151;0.216;0.270;0.227;0.411;0.206;#MMM -0.036;-0.072;0.072;0.144;-0.072;-0.108;0.108;0.072;#MO 0.081;-0.081;0.027;0.081;-0.054;0.027;-0.027;-0.108;#MRK 0.083;0.083;0.041;0.331;0.083;0.248;0.166;0.041;#MSFT 0.049;0.000;0.243;0.680;0.194;0.243;0.340;0.097;#PFE -0.045;0.060;0.104;0.015;-0.179;-0.149;-0.224;-0.224;#PG 0.097;-0.032;0.000;0.129;0.129;0.064;0.097;0.064;#T -0.277;-0.440;-0.326;-0.358;-0.537;-0.619;-0.570;-0.733;#TRV -0.081;-0.209;0.035;0.325;0.198;0.093;0.128;-0.035;#UTX 0.054;0.000;0.054;0.190;0.136;0.326;0.380;0.353;#VZ -0.091;-0.091;-0.036;0.036;-0.072;0.000;0.145;-0.127;#WMT -0.062;-0.211;0.087;0.198;0.186;0.050;0.347;0.508;#XOM
som.mq5(ColorScheme=3, CellsX=30,CellsY=30, ImageXSize=200, ImageXSize=200, DataFileName="dj.csv") 실행 후, 8개의 그림을 얻게되며 그 각각은 30, 60, 90, 120, 150, 180, 210 및 240 분 타임 인터벌에 해당됩니다.
2011년 5월 23일 4시간 동안의 시장 성장률 데이터(미국 주식)의 코호넨 맵은 21번 그림에 그려져있습니다.
21번 그림. 미국 증시 코호넨 맵 (2011년 5월 23일 매매 세션 마지막 4시간).
21번 그림에서 보실 수 있듯이 #C (Citigroup Inc.), #T (AT&T Inc.), #JPM (JPMorgan Chase & Co), #BAC (Bank of America) 간의 역학관계도 유사합니다. 해당 종목들은 장기적 적색 클러스터로 분류되었습니다.
마지막 1.5시간(M30, M60, M90) 동안 역동성은 녹색으로 변했지만 일반적으로(M240) 종목은 적색권에 있었습니다.
코호넨 지도를 사용하여 주식의 상대적 역학을 시각화하고, 선두주자와 뒤쳐진 주자, 그 환경을 찾을 수 있습니다. 비슷한 데이터의 요소들이 클러스터를 형성합니다.
21a 그림에서 볼 수 있듯이, Citigroup Inc 주식의 매매가가 제일 많이 하락했습니다. 일반적으로 금융회사들의 모든 주식은 레드존에 있습니다.
21a 그림. 2011년 5월 23일 시장 히트맵 (Source: http://finviz.com)
마찬가지로 FOREX 시장의 코호넨 맵을 계산할 수 있습니다(그림 22).
22번 그림. FOREX 시장 코호넨 맵 (2011년 5월 24일, 유럽 시장 세션)
이하의 쌍이 사용되었습니다: EURUSD, GBPUSD, USDCHF, USDJPY, USDCAD, AUDUSD, NZDUSD, USDSEK, AUDNZD, AUDCAD, AUDCHF, AUDJPY, CHFJPY, EURGBP, EURAUD, EURCHF, EURJPY, EURNZD, EURCAD, GBPCHF, GBPJPY, CADCHF.
성장률은 fx.mq5 스크립트를 이용하여 fx.csv에 저장되었습니다.
M30;M60;M90;M120;M150;M180;M210;M240;Title 0.058;-0.145;0.045;-0.113;-0.038;-0.063;0.180;0.067;EURUSD 0.046;-0.100;0.078;0.094;0.167;0.048;0.123;0.160;GBPUSD -0.048;0.109;-0.142;-0.097;-0.219;-0.143;-0.277;-0.236;USDCHF 0.042;0.097;0.043;-0.024;-0.009;-0.067;0.024;0.103;USDJPY -0.045;0.162;0.155;0.239;0.217;0.246;0.157;0.227;USDCAD 0.095;-0.126;-0.018;-0.141;-0.113;-0.062;0.081;-0.005;AUDUSD 0.131;-0.028;0.167;0.096;-0.013;0.147;0.314;0.279;NZDUSD -0.047;0.189;-0.016;0.107;0.084;0.076;-0.213;-0.133;USDSEK -0.034;-0.067;-0.188;-0.227;-0.102;-0.225;-0.234;-0.291;AUDNZD 0.046;0.039;0.117;0.102;0.097;0.170;0.234;0.216;AUDCAD 0.057;-0.016;-0.158;-0.226;-0.328;-0.215;-0.180;-0.237;AUDCHF 0.134;-0.020;0.024;-0.139;-0.124;-0.127;0.107;0.098;AUDJPY 0.083;-0.009;0.184;0.084;0.208;0.082;0.311;0.340;CHFJPY 0.025;-0.036;-0.030;-0.200;-0.185;-0.072;0.058;-0.096;EURGBP -0.036;-0.028;0.061;0.010;0.074;-0.006;0.088;0.070;EURAUD 0.008;-0.049;-0.098;-0.219;-0.259;-0.217;-0.094;-0.169;EURCHF 0.096;-0.043;0.085;-0.124;-0.049;-0.128;0.206;0.157;EURJPY -0.073;-0.086;-0.119;-0.211;-0.016;-0.213;-0.128;-0.213;EURNZD 0.002;0.009;0.181;0.119;0.182;0.171;0.327;0.284;EURCAD -0.008;0.004;-0.077;-0.015;-0.054;-0.127;-0.164;-0.080;GBPCHF 0.079;-0.005;0.115;0.079;0.148;-0.008;0.144;0.253;GBPJPY 0.013;-0.060;-0.294;-0.335;-0.432;-0.376;-0.356;-0.465;CADCHF
가격뿐 아니라 다양한 기간에 인디케이터 값을 사용할 수 있습니다.
2.6. 예시 6 최적화 결과 분석
MetaTrader 5 클라이언트 터미널의 전략 테스터는 패러미터 공간의 구조를 탐색하고 최상의 전략 패러미터 세트를 찾을 수 있는 기회를 제공합니다. 또한 "Optimization Results"(최적화 결과) 탭의 상황에 맞는 메뉴에서 "XML로 내보내기(MS Office Excel)" 옵션을 사용하여 최적화 결과를 내보낼 수도 있습니다.
테스터 통계 역시 최적화 결과에 포함되어있습니다 (41 열):
- 결과
- 수익
- 총 수익
- 총 손실
- 인출
- 예상 보상
- 수익 팩터
- 회복 팩터
- 샤프율
- 마진 레벨
- 커스텀
- 최소 밸런스
- 밸런스 DD 최대
- 밸런스 DD 최대 (%)
- 밸런스 DD 상대적
- 밸런스 DD 상대적 (%)
- 최소 지분
- 지분 DD 최대
- 지분 DD 최대 (%)
- 지분 DD 상대적
- 지분 DD 상대적 (%)
- 매매
- 거래
- 숏 매매
- 이윤 숏 매매
- 롱 매매
- 이윤 롱 매매
- 이윤 매매
- 손실 매매
- 최대 이윤 매매
- 최대 손실 매매
- 최대 연속 승리
- 최대 연속 승리 ($)
- 최대 연속 이윤
- 최대 연속 이윤 카운트
- 최대 연속 손실
- 최대 연속 손실 ($)
- 최대 연속 손실
- 최대 연속 손실 카운트
- 평균 연속 승리
- 평균 연속 손실
테스터 통계를 사용하면 패러미터 공간 분석에 도움이 됩니다. 주목할 만한 점은 통계의 많은 패러미터가 밀접하게 연관되어 있으며 무역 성과 결과에 좌우된다는 점입니다.
예를 들어, 최상의 거래 결과는 이익, 이익률, 회수율 및 샤프율 패러미터의 값이 가장 큽니다. 이 사실을 통해 결과를 분석할 수 있습니다.
MovingAverage.mq5 Expert Advisor의 최적화 결과
이 챕터에서는 MetaTrader 5 클라이언트 터미널의 표준 패키지에 포함된 MovingAverage.mq5 Expert Advisor의 최적화 결과 분석을 살펴보겠습니다. 이 Expert Advisor는 가격 교차 및 이동 평균 인디케이터를 기반으로 합니다. MovingPeriod와 MovingShift의 두 가지 입력 패러미터가 있습니다. 즉, 결과적으로 43개의 열이 있는 XML 파일이 생성됩니다.
패러미터의 43차원 공간은 고려하지 않겠습니다. 가장 흥미로운 점은 다음과 같습니다.
- Profit;
- Profit Factor;
- Recovery Factor;
- Sharpe Ratio;
- Trades;
- ProfitTrades(%);
- MovingPeriod;
- MovingShift;
ProfitTrades(%) 파라미터(결과에 없음)를 추가했습니다. 이는 이윤 매매의 퍼센트를 의미하며 ProfitTrades(28)을 Trades(22)로 나눈 후 100을 곱한 것 입니다.
MetaTrader 5 전력 테스터 입력 패러미터 400세트를 위해 optim.csv 파일을 9열로 준비해봅시다.
Profit;Profit Factor;Recovery Factor;Sharpe Ratio;Trades;ProfitTrades(%);MovingPeriod;MovingShift;Title -372.3;0.83;-0.51;-0.05;71;28.16901408;43;6;43 -345.79;0.84;-0.37;-0.05;66;27.27272727;50;6;50 ...
이동 기간의 값을 제목 열로 사용했으므로 코호넨 맵의 패턴을 "표시"하는 데 사용됩니다.
전략 테스터에서는 다음 패러미터를 사용하여 MovingPeriod 및 MovingShift 값을 최적화했습니다.
- 심볼 - EURUSD,
- 기간 - H1,
- 틱 생성 모드 - "1 Minute OHLC",
- 테스트 기간 - 2011.01.01-2011.05.24,
- 최적화 - Fast (genetic algorithm),
- 최적화 - Balance max.
23번 그림. MovingAverage EA 최적화 결과의 코호넨 맵 (구성 요소 평면 표현)
위쪽 줄의 구성 요소 평면(수익, 수익률, 회수율 и 샤프율)을 봅시다.
24번 그림에 나타나있습니다.
24번 그림. 수익, 수익률, 회수율 및 샤프율 패러미터의 구성 요소 평면
첫 번째는 최적화 결과가 가장 좋은 영역을 찾는 것이었습니다.
24번 그림에서 볼 수 있으며, 최대값을 가진 영역은 왼쪽 상단 모서리에 위치해 있습니다 숫자는 이동 평균 인디케이터의 평균 주기에 해당합니다(이동 주기 파라미터, 제목으로 사용). 숫자 위치는 모든 구성 요소 평면에서 동일합니다. 각 구성요소 평면에는 고유의 값 범위가 있으며, 값은 그라데이션 패널에 인쇄됩니다.
최상의 최적화 결과는 수익, 수익률, 회수율 및 샤프율의 값이 가장 크기 때문에 지도에 표시된 지역에 대한 정보를 확인할 수 있습니다(그림 24 참조).
25번 그림에서 매매, 수익매매(%),이동 기간 및 이동 시프트의 구성요소 평면을 볼 수 있습니다.
25번 그림. 매매, 이익매매(%),이동 기간 및 이동 시프트 패러미터의 구성요소 평면
구성 요소 평면 분석
첫 눈에 딱히 그럴싸해보이는 것은 없습니다. 처음 4개 구성 요소 평면(수익, 수익률, 회수율 및 샤프율)은 무역 시스템의 성능에 직접적으로 좌우되기 때문에 비슷해 보입니다.
그림 24에서 볼 수 있듯이 왼쪽 상단 영역이 매우 흥미롭네요(예를 들어, 이동 주기를 45 ~ 50으로 설정하면 최상의 결과를 얻을 수 있습니다).
Expert Advisor는 추세를 기반으로 한 전략인 EURUSD의 시간별 기간에 테스트를 거쳤으며, 이러한 값을 "시장 동향" 메모리로 간주할 수 있습니다. 사실이라면 2011년 상반기 시장 동향 메모리의 값은 이틀입니다.
다른 구성 요소 평면도 살펴봅시다.
26번 그림. 매매-이동기간 구성 요소 평면
그림 26에서 이동 기간 (파란색 영역)의 값이 낮을수록 매매(노란색-빨간색 영역)의 값이 커진다는 것을 알 수 있습니다. 이동 평균의 기간이 낮으면 교차점이 많습니다.
또한 이 사실은 Trade 구성 요소 평면(숫자가 20 미만인 녹색 영역)에서 확인할 수 있습니다.
27번 그림.. 매매-이동 시프트 구성 요소평면
이동 시프트(노란색 영역)가 증가함에 따라 매매 횟수가 감소합니다(파란색 영역). 이동 시프트와 24번 그림의 구성요소 평면을 비교하면 이동 시프트 패러미터가 이 거래 전략의 수행에 그다지 중요하지 않음을 알 수 있습니다.
이득을 남긴 매매의 비율인 ProfitTrades(%)은 MovingPeriod 또는 MovingShift에 직접 의존하지 않으며, 이는 거래 시스템의 필수적인 특성입니다. 다시 말하면, 입력 패러미터와의 상관 관계 분석은 아무런 의미가 없습니다.
더 복잡한 무역 전략도 비슷한 방법으로 분석될 수 있습니다. 거래 시스템의 가장 중요한 매개 변수를 찾아 제목으로 사용해야 합니다.
마치며
SOF 맵의 주요 이점은 고차원 데이터의 2차원 이산 표현을 생성할 수 있다는 것입니다. 유사한 특성을 가진 데이터가 클러스터를 형성하고 상관 관계 분석을 단순화합니다.
더 자세한 내용과 다른 어플리케이션에 관해서는 Guido Deboeck와 Teuvo Kohonen이 저술한 Visual Explorations in Finance: with Self-Organizing Maps에서 찾아볼 수 있습니다.
부록
러시아어 버전이 나온 후, 알렉스 세르기프(Alex Sergeev)가 업그레이드 된 클래스 버전을 만들어냈습니다. (SOM_Alex-Sergeev_en.zip).
변경 내용:
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; // open folder with maps after finish
CSOM 클래스의 변경점:
- 차트를 가리는 CSOM::HideChart메소드추가
- 클래스 멤버 m_chart, m_wnd, m_x0, m_y0 추가 - (이미지 차트, 창, 좌표 표시).
+ m_sID - 객체 명 접두사 추가 접두사엔 이름이 쓰이며, 기본값으로 "SOM" 접두사가 사용됩니다. - 모든 맵은 m_sID 폴더에 저장됩니다.
- bmp 파일들은 패턴의 열 이름으로 명명됨.
- CSOM::변경, ShowBMP 메소드 (맵이 \Images 대신 \Files 폴더에 저장되어 처리 속도를 가속).
- CSOM::NetDeinit 의 이름이 CSOM::HideBMP로 변경되었습니다.
- CSOM::ReadCSVData 메소드 수정, 첫 열에 표제가 들어갑니다.
- CSOM::Train(bool bShowProgress)에서 중간단계 맵을 보여주는 플래그 추가.
- CSOM::Train에서 중간단계 맵을 보는 기능은 2초마다 이루어집니다 (반복 대신) 진행 과정은 Comment. 을 이용하여 차트에서 보여집니다.
- 최적화된 이름과 몇가지 변수, 클래스 메소드는 카테고리에 따라 정렬되어있습니다.
bmp 작성은 상당히 느린 프로세스입니다 만약 필요하지않다면 매번 그리진 마시기 바랍니다.
SOM 이미지와 최적화된 값은 아카이브에 저장되어있습니다.
MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/283
![Expert Advisor 최적화 시 커스텀 조건 만들기](https://c.mql5.com/2/0/MQL5_Custom_Optimization_Options.png)
![통계적 추정](https://c.mql5.com/2/0/MQL5_Statistical_estimation.png)
![천재반을 위한 MQL5 Wizard](https://c.mql5.com/2/0/wizard_chainik_ru.png)
![소스 코드의 트레이싱, 디버깅, 및 구조 분석](https://c.mql5.com/2/0/Trace_program.png)