트레이딩의 머신러닝: 이론, 모델, 실전 및 알고리즘 트레이딩 - 페이지 3257

 
Forester #:
통계.mqh에서

함수
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에 남겨두고 행렬의 두 번째 행은 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}};
단일 행렬을 제공합니다.
 
fxsaber #:

피어슨은 행 사이가 아니라 열 사이를 계산하나요?

ZY 그런 것 같습니다. 단위 행렬을 생성합니다.
전치할 수 있습니다.
 

Alglib은 좋은 라이브러리로, MO를 위한 모든 것을 갖추고 있습니다. 신경망은 초기 버전에서 매우 느렸습니다.

 
Forester #:
통계.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 


알글립이 표준 행렬 방식보다 행렬을 더 빠르게 계산하는 것을 알 수 있습니다.

그러나 패턴 검색의 경우 상관 관계 행렬을 계산하는 것은 RAM 소비 측면에서 미친 짓입니다.


위의 예에서와 같은 크기의 원본 행렬을 읽는 데 파이썬이 얼마나 걸리나요?

 
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 

네이티브가 느리다는 것이 이상합니다. 그냥 복사했을 수도 있습니다. Alglib에 라이선스에 따라 고유 한 가속 알고리즘이있을 가능성은 거의 없습니다.

Alglib의 다른 두 가지 변형을 사용해 보셨나요?
모든 행에서 모든 행 또는 모든 행에서 모든 행으로 루프로 계산하면 메모리가 더 경제적입니다 (2 행 또는 1 행 + 매트릭스). 그러나 시간이 더 오래 걸릴 것이고 정확히 기억 나지 않지만 내장 함수보다 느릴 것이라고 생각합니다.

 
fxsaber #:

그러나 패턴을 찾기 위해 상관관계 행렬을 읽는 것은 RAM을 많이 소모하는 작업입니다.

메모리는 더 나쁩니다.
시작하기 전에



그리고 Alglibov PearsonCorrM 메모리가 항상 성장하고 있습니다 : 나는 화면에서 5g과 4.6을 보았습니다.


그리고 표준 매트릭스 작업 중에.

분명히 표준은 최소 메모리 사용량에 최적화되어 있고 Alglibov는 속도에 최적화되어 있습니다.

 
Forester #:

i7-6700에서 더 빠르게 작업할 수 있도록 내장된 것을 사용했습니다.

코드에 CPU 및 EX5 명령어 데이터를 추가했습니다.
 
Forester #:

그리고 Alglib의 PearsonCorrM을 실행하는 동안 메모리가 계속 증가하고 5기가가 보였고 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);
}