トレーディングにおける機械学習:理論、モデル、実践、アルゴトレーディング - ページ 3257

 
Forester #:
in statistics.mqh.

functions
PearsonCorrM - すべての行のすべての行に対する相関が最も速い。

どこかが間違っている。
#include <Math\Alglib\statistics.mqh> 

void OnStart()
{
  const matrix<double> matrix1 = {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}};
  
  const CMatrixDouble Matrix1(matrix1);
  CMatrixDouble Matrix2;
    
  if (CBaseStat::PearsonCorrM(Matrix1, 3, 3, Matrix2))  
    Print(Matrix2.ToMatrix());
}
 
fxsaber #:
どこか間違っているのだろうか。

しかし、次の文字列では動作する。

const matrix<double> matrix1 = {{2, 2, 3}, {3, 2, 3}, {1, 2, 1}};

[[1,0,0.8660254037844387]
[0,0,0]
[0.8660254037844387,0,1]]

どうやら、ある列のデータがすべて同じであれば、計算はスキップされるようだ。
列目のデータはすべて2のままにしておいたので、行列の2行目は0のままだった。対角線を1で埋めるのが正しいのだろうが。

追記最初はAlglibのバグだと思った。

古いコードでは要素の値は
m[row].Set(col, val);
そして現在は
m.Set(row,col, val)で設定されていました;

後方互換性がないのは残念だ。まあ、私には関係ないことだ。私は今Alglibを使って仕事をしているわけではない。
一番悲しいのは、古いバージョンの

m[row].Set(col, val);

がエラーメッセージを書かず、ただ何もしないことだ。人々はただ置き換えないだけで、コードを変更する必要があることに気づかない。しかし、行列は変更されません。

 
Forester #:

どうやら、ある列のデータがすべて同じ場合、計算はスキップされるようだ。

ピアソンは行間ではなく列間で計算するのか?

そのようだ。
const matrix<double> matrix1 = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
1つの行列が得られます。
 
fxsaber #:

ピアソンは行間ではなく列間で計算するのですか?

ZY そのようです。単位行列ができます。
それを転置することができます。
 

Alglibは良いライブラリで、MOに必要なものはすべて揃っている。初期のバージョンではそうだった。

 
Forester #:
in statistics.mqh.

PearsonCorrM - すべての行に対するすべての行の相関が最も速い。

これに基づいて相関行列を計算した。

#include <Math\Alglib\statistics.mqh> // https://www.mql5.com/ru/code/11077

const matrix<double> CorrMatrix( const matrix<double> &Matrix )
{
  matrix<double> Res = {};
  
  const CMatrixDouble MatrixIn(Matrix);
  CMatrixDouble MatrixOut;  

  if (CBaseStat::PearsonCorrM(MatrixIn, MatrixIn.Rows(), MatrixIn.Cols(), MatrixOut)) // https://www.mql5.com/ru/code/11077
    Res = MatrixOut.ToMatrix();
  
  return(Res);
}


性能を測定した。

#property script_show_inputs

input int inRows = 100; // Длина строки
input int inCols = 15000; // Количество строк

void FillArray( double &Array[], const int Amount )
{
  for (uint i = ArrayResize(Array, Amount); (bool)i--;)
    Array[i] = MathRand();
}

bool IsEqual( matrix<double> &Matrix1, const matrix<double> &Matrix2 )
{
//  return(MathAbs((Matrix1 - Matrix2).Mean()) < 1e-15); // Дорого по памяти.
  
  Matrix1 -= Matrix2;  
  
  const bool Res = (MathAbs(Matrix1.Mean()) < 1 e-15);
  
  Matrix1 += Matrix2;
  
  return(Res);
}

#define  TOSTRING(A) #A + " = " + (string)(A) + " "

#define  BENCH(A)                                                              \
  StartMemory = MQLInfoInteger(MQL_MEMORY_USED);                              \
  StartTime = GetMicrosecondCount();                                          \
  A;                                                                          \
  Print(#A + " - " + (string)(GetMicrosecondCount() - StartTime) + " mcs, " + \
       (string)(MQLInfoInteger(MQL_MEMORY_USED) - StartMemory) + " MB"); 

void PrintCPU()
{
#ifdef _RELEASE
  Print("EX5: " + (string)__MQLBUILD__ + " " + __CPU_ARCHITECTURE__ + " Release.");
#else // #ifdef _RELEASE
  Print("EX5: " + (string)__MQLBUILD__ + " " + __CPU_ARCHITECTURE__ + " Debug.");
#endif // #ifdef _RELEASE #else
  Print(TOSTRING(TerminalInfoString(TERMINAL_CPU_NAME)));
  Print(TOSTRING(TerminalInfoInteger(TERMINAL_CPU_CORES)));
  Print(TOSTRING(TerminalInfoString(TERMINAL_CPU_ARCHITECTURE)));
}

void OnStart()
{  
  PrintCPU();
  
  double Array[];
  FillArray(Array, inRows * inCols);
  
  matrix<double> Matrix;  
  Matrix.Assign(Array);
  Matrix.Init(inCols, inRows);
  Matrix = Matrix.Transpose();
  
  ulong StartTime, StartMemory;
  
  Print(TOSTRING(inRows) + TOSTRING(inCols));

  BENCH(matrix<double> Matrix1 = CorrMatrix(Matrix)) // https://www.mql5.com/ru/code/11077
  BENCH(matrix<double> Matrix2 = Matrix.CorrCoef(false)); // https://www.mql5.com/ru/docs/basis/types/matrix_vector
//  BENCH(matrix<double> Matrix3 = CorrMatrix(Array, inRows)); // https://www.mql5.com/ru/code/17982 

  Print(TOSTRING(IsEqual(Matrix1, Matrix2)));
//  Print(TOSTRING(IsEqual(Matrix3, Matrix2)));  
}


結果は

EX5: 3981 AVX Release.
TerminalInfoString(TERMINAL_CPU_NAME) = Intel Core i7-2700 K  @ 3.50 GHz 
TerminalInfoInteger(TERMINAL_CPU_CORES) = 8 
TerminalInfoString(TERMINAL_CPU_ARCHITECTURE) = AVX 
inRows = 100 inCols = 15000 
matrix<double> Matrix1 = CorrMatrix(Matrix) - 14732702 mcs, 1717 MB
matrix<double> Matrix2 = Matrix.CorrCoef(false) - 40318390 mcs, 1717 MB
IsEqual(Matrix1, Matrix2) = true 


Alglibは標準的な行列法よりも高速に行列を計算することがよくわかる。

しかし、パターン検索の場合、相関行列の計算はRAM消費の点で非常識だ。


上の例と同じサイズの元行列をPythonが読み込むのにどれくらい時間がかかるだろうか?

 
fxsaber #:

しかし、パターンを見つけるために相関行列を読み込むのは、RAMを消費する狂気の沙汰だ。

私のi7-6700では、内蔵の方が速く動作した。

inRows = 100 inCols = 15000 
matrix<double> Matrix1 = CorrMatrix(Matrix) - 14648864 mcs, 1717 MB
matrix<double> Matrix2 = Matrix.CorrCoef(false) - 29589590 mcs, 1717 MB
IsEqual(Matrix1, Matrix2) = true 

ネイティブの方が遅いというのは不思議だ。It is unlikely that Alglibe has some unique accelerated algorithm under licence.

Have you tried the other 2 variants from Alglib?
If you count in loops every row to every row or every row to all rows, memory will be more economical (2 rows or 1 row + matrix).しかし、正確には覚えていませんが、組み込み関数よりも時間がかかると思います。

 
fxsaber #:

しかし、パターンを見つけるために相関行列を読み込むのは、RAMを消費する狂気の沙汰だ。


起動前



そして、Alglibov PearsonCorrMの作業中、メモリはどんどん増えていく。


標準のMatrix.CorrCoefの実行中も、メモリが増え続けている。

どうやら、標準のものはメモリ使用量が最小になるように最適化されており、Alglibovのものは速度が速くなるように最適化されているようだ。

 
Forester #:

i7-6700で、内蔵の方が速く動くようになった。

コードにCPUとEX5の命令データを追加した。
 
Forester #:

そして、AlglibのPearsonCorrMを実行している間、メモリは増え続け、5ggが表示され、4,6が画面に表示された。

この行のせいで消費量がほぼ倍になっている。

取引、自動取引システム、取引戦略のテストに関するフォーラム

トレーディングにおける機械学習:理論、モデル、実践とアルゴ-トレーディング

fxsaber, 2023.09.25 18:01

#include <Math\Alglib\statistics.mqh> // https://www.mql5.com/ru/code/11077

const matrix<double> CorrMatrix( const matrix<double> &Matrix )
{
  matrix<double> Res = {};
  
  const CMatrixDouble MatrixIn(Matrix);
  CMatrixDouble MatrixOut;  

  if (CBaseStat::PearsonCorrM(MatrixIn, MatrixIn.Rows(), MatrixIn.Cols(), MatrixOut)) // https://www.mql5.com/ru/code/11077
    Res = MatrixOut.ToMatrix();
  
  return(Res);
}

これはCMatrixDoubleから matrix<double>への 移行に過ぎません。メモリの関係で、この行列の比較までしなければならなかった。

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

トレーディングにおける機械学習:理論、モデル、実践、アルゴトレーディング

fxsaber, 2023.09.25 18:01

bool IsEqual( matrix<double> &Matrix1, const matrix<double> &Matrix2 )
{
//  return(MathAbs((Matrix1 - Matrix2).Mean()) < 1e-15); // Дорого по памяти.
  
  Matrix1 -= Matrix2;  
  
  const bool Res = (MathAbs(Matrix1.Mean()) < 1 e-15);
  
  Matrix1 += Matrix2;
  
  return(Res);
}
理由: