Skip to content

Commit

Permalink
ScatterCurvePlots -> Plot patches
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaJoctan committed Mar 3, 2024
1 parent 336abf1 commit bb0ddb3
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 37 deletions.
16 changes: 8 additions & 8 deletions Dimensionality Reduction/LDA.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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))
{
Expand All @@ -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);

//---

Expand All @@ -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());
}
Expand All @@ -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());
}
Expand Down Expand Up @@ -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";
Expand Down
18 changes: 9 additions & 9 deletions Dimensionality Reduction/PCA.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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))
Expand All @@ -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

Expand All @@ -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
}
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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);
Expand Down
16 changes: 8 additions & 8 deletions Dimensionality Reduction/TruncatedSVD.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,19 @@ 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

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());
Expand All @@ -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_);
}
Expand All @@ -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)
{
Expand Down Expand Up @@ -138,7 +138,7 @@ ulong CTruncatedSVD::_select_n_components(vector &singular_values)
for (uint i=0; i<k.Size(); i++)
k[i] = i+1;

plt.ScatterCurvePlots("Explained variance plot",k,explained_variance_ratio,"variance","components","Variance");
plt.Plot("Explained variance plot",k,explained_variance_ratio,"variance","components","Variance");

return explained_variance_ratio.ArgMax() + 1; //Choose k for maximum explained variance
}
Expand Down
53 changes: 41 additions & 12 deletions Dimensionality Reduction/base.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
#property copyright "Copyright 2023, Omega Joctan"
#property link "https://www.mql5.com/en/users/omegajoctan"
//+------------------------------------------------------------------+
//| Base class for dimension reduction, containing most useful |
//| BaseDimRed class for dimension reduction, containing most useful |
//| that are necessary for the algorithms in this folder |
//+------------------------------------------------------------------+
class Base

#include <MALE5\MatrixExtend.mqh>

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);
Expand All @@ -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:
Expand All @@ -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<ret.Size(); i++)
ret[i] = v[i];

Expand All @@ -67,19 +82,33 @@ vector Base::Slice(const vector &v, uint from_0_to)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
matrix Base::subtract(const matrix&mat, const vector &v)
matrix BaseDimRed::subtract(const matrix&mat, const vector &v)
{
matrix ret = mat;

for (ulong i=0; i<mat.Rows(); i++)
ret.Row(mat.Row(i)-v, i);
if (mat.Rows()!=v.Size() && mat.Cols()!=v.Size())
{
printf("%s Dimensions Mismatch",__FUNCTION__);
matrix empty = {};
return empty;
}

bool isrows = v.Size()==mat.Rows() ? true : false;

for (ulong i=0; i<(isrows?mat.Cols():mat.Rows()); i++)
{
if (isrows)
ret.Col(mat.Col(i)-v, i);
else
ret.Row(mat.Row(i)-v, i);
}

return ret;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Base::ReplaceNaN(matrix &mat)
void BaseDimRed::ReplaceNaN(matrix &mat)
{
for (ulong i = 0; i < mat.Rows(); i++)
for (ulong j = 0; j < mat.Cols(); j++)
Expand All @@ -89,7 +118,7 @@ void Base::ReplaceNaN(matrix &mat)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
matrix Base::Sort(matrix &mat, vector &args)
matrix BaseDimRed::Sort(matrix &mat, vector &args)
{
matrix m = mat;

Expand All @@ -107,7 +136,7 @@ matrix Base::Sort(matrix &mat, vector &args)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
vector Base::Sort(vector &v, vector &args)
vector BaseDimRed::Sort(vector &v, vector &args)
{
vector vec = v;

Expand Down

0 comments on commit bb0ddb3

Please sign in to comment.