Maschinelles Lernen im Handel: Theorie, Modelle, Praxis und Algo-Trading - Seite 3257

 
Forester #:
in statistics.mqh.

functions
PearsonCorrM - Die Korrelation aller Zeilen zu allen Zeilen ist am schnellsten.

Falsch irgendwo, aber ich sehe es nicht.
#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 #:
Ich liege irgendwo falsch, aber ich sehe es nicht.

Aber es funktioniert mit dieser Zeichenkette

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

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

Offenbar wird die Berechnung übersprungen, wenn alle Daten in einer Spalte gleich sind.
In der 2. Spalte habe ich alle Daten in 2 belassen und die 2. Zeile der Matrix blieb Null. Obwohl es wahrscheinlich richtig ist, die Diagonale mit 1en zu füllen.

PS. Zuerst dachte ich, es sei ein Fehler in Alglib.

Im alten Code wurden die Werte der Elemente durch
m[row].Set(col, val);
gesetzt und jetzt
m.Set(row,col, val);

Es ist schade, dass es keine Abwärtskompatibilität gibt. Nun, für mich spielt das keine Rolle. Ich arbeite jetzt nicht mit Alglib. Wenn die alten Codes von jemandem nicht mehr funktionieren, wird es notwendig sein, sie zu reparieren.
Das Traurigste ist, dass die alte Version von

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

keine Fehlermeldungen ausgibt, sondern einfach gar nichts tut. Die Leute werden es einfach nicht ersetzen und nicht wissen, dass sie den Code ändern müssen. Es wird etwas gezählt, aber mit unveränderten Matrizen.

 
Forester #:

Wenn alle Daten in einer Spalte gleich sind, wird die Berechnung offenbar übersprungen.

Pearson rechnet nicht zwischen Zeilen, sondern zwischen Spalten?

Sieht so aus.
const matrix<double> matrix1 = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
Es ergibt eine einzige Matrix.
 
fxsaber #:

Pearson rechnet nicht zwischen Zeilen, sondern zwischen Spalten?

ZY Es scheint so. Es ergibt eine Einheitsmatrix.
Man kann sie transponieren.
 

Alglib ist eine gute Bibliothek, sie hat alles für MO. Neuronale Netze sind super langsam dort, es war so in frühen Versionen.

 
Forester #:
in statistics.mqh.

PearsonCorrM - Die Korrelation aller Zeilen zu allen Zeilen ist am schnellsten.

Auf ihrer Grundlage habe ich die Korrelationsmatrix berechnet.

#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);
}


Habe die Leistung gemessen.

#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)));  
}


Ergebnis.

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 


Es ist gut zu sehen, dass Alglib die Matrix schneller berechnet als die Standard-Matrix-Methode.

Für die Mustersuche ist die Berechnung der Korrelationsmatrix jedoch ein Wahnsinn, was den RAM-Verbrauch angeht.


Wie lange braucht Python, um die gleiche Größe der Originalmatrix wie im obigen Beispiel zu lesen?

 
fxsaber #:

Es ist jedoch ein RAM-verzehrender Wahnsinn, eine Korrelationsmatrix zu lesen, um Muster zu finden.

Meine eingebaute funktionierte auf meinem i7-6700 schneller.

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 

Es ist seltsam, dass der eingebaute Algorithmus langsamer ist, sie könnten ihn einfach kopiert haben. Es ist unwahrscheinlich, dass Alglibe einen einzigartigen beschleunigten Algorithmus unter Lizenz hat.

Haben Sie die anderen 2 Varianten von Alglib ausprobiert?
Wenn Sie in Schleifen jede Zeile zu jeder Zeile oder jede Zeile zu allen Zeilen zählen, wird der Speicher sparsamer (2 Zeilen oder 1 Zeile + Matrix). Aber es wird länger dauern, ich weiß es nicht mehr genau, aber ich glaube, es wird langsamer sein als die eingebaute Funktion.

 
fxsaber #:

Es ist jedoch ein RAM-verzehrender Wahnsinn, eine Korrelationsmatrix zu lesen, um Muster zu finden.

Mit dem Speicher ist es noch schlimmer.
Vor dem Start



Und während der Arbeit von Alglibov PearsonCorrM wächst der Speicher ständig: Ich sah 5 gg und 4,6 auf dem Bildschirm.


und während der Arbeit mit dem Standard Matrix.CorrCoef.

Offensichtlich ist das Standardprogramm auf minimalen Speicherverbrauch optimiert, während das Alglibov-Programm auf Geschwindigkeit optimiert ist.

 
Forester #:

Ich habe den eingebauten schneller zum Laufen gebracht: mit einem i7-6700.

Ich habe dem Code CPU- und EX5-Befehlsdaten hinzugefügt.
 
Forester #:

Und während Alglib's PearsonCorrM läuft, wächst der Speicher weiter: und 5 gg wurde gesehen, 4,6 wurde auf dem Bildschirm angezeigt

Der Verbrauch wird durch diese Zeile fast verdoppelt.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Maschinelles Lernen im Handel: Theorie, Modelle, Praxis und Algo-Trading

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);
}

Das ist nur ein Übergang von CMatrixDouble zu matrix<double>. Ich musste sogar diesen Matrixvergleich wegen des Speichers machen.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Maschinelles Lernen im Handel: Theorie, Modelle, Praxis und Algo-Trading

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);
}
Grund der Beschwerde: