Aprendizado de máquina no trading: teoria, prática, negociação e não só - página 3257

 
Forester #:
em statistics.mqh.

functions
PearsonCorrM - A correlação de todas as linhas com todas as linhas é a mais rápida.

Está errado em algum lugar, mas não estou vendo isso.
#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 #:
Estou errado em algum lugar, mas não estou vendo isso.

Mas ele funciona com esta string

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

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

Aparentemente, se todos os dados em uma coluna forem os mesmos, o cálculo será ignorado.
Na segunda coluna, deixei todos os dados em 2 e a segunda linha da matriz permaneceu zero. Embora provavelmente seja correto preencher a diagonal com 1s.

PS. No início, pensei que fosse um bug do Alglib.

No código antigo, os valores dos elementos eram definidos por meio de
m[row].Set(col, val);
E agora
m.Set(row,col, val);

É uma pena que não haja compatibilidade com versões anteriores. Bem, isso não importa para mim. Não estou trabalhando com o Alglib agora. Se os códigos antigos de alguém pararem de funcionar, será necessário corrigi-los.
O mais triste é que a versão antiga de

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

não escreve mensagens de erro, ela simplesmente não faz nada. As pessoas simplesmente não substituirão e não saberão que precisam alterar o código. Ele contará alguma coisa, mas com matrizes inalteradas.

 
Forester #:

Aparentemente, se todos os dados em uma coluna forem iguais, o cálculo será ignorado.

A Pearson não calcula entre linhas, mas entre colunas?

Parece que sim.
const matrix<double> matrix1 = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
Ele fornece uma única matriz.
 
fxsaber #:

A Pearson não calcula entre linhas, mas entre colunas?

ZY Parece que sim. Ele produz uma matriz unitária.
Você pode transpô-la.
 

A Alglib é uma boa biblioteca, ela tem tudo para MO. As redes neurais são muito lentas lá, era assim nas primeiras versões.

 
Forester #:
em statistics.mqh.

PearsonCorrM - A correlação de todas as linhas com todas as linhas é a mais rápida.

Com base nisso, calculei a matriz de correlação.

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


Medi o desempenho.

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


Resultado.

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 


É possível ver que o Alglib calcula a matriz mais rapidamente do que o método de matriz padrão.

Entretanto, para a pesquisa de padrões, o cálculo da matriz de correlação é insano em termos de consumo de RAM.


Quanto tempo o Python leva para ler o mesmo tamanho da matriz original, como no exemplo acima?

 
fxsaber #:

No entanto, é uma loucura que consome muita memória RAM ler uma matriz de correlação para encontrar padrões.

Minha matriz nativa funcionou mais rápido no meu 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 

É estranho que o nativo seja mais lento, eles podem ter apenas copiado. É improvável que o Alglibe tenha algum algoritmo acelerado exclusivo sob licença.

Você já tentou as outras duas variantes do Alglib?
Se você contar em loops cada linha para cada linha ou cada linha para todas as linhas, a memória será mais econômica (2 linhas ou 1 linha + matriz). Mas isso levará mais tempo, não me lembro exatamente, mas acho que será mais lento do que a função integrada.

 
fxsaber #:

No entanto, é uma loucura que consome muita memória RAM ler uma matriz de correlação para encontrar padrões.

A situação é pior com relação à memória.
Antes de iniciar



E durante o trabalho do Alglibov PearsonCorrM, a memória está aumentando o tempo todo: vi 5 gg e 4,6 na tela.


e durante o trabalho do Matrix.CorrCoef padrão.

Aparentemente, o padrão é otimizado para uso mínimo de memória, e o Alglibov é otimizado para velocidade.

 
Forester #:

Consegui que o integrado funcionasse mais rápido: em um i7-6700.

Adicionei dados de instruções da CPU e do EX5 ao código.
 
Forester #:

E ao executar o PearsonCorrM do Alglib, a memória continua crescendo: e 5 gg foram vistos, 4,6 apareceram na tela

Quase dobra a quantidade de consumo devido a essa linha.

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Aprendizado de máquina na negociação: teoria, modelos, prática e 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);
}

Essa é apenas uma transição de CMatrixDouble para matrix<double>. Tive até que fazer essa comparação de matrizes por causa da memória.

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Aprendizado de máquina na negociação: teoria, modelos, prática e 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);
}
Razão: