diff --git a/Dimensionality Reduction/LDA.mqh b/Dimensionality Reduction/LDA.mqh index 1248093..66e1f1d 100644 --- a/Dimensionality Reduction/LDA.mqh +++ b/Dimensionality Reduction/LDA.mqh @@ -73,7 +73,7 @@ matrix CLDA::fit_transform(const matrix &x, const vector &y) this.mean = x.Mean(0); - matrix x_centered = Base::subtract(x, this.mean); + matrix x_centered = BaseDimRed::subtract(x, this.mean); matrix class_means(classes.Size(), x.Cols()); class_means.Fill(0.0); @@ -113,7 +113,7 @@ matrix CLDA::fit_transform(const matrix &x, const vector &y) } - matrix diff = Base::subtract(class_samples, class_means.Row(i)); //Each row subtracted to the mean + matrix diff = BaseDimRed::subtract(class_samples, class_means.Row(i)); //Each row subtracted to the mean if (diff.Rows()==0 && diff.Cols()==0) //if the subtracted matrix is zero stop the program for possible bugs or errors { DebugBreak(); @@ -138,7 +138,7 @@ matrix CLDA::fit_transform(const matrix &x, const vector &y) matrix SBSW = SW.Inv().MatMul(SB); - Base::ReplaceNaN(SBSW); + BaseDimRed::ReplaceNaN(SBSW); if (!SBSW.Eig(eigen_vectors, eigen_values)) { @@ -154,8 +154,8 @@ matrix CLDA::fit_transform(const matrix &x, const vector &y) vector args = MatrixExtend::ArgSort(eigen_values); MatrixExtend::Reverse(args); - eigen_values = Base::Sort(eigen_values, args); - eigen_vectors = Base::Sort(eigen_vectors, args); + eigen_values = BaseDimRed::Sort(eigen_values, args); + eigen_vectors = BaseDimRed::Sort(eigen_vectors, args); //--- @@ -171,7 +171,7 @@ matrix CLDA::fit_transform(const matrix &x, const vector &y) else //plot the scree plot extract_components(eigen_values); - this.projection_matrix = Base::Slice(eigen_vectors, this.m_components); + this.projection_matrix = BaseDimRed::Slice(eigen_vectors, this.m_components); return x_centered.MatMul(projection_matrix.Transpose()); } @@ -186,7 +186,7 @@ matrix CLDA::transform(const matrix &x) matrix empty = {}; return empty; } - matrix x_centered = Base::subtract(x, this.mean); + matrix x_centered = BaseDimRed::subtract(x, this.mean); return x_centered.MatMul(this.projection_matrix.Transpose()); } @@ -269,7 +269,7 @@ uint CLDA::extract_components(vector &eigen_values, double threshold=0.95) vector vars = eigen_values; - plt.ScatterCurvePlots("Scree plot",v_cols,vars,"EigenValue","LDA","EigenValue"); + plt.Plot("Scree plot",v_cols,vars,"EigenValue","Principal Components","EigenValue", CURVE_POINTS_AND_LINES); //--- string warn = "\n<<<< WARNING >>>>\nThe Scree plot doesn't return the determined number of k m_components\nThe cummulative variance Or kaiser will return the number of k m_components instead\nThe k returned might be different from what you see on the scree plot"; diff --git a/Dimensionality Reduction/PCA.mqh b/Dimensionality Reduction/PCA.mqh index ddcc15b..213ddef 100644 --- a/Dimensionality Reduction/PCA.mqh +++ b/Dimensionality Reduction/PCA.mqh @@ -82,15 +82,15 @@ matrix CPCA::fit_transform(matrix &X) this.mean = X.Mean(0); - matrix X_centered = Base::subtract(X, this.mean); - Base::ReplaceNaN(X_centered); + matrix X_centered = BaseDimRed::subtract(X, this.mean); + BaseDimRed::ReplaceNaN(X_centered); matrix cov_matrix = cova(X_centered, false); matrix eigen_vectors; vector eigen_values; - Base::ReplaceNaN(cov_matrix); + BaseDimRed::ReplaceNaN(cov_matrix); if (!cov_matrix.Eig(eigen_vectors, eigen_values)) printf("Failed to caculate Eigen matrix and vectors Err=%d",GetLastError()); @@ -99,8 +99,8 @@ matrix CPCA::fit_transform(matrix &X) vector args = MatrixExtend::ArgSort(eigen_values); MatrixExtend::Reverse(args); - eigen_values = Base::Sort(eigen_values, args); - eigen_vectors = Base::Sort(eigen_vectors, args); + eigen_values = BaseDimRed::Sort(eigen_values, args); + eigen_vectors = BaseDimRed::Sort(eigen_vectors, args); //--- if (MQLInfoInteger(MQL_DEBUG)) @@ -114,7 +114,7 @@ matrix CPCA::fit_transform(matrix &X) if (MQLInfoInteger(MQL_DEBUG)) printf("%s Selected components %d",__FUNCTION__,m_components); - this.components_matrix = Base::Slice(eigen_vectors, m_components, 1); //Get the components matrix + this.components_matrix = BaseDimRed::Slice(eigen_vectors, m_components, 1); //Get the components matrix //MatrixExtend::NormalizeDouble_(this.components_matrix, 5); //this.components_matrix = scaler.fit_transform(this.components_matrix.Transpose()); //Normalize components matrix @@ -138,7 +138,7 @@ matrix CPCA::transform(matrix &X) this.m_components = n_features; } - matrix X_centered = Base::subtract(X, this.mean); + matrix X_centered = BaseDimRed::subtract(X, this.mean); return X_centered.MatMul(this.components_matrix.Transpose()); //return the pca scores } @@ -205,7 +205,7 @@ uint CPCA::extract_components(vector &eigen_values, double threshold=0.95) //matrix_utils.Sort(vars); //Make sure they are in ascending first order //matrix_utils.Reverse(vars); //Set them to descending order - plt.ScatterCurvePlots("Scree plot",v_cols,vars,"EigenValue","PCA","EigenValue"); + plt.Plot("Scree plot",v_cols,vars,"EigenValue","Principal Components","EigenValue",CURVE_POINTS_AND_LINES); //--- string warn = "\n<<<< WARNING >>>>\nThe Scree plot doesn't return the determined number of k components\nThe cummulative variance will return the number of k components instead\nThe k returned might be different from what you see on the scree plot"; @@ -286,7 +286,7 @@ matrix cova(matrix &data, bool row_var=true) data = data.Transpose(); // Transpose if each row represents a data point // Step 1: Center the data - matrix centered_data = Base::subtract(data, data.Mean(0)); + matrix centered_data = BaseDimRed::subtract(data, data.Mean(0)); // Step 2: Calculate the covariance matrix matrix covariance_matrix = centered_data.Transpose().MatMul(centered_data) / (data.Rows() - 1); diff --git a/Dimensionality Reduction/TruncatedSVD.mqh b/Dimensionality Reduction/TruncatedSVD.mqh index 57d4756..79c16ba 100644 --- a/Dimensionality Reduction/TruncatedSVD.mqh +++ b/Dimensionality Reduction/TruncatedSVD.mqh @@ -63,11 +63,11 @@ matrix CTruncatedSVD::fit_transform(matrix &X) //--- Center the data (subtract mean) this.mean = X.Mean(0); - matrix X_centered = Base::subtract(X, this.mean); + matrix X_centered = BaseDimRed::subtract(X, this.mean); //--- Compute the covariance matrix - Base::ReplaceNaN(X_centered); + BaseDimRed::ReplaceNaN(X_centered); matrix cov_matrix = X_centered.Cov(false); //--- Perform SVD on the covariance matrix @@ -75,7 +75,7 @@ matrix CTruncatedSVD::fit_transform(matrix &X) matrix U={}, Vt={}; vector Sigma={}; - Base::ReplaceNaN(cov_matrix); + BaseDimRed::ReplaceNaN(cov_matrix); if (!cov_matrix.SVD(U,Vt,Sigma)) Print(__FUNCTION__," Line ",__LINE__," Failed to calculate SVD Err=",GetLastError()); @@ -86,13 +86,13 @@ matrix CTruncatedSVD::fit_transform(matrix &X) Print(__FUNCTION__," Best value of K = ",m_components); } - this.components_ = Base::Slice(Vt, this.m_components).Transpose(); - Base::ReplaceNaN(this.components_); + this.components_ = BaseDimRed::Slice(Vt, this.m_components).Transpose(); + BaseDimRed::ReplaceNaN(this.components_); if (MQLInfoInteger(MQL_DEBUG)) Print("components_T[",components_.Rows(),"X",components_.Cols(),"]\n",this.components_); - this.explained_variance_ = MathPow(Base::Slice(Sigma, this.m_components), 2) / (X.Rows() - 1); + this.explained_variance_ = MathPow(BaseDimRed::Slice(Sigma, this.m_components), 2) / (X.Rows() - 1); return X_centered.MatMul(components_); } @@ -101,7 +101,7 @@ matrix CTruncatedSVD::fit_transform(matrix &X) //+------------------------------------------------------------------+ matrix CTruncatedSVD::transform(matrix &X) { - matrix X_centered = Base::subtract(X, this.mean); + matrix X_centered = BaseDimRed::subtract(X, this.mean); if (X.Cols()!=this.n_features) { @@ -138,7 +138,7 @@ ulong CTruncatedSVD::_select_n_components(vector &singular_values) for (uint i=0; i + +class BaseDimRed { public: - Base(void); - ~Base(void); + BaseDimRed(void); + ~BaseDimRed(void); static matrix Slice(const matrix &mat, uint from_0_to, int axis=0); static vector Slice(const vector &v, uint from_0_to); @@ -25,10 +28,16 @@ public: //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ -matrix Base::Slice(const matrix &mat, uint from_0_to, int axis=0) +matrix BaseDimRed::Slice(const matrix &mat, uint from_0_to, int axis=0) { matrix ret = {}; + if (from_0_to==0) + { + printf("%s Cannot slice a vector from index 0 to 0",__FUNCTION__); + return mat; + } + switch(axis) { case 0: @@ -55,10 +64,16 @@ matrix Base::Slice(const matrix &mat, uint from_0_to, int axis=0) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ -vector Base::Slice(const vector &v, uint from_0_to) +vector BaseDimRed::Slice(const vector &v, uint from_0_to) { vector ret(from_0_to); + if (from_0_to==0) + { + printf("%s Cannot slice a vector from index 0 to 0",__FUNCTION__); + return v; + } + for (uint i=0; i