L'apprentissage automatique dans la négociation : théorie, modèles, pratique et algo-trading - page 3257

 
Forester #:
dans statistics.mqh.

functions
PearsonCorrM - La corrélation de toutes les lignes avec toutes les lignes est la plus rapide.

Il y a une erreur quelque part, mais je ne la vois pas.
#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 #:
Je me trompe quelque part, mais je ne le vois pas.

Mais cela fonctionne avec cette chaîne

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

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

Apparemment, si toutes les données d'une colonne sont identiques, le calcul est ignoré.
Dans la deuxième colonne, j'ai laissé toutes les données à 2 et la deuxième ligne de la matrice est restée à zéro. Bien qu'il soit probablement correct de remplir la diagonale avec des 1.

PS. J'ai d'abord pensé qu'il s'agissait d'un bogue avec Alglib.

Dans l'ancien code, les valeurs des éléments étaient fixées par
m[row].Set(col, val) ;
Et maintenant
m.Set(row,col, val) ;

Il est dommage qu'il n'y ait pas de compatibilité ascendante. Cela n'a pas d'importance pour moi. Je ne travaille pas avec Alglib en ce moment. Si les anciens codes de quelqu'un cessent de fonctionner, il sera nécessaire de les corriger.
Le plus triste est que l'ancienne version de

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

n'écrit pas de message d'erreur, elle ne fait tout simplement rien. Les gens ne remplaceront pas et ne sauront pas qu'ils doivent changer le code. Il comptera quelque chose, mais avec des matrices inchangées.

 
Forester #:

Apparemment, si toutes les données d'une colonne sont identiques, le calcul est ignoré.

Pearson ne calcule pas entre les lignes, mais entre les colonnes ?

On dirait bien.
const matrix<double> matrix1 = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
Il donne une seule matrice.
 
fxsaber #:

Pearson ne calcule pas entre les lignes, mais entre les colonnes ?

ZY Il semble que oui. Il produit une matrice unitaire.
On peut la transposer.
 

Alglib est une bonne bibliothèque, elle a tout ce qu'il faut pour la MO. Les réseaux neuronaux y sont très lents, c'était le cas dans les premières versions.

 
Forester #:
dans statistics.mqh.

PearsonCorrM - La corrélation de toutes les lignes avec toutes les lignes est la plus rapide.

Sur cette base, j'ai calculé la matrice de corrélation.

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


J'ai mesuré la performance.

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


Résultat.

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 


Il est évident qu'Alglib calcule la matrice plus rapidement que la méthode matricielle standard.

Cependant, pour la recherche de motifs, le calcul de la matrice de corrélation est insensé en termes de consommation de RAM.


Combien de temps faut-il à Python pour lire la même taille de la matrice originale que dans l'exemple ci-dessus ?

 
fxsaber #:

Cependant, la lecture d'une matrice de corrélation pour trouver des modèles est une folie qui consomme de la mémoire vive.

Ma matrice intégrée a fonctionné plus rapidement sur mon 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 

C'est étrange que l'algorithme natif soit plus lent, ils auraient pu simplement le copier. Il est peu probable qu'Alglibe dispose d'un algorithme accéléré unique sous licence.

Avez-vous essayé les 2 autres variantes d'Alglib ?
Si vous comptez en boucle chaque ligne vers chaque ligne ou chaque ligne vers toutes les lignes, la mémoire sera plus économique (2 lignes ou 1 ligne + matrice). Mais cela prendra plus de temps, je ne me souviens pas exactement, mais je pense que ce sera plus lent que la fonction intégrée.

 
fxsaber #:

Cependant, la lecture d'une matrice de corrélation pour trouver des modèles est une folie qui consomme de la mémoire vive.

C'est pire avec la mémoire.
Avant le lancement



Et pendant le travail d'Alglibov PearsonCorrM la mémoire augmente sans cesse : j'ai vu 5 gg et 4.6 à l'écran.


et pendant le travail de Matrix.CorrCoef standard.

Apparemment, le programme standard est optimisé pour une utilisation minimale de la mémoire, et le programme Alglibov est optimisé pour la vitesse.

 
Forester #:

J'ai réussi à faire fonctionner la version intégrée plus rapidement : sur un i7-6700.

J'ai ajouté les données des instructions CPU et EX5 au code.
 
Forester #:

Et pendant l'exécution de PearsonCorrM d'Alglib, la mémoire continue de croître : et 5 gg ont été vus, 4,6 ont été affichés à l'écran.

La consommation due à cette ligne a presque doublé.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

L'apprentissage automatique dans le trading : théorie, modèles, pratique et 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);
}

C'est juste une transition de CMatrixDouble à matrix<double>. J'ai même dû faire cette comparaison de matrices à cause de la mémoire.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

L'apprentissage automatique dans le trading : théorie, modèles, pratique et 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);
}
Raison: