アルゴリズムトレードにおける Kohonen ニューラルネットワークの活用 パート II. 最適化と予測

Stanislav Korotky | 30 4月, 2019

本稿では、Kohonen ネットワークをトレーダーのツールとして検討していきます。 Part I では、必要なアルゴリズムを追加して、一般に公開されているニューラルネットワーククラスを修正し、改善しました。 今回はこれを実践に応用しましょう。 この記事では、Kohonen マップを使用して、最適なEAパラメータの選択や時系列の予測などの問題を解決していきます。


最適なEAパラメータの検索

共通の原則

ロボットの最適化の問題は、MetaTrader を含む多くのトレードプラットフォームで解決されています。 この組み込みテスターは、多種多様なツール、高度なアルゴリズム、分散計算、きめ細かい統計評価を提供しています。 しかし、ユーザの観点から、最適化においては、プログラムによって生成された情報のその弾幕の分析に基づいて、最終的なタスクパラメータを選択する段階という、常に1つのより重要な最終段階が存在します。 本ウェブサイトに掲載されている Kohonen マップを扱った前の記事では、最適化結果を視覚的に分析する例を紹介しました。 しかし、これはユーザーが自分でEAの分析を行わなければならないことを示唆します。 理想的には、ニューラルネットワークからより具体的な推奨項目を取得したいと考えています。 全体として、アルゴリズムトレードはユーザーを巻き込むことなくプログラムによってトレードされます。

最適化を完了すると、多くのオプションを含む長いテスターレポートが通常表示されます。 並べ替えの対象となる列に応じて、その深さから、利益、シャープレシオなど、関連する基準の最適性を意味する異なる設定を抽出します。 最も信頼する基準を決定したとしても、システムはしばしば同じ結果を持つ設定を提供します。 どう選択するればいいでしょうか?

トレーダーは、計算に標準インデックスを含む独自の合成基準を実践しています—このアプローチでは、レポート内で等しい文字列を受け取ることは本当に少なくなります。 しかし、実際には、上記の基準のメタ最適化の領域に問題を置き換えています (その式を正しく選択する方法は何でしょうか?)。 そして、これはまた別のトピックです。 そこで、一般の最適化結果の分析に戻ります。

私の意見では、最適なEAパラメータのセットを選択するには、ターゲット関数の値の範囲内で最長の「プラトー 」を検索することに基づいて、その "プラトー " の設定された最小レベルを持つ必要があります。 トレーディングの文脈では、 「プラトー」のレベルは平均収益性と比較することができますが、その長さは信頼性、すなわちシステムの堅牢性と安定性において比較することができます。

部分的に、一部のデータ解析技術を意図的に検討した後、そのような "プラトー " が クラスタ化 を使用して検索できることが示唆されました。

残念ながら、必要な特性を持つクラスタを取得するための統一または汎用的な方法はありません。 特に、クラスタ数が "多すぎる" 場合、これらは小さくなり、再学習のすべての症状を示すため、情報の一般化が不十分になります。 クラスタが少なすぎる場合、かなり訓練されていない状態であるため、根本的に異なるサンプルを自分自身に受け入れます。 各タスク、数、およびデータの構造ごとに特定の閾値があるため、 "余り " の用語は明確な定義を持っていません。 したがって、通常、とにかく実験を行うことが推奨されます。

クラスタの数は、マップのサイズと適用されたタスクに論理的に関連しています。 今回のケースでは、以前は formula (7) によってサイズを設定することに決めたので、前者の要素は一方向にしか機能しません。 したがって、このサイズを知ると、クラスタ数の上限が設定され、片側のサイズよりも多くのクラスタが存在することはほとんどありません。 一方、適用されたタスクに基づいて、クラスタのペアだけがおそらく合っています。つまり、"良い " と "悪い " と設定します。 これが実験を行うことができる範囲です。 このすべては、K-means のようなクラスタの数を明確に示すことに基づくアルゴリズムにのみ適用されます。 代替アルゴリズムは、そのような設定を持っていませんが、品質によってクラスタを配置するために、与えられたものより上の数字を持つすべてのクラスタを除外することができます。

その後、 Kohonen ネットワークを使用してクラスタ化を実行します。 しかし、実践に行く前に、細かい点について考察する必要があります。

多くのロボットは、大規模なパラメータの空間で最適化されています。 したがって、最適化は遺伝的アルゴリズムによって行われます。 これは時間とリソースを節約できます。 しかし、収益性の高い領域に "落ち着く "という特徴があります。 原理的には、これは意図したものです。 しかし、Kohonen マップの面では、良いことではありません。 この問題は、Kohonen マップがインプット空間内のデータ分布に敏感で、実際に結果のトポロジーに反映されることです。 パラメータの悪いバージョンの中には、初期の段階で遺伝学によって除外され、多くの詳細で遺伝学によって継承されているものよりもはるかに良いものが稀に発生します。 結果として、Kohonen ネットワークは、対象の関数の危険な谷が見つかると伝えられるところでは良いバージョンが見つかったことに気付くために省略することができます。 相場の特性は常に変動するため、すぐ近くに危険な損失につながるようなパラメータを避けることが重要です。

これらの問題を解決する方法は次のとおりです。

  1. それは完全なものを支持して遺伝的最適化をあきらめることです。常に最大限に可能であるとは限らないため、階層的なアプローチを実装すること、すなわち、最初に大きなステップで遺伝的最適化を実行し、興味深い領域をローカライズしてから、中で完全な最適化を実行します。 (Kohonen ネットワーク);また、最適化されるべきパラメータのリストのは、最初、不安定なために、自由度の数をシステムに提供すると考えられます。そして第2に、最適化はフィッティングに変換されます。したがって、物理的な意味と基本的な分析に基づいて、パラメータの大部分の永続的な値を選択することを推奨します (例えば、戦略の種類に応じて時間枠を選択する必要があります: デイトレード戦略、中期的なもの、週など)。その後、最適化スペースを削減し、遺伝的システムを放棄します。
  2. 遺伝的最適化を数回繰り返すには、最大値と最小値の両方を基準とし、ターゲット関数のゼロを使用します。たとえば、次のような最適化を実行できます。
    • By profit factor (PF), as usual;
    • By its inverse quantity, 1/PF;
    • By formula (min(PF, 1/PF) / max(PF, 1/PF)) that would collect statistics around 1;
    その後、すべての最適化の結果を統合し、ネットワークによって統一された全体として分析します。
  3. まだ研究する価値があるものの半分です。最適化されたインデックス (実際には、EAパラメータではないすべての経済インデックス) を除いたメトリックで Kohonen マップを構築します。言い換えれば、ネットワークを学習させる際に、ニューロンの加重とインプットの類似性の尺度は、EAパラメータに関連する選択されたコンポーネントによってのみ計算されなければなりません。近接性のインジケータは、経済インデックスによって計算され、おそらく、システムの不安定性の証拠を提供し、パラメータの面でトポロジ分散を参照します。どちらの場合も、ニューロンの加重は完全な方法で (すべてのコンポーネントによって) 適合されます。

直近のバージョン N3 は、ネットワークトポロジがEAパラメータの分布 (方向に応じた経済インデックス) のみを反映することを意味します。 実際、最適化テーブルからの完全な行でネットワークを学習させると、利益、ドローダウン、取引数などの列は、EAパラメータのよりも少なくない範囲のニューロンの総分布を形成します。 これは視覚的な分析の問題が一般的な理解に到達し、どのパラメータが主にどのインデックスに影響するかの結論を引き出すために良いかもしれません。 しかし、実際の分布は経済インデックスによって変化するため、パラメータを分析する点においては悪いことです。

原則として、最適化結果を分析する場合、インプットベクトルを論理的に別個の2つのコンポーネント (EAインプットとそのインデックス (アウトプット)) に分割します。 Kohonen ネットワークを完全なベクトルで学習させるには、 "アウトプット" と "アウトプット " (2 方向の無条件の関係) の依存性を特定します。 ネットワークが関数の一部でのみ学習させられている場合、指示された関係を見てみることができます: "インプット " によってクラスタリングされる方法 "アウトプット "、またはその逆に、 "アウトプット" によってクラスタ化された "アウトプットです。


SOM エクスプローラのさらなる開発

一部の関数をマスキングしてこのティーチングモードを実装するには、CSOM および CSOMNode のクラスをさらに開発する必要があります。

距離はクラス CSOMNode で計算されます。 特定のコンポーネントを計算から除外することは、クラスのすべてのオブジェクトに対して統一されるため、関連する変数統計を作成します。

    static int dimensionMax;
    static ulong dimensionBitMAk;

dimensionMax は、計算されるニューロン加重の最大量を設定することができます。 たとえば、空間の次元が5の場合、4に等しい dimensionMax は、ベクトルの直近の構成要素が計算から除外されることを意味するものとします。

dimensionBitMAk は、ビットマスクを使用してランダムに配置されたコンポーネントを除外することができます。つまり、i 番目のビットが1に等しい場合、i 番目のコンポーネントは処理されます。0に等しい場合は、そうではありません。

変数を配置する静的メソッドを追加してみましょう。

static void CSOMNode::SetFeatureMAk(const int dim = 0, const ulong bitMAk = 0)
{
  dimensionMax = dim;
  dimensionBitMAk = bitMAk;
}

次に、新しい変数を使用して距離の計算を変更します。

double CSOMNode::CalculateDistance(const double &vector[]) const
{
  double distSqr = 0;
  if(dimensionMax <= 0 || dimensionMax > m_dimension) dimensionMax = m_dimension;
  for(int i = 0; i < dimensionMax; i++)
  {
    if(dimensionBitMAk == 0 || ((dimensionBitMAk & (1 << i)) != 0))
    {
      distSqr += (vector[i] - m_weights[i]) * (vector[i] - m_weights[i]);
    }
  }
  return distSqr;
}

ここでは、クラスの CSOM によってニューロンの制限が適切に課されるようにするだけで済みます。 CSOM に同様のパブリックメソッドを追加してみましょう。

void CSOM::SetFeatureMAk(const int dim, const ulong bitMAk)
{
  m_featureMAk = 0;
  m_featureMAkSize = 0;
  if(bitMAk != 0)
  {
    m_featureMAk = bitMAk;
    Print("Feature MAk enabled:");
    for(int i = 0; i < m_dimension; i++)
    {
      if((bitMAk & (1 << i)) != 0)
      {
        m_featureMAkSize++;
        Print(m_titles[i]);
      }
    }
  }
  CSOMNode::SetFeatureMAk(dim == 0 ? m_dimension : dim, bitMAk);
}

テストEAでは、ユーザーがフィーチャマスクを設定し、シンボル ' 1 ' と ' 0 ' の可用性を解析する文字列パラメータ FeatureMAk を作成します。

    ulong MAk = 0;
    if(FeatureMAk != "")
    {
      int n = MathMin(StringLen(FeatureMAk), 64);
      for(int i = 0; i < n; i++)
      {
        MAk |= (StringGetCharacter(FeatureMAk, i) == '1' ? 1 : 0) << i;
      }
    }
    KohonenMap.SetFeatureMAk(0, MAk);

このすべては、学習の方法を起動する直前に行われます。したがって、学習中および U 行列とクラスタを計算する段階での距離の計算に影響を与えます。 しかし、場合によっては、マスクなしでネットワークを教え、クラスタのみを見つけるためにマスクを適用するなど、他のルールによって クラスタ化 を実行することは興味深いでしょう。 このために、デフォルトでは ' false ' に等しい制御パラメータ ApplyFeatureMAkAfterTraining を追加で紹介します。 しかし、 ' true ' に設定されている場合、学習の後に SetFeatureMAk を呼び出します。

再びツールを改善している間、インプットベクトルとして、トレードロボットのタスク設定を使用するという事実に関連するもう一つのポイントを扱います。

EAパラメータの値をネットワークにアップロードして、セットファイルから直接分析すると便利です。 このために、次の関数を記述します。

bool LoadSettings(const string filename, double &v[])
{
  int h = FileOpen(filename, FILE_READ | FILE_TXT);
  if(h == INVALID_HANDLE)
  {
    Print("FileOpen error ", filename, " : ",GetLastError());
    return false;
  }
  
  int n = KohonenMap.GetFeatureCount();
  ArrayResize(v, n);
  ArrayInitialize(v, EMPTY_VALUE);
  int count = 0;

  while(!FileIsEnding(h))
  {
    string line = FileReadString(h);
    if(StringFind(line, ";") == 0) continue;
    string name2value[];
    if(StringSplit(line, '=', name2value) != 2) continue;
    int index = KohonenMap.FindFeature(name2value[0]);
    if(index != -1)
    {
      string values[];
      if(StringSplit(name2value[1], '|', values) > 0)
      {
        v[index] = StringToDouble(values[0]);
        count++;
      }
    }
  }
  
  Print("Settings loaded: ", filename, "; features found: ", count);
  
  ulong MAk = 0;
  for(int i = 0; i < n; i++)
  {
    if(v[i] != EMPTY_VALUE)
    {
      MAk |= (1 << i);
    }
    else
    {
      v[i] = 0;
    }
  }
  if(MAk != 0)
  {
    KohonenMap.SetFeatureMAk(0, MAk);
  }
 
  FileClose(h);
  return count > 0;
}

その中で、セットファイルの文字列を解析し、学習されたネットワークの特徴に対応するパラメータの名前を見つけます。 一致する設定はベクターに保存され、一致しないものはスキップされます。 フィーチャーマスクは、使用可能なコンポーネントに対してのみ unities で埋められます。 この関数は、設定が読み取られたという事実の論理関数を返します。

さて、設定のファイルからパラメータをダウンロードするには、この関数があるとき、 DataFileName のチェックがある場合、if 演算子のブランチに次の文字列を挿入します! = "":

      //パターンの特殊なケースとしてファイルを設定します。
      if(StringFind(DataFileName, ".set") == StringLen(DataFileName) - 4)
      {
        double v[];
        if(LoadSettings(DataFileName, v))
        {
          KohonenMap.AddPattern(v, "SETTINGS");
          ArrayPrint(v);
          double y[];
          CSOMNode *node = KohonenMap.GetBestMatchingFeatures(v, y);
          Print("Matched Node Output (", node.GetX(), ",", node.GetY(),
            "); Hits:", node.GetHitsCount(), "; Error:", node.GetMSE(),
            "; Cluster N", node.GetCluster(), ":");
          ArrayPrint(y);
          KohonenMap.CalculateOutput(v, true);
          hasOneTestPattern = true;
        }
      }

設定はSETTINGSでマークされます。


ワーキングEA

ここで、最適なパラメータを選択するという問題に近づきました。

最適化の結果をクラスタリングの理論をテストするには、まず、ワーキングEAを作成する必要があります。 MQL5 Wizard と標準モジュールを使ってを生成し、これを WizardTest と名付けました (そのソースコードはこの記事の最後に添付されています)。 インプットのリストを次に示します。

input string             Expert_Title                 ="WizardTest"; //ドキュメント名
ulong                    Expert_MagicNumber           =17897;        // 
bool                     Expert_EveryTick             =false;        // 
//---メインシグナルのインプット
input int                Signal_ThresholdOpen         =10;           //開くためのシグナル閾値 [0... 100]
input int                Signal_ThresholdClose        =10;           //決済するシグナル閾値 [0... 100]
input double             Signal_PriceLevel            =0.0;          //トレードを実行するための価格レベル
input double             Signal_StopLevel             =50.0;         //SLレベル (ポイント単位)
input double             Signal_TakeLevel             =50.0;         //TPレベル (ポイント単位)
input int                Signal_Expiration            =4;            //未決済オーダーの終了 (足)
input int                Signal_RSI_PeriodRSI         =8;            //相対力指数 (8,...)計算期間
input ENUM_APPLIED_PRICE Signal_RSI_Applied           =PRICE_CLOSE;  //相対力指数 (8,...)価格シリーズ
input double             Signal_RSI_Weight            =1.0;          //相対力指数 (8,...)ウェイト [0... 1.0]
input int                Signal_Envelopes_PeriodMA    =45;           //エンベロープ (45, 0, MODE_SMA,...)平均化期間
input int                Signal_Envelopes_Shift       =0;            //エンベロープ (45, 0, MODE_SMA,...)タイムシフト
input ENUM_MA_METHOD     Signal_Envelopes_Method      =MODE_SMA;     //エンベロープ (45, 0, MODE_SMA,...)平均化方法
input ENUM_APPLIED_PRICE Signal_Envelopes_Applied     =PRICE_CLOSE;  //エンベロープ (45, 0, MODE_SMA,...)価格シリーズ
input double             Signal_Envelopes_Deviation   =0.15;         //エンベロープ (45, 0, MODE_SMA,...)偏差
input double             Signal_Envelopes_Weight      =1.0;          //エンベロープ (45, 0, MODE_SMA,...)ウェイト [0... 1.0]
input double             Signal_AO_Weight             =1.0;          //オーサムオシレータの重み [0... 1.0]
//---トレーリングのインプット
input double             Trailing_ParabolicSAR_Step   =0.02;         //速度増分
input double             Trailing_ParabolicSAR_Maximum=0.2;          //最大レート
//---資金のインプット
input double             Money_FixRisk_Percent=5.0;          //リスクの割合

研究の目的のため、すべてではなく、パラメータだけを最適化します。

Signal_ThresholdOpen
Signal_ThresholdClose
Signal_RSI_PeriodRSI
Signal_Envelopes_PeriodMA
Signal_Envelopes_Deviation
Trailing_ParabolicSAR_Step
Trailing_ParabolicSAR_Maximum

2018 (20180101-20180701) の1月から6月末まで EURUSD D1、M1 OHLC、利益によってEAの遺伝的最適化を行いました。 この記事の最後に、最適化されるパラメータの設定を持つセットファイルが添付されています (WizardTest-1)。 最適化結果はファイル Wizard2018plus (もトレーリングストップに添付) に保存され、外れ値が除外され、特に5未満のトレード量、irreal シャープファクタがあります。 さらに、遺伝的最適化は、定義によって、収益性の高いコリドーへのシフトを生成したので、利益が少なくとも1万になったインプットを保持しました。

また、バランスや期待ペイオフなどの他のものに実際に依存しているので、インデックス列のペアを削除し、PF (プロフィットファクタ)、RF (ラリーファクタ)、シャープファクタなどの他の候補があります。

情報の最大値に耐えることができる独立したコンポーネントの最小セットでインプットの構造を選択することは、ニューラルネットワークを効率的に使用するための重要な条件です。

最適化結果を含む csv ファイルを開き、上記で言及した疑わしい問題を見ます。等しく有益なインデックスと異なるパラメータを含む大量の文字列です。 試してみて、合理的なオプションを行使してみましょう。

将来的に選択したオプションを評価するための参照点を持つために、最適化結果の最初の文字列からパラメータセットのフォワードテストを見てみましょう (WizardTest-1 を参照してください)。 テスト日は、2018年7月1日 ~ 2018年12月1日です。

最初にリストされた設定の選択に関するテスターレポート

最初にリストされた設定の選択に関するテスターレポート

これらのことを心にとめて、実際には、あまり良い数字ではないものを、ネットワークにするつもりです。


ニューラルネットワーク解析

Csv ファイルのインプット数は約2000です。 したがって、式 (7) で算出された Kohonen ネットワークサイズは15となります。

CSOM Explorer を起動し、データファイル名 (Wizard2018plus) を DataFileName、CellsX と CellsY の15でインプットし、100に等しい EpochNumber を保持します。 すべての平面を同時に表示するには、小さな画像を選択します: 210 の ImageW と ImageH のそれぞれに対して、6と MaxPicturesです。 EAの動作の結果、以下のように実質的に取得します。

EA最適化結果に関する Kohonen ネットワークの学習

EA最適化結果に関する Kohonen ネットワークの学習

上の行は経済インデックスのマップで完全に構成されており、2行目と3行目の最初のマップはEAのタスクパラメータであり、直近の5つのマップは Part I で構築された特別なマップです。

マップを詳しく見てみましょう:

利益、PF、RF、および現用EAの最初の3つのパラメータ

利益、PF、RF、および現用EAの最初の3つのパラメータ

シャープファクタ、ドローダウン、トレード数、EAの2番目の3つのパラメータ

シャープファクタ、ドローダウン、トレード数、EAの2番目の3つのパラメータ

EAの直近のパラメータ、ヒットカウンタ、U 行列、量子化エラー、クラスタ、およびネットワークアウトプット

EAの直近のパラメータ、ヒットカウンタ、U 行列、量子化エラー、クラスタ、およびネットワークアウトプット

取得したマップのエキスパート分析を、手動で実行しましょう。

利益面では、右上隅と左上隅にほぼ等しい値 (赤) を持つ2つの適切な領域を見ることができ、右の1つは大きく、より集中的に強調表示されます。 しかし、PF、RF、シャープファクタを持つ平面の並列解析は、右上隅の最良の選択を納得させます。 これはより少ないドローダウンによっても確認されます。

右上隅に注意を払って、EAのパラメータに関連するコンポーネントに移動してみましょう。 最初の5つのパラメータのマップでは、このスポットは安定して色付けされているので、最適な値に名前を付けることができます (各マップの右上ニューロンのマウスカーソルをポイントすると、ヒントに関連する値が表示されます)。

Signal_ThresholdOpen = 40
Signal_ThresholdClose = 85
Signal_RSI_PeriodRSI = 73
Signal_Envelopes_PeriodMA = 20
Signal_Envelopes_Deviation = 0.5

残りの2つのパラメータのマップは、その色を右上隅でアクティブに変更するため、どの値を選択するかは不明です。 ヒットのカウンタから判断すると、上の一番右のニューロンが好ましいです。 U 行列とエラーマップ上で "静かな雰囲気 " であることを確かめるのも理にかなっています。 ここではすべてが問題ないため、次の値を選択します。

Trailing_ParabolicSAR_Step = 0.15
Trailing_ParabolicSAR_Maximum = 1.59

パラメータを使用してEAを実行します (WizardTest-plus-allfeatures-manual を参照)、2018 12 月1日まで同じフォワード期間にします。 以下の結果が得られます。

Kohonen マップを視覚的に分析することに基づいて選択された設定に関するテスターレポート

Kohonen マップを視覚的に分析することに基づいて選択された設定に関するテスターレポート

この結果は、最初の文字列からランダムに選択されたものよりも著しく優れています。 しかし、まだ失望する結果になる可能性があるので、ここで再考した方がよいです。

これは聖杯ではなく、テストEAです。 このタスクは、ニューラルネットワークベースのアルゴリズムがどのように機能するかを示すためにソースデータを生成することです。 記事が公開された後、実際のトレードシステムの大量にツールをテストし、おそらく、より良い使用に適応することが可能になります。

日付の同じ範囲内の csv ファイルからの設定のすべてのオプションに得ることができる主となる値に現在の結果を比較してみましょう。

すべてのフォワードテストの結果

すべてのフォワードテストの結果

フォワードテストにおける利益配分統計

フォワードテストにおける利益配分統計

統計は以下の通りです。: 平均は1007、標準偏差は1444、中央値は1085、最も低いのは、それぞれ-3813.78 と4202.82 です。 したがって、EAの評価を使用して、平均プラス標準偏差よりも高い利益を得ています。

今回のタスクは、質的に類似した選択を自動的に行う方法を学ぶことです。 これを行うには、クラスタ化を使用します。 クラスタには、望ましい使用のオーダーで番号が付けられているため、クラスタ0を検討します (ただし、基本的には、クラスタ1-5 は、設定のポートフォリオとのトレードに使用できます)。

マップ上のクラスタの色は、常に以下に示すように、インデックス番号に関連付けられます。

{clrRed, clrGreen, clrBlue, clrYellow, clrMagenta, clrCyan, clrGray, clrOrange, clrSpringGreen, clrDarkGoldenrod}

数字を区別することが困難な小さな画像で識別するのに役立ちます。

SOM エクスプローラは、クラスタセンターの座標をログに表示します (現在のマップの場合など)。

Clusters [20]:
[ 0] "Profit"                        "Profit Factor"                 "Recovery Factor"               "Sharpe Ratio"                 
[ 4] "Equity DD %"                   "Trades"                        "Signal_ThresholdOpen"          "Signal_ThresholdClose"        
[ 8] "Signal_RSI_PeriodRSI"          "Signal_Envelopes_PeriodMA"     "Signal_Envelopes_Deviation"    "Trailing_ParabolicSAR_Step"   
[12] "Trailing_ParabolicSAR_Maximum"
N0 [3,2]
[0] 18780.87080     1.97233     3.60269     0.38653    16.76746    63.02193    20.00378
[7]    65.71576    24.30473    19.97783     0.50024     0.13956     1.46210
N1 [1,4]
[0] 18781.57537     1.97208     3.59908     0.38703    16.74359    62.91901    20.03835
[7]    89.61035    24.59381    19.99999     0.50006     0.12201     0.73983
...

初めに、レジェンドの特徴があります。 次に、クラスタごとに、その数、X と Y の座標、および特徴の値があります。

ここでは、0番クラスタに対して、次のEAのパラメータを使用します。

Signal_ThresholdOpen=20
Signal_ThresholdClose=66
Signal_RSI_PeriodRSI=24
Signal_Envelopes_PeriodMA=20
Signal_Envelopes_Deviation=0.5
Trailing_ParabolicSAR_Step=0.14
Trailing_ParabolicSAR_Maximum=1.46

パラメータ (WizardTest-plus-allfeatures-auto-noMAks) を使用してフォワードテストを実行し、レポートを受信します。

フィーチャーマスクなしで Kohonen マップのクラスタから自動的に選択された設定のテスターレポート

フィーチャーマスクなしで Kohonen マップのクラスタから自動的に選択された設定のテスターレポート

この結果は、最初のランダムなテストよりもはるかに優れておらず、EAよりも著しく悪いです。 これがクラスタ化品質についてのすべてです。 現時点では、経済インデックスとEAパラメータの両方を含むすべての関数が一度に実行されています。 ただし、トレード金額のみの観点から、 "プラトー " を検索する必要があります。 すなわち、最初の6つのものを クラスタ化 に適用してみましょう。 これを行うには、以下を設定します。

FeatureMAk=1111110000000
FeatureMAkAfterTraining=true

そして、学習を再開します。 SOM エクスプローラの クラスタ化 は最終的な学習段階として実行され、得られたクラスタはネットワークファイルに保存されます。 後でロードされたネットワークが、 "認識 " 新しいサンプルにすぐに使用するために必要です。 このようなサンプルは、セットファイルの分析のように (ベクトルが不完全である可能性がある) すべてのインデックスよりも少ない場合があります (EAのパラメータのみが含まれます) が、経済インデックスは存在しません (意味がありません)。 したがって、このようなサンプルでは、独自のフィーチャマスクが関数 LoadSettings に構築され、このマスクがベクトルの既存のコンポーネントに対応し、そのマスクがネットワークに適用されます。 したがって、クラスタ化 マスクは、ベクトルのマスクと矛盾しないようにするために、ネットワーク内に暗黙的に存在していなければなりません。

しかし、新しいマスクを使用して学習に戻りましょう。 U 行列とクラスタの平面を変更します。 クラスタのパターンは大きく変化します (左の画像はマスクを適用する前、右はマスクを適用した後のものです)。

経済インデックスによってマスクを適用する (左) と (右) なしで構築されたKohonen マップ上のクラスタ

現在、ゼロクラスタの値は異なります。

N0 [14,1] 
[0] 17806.57263     2.79534     6.78011     0.48506    10.70147    49.90295    40.00000
[7]    85.62392    73.51490    20.00000     0.49750     0.13273     1.29078

EAの評価右上隅に位置するニューロン、すなわち、座標 [14, 0] を有することを選択しました。 システムは近隣ニューロン [14, 1] になります。 この加重はほど大きくはありません。 動作しているEAのパラメータに提案された設定を移動させてみましょう。

Signal_ThresholdOpen=40
Signal_ThresholdClose=86
Signal_RSI_PeriodRSI=74
Signal_Envelopes_PeriodMA=20
Signal_Envelopes_Deviation=0.5
Trailing_ParabolicSAR_Step=0.13
Trailing_ParabolicSAR_Maximum=1.29

以下の結果が得られます。

経済インデックスのマスクを使用して、Kohonen マップのクラスタから自動的に選択された設定のテスターレポート

経済インデックスのマスクを使用して、Kohonen マップのクラスタから自動的に選択された設定のテスターレポート

これはパラメータの差に関係なく、エキスパートの結果と同じです。

クラスタ化 の結果をEAの設定に移動しやすくするために、選択したクラスタの関数の名前と値を持つセットファイルを生成するヘルパー関数を記述します (デフォルトではゼロ)。 この関数は SaveSettings という名前で、新しいパラメータ SaveClusterAsSettings にエクスポートするクラスタのインデックスが含まれている場合は、操作します。 デフォルトでは、このパラメータには-1 が含まれており、セット・ファイルを生成する必要がないことを意味します。 関数の適用された感覚については、この関数は "知っている " ではなく、セットファイルに名前が付けられたすべてのものを保存するので、利益、プロフィットファクタなどのトレーディングインデックスもそこに存在することは明らかです。 ユーザーは、EAの実際のパラメータに対応する関数のみを生成されたファイルからコピーすることができます。パラメータの値は実数として保存されるため、整数型のパラメータを修正する必要があります。

見つかった設定をポータブル形式で保存できるようになったので、クラスタ 0 (Wizard2018plusCluster0) の設定を作成して SOM エクスプローラにロードします (ユーティリティがすでにセットファイルを読み取ることができたことを通知する必要があります)。 パラメータ NetFileName では、前の学習段階で作成されたネットワークの名前を指定する必要があります (Wizard2018plus は、Wizard2018plus のデータを使用していたので、各学習サイクルにはファイルに保存され、その名前はインプットの1つですが、som の拡張子が付いています)。 パラメータ DataFileName では、生成されたセットファイルの名前を指定します。 マークSETTINGは、クラスタ C0 の中心と重なっています。

その後の実験中に書き換えられないために、ネットワークで som ファイルの名前を変更します。

最初の実験は次のようになります。 「リバース 」マスクを使用してネットワークを学習させます—EAパラメータによって、除外されたトレード数字があります。 これを行うには、パラメータ DataFileName で再度ファイル Wizard2018plus を指定し、パラメータ NetFileName をクリアし、設定します。 

FeatureMAk=0000001111111

FeatureMAkAfterTraining はまだ ' true ' に設定されているので、マスクは クラスタ化 のみに影響することに注意してください。

学習が完了したら、学習されたネットワークをロードし、セットファイルをテストします。 これを行うには、作成されたネットワークファイル Wizard2018plus の名前をパラメータ NetFileName に移動し、Wizard2018plusCluster0 をコピーして DataFileName に再設定します。 マップの合計セットは変更されずに残りますが、U-マトリクスによってクラスタが異なります。

クラスタ化 結果は下の画像の左側に表示されます。

EAパラメータ上のマスクで構築された Kohonen マップ上のクラスタ: クラスタ化 段階 (左側) とネットワーク学習と クラスタ化 ステージ (右) のみ

設定の選択は、ゼロクラスタに到達し、サイズが大きくなるという事実によって確認されます。

2番目の実験として、(EAパラメータによって) 同じマスクでネットワークをもう一度学習させます。 ただし、学習段階でも拡張します。

FeatureMAkAfterTraining=false

マップの完全なセットは以下に示されていますが、クラスタ内の変更は上の画像の右にある大きなスケールに示されています。 ここで、ニューロンは、パラメータの類似性によってのみクラスタ化されます。 マップは、次のように読み取る必要があります。選択したパラメータに表示される経済インデックスは何か。 テストの設定はクラスタ番号2に落ちましたが (2 より悪いですが、それほど大きくありません)、サイズは最大のもの1つであり、ポジティブな特徴です。

EAパラメータによってマスクで構築された Kohonen マップ

EAパラメータによってマスクで構築された Kohonen マップ

関心のある読者は、経済インデックスを持つマップが、もはやそのような表現的なトポロジーではないことに気づくでしょう。 ただし、チェックの本質は、パラメータに基づいてクラスタの構造を特定し、選択した設定がこのクラスタシステム内で適切に配置されていることを確認することであるため、現在は必要ありません。

"Inversed " 研究は、経済インデックスによるマスクとの完全な学習と クラスタ化 になります:

FeatureMAk=1111110000000
FeatureMAkAfterTraining=false

結果は次のとおりです。

経済インデックスによるマスクで構成された Kohonen マップ

経済インデックスによるマスクで構成された Kohonen マップ

今では、コントラストの色は経済インデックスの最初の6つの面に集中していますが、パラメータのマップはかなり不定形です。 特に、パラメータ Trailing_ParabolicSAR_Step と Trailing_ParabolicSAR_Maximum の値が実質的に変化しない (マップは単調である) ことがわかり、最適化から除外され、平均に基づいていることを意味します。0.11 や1.14 などがそうです。 パラメータのマップの中で、Signal_ThresholdOpen は、そのコントラストで際立っている、正常にトレードするために0.4 に等しい Signal_ThresholdOpen を選択する必要があることから明らかになります。 Map U 行列は、明らかに2つの "プール "、上と下のものに分割され、上のものは成功のものであり、下は失敗です。 ヒットのマップは希少かつ不均一である (スペースの最大の部分はギャップですが、アクティブニューロンはカウンタの大きな値を持っています)、利益は研究中のEAの明白なレベルによってグループ化されているためです。

このマップは、次のように読み取る必要があります。選択した経済インデックスに表示されるパラメータは何か、と...

直近の実験では、クラスタに適度な名前を付けられるように、SOM エクスプローラを少し開発します。 各クラスタ内のコードベクターの特定のコンポーネントの値を分析し、コンポーネントの値の範囲と比較する関数 SetClusterLabels を記述します。 ニューロンの加重値が最も高い値または低い数値に近づくとすぐに、関連するコンポーネントの名前でマークされる理由になります。 たとえば、0番の関係 (利益に対応する) の加重が他のクラスタの加重を超える場合は、このクラスタが高値の利益によって特徴付けられることを意味します。 極値の符号は、最大または最小、インジケータの意味によって決定されることに留意すべきです。 関連して、 ' + ' の符号で正の効果を持つ適応と「-」の符号で負の効果を持つものをマークする特別なインプット FeatureDirection を導入します。 この場合、EAの動作パラメータの値はまったく同じであり、定義範囲の境界への近さに応じて良いか悪いと解釈されないので、経済インデックスのみをマークするのが妥当であることに注意してください。 したがって、最初の6つの関数についてのみ、FeatureDirection の値を設定してみましょう。

FeatureDirection=++++-+

これは、ラベルが経済インデックス (左側) と、EAパラメータにマスクを持つ学習と クラスタ化 を持つネットワークに、完全なベクトルと クラスタ化 の学習によってネットワークを探す方法です。

クラスタラベルの場合: クラスタ化 ステージでの経済インデックスによるマスクの使用 (左側) と学習および クラスタ化 ステージでのパラメータによるマスクの使用 (右)

どちらの場合も、選択した設定がプロフィットファクタのクラスタに入るので、このインジケータでは最高の効率が期待できます。 ただし、ソースデータは遺伝的最適化から取得され、許容可能なオプションを選択するためのフィルタとして機能するため、ここではすべてのラベルが正であることを考慮に入れる必要があります。 完全最適化のデータを分析すると、その性質によって負であるクラスタを識別できます。

したがって、Kohonen マップ上の クラスタ化 を使用してEAの最適パラメータを検索することを一般的に検討してきました。 このアプローチは柔軟性があるため、複雑です。 さまざまな クラスタ化 とネットワーク学習法を使用すること、およびインプットを前処理することを意味します。 最適なオプションを検索することも、タスクロボットの特異性に大きく依存します。 SOM エクスプローラで提示されたツールを使用すると、データ処理のこのスライスの学習を開始するだけでなく、拡張して改善することができます。


最適化結果の色分けされた分類

クラスタ化 の方法と品質がEAの最適設定の正しい検索に強く影響するため、ニューロンの近接性を評価することなく、よりシンプルな方法で同じ問題を解決してみましょう。

RGB カラーモデル内の Kohonen マップ上のフィーチャのウェイトを表示して、淡いポイントを選択します。 RGB カラーモデルは3つの平面で構成されているので、この方法で正確に3つの特徴を視覚化することができます。 多かれ少なかれある場合は、RGB 色の代わりに明るいグレーのグラデーションで表示します。

特徴を選択する際に、最も独立したもの (すでにここで既に言及されている) を選択することが望ましいことを思い出さなければなりません。

新しいアプローチを実装するにあたって、同時に自分たちのもので CSOM クラスを拡張する可能性を実証します。 親クラス CSOMDisplay の仮想メソッドをオーバーライドし、これを介して RGB マップが直近の DIM_OUTPUT 平面の代わりに表示されることを達成するクラス CSOMDisplayRGB を作成してみましょう。

class CSOMDisplayRGB: public CSOMDisplay
{
  protected:
    int indexRGB[];
    bool enabled;
    bool showrgb;

    void CalculateRGB(const int ind, const int count, double &sum, int &col) const;
  
  public:
    void EnableRGB(const int &vector[]);
    void DisableRGB() { enabled = false; };
    virtual void RenderOutput() override;
    virtual string GetNodeAsString(const int node_index, const int plane) const override;
    virtual void Reset() override;
};

完全なコードは、本取引に添付されています。

このバージョンを使用するには、SOM エクスプローラ RGB の変更を作成し、次の変更を行いましょう。

RGB モードを有効にするには、インプットを追加します。

input bool ShowRGBOutput = false;

Map オブジェクトが派生クラスになります。

CSOMDisplayRGB KohonenMap;

別のコードブランチで RGB 平面の直接表示を実装する予定です。

  if(ShowRGBOutput && StringLen(FeatureDirection) > 0)
  {
    int rgbMAk[];
    ArrayResize(rgbMAk, StringLen(FeatureDirection));
    for(int i = 0; i < StringLen(FeatureDirection); i++)
    {
      rgbMAk[i] = -(StringGetCharacter(FeatureDirection, i) - ',');
    }
    KohonenMap.EnableRGB(rgbMAk);
    KohonenMap.RenderOutput();
    KohonenMap.DisableRGB();
  }

すでに使い慣れているパラメータ FeatureDirection を使用します。 これを使用して、RGB 空間に含まれる特定の関数 (全関数セットの) を選択することができます。 たとえば、Wizard2018plus を使用した例では、次のように記述するだけで十分です。

FeatureDirection=++,,-

最初の2つの関数、利益と PF は、直接マップに入るために ( ' + ' の兆候に対応しています)、5番目の特徴であるドローダウンは反転値です ('-' の符号に対応しています)。 ', ' に対応する関数はスキップされます。 その後のすべてのものも考慮されません。 WizardTest-rgb の設定でファイルが添付されています (ネットワークファイル Wizard2018plus は、前のステージから利用可能であったはずです)。

設定 (左側) で RGB 空間がどのように表示されるかを次に説明します。

特徴 (利益、PF、ドローダウン) と (PF、ドローダウン、取引) の RGB 空間

特徴 (利益、PF、ドローダウン) と (PF、ドローダウン、取引) の RGB 空間

色は優先順位の特徴に関連しています: 利益は赤、PF は緑、ドローダウンは青です。 最も明るいニューロンは「RGB」でマークされています。

ログには、「淡い」ニューロンの座標と最良の設定のオプションとして機能することができるその特徴の値が表示されます。

利益と PF は強く相関しているため、マスクを別のものに置き換えます:

FeatureDirection=,+,,-+

この場合、利益はスキップされますが、取引の数が追加されます (一部のブローカーはボリュームにボーナスを提供します)。 この結果は上の画像の右側にあります。 ここでは、色の一致は異なります: PF は赤、ドローダウンは緑、取引の数は青です。

唯一の関数 PF とドローダウンを選択した場合、 (左) グレースケールでマップを取得します。

特徴 (PF およびドローダウン) および (利益) の RGB スペース

特徴 (PF およびドローダウン) および (利益) の RGB スペース

確認のため、利益などの関数を1つだけ選択し、白黒モードが最初の平面に対応していることを確認します (上記の右側を参照)。


フォワードテストの分析

MetaTrader テスターは選択された設定のフォワードテストでEA最適化を補完できることが知られています。 Kohonen マップを使用してこの情報を分析に使用しようとして、この方法で設定の特定のオプションを選択しないのはばかげています。 概念的には、過去および未来の高値金利のクロスセクションのクラスタまたは色付きの領域には、最も安定した収益を提供する設定が含まれている必要があります。

これを行うには、フォワードテストと一緒に WizardTest の最適化結果を見てみましょう (最適化が20180101-20180701 の間隔内に利益に実行されたことを思い出す必要があり、フォワードテストは、応じて、上で行われました20180701-20181201)、過去および未来の利益を除いて、すべての兆候を削除し、ネットワークの新しいインプットファイルを取得します— Wizard2018-with-forward (添付されている)。 WizardTest-with-forward のファイルも付属します。

EAパラメータを含むすべての関数によってネットワークを学習させると、次のような結果が得られます。

Kohonen マップのすべての関数によるフォワードテスト分析 つまり、収益性要因とEAパラメータ

Kohonen は、すべての関数、すなわち収益性要因とEAパラメータによるフォワードテスト分析によるマップを提供します。

未来の利益の領域は、過去の利益よりも大幅に小さく、ゼロクラスタ (赤) にはこの場所が含まれていることがわかります。 さらに、2つの適応(FeatureDirection=++) のマスクによる色分析を含め、直近の map の淡い点もこのクラスタに入ります。 ただし、クラスタセンターと淡いポイントには、超収益性の高い設定はありませんが、テスターの結果は正ですが、以前に得られたものより2倍悪くなっています。

最初の2つの関数のマスクを使用して Kohonen マップを構築します。 これを行うには、FeatureMAk = 110000000 (WizardTest-with-forward-MAk11 を参照) とネットワークの reteach を使用して他の設定を適用します。 この結果は次のようになります。

プロフィットファクタによるフォワードテスト分析による Kohonen マップ

ここでは、最初の2つの平面が最もよく表現された空間構造を持っており、直近のマップでもハイライトされる左下隅に高値値 (利益) を持つ領域を越えていることがわかります。 そのニューロンから設定を取った, 次の結果を取得します:

 "利益安定性 " の原則に基づいて選択された設定のテスターレポート

"利益安定性 " の原則に基づいて選択された設定のテスターレポート

これはまた以前に得られた利益よりも悪いです。

したがって、この実験では最適な設定を見つけることができませんでした。 同時に、ニューラルネットワーク分析にフォワードテストの結果を含むことは正しいと思われ、おそらく推奨されるアプローチになるはずです。 正確にニュアンスが成功するために欠けていたものと成功はすべてのケースで保証されているかどうか、コメントで考察することを提案します。 おそらく、得られた結果は、テストEAが安定したトレードには適していないことを証明するだけです。


時系列予測

外観

Kohonen ネットワークは、データのビジュアル分析と クラスタ化 を実行するために最も頻繁に使用します。 ただし、予測にも使用できます。 この問題は、インプットデータベクトルがティックマークを表しており、その主要部分が通常サイズ (n-1)、ベクトルサイズである n を使用して、最後に、通常最新のティックマークを予測することを意味します。 基本的に、この問題は、ノイズまたは部分的に失われたデータを restituting することに似ています。 しかし、独自の特異性があります。

Kohonen ネットワークを使用した予測には、さまざまなアプローチがあります。 ここでは、ほんの一部です。

1つの Kohonen ネットワーク (A) は、不完全なベクトルのサイズ (n-1)、つまり直近の構成要素を持たないデータを学習します。 第1のネットワークの各ニューロン i について、追加の Kohonen map (Bi) は、n のサイズの完全なベクトルの切り捨てられたセットに学習されるが、ネットワーク a のニューロン i に表示された不完全なものと一致します。ネットワーク B のニューロンに基づく、直近の座標 n の特定の値の確率が計算されます。 後で、操作段階で、未来のティックマークはネットワーク B から得られる確率に従ってシミュレートされ、予測されるベクトルがネットワーク A のニューロン i に入るとすぐになります。

別のオプション。 Kohonen マップでは、完全なベクトルで学習されています。 2番目の Kohonen マップ (B) は、変更されたベクトル (値の代わりにインクリメントが行われる) で学習されます。

yk = xk+1 - xk, k = 1 .. n - 1

ここで、ykと xkは、それぞれ初期ベクトルと変更されたベクトルの構成要素です。 明らかに、変更されたベクトルのサイズは、初期の1によるものよりも小さいです。 そして、両方のネットワークのインプットをティーチングデータとともに供給し、第1のネットワークにおけるニューロン i に対するフルベクターの同時表示の数を計算し、第2のニューロン j とします。 したがって、ニューロン j (ネットワーク B) に入るベクトル y の条件付き確率 pijを取得し、関連するベクター x がニューロン i (ネットワーク A) に入ったことを示します。 操作段階では、ネットワーク A は不完全なベクトル x (直近の成分なし) で供給され、最も近いニューロン i * によって (n-1) 成分が見出され、その後、増分が確率 pi *に従って生成されます。 この方法は、他のものと同様に、予測されるコンポーネントのランダムな値を生成することであり、最も可能性の高い結果を見つけることであるモンテカルロ法に関連しています。

このリストには、SOM ニューロンのいわゆるファンクション SOMs と自己回帰モデルの両方が含まれており、埋め込みの空間内の確率アトラクタの クラスタ化 さえも含んでいるため、はるかに長くなる可能性があります。

しかし、すべて Kohonen ネットワークを特徴づけるベクトル量子化現象に基づいています。 ネットワークが学習させられているように、ニューロン漸近の加重は、表すクラス (インプットのサブセット) の平均値にトレンドがあります。 平均値のそれぞれは、学習選択の場合と同じ統計法則を使用して、新しいデータの不足している (または未来予測される) 値の最良の評価を提供します。 クラスをよりコンパクトで分割するほど、評価が正確になります。

Kohonen ネットワークの単一インスタンスを含むベクトル量子化に基づいて、最もシンプルな予測手法を使用する予定です。 しかし、これでも、困難な点があります。

時系列の完全なベクトルを使用してネットワークインプットをフィードします。 ただし、距離は最初の (n-1) コンポーネントに対してのみ計算されます。 重みはすべてのコンポーネントに完全に合わせられます。 次に、予測を目的として、不完全なベクトルでネットワークインプットをフィードし、成分 (n-1) に最適なニューロンを見つけ、直近の n 番目のシナプスの加重値を読み取ります。 これが予測になります。

CSOM クラスでは、対応する準備がすべて整いました。距離の計算に関与するフィーチャの空間の寸法にマスクを設定する方法 SetFeatureMAk があります。 しかし、アルゴリズムを実装する前に、正確に何を予測するかを決定する必要があります。


クラスタインジケータユニティ

トレーダーの間では、一連のクオートは非自明な時間プロセスを表すと認識されます。 多くのランダムさ、頻繁な位相変化、および影響を及ぼす要因が多数含まれており、原則としてオープンシステムです。

この問題をシンプル化するために、より大きな時間枠の1つである日次分析を選択します。 その時間枠では、ノイズは小さな時間枠よりも影響が小さくなります。 また、相場を動かすような強力なニュースが比較的まれに表示され、予測に使えます。 私の意見では、一番いいのは金属、すなわち金と銀です。 特定の国の支払い手段ではなく、原材料と保護資産としての役割を果たすため、一方ではボラティリティが低く、通貨と密接に結びついています。

理論的には、未来の動きは、現在の相場を考慮し、外国為替相場に対応する必要があります。

したがって、金属の価格と集計で表される基本通貨の同期的な変化を受け取る方法が必要です。 特定の時間において、 n 個の成分を持つベクトルでなければならず、それぞれが通貨または金属の相対的なコストに対応します。 そして、予測の目標は、そのようなベクトルによる予測で構成され、いずれかのコンポーネントの次の値です。

このために、オリジナルのクラスタインジケータ Unity が作成されました (そのソースコードは本稿に添付されています)。 その操作の本質は、以下のアルゴリズムで説明されています。 可能な限り、すなわち、1通貨ペア、EURUSD、ゴールド、XAUUSD によって例示されていると考えてみましょう。

各ティックマーク (一日の始まり/終わりの現在の価格) は、明白な公式によって記述されています。

EUR / USD = EURUSD

XAU / USD = XAUUSD

ここで、変数 EUR、USD、および XAU は資産の特定の独立した "コスト " であり、EURUSD と XAUUSD は定数 (既知のクオート) です。

変数を見つけるために、unity によって変数の2乗和を制限して、システムにもう1つの式を追加してみましょう。

EUR*EUR + USD*USD + XAU*XAU = 1

したがって、インジケータの名前はUnityです。

簡単な置換を使用して、次を取得します。

EURUSD*USD*EURUSD*USD + USD*USD + XAUUSD*USD*XAUUSD*USD = 1

USD を見つけます。

USD = sqrt(1 / (1 + EURUSD*EURUSD + XAUUSD*XAUUSD))

その後、他のすべての変数。

または、より一般的に表されます。

x0 = sqrt(1 / (1 + sum(C(xi, x0)**2))), i = 1..n

xi = C(xi, x0) * x0, i = 1..n

ここで、n は変数の数、C (xi、x0) は関連する変数を含む i 番目のペアのクォートです。 変数の数は、ツールよりも1高いことに注意してください。

係数 C は計算に関与するため、通常は深く変化するクオートです。インジケータでは、さらに取引サイズによって乗算されます。したがって、ほぼ同等である (または、少なくとも同じ大きさである) 値が取得されます。 インジケータウィンドウに表示するには (ちょうど1つの情報に), true に設定する必要があります AbsoluteValues という名前のインプットがあります。 デフォルトでは、もちろん false に等しく、インジケータは常に変数の増分を計算します:

yi = xi0 / xi1 - 1,

ここで、xi0と xi1は、それぞれ最後と2番目の直近の足の値です。

ここではインジケータ実装の技術的な詳細については考慮しませんが、ソースコードを個別に学習することができます。

したがって、次の結果が得られます。

クラスタ (マルチ通貨) インジケータUnity、XAUUSD

クラスタ (マルチ通貨) インジケータUnity、XAUUSD

現在のチャート (この場合、XAU と USD) のタスクツールを構成する資産のラインは広く表示されますが、他のラインは通常の厚さです。

インジケータの他のインプットの中で以下のことを言及する必要があります:

たとえば、金価格の変化を予測するためのデータを含むファイルを準備するには、パラメータツール ( "EURUSD、GBPUSD、USDCHF、USDJPY、AUDUSD、USDCAD、NZDUSD、XAUUSD ") で指定する必要がありますが、' true ' はShiftLastBuffer で指定されます。 実質的に以下の構造を持つ csv ファイルが得られます。

           datetime;      EUR;     USD;      GBP;      CHF;      JPY;      AUD;      CAD;      NZD;      XAU; FORECAST
2016.12.20 00:00:00; 0.001825;0.000447;-0.000373; 0.000676;-0.004644; 0.003858; 0.004793; 0.000118;-0.004105; 0.000105
2016.12.21 00:00:00; 0.000228;0.003705;-0.001081; 0.002079; 0.002790;-0.002885;-0.003052;-0.002577; 0.000105;-0.000854
2016.12.22 00:00:00; 0.002147;0.003368;-0.003467; 0.003427; 0.002403;-0.000677;-0.002715; 0.002757;-0.000854; 0.004919
2016.12.23 00:00:00; 0.000317;0.003624;-0.002207; 0.000600; 0.002929;-0.007931;-0.003225;-0.003350; 0.004919; 0.004579
2016.12.27 00:00:00;-0.000245;0.000472;-0.001075;-0.001237;-0.003225;-0.000592;-0.005290;-0.000883; 0.004579; 0.003232

直近の2つの列には、1行ずつシフトする同じ番号が含まれていることに注意してください。 したがって、2016年12月20日付けの文字列では、列予測におけるその日の XAU の増加と12月21日のインクリメントの両方を見ることができます。


SOM-Forecast

Kohonen ネットワークに基づいて、予測エンジンを実装する時間です。 まず、どのように動作するかを理解するために、すでに知っている SOM エクスプローラをベースにして、予測問題に適応します。

インプットを中心に変更が反映されます。 マスクの設定に関連するすべてのものを削除してみましょう: FeatureMAk、ApplyFeatureMAkAfterTraining、および FeatureDirection は、予測用のマスクが既知であるため、ベクタサイズの n ティックマークが使用可能な場合は、最初の (n-1) のものだけが含まれます。 しかし、必要に応じて、このマスクを無効にし、Kohonen ネットワークの古典的に表現された分析関数を使用できるようになる特別な論理オプション、ForecastMode を、追加する予定です。 相場、または同じ日内の相関を見るために、静的な状態で、Unity で指定されたツールのシステムを探るために必要とします。

ForecastMode が「真」に等しい場合、マスクを配置します。 ' False ' の場合、マスクはありません。

    if(ForecastMode)
    {
      KohonenMap.SetFeatureMAk(KohonenMap.GetFeatureCount() - 1, 0);
    }

ネットワークがすでに学習され、テストデータを持つ csv ファイルがインプット DataFileName で指定されているとすぐに、ForecastMode の予測品質を次のようにチェックします。

      if(ForecastMode)
      {
        int m = KohonenMap.GetFeatureCount();
        KohonenMap.SetFeatureMAk(m - 1, 0);
        
        int n = KohonenMap.GetDataCount();
        double vector[];
        double forecast[];
        double future;
        int correct = 0;
        double error = 0;
        double variance = 0;
        for(int i = 0; i < n; i++)
        {
          KohonenMap.GetPattern(i, vector);
          future = vector[m - 1]; // preserve future
          vector[m - 1] = 0;      // make future unknown for the net (it's not used anyway due to the mask)
          KohonenMap.GetBestMatchingFeatures(vector, forecast);
          
          if(future * forecast[m - 1] > 0) // check if the directions match
          {
            correct++;
          }
          
          error += (future - forecast[m - 1]) * (future - forecast[m - 1]);
          variance += future * future;
        }
        Print("Correct forecasts: ", correct, " out of ", n, " => ", DoubleToString(correct * 100.0 / n, 2), "%, error => ", error / variance);
      }

ここでは、各テストベクトルは GetBestMatchingFeatures を使用してネットワークに提示され、応答は ' 予測 ' ベクトルです。 直近のコンポーネントは、テストベクターからの正しい値と比較されます。 一致する方向は ' 正しい ' 変数でカウントされ、データ自体の散布に関連して、総需要予測 ' エラー ' が累積されます。

学習と ReframeNumber に指定されている検証セット (パラメータ ValidationSetPercent が満たされている) がゼロより上にある場合、新しい CSOM クラス関数である TrainAndReframe が操作に関与します。 これより、段階的にネットワークサイズを増やし、検証セットの学習エラーの変化を追跡して、エラーが減少しなくなり、成長し始めるとすぐにこのプロセスをストップすることができます。 ネットワークの計算能力を向上させることによって特定のベクトルに加重を適応させる瞬間であり、一般化し、未知のデータを扱う能力を失うことにつながります。

サイズを選択したので、ValidationSetPercent と ReframeNumber を0にリセットし、いつものように学習の方法を適用してネットワークを学習させます。

最後に、クラスタ SetClusterLabels のマーキングの関数を少し変更します。 それぞれが正と負の極値の両方を示すことができるので、ラベルに移動シンボルを含めます。 したがって、1と同じ関数は、プラスとマイナスで、2回、マップ上に見つけることができます。

void SetClusterLabels()
{
  const int nclusters = KohonenMap.GetClusterCount();

  double min, max, best;
  
  double bests[][3]; // [][0 - value; 1 - feature index; 2 - direction]
  ArrayResize(bests, nclusters);
  ArrayInitialize(bests, 0);
  
  int n = KohonenMap.GetFeatureCount();
  for(int i = 0; i < n; i++)
  {
    int direction = 0;
    KohonenMap.GetFeatureBounds(i, min, max);
    if(max - min > 0)
    {
      best = 0;
      double center[];
      for(int j = nclusters - 1; j >= 0; j--)
      {
        KohonenMap.GetCluster(j, center);
        double value = MathMin(MathMax((center[i] - min) / (max - min), 0), 1);
        
        if(value > 0.5)
        {
          direction = +1;
        }
        else
        {
          direction = -1;
          value = 1 - value;
        }
        
        if(value > bests[j][0])
        {
          bests[j][0] = value;
          bests[j][1] = i;
          bests[j][2] = direction;
        }
      }
    }
  }

  //... ...
  
  for(int j = 0; j < nclusters; j++)
  {
    if(bests[j][0] > 0)
    {
      KohonenMap.SetLabel(j, (bests[j][2] > 0 ? "+" : "-") + KohonenMap.GetFeatureTitle((int)bests[j][1]));
    }
  }
}

さて、SOM の予測は準備ができていると考えてみましょう。 インジケータの Unity の値インプットをフィードします。


分析

まず、相場全体 (選択された資産のセット) を静的、またはむしろ統計的文脈で分析してみましょう。 日によって厳密にインジケータ Unity によってエクスポートされたデータで、各文字列は、「未来」からの追加の列なしで、1つの D1 足上の適応症に対応します。

このために、 ShiftLastBuffer を ' false ' に設定しながら、インジケータで外国為替商品、金、銀、および SaveToFile のファイル名のセットを指定します。 この方法で得られる模範的なファイルは、この記事の最後に添付されています。unity500-noshift.csvです。

SOM-予測を使用して、このデータにネットワーク (som-forecast-unity500-noshift.set を参照してください), 次のマップを取得します:

Kohonen マップ上の外国為替相場、金、銀の視覚的分析 D1 のインジケータの統一

Kohonen マップ上の外国為替相場、金、銀の視覚的分析 D1 のインジケータの統一

上の2つの行は、アセットのマップです。 比較することで、少なくとも直近の500日に働いていた永久的なリンクを識別することができます。 特に、センター内の2つの多色スポットは、目をキャッチ: GBP の青と AUD の黄色です。 資産がしばしば逆相にあったことを意味し、強い動き、すなわち、相場平均の分散レベルのブレイクスルーで GBPAUD の売りが優勢であることを示します。 このトレンドは持続し、この方向に未決済オーダーを入れるオプションを提供します。

XAG の成長は右上隅に見られますが、CHF はそこに落ちています。 そして、左下隅にその逆である: CHF が成長し、XAG の滝。 資産は常に強い動きでダイバージェンスするため、両方向のブレイクスルーでトレードすることができます。 予想通り、ユーロと CHF は似ています。

他の特定の関数は、マップ上にあります。 実際、予測を始める前に、ある程度前に見る機会がありました。

クラスタについて詳しく見てみましょう。

Kohonen マップ上の外国為替、金、銀のクラスタ D1 のインジケータ統一

Kohonen マップ上の外国為替、金、銀のクラスタ D1 のインジケータ統一

また、例えば、通常は起こらないものについての情報を提供します (またはめったにそうではありません), すなわち: EUR は、円または CAD の下落で成長しません。 GBP はしばしば CHF の落下と同時に成長し、その逆も同様です。

クラスタサイズ、通貨 EUR、GBP、および CHF によって判断することは、最も幅が広いです。 その動きは、より頻繁に他の通貨の動きに取って代わります。しかし、米ドルは、この点で、負け越します。 クラスタ番号も重要であると仮定すると (クラスタはソートされています)、最初の3つです。 つまり、+ CHF、-JPY、および + GBP は、明らかに最も頻度の高い日の動きになります。 (トレンドではないが、正確には周期性が意味されているので、' レンジ ' 期間中であっても、より多くの「ステップ」が上向きの1つの大きな「ステップ」によって補償される可能性がある)。

さて、最終的に予測の問題に行きます。


予測

Fx とゴールド ( "EURUSD、GBPUSD、USDCHF、USDJPY、AUDUSD、USDCAD、NZDUSD、XAUUSD ") をインジケータに、BarLimit の足数 (デフォルトは 500)、SaveToFile のファイル名 (unity500xau など)、およびフラグの設定を含むツールのセットを指定しましょう。ShiftLastBuffer を「真」 (予測に追加の列を作成するモード) にします。 多通貨インジケータであるため、利用可能なデータの数は、すべてのツールからの最短ヒストリーに制限されています。 MetaQuotes-Demoのサーバーでは、時間枠 D1 に、少なくとも2000の足があります。 よって、ここでは、別のポイントを検討するのに役立ちます: 相場が大幅に変更されている可能性が高いため、このような深さにネットワークを学習させることが合理的であるかどうかです。 2-3 年のヒストリー、あるいは1年 (D1 の250の足) は、おそらく現在のルール性を識別するのにより適しているでしょう。

サンプルの unity500xau.csv ファイルは、最後に添付されています。

SOM 予測にロードするには、次のインプットを設定します: DataFileName — unity500xau、ForecastMode —true、ValidationSetPercent-10、重要である: ReframeNumber —10. このようにして、ネットワークサイズ 10 * 10 (デフォルト値) のティーチングを実行し、検証選択でのエラーのチェックを有効にし、エラーが減少しても徐々にネットワークのサイズを増加させながらを教え続けます。 最大10のサイズの増加は、TrainAndReframeメソッドで行われます。各次元で2ニューロンです。 したがって、インプットに最適なネットワークサイズを検出します。 設定のあるファイル (som-forecast-unity500xau.set) が添付されています。

ネットワークを徐々に教えたり増やしたりしながら、ログには実質的に以下のものが表示されます (要約された形式で提供)。

FileOpen OK: unity500xau.csv
HEADER: (11) datetime;EUR;USD;GBP;CHF;JPY;AUD;CAD;NZD;XAU;FORECAST
Training 10*10 hex net starts
...
Exit by validation error at iteration 104; NMSE[old]=0.4987230270708455, NMSE[new]=0.5021707785446128, set=50
Training stopped by MSE at pass 104, NMSE=0.384537545433749
Training 12*12 hex net starts
...
Exit by validation error at iteration 108; NMSE[old]=0.4094350709134669, NMSE[new]=0.4238670029035179, set=50
Training stopped by MSE at pass 108, NMSE=0.3293719049246978
...
Training 24*24 hex net starts
...
Exit by validation error at iteration 119; NMSE[old]=0.3155973731785412, NMSE[new]=0.3177587737459486, set=50
Training stopped by MSE at pass 119, NMSE=0.1491464262340352
Training 26*26 hex net starts
...
Exit by validation error at iteration 108; NMSE[old]=0.3142964426509741, NMSE[new]=0.3156342534501801, set=50
Training stopped by MSE at pass 108, NMSE=0.1669971604289485
MSE が増加したため、map サイズの増分を終了
...
マップファイル unity500xau.som 保存済み

これより、ネットワークサイズ 26 * 26 においてプロセスがストップしました。 一見、エラーが最も低かった 24 * 24 を選択しそうです。 しかし、実際にニューラルネットワークで機能する場合、常に他の可能性も模索します。 RandomSeed、パラメータの1つは、ネットワークで初期の加重を設定するために使用するランダムデータジェネレータを初期化する責任があります。 RandomSeed を変更するたびに、新しい特性を持つ新しいネットワークが得られます。 そして、他のすべての要因が等しい、他のインスタンスよりも良く、または悪く学習しています。 したがって、ネットワークサイズだけでなく、学習の選択のサイズを含む他の設定を選択するには、通常、多くのテストを行い、多くのエラーを作る必要があります。 次に、この原則に従って、ティーチングデータの選択を減らし、ネットワークサイズを 15 * 15 まで減らします。 さらに、ベクトルの時間的な量子化については、記述された方法の非正規の修正を使用することもあります。 この変更は、フラグ ForecastMode が無効になっていることをネットワークに学習させることと、予測のみの場合に有効にすることで構成されます。 場合によっては、より正の効果が得られます。 ニューラルネットワークの使用は、出来合いの食事を提供するわけではありません。ただの調理法です。 そして実験は禁止されていません。

学習させる前に、ソースファイル (今回の場合、unity500xau.csv) は2つに分割する必要があります。 この問題は、学習させる際に、データの予測品質を検証する必要があるということです。 学習にネットワークによって使用するのと同じデータで行う意味がありません (より正確には、正しい答えの割合が unreally 高値であることを自分で見るのは理にかなっています-(チェックすることができます)。 そのため、残りのものを使用して新しいネットワークを教えながら、別のファイルでテストするために50のベクトルをコピーしてみましょう。 関連するファイル、unity500xau-training、unity500xau-validation を添付して見つけることができます。

パラメータ DataFileName の unity500xau-トレーニングを指定します (extension .csv が示唆されます)、CellsX と CellsY の値はそれぞれ24で、ValidationSetPercent は0、ReframeNumber は0、ForecastMode はまだ ' true ' です (参照してください。som-forecast-unity500xau-training) を指定します。 トレーニングの結果、次のようにマップを取得します。

Kohonen ネットワークは D1 上の金の動きを予測

Kohonen ネットワークは D1 上の金の動きを予測

これはまだ予測ではありませんが、ネットワークが何かを学んだことを視覚的に確認します。 正確には、検証ファイルでインプットを与えたことを確認します。

これを行うには、次の設定をインプットしてみましょう。 ファイル名 unity500xau は、パラメータ NetFileName に転送されるようになりました (すでに学習させられているネットワークのファイルの名前であり、このファイルが som の暗黙の拡張子を持っています)。 パラメータ DataFileName では、unity500xau-validationを指定します。 ネットワークはすべてのベクトルを予測し、ログに統計情報を表示します。

ロードされたマップファイル unity500xau-training.som
FileOpen OK: unity500xau-validation.csv
HEADER: (11) datetime;EUR;USD;GBP;CHF;JPY;AUD;CAD;NZD;XAU;FORECAST
Correct forecasts: 24 out of 50 => 48.00%, error => 1.02152123166208

残念ですが、予測精度はランダムによる推測のレベルです。 聖杯は、インプットのようなシンプルな選択から結果を得ることができるのでしょうか。 おそらく無理でしょう。 さらに、推測でヒストリーデプスを選びましたが、この問題も調査する必要があります。 また、需要予測を容易にするために、シルバーを追加するなどの一連のツールを使用し、一般的には、他の資産に依存するアセットのうちどれを明確にする必要があります。 以下では、シルバーを使用した例を考察します。

インプットのより多くの文脈を紹介するために、インジケータ Unity にちょうど1日と直近のもの両方に基づくベクトルを形成するオプションを追加しました。 このために、パラメータ BarLookback が追加され、前のモードに対応するデフォルトで1になります。 ただし、ここで5をインプットした場合、ベクトルには5日間にわたるすべての資産のティックマークが含まれます (基本的には、1週間は基本期間の1つです)。 9つの資産 (8 つの通貨と金) の場合、46の値は csv ファイルの各文字列に格納されます。 かなり多くが加算され、計算は遅くなり、マップを分析することはより困難になります。小さなマップでさえ画面に収まらず、大きなものはチャート上のヒストリーを不足する可能性があります。

注 このような多数のマップを OBJ_BITMAP (MaxPictures = 0) などのオブジェクトのモードで表示すると、チャート上に十分な数の足がない可能性があります。非表示になりますが、画像をリンクするために使用します。

メソッドのパフォーマンスを示すために、 15 * 15 のサイズのネットワークをバックして3日間に決めました。 ファイル unity1000xau3-training.csv と unity1000xau3-validation.csv は、本取引に添付されています。 最初のファイルでネットワークを教え、2番目に検証したことで、正確な予測の 58% を得ます。

ロードされたマップファイル unity1000xau3-training.som
FileOpenOK: unity1000xau3-validation
HEADER: (29) datetime;EUR3;USD3;GBP3;CHF3;JPY3;AUD3;CAD3;NZD3;XAU3;EUR2;USD2;GBP2;CHF2;JPY2;AUD2;CAD2;NZD2;XAU2;EUR1;USD1;GBP1;CHF1;JPY1;AUD1;CAD1;NZD1;XAU1;FORECAST
Correct forecasts: 58 out of 100 => 58.00%, error => 1.131192104823076

十分に良いですが、ネットワーク内のプロセスのランダムな性質を忘れてはいけません。他のインプットと別の初期化で、偉大な結果を取得します。 システム全体を再チェックし、何度も再構成する必要があります。 実際には、複数のインスタンスが生成され、最適なものが選択されます。 さらに、決定を下す際には、1つのネットワークだけでなく、コミッションを使用することもできます。


Unity-Forecast

予測を目的として、マップを画面に表示する必要はありません。 EAやインジケータなどの MQL プログラムでは、CSOMDisplay ではなくクラス CSOM を使用することができます。 Unity に似ていますが、予測を表示するための追加のバッファを持つインジケータユニティ予測を作成しましょう。 「未来の」値を取得するために使用する Kohonen ネットワークは、(SOM-予測で) 個別に教え、その後、インジケータにロードすることができます。 または、インジケータで直接ネットワークを「外」でトレーニングすることもできます。 両方のモードを実装してみましょう。

ネットワークをロードするために、インプット NetFileName を追加してみましょう。 ネットワークを学習させるには、SOM 予測: CellsX、CellsY、HexagonalCell、UseNormalization、EpochNumber、ShowProgress、および RandomSeed に含まれているものと同様のパラメータグループを追加してみましょう。

ここではパラメータ AbsoluteValues は必要ないので、' false ' 定数で置き換えてみましょう。 新しいインジケータは常に予測を意味するため、ShiftLastBuffer はどちらも意味を成さません。 Csv へのエクスポート-ファイルは除外されているので、パラメータ SaveToFile を削除してみましょう。 代わりに、フラグ SaveTrainedNetworks を追加します: ' true ' の場合、インジケータは SOM-予測でマップを研究するためにためにファイルに学習されたネットワークを保存します。

パラメータ BarLimit は、開始時に表示される足の数と、ネットワークのトレーニングに使用する足の数の両方として使用します。

新しいパラメータ RetrainingBars は、ネットワークを再トレーニングする必要がある経過後に、足の数を指定することを可能にします。

ヘッダーファイルを含めてみましょう:

#include <CSOM/CSOM.mqh>

ティックプロセッサでは、新しい足の空き時間をチェックします (すべてのツールの足による同期が必要です—このデモプロジェクトでは行われていません)、ネットワークを変更する場合は、ファイル NetFileName からロードするか、インジケータのデータで教えてください関数 TrainSOM で自体。その後、関数 ForecastBySOM を使用して予測します。

  if(LastBarCount != rates_total || prev_calculated != rates_total)
  {
    static int prev_training = 0;
    if(prev_training == 0 || prev_calculated - prev_training > RetrainingBars)
    {
      if(NetFileName != "")
      {
        if(!KohonenMap.Load(NetFileName))
        {
          Print("Map loading failed: ", NetFileName);
          initDone = false;
          return 0;
        }
      }
      else
      {
        TrainSOM(BarLimit);
      }
      prev_training = prev_calculated > 0 ? prev_calculated : rates_total;
    }
    ForecastBySOM(prev_calculated == 0);
  }

関数 TrainSOM および ForecastBySOMを、以下に示します (簡略化された形式)。 完全なソースコードは、本稿に添付されています。

CSOM KohonenMap;

boolTrainSOM (const intの制限)
{
  KohonenMap.Reset();

  LoadPatterns(limit);
  
  KohonenMap.Init(CellsX, CellsY, HexagonalCell);
  KohonenMap.SetFeatureMAk(KohonenMap.GetFeatureCount() - 1, 0);
  KohonenMap.Train(EpochNumber, UseNormalization, ShowProgress);

  if(SaveTrainedNetworks)  
  {
    KohonenMap.Save("online-" + _Symbol + CSOM::timestamp() + ".som");
  }
  
  return true;
}

bool ForecastBySOM(const bool anew = false)
{
  double vector[], forecast[];
  
  int n = workCurrencies.getSize();
  ArrayResize(vector, n + 1);
  
  for(int j = 0; j < n; j++)
  {
    vector[j] = GetBuffer(j, 1); // 1-st bar is the latest completed
  }
  vector[n] = 0;
  
  KohonenMap.GetBestMatchingFeatures(vector, forecast);
  
  buffers[n][0] = forecast[n];
  if(anew) buffers[n][1] = GetBuffer(n - 1, 1);
  
  return true;
}

実際には、開いた瞬間に、現在の0番足の終値を予測していることに注意してください。 したがって、他のバッファと関連して、インジケータ内の ' future ' バッファのシフトはありません。

今回は、シルバーの動作を予測し、テスターでプロセス全体を視覚化してみましょう。 このインジケータは、過去250日 (1 年) にわたって「オン・ザ・ゴー」を学習し、20日ごと (1 ヶ月) ごとに再トレーニングします。 設定が unity-forecast-xag のファイルは、この記事の最後に記載されています。 ツールのセットが拡張されていることに注意することが重要です: EURUSD、GBPUSD、USDCHF、USDJPY、AUDUSD、USDCAD、NZDUSD、XAUUSD、XAGUSD。 したがって、外国為替相場と銀自体、および金の両方に基づいて XAG を予測します。

これはテストが7月1日、2018から12月1日、2018の期間にどのように表示されるかを表したものです。

Unity-Forecast:予測: MetaTrader5 テスターにおける外国為替および金クラスタにおける銀の動きの予測

Unity-Forecast:予測: MetaTrader5 テスターにおける外国為替および金クラスタにおける銀の動きの予測

時には、精度は 60% に達します。 基本的には、予測オブジェクトを基本的に選択し、インプットを準備し、長時間、細心の注意をもって設定する必要がある場合には、この方法が有効であると結論づけることができます。

注意! 「外」でネットワークをトレーニングすると、インジケータ (および同じ銘柄/時間枠の他のインジケータ) がブロックされるため、お勧めできません。 実際には、このコードはEAで実行されるものとします。 ここでは、説明の目的のためにインジケータに配置しています。 インジケータのネットワークを更新するには、スケジュールによってマップを生成するEAを使用することができますが、このインジケータは NetFileName で指定された名前でリロードします。

次のオプションは、予測の質を高めるために考慮することができます: 週番号などの外部要因をインプットに追加したり、 Kohonen ネットワークまたは Kohonen ネットワークに基づいて、より洗練されたメソッドを実装すると共に、他の種類のネットワークです。


結論

この記事では、トレーダーの問題を解決するための Kohonen ネットワークの実用化について説明しました。 ニューラルネットワークベースの技術は、様々なデータ処理方法を含むことを可能にする強力かつ柔軟なツールです。 同時に、インプット変数、ヒストリーデプス、パラメータの組み合わせを慎重に選択する必要があるため、成功するかどうかはユーザーの専門知識とスキルによって大きく左右されます。 ここで考えられているクラスでは、実際に Kohonen ネットワークをテストし、使用して必要な経験を積み、自分のタスクに適応させることができます。