自己組織化特徴マップ(Kohonenマップ) - サブジェクトリビジッティング

5 9月 2016, 16:37
Nikolay Demko
0
669
す。Kohonenマップで困難に直面し、MQL4とMQL5でのプログラミングの基本的なレベルがわかる研究者や経験豊富なプログラマーを対象としています。
自己組織化特徴マップ(Kohonenマップ) - サブジェクトリビジッティング
この記事では、Kohonenマップで動作するのテクニックについて説明します。Kohonenマップで困難に直面し、MQL4とMQL5でのプログラミングの基本的なレベルがわかる研究者や経験豊富なプログラマーを対象としています。

イントロダクション

この記事は、以前公開された記事"メタトレーダー5の自己組織化特徴マップ (Kohonenマップ)の続きです。この大部分が改訂され、サイドプロジェクトでアプリケーションに適合させました。Kohonenの神経回路網のアルゴリズムは、メインアルゴリズム自体を編集するために、プロジェクトにマップ接続し、初心者から経験豊富なプログラマーを支援することを目的としています。そこの記事で使用したパターンのみですが、コードの様々な使用例が置かれています。


Kohonenマップの理論

自己組織化特徴マップ(SOM)は、すべてのニューロンをn次元入力ベクトル(パターン)に接続する1層のネットワークです。入力ベクトル(パターン) - 対象オブジェクトの説明です。

トレーニングのために競争メカニズムが適用されます。入力にパターン網を送信する場合、入力パターンとは異なるベクトルを持つニューロンが勝ちます。以下の比率がwinnerニューロンに適用されます。

式1

ただし ここで:

  • N - ニューロンの量
  • J - 勝ちニューロンの数
  • D(X、W) - xとwのベクトル間の距離。

ユークリッド空間は、距離として使用されます。

式2

この実装では、勝ちニューロンの検索は、 CSOM_Net_BaseクラスのBestMatchingNode関数の中で行われます。

学習の半径は、勝ちニューロンの周囲に形成されています。学習の半径は、ニューロンが、この繰り返しを受けているかを定義します。勝ちニューロンは、最終段階での学習の半径内に収まるように、反復とともに減少します。

勝ちニューロンの近傍

学習の半径内のニューロンの重みは、Kohonenルールに適合しています:

Kohonenルール

ただし ここで:

  • X - 入力パターン、
  • k - 反復の数、
  • ni(k)- k番目の反復での学習の半径からi番目のニューロンのトレーニング比。

学習の半径外のニューロンの重みは適応されていません。この実装では、重みはAdjustWeights CSOMNodeクラスの関数です。

ni(k)のトレーニング速度比は、2つの部分に分割されています。

  • ni(d,k)近傍関数

近傍関数

  • a(k)はトレーニング速度関数

トレーニング速度の関数

ここで、A及びBは定数で選択されます。

この関数は、初期段階では、高い速度と長い半径を有する、トレーニングループ数に反比例するパターンが平均化されます。トレーニングの終わりには、最終的に入力パラメータに調整します。

一般的に、特定の神経細胞の適応ダイナミクスは、勾配の下降として提示することができます。

傾斜降下

Kohonenネットワークをトレーニングすると、いわゆる「デッドニューロン」の問題が発生します。遠く離れた入力パターンから初期重み係数を有するニューロンは、トレーニングの長さにもかかわらず、競争に勝つことはできません。この実装では、Kohonenの学習アルゴリズムのシステムの問題は、2つのリビジョンで解決しました。

まず、トレーニングセットからランダムなパターンを選択する関数が修正されました。C_PRNG_UDクラスは、すべての値がNの反復のために表示される保証がないrand()/Nの代わりに使用されます。これは、ランダムパターンを配置します。第二に、ニューロンの重みがなく、パターンだけで遭遇する範囲から、ランダムな値で初期化されます。

競争に勝たないニューロン「デッドニューロン」に遭遇した場合でも - パターンとの間のブリッジとして役割を果たし、勝ちニューロンの周辺にするとトレーニングの対象となります。


Kohonenネットワークの使用例と実装

Kohonenマップのソフトウェア実装を説明します。実装は、2つの測定値に基づいて行われます:パターンの次元(m_dimension)とノードの合計(m_total_nodes)。しかし、視覚的にカードが3次元の m_total_nodes m_xcells* mycells長方形に折り畳まれるように提示されます。したがって、ノードに、重みと位置の両方に関する情報が格納されます。

class CSOMNode
  {
protected:
   
   //---ノードゾーンの座標
   int               m_x1;
   int               m_y1;
   int               m_x2;
   int               m_y2;
   
   //---ノード中心の座標
   double            m_x;
   double            m_y;
   
   //---ノードの重み
   double            m_weights[];
   ...

CSOMNodeクラスは、組成CSOMNode m_som_nodes[]の例の1次元配列の形で CSOM_Net_Base基本クラスに含まれています。これは、Kohonenネットワークです。その他の関数は、単にトレーニングとネットワークの活用を提供します。

前の記事では、パターンサンプルの多様性を強調し、インターフェースのグラフィカルな多様性を実証しました。この記事では、接続のパターン例のバリエーションが考えられます。サイドプロジェクトに簡単に接続するためにソースコードを修正しました。実装は5つのクラスに分類されます。

class CSOM_Net_Base
class CSOM_Net_Data   : public CSOM_Net_Base
class CSOM_Net_Train  : public CSOM_Net_Data
class CSOM_Net_Img    : public CSOM_Net_Train
class CSOM_Net_Demo   : public CSOM_Net_Img

この宣言は、クラスのカスケード接続をします。接続されたプロジェクト内の一部の関数に需要がない場合、このメソッドは、子クラスを接続しないようにすることもあるので、次のすべての関数がカットされます。

public関数のリストは、次のとおりです。

class CSOM_Net_Base
  {
public:
   //---Kohonenネットワークのパブリックノード
   CSOMNode         *public_node;
   //---public_node publicエリアへのINDセットノードを送信
   void              GetNode(int ind){ public_node=m_som_nodes[ind].GetObjPointer(); };
   //---パターンの次元を返す関数。
   int               GetDimension(){return(m_dimension);};
   //---ファイルからロードするネットワークの関数                 
   bool              DownloadNet(string file_name);
   //---マスクで指定されたベクトルに基づいて、最適なノードを見つけるための関数
   int               BestMatchingNode(const double &vector[]);
   //---指定されたベクトルに基づいて、次元のサイズにして、最適なノードを見つけるための関数
   int               BestMatchingNode(const double &vector[],int dimension);
   //---パターンに類似しているノードを検索するためのビットマスクを充填する関数は、(マスクは、検索するフィールドを決定)
   bool              InitSetByteMap(int num,bool value);
  };
  
class CSOM_Net_Data : public CSOM_Net_Base
  {
public:
   //---指定されたファイルからトレーニングのデータをロードするための関数
   bool              LoadPatternDataFromFile(string filename);
   //---トレーニングセットにベクトルを追加する関数
   void              AddVectorToPatternsSet(double &vector[],string title);
   //---トレーニングセットからパターンをコピーするための関数    
   bool              GetPatterns(int ind_pattern,double &vector[]);
   //---トレーニングセットからのパターンのタイトルを返す関数  
   string            GetTitlesPatterns(int ind_pattern);
   //---パターンの合計を返す関数
   int               GetTotalsPatterns();
  }; 
  
class CSOM_Net_Train : public CSOM_Net_Data
  {
public:
   //---ネットワークを初期化取得する関数
   void              InitParameters(int iterations,int xcells,int ycells);
   //---トレーニングネットワークの関数
   void              Train();
   //---ファイルにネットワークを保存するための関数 
   void              SaveNet(string file_name);
   //---仮想関数(本体はCSOM_Net_Imgの子に記述されています) 
   virtual void      Render(){};
   virtual void      ShowBMP(bool back){};
  }; 
  
class CSOM_Net_Img : public CSOM_Net_Train
  {
public:
   //---ネットワークを初期化取得する関数
   void              InitParameters(int iterations,int xcells,int ycells,
                                    int bmpwidth,int bmpheight,
                                    bool p_HexagonalCell,bool p_ShowBorders,bool p_ShowTitles,
                                    int p_ColorScheme,int p_MaxPictures);
   //---ネットワークの状態を表示する関数
   void              Render();
   //---チャート上のBMP画像を表示する関数  
   void              ShowBMP(bool back);
   //---BMPファイルにリソースを保存するための関数
   void              SaveBMP();
   //---チャートからBMP画像を削除する初期化解除関数
   void              NetDeinit();
  };
  
class CSOM_Net_Demonstration : public CSOM_Net_Img
  {
public:
   //--- - 子の使用例の機会を増やす関数
   void              ShowTrainPatterns();
  };

添付ファイルは、Kohonenマップを使用してオプションを持つ5つの例です。この例は、クラスカスケードの順に番号が付けられています。例を一つずつ分析しましょう。


ネットワークの作成、基本的なクラス

最初の例は、somnetを動作させるための拡張子、前にトレーニングされたネットワークを格納するために使用されます。この例では、ソフトウェアの実装から送信されたパターンを区別するために、エキスパートアドバイザーにトレーニングされたネットワークに接続するメソッドを提供します。簡単にするために、ファイルデータは、FileReadArray関数を用いて得られます。ライン(パーサ)を認識するために複雑なシステムを必要としません。それに加えて、リセットや配列を使用してデータを取得する際、高速です。

Sample1_SOM_Net_Baseは、トレーニングされたネットワークが(拡張子なし)パラメータに示されているバイナリファイルからロードされるメソッドを示しています。

input string SOM_Net="SOM\\SOM_Net";

somnetは、拡張子が自動的に挿入されます。アルゴリズムの認識に適さないファイルがロードされていないので、混乱を防ぐことができます。

ネットワークの負荷はDownloadNet(string file_name)関数で発生します。関数の詳細な検査に続いて、somnet ファイルが明確になります。double型の3つのメモリセルからなるヘッダが(ファイルから取得した配列の残りの部分)ファイルの先頭に書かれています。最初のフィールドは、パターンプラス6の次元を格納します。6つのフィールドは、ノードの座標を格納するために必要とされます。しかし、6が一定値であるため、配列のヘッダの最初のフィールドから6を差し引いてパターン次元を得ることができます。第2および第3象限は、変数 m_xcellsm_ycells(ネットワークのビジュアルにおけるXとYのサイズ)を格納します。これらを乗算することによって、ネットワーク内のノードの数を取得することができます。

ネットワーク全体がロードされるまで、ベクトルによるネットワーク・データ・ベクトルを取得することで行われます。

例を見ていきましょう。ネットワークがロードされた後、vector[]パターンは定数で満たされています。定数の初期化は、一例です。BestMatchingNode関数は、最も類似したノードのインデックスを検索します。その後、ノードはCSOMNodeクラスの関数への安全なアクセスのためpublic部に送信されます。

BestMatchingNode関数に、焦点を当てます。アプリケーションの3つのメソッドがあります。マスクの初期化なしでBestMatchingNode(const double &vector[])オーバーロードを呼び出すときに、関数が自身をマスクが初期化するので、すべてのベクトルを通じて、検索ができるようになります。すなわち、すべてのフィールドを介して実行されます。InitSetByteMap(int num,bool value)の初期化が各フィールドに呼び出された場合、マスクはその後、フィールドでオンに切り替わります。不完全な情報に基づいて、ノードを検索する能力は、このように達成されます。別のBestMatchingNode(const double &vector[],int dimension) が使用されている場合は、次元パラメータによって関数に送られた数まで順番になります。


パターンデータのロード

2番目のサンプル Sample2_SOM_Net_Dataは、次の関数拡張 CSOM_Net_Dataクラスの接続を示しています。このクラスは CSOM_Net_Baseの子として宣言されているので、子が持っているすべての関数を持っています。このクラスがロードパターンのパーサ関数へのイントロとして作成されます。パーサを用いて得られたパターンは、認識の負荷トレーニングパターンに使用することができます。

パターンを持つファイルの名前は、パラメータで設定されています:

input string DataFileName="SOM\\optim.csv";

ファイル名は、ファイルの完全な名前で、拡張子を持ちます。構文解析ファイルは、FILE_CSVフラグを持つファイルとして開かれます。

そして、前の例と同様の関数が呼び出されます。:パターンループ、ネットワークの負荷、ファイルの読み込み、ファイルの解析。

パーサがオンに設定されているファイル形式を検討する必要があります。

ファイルの最初の行は、Titleで埋めなくてはなりません。これは必須の条件です。ファイルのヘッダが満たされていない場合は、パーサーは最初の行から上側のサンプルをカットし、列名を作成するために使用します。

パターンを持つファイル

ファイルの列は、同じ深さのパターンデータを格納するために使用されます。したがって、行は別々のパターンを記憶します。言い換えれば、ベクトルが水平に配置され、そしてすべてのベクトルの同じフィールドが垂直になります。

パーサーは組み込みの配列m_patterns_sets_arrayとフィールドのヘッダーをパターンデータを配置し、m_som_titles配列(下位クラスで宣言)に格納し 、m_patterns_titles 行番号を持つ配列を満たします。ファイル内のその行によって必要なパターンを見つけることにより、問題はありません。


ネットワークトレーニング

第三のサンプルSample3_SOM_Net_Trainは、最も魅力的です。まず、第2の基本クラスとトレーニングKohonenマップのクラスである、 CSOM_Net_Trainで接続されています。次に、自動化トレーニングの最後のクラスがあり、それ以降のクラスはグラフィカルシェルです。よって、すべてのセクションの3クラスで"Theory of Kohonen maps"が実装されています"。第4に、このクラスがフォークを持っています。

その後のクラスについては、計算やトレーニングステージを表示するBMP画像を描画する関数は、ネットワークのトレーニング関数で Train()を呼び出さなければなりません。しかし、第3のサンプルは何のチャートも持っていないので、これらの関数の本体はここでは必要ありません。これを解決するためには、virtualとして宣言されているRender()ShowBMP(bool back)関数を持ち、必要コードはCSOM_Net_Imgの 子に定義されています。

今、トレーニングに移ります。このパラメータは、トレーニングの前に、ネットワークに送信する必要があります。このような目的のために、パラメータが転送される場所:トレーニングの繰り返し回数iterationsとネットワーク二つのパラメータに分割サイズ - xcells ycells(XとYのサイズ)にサービス関数InitParameters(int iterations,int xcells,int ycells)があります。。

トレーニング・ループは、Train() 関数に配置されています。トレーニングループを呼び出す前に、ネットワークを初期化する必要があります。均等にクラスを初期化し、配列のサイズを定義し、設定された範囲からランダムなデータを持つノードを初期化するために、パターン列を使用して、最大値と最小値を計算します。

実際のトレーニングの反復は、別の関数TrainIterations(int &p_iter)の理解で簡単になります。他のプログラマが、必要に応じて、独自の修正案を作ることができるように、この実装があります。この関数がTheory of Kohonen maps"セクションで説明したアルゴリズムで、再びそれを記述する必要はありません。

一般的には、第3のサンプルからネットワークを接続するの整合性を示しています。 CSOM_Net_Trainクラス:パラメータを送信し、トレーニングパターンを使用してファイルをロードするトレーニングを呼び出し、ファイルのネットワークを保存します。

ネットワーク・ファイルを読み取る関数を使う際には、保存と読み出しの関数を同時にフォーマットするべきだとを前述しました。

void CSOM_Net_Train::SaveNet(string file_name)
bool CSOM_Net_Base::DownloadNet(string file_name)

ソネットファイルのバイナリ表現

double型は、ネットワークデータで優先されます。したがって、ネットワークは、double型の1次元配列に保存されます。残りのデータは、この型に変換されます。

まず、ヘッダは、ネットワークに保存されています。これらは、ネットワークに関する必要なデータが保存されている5つのdoubleフィールドです。

  1. 6+dimension_node- パターンの長さを加えた6(ノード内の6つの追加フィールドが格納座標に必要)。
  2. m_xcells - 水平方向のノード数。
  3. m_ycells - 垂直方向のノード数。
  4. m_xsize - 水平bmpファイルサイズ。
  5. m_ysize - 縦bmpファイルサイズ。

ノードネットワークにコピーするとき、実行されます。ノード座標、約6データム - ノードの重み。すべてのデータは、ノードによるこのメソッドでノードをコピーされます。

double型にバイナリ転送されるTitles列挙の行は、ネットワークに追加されます。

よって、これが得られます。パターンサイズとヘッダからノードの数が得られます。このデータは、ノードデータが開始位置と終了位置を計算するために使用することができます。Titlesネットワークは、ファイルの終わりまでのノードのエンドポイントから保存されます。必要なメモリを予測することは不可能なため、ファイルの末尾に配置されています。


グラフィカルシェル

第4のサンプルは、 Sample4_SOM_Net_Imgグラフィカルシェルの接続です。前回の記事では、グラフィックライブラリに接続に必要であったcintbmp.mqhを呼び出すために、Dmitry Fedoseevによって書かれました。しかし、すべてのWinAPIのDLLの呼び出しを削除するため、修正しなければなりませんでした。Marketのコードの使用を可能にします。更新されたファイルは、著者に関する情報が含まれていますが、名前を cintbmp2.mqhに変更しました。

画像にファイルをImageディレクトリに保存する唯一の関数は、BMPファイルをロードするために使用され、変更されました。ファイル表示のためではなく、節約のために記録されています。目的を表示するため、常にDLLライブラリの呼び出しを回避するのに役立つリソースがロードされます。

関数の呼び出しのシーケンスは、前のサンプルに似ています。グラフィカルシェルが接続されているため、設定の追加のパラメータは、その動作に必要とされます。したがって、前の子クラスで宣言した初期化関数は、グラフィカルシェルの新しいパラメータに合わせて再開されます。

void   InitParameters(int iterations,int xcells,int ycells,
                       int bmpwidth,int bmpheight,
                       bool p_HexagonalCell,bool p_ShowBorders,bool p_ShowTitles,
                       int p_ColorScheme,int p_MaxPictures);

パラメータは、クラスコードでグローバルに宣言された変数を防止する関数のインターフェイスを通過します。それ以外の場合、変数の名前が異なるケースがあるサイドプロジェクトへの接続を複雑にします。

CSOM_Net_Trainクラスのサンプルからトレーニング関数Train()を呼び出します。しかし、関数の本体にチャートで動作するコードRender()ShowBMP(bool back)があるので、トレーニングのプロセスを表示することにつながります。Train()の後、これらの関数は、最後の変更を表示するようにコールされます。

トレーニングの終了


機能拡張

第5のサンプルでは、Sample5_SOM_Net_Playerで拡張クラスの例を表示します。ネットワークのための基本的な考えで、既存のコードを確認することができます。このためには、基本クラスのうち1つの子としてクラスを宣言します。

なぜ、子クラスを記述する必要があるのでしょう?クラスから継承されたprotectedコマンドによるすべてのクラスのすべての関数を実行します。たとえば、CSOM_Net_Imgクラスの子として接続するとき、protectedpublicとして宣言されているすべての関数とデータへのアクセスを取得します。この方法は、プログラムを取得する必要があるか否かに応じて、構成することができます。

よって、CSOM_Net_ Playerクラスの拡張には、Kohonenネットワークを制御するためのグラフィックパネルがあります。Dmitry FedoseevグラフィックライブラリでIncGUI_v3.mqhファイルが接続されています。この改善は、グラフィックラベル(サイデではなく、オブジェクトの上)とラベルの色の表示に影響を与えました。元のファイルに変更を加えていない、ライブラリクラスの継承を宣言しました。

グラフィックパネルの作成は、コードの大部分を占めるにもかかわらず、困難をもたらすことはありません。これは、コードを刻印するための定期的なルーチンワークです。Kohonenニューラルネットワークとグラフィックパネルとグラフィカルシェルとの間の調整にさらに詳しく説明したいと思います。

まず、ネットワークの起動のプロセスは、2つのパートを備えるます。最初のパートは、バイナリファイルsomnetへトレーニングされたネットワークを実行します。第2のパートがロードされたパターンに基づいて、適切なノード用のファイルや検索からネットワークをロードします。。ニューラルネットワークを持つファイルのパターンを持つファイル、入力フィールドのパスの入力欄があります。:データを表示するのと同じフィールドを使用していますが、両方のパートは、独立しています。

しかし、モードが完全に独立しています。そして、トレーニングのパターン認識と同じファイルから取得する必要はありません。同じことは、ニューラルネットワークに適用されます。1つのファイルにネットワークをトレーニングし、「運用」にモードを切り替えて、他のネットワークを読み込むことができます。

重要:モードの切り替えはゼロ状態にモデムをリセットします。

よって、モードは独立しています。しかし、どうやってボタンの状態を変更するプログラムの迅速な応答が達成されたでしょうか?問題は、プログラムがトレーニングやパターンを検索するループを使用していないということです。これは、イベントに基づいて配置されています。

プログラムは、トレーニングモードに入ると、初期化パラメータをロードするメモリを用意し、繰り返し、その後333の下にそれ自体がユーザイベントを送信します。イベントハンドラへのエントリは、オブジェクトの編集とユーザイベント333を終了し、オブジェクト上でマウスをクリックすることによってフィルタリングされます。

中断がなかった場合(「スタート」と「トレーニング」ボタンの状態が変更されていない、まだトレーニングのエントリのアクセス権を持っている場合)、この方法では、新しいトレーニング反復が発生し、新しいメッセージ333が送信されます。ネットワークがトレーニングされるまで、ループを停止し、ユーザがトレーニングを停止ボタンを使用するまで続きます。

割り込み方式は、パターンサーチのモードで実施されます。

パネルインタフェースを、明確にしようとしています。大抵、前のサンプルからinput変数を繰り返します。いくつかのボタンや入力フィールドの値が表示されます:


必要とされているパネルを起動する:

  • ディレクトリによってzipアーカイブからファイルを整理。
  • ディレクトリ MQL5\のFiles\SOM\へ - パターンを持つファイル。
  • ディレクトリ MQL5\Images\SOMの\へ - ボタンのBMP画像を持つファイル。
  • ディレクトリ MQL5\Projects\SOMの\へ - プログラムとファイル。
  • すべてのmq5ファイルをコンパイルします。


結論

40年前、ニューラルネットワークは、科学の最先端にありました。約20年前、ニューラルネットワークアルゴリズムに精通している人はユニークな専門家であると考えられました。今は、「ニューラルネットワーク」という言葉は誰にとっても難しいものではありません。ファジーロジックのアルゴリズム、ニューラルネットワークは、とても複雑ではありません。この記事では、Kohonenマップにいくつかの光を当てました。役立つことを願っています。

MetaQuotes Software Corp.によりロシア語から翻訳された
元の記事: https://www.mql5.com/ru/articles/2043

添付されたファイル |
project_som.zip (267.78 KB)
機械学習モデルの評価と変数の選択 機械学習モデルの評価と変数の選択

この記事では、機械学習モデルで使用する入力変数(予測変数)の選択、前処理および評価の詳細に焦点を当てています。新しいアプローチと予測分析とモデルの可能性と過学習への影響を考慮します。モデルを使用した全体的な結果は、この段階の結果に依存します。予測変数の選択に、新しい、オリジナルなアプローチを提供します。

グラフィカルインタフェースVII: テーブルコントロール(チャプター 1) グラフィカルインタフェースVII: テーブルコントロール(チャプター 1)

MetaTraderグラフィカルインタフェースに関するシリーズの第七部では、テキストラベル、エディットボックスとレンダーボックスの3つのテーブルタイプについてお話します。後1つの重要かつ頻繁に使用されるコントロールはタブで、これは、他のコントロールのグループを表示/非表示してMQLアプリケーション内でスペースを有効に使ったインタフェースを開発することを可能にします。

グラフィカルインタフェースVII: タブコントロール(チャプター2) グラフィカルインタフェースVII: タブコントロール(チャプター2)

第七部の最初の章では、テーブルを作成するためのコントロールであるテキストラベルテーブル(CLabelsTable)、エディットボックステーブル(CTable)およびレンダーテーブル(CCanvasTable)の3つのクラスが紹介されました。本稿(チャプター2)ではタブコントロールが考察されます。

グラフィカルインタフェースVIII:カレンダーコントロール(チャプター1) グラフィカルインタフェースVIII:カレンダーコントロール(チャプター1)

このMetaTraderでのグラフィカルインタフェースの作成に専念した記事シリーズの第八部では、カレンダー、ツリービュー、およびファイルナビゲーターのような複雑な複合コントロールが検討されます。情報が大量のため、それぞれは個別の記事に書かれています。この部分の最初の章では、カレンダーコントロールとその拡張バージョンであるドロップダウンカレンダーに ついて説明します。