交易中的机器学习:理论、模型、实践和算法交易 - 页 3257

 
Forester #:
在 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,因此矩阵的第 2 行仍然为零。尽管用 1 填满对角线可能是正确的。

PS.起初我以为是 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 #:

Pearson 不在行间计算,而是在列间计算?

ZY 似乎是这样。它会产生一个单位矩阵。
你可以对它进行转置。
 

Alglib 是一个很好的库,它拥有 MO 的所有功能。神经网络的运行速度超慢,早期版本就是如此。

 
Forester #:
in statistics.mqh.PearsonCorrM。

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 #:

然而,读取相关矩阵来寻找模式非常消耗内存。

我的内置矩阵在 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 的其他两个变体吗?
如果你在循环中计算每一行到每一行或每一行到所有行,内存会更节省(2 行或 1 行 + 矩阵)。但需要的时间会更长,我不太记得了,但我认为会比内置函数慢。

 
fxsaber #:

然而,读取相关矩阵来寻找模式非常消耗内存。


启动前



在使用 Alglibov PearsonCorrM 时,内存一直在增长:我在屏幕上看到了 5 gg 和 4.6。


以及在运行标准 Matrix.CorrCoef 时。

显然,标准的 Matrix.CorrCoef 是为了最小化内存使用量而优化的,而 Alglibov 的 Matrix.CorrCoef 则是为了提高速度而优化的。

 
Forester #:

我使用 i7-6700 时,内置电池的运行速度更快。

我在代码中添加了 CPU 和 EX5 指令数据。
 
Forester #:

在运行 Alglib 的 PearsonCorrM 时,内存不断增加:看到 5 gg,屏幕上出现了 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);
}

这只是从CMatrixDoublematrix<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);
}