From 21d7548998e1ac44f81160c967180342c51d8894 Mon Sep 17 00:00:00 2001 From: kausthub-kannan Date: Tue, 3 Oct 2023 21:20:04 +0530 Subject: [PATCH 1/6] Added Principal Component Analysis --- .../principal_component_analysis.py | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 machine_learning/principal_component_analysis.py diff --git a/machine_learning/principal_component_analysis.py b/machine_learning/principal_component_analysis.py new file mode 100644 index 000000000000..38d431f167eb --- /dev/null +++ b/machine_learning/principal_component_analysis.py @@ -0,0 +1,89 @@ +""" + Principal Component Analysis (PCA) is an unsupervised learning + algorithm that is used for the dimensionality reduction in machine + learning. It is a statistical procedure that uses an orthogonal + transformation to convert a set of observations of possibly correlated + variables into a set of values of linearly uncorrelated variables called + principal components. + + Data: The data used for PCA is a set of 500 data points, each with 4 + features. The data is assumed to be in normal form. + + Reference: https://en.wikipedia.org/wiki/Principal_component_analysis + +""" +import numpy as np + + +class PCA: + def __init__(self, n_components: int) -> None: + """ + Create a PCA object with the given number of components + """ + self.n = n_components + self.mean = None + self.components = None + + def fit(self, x: np.ndarray[float]) -> np.ndarray[float]: + """ + Fit the PCA model to the given data and find the principal components + The process of performing PCA involves the following steps: + 1. Normalize the data by subtracting the mean from each data point + 2. Calculate the covariance matrix of the normalized data + 3. Calculate the eigenvalues and eigenvectors of the covariance matrix + 4. Sort the eigenvalues and eigenvectors in descending order of the eigenvalues + 5. Choose the first n eigenvectors, where n is the number of components + """ + self.mean = np.mean(x, axis=0) + x = x - self.mean + + cov = np.cov(x.T) + + eigen_vector, eigen_value = np.linalg.eig(cov) + eigen_vector = eigen_vector.T + + indexes = np.argsort(eigen_value)[::-1] + eigen_vector = eigen_vector[indexes] + + self.components = eigen_vector[: self.n] + return self.components + + def transform(self, x: np.ndarray[float]) -> np.ndarray[float]: + """ + Transform the given data using the fitted PCA model + + >>> test_data = np.array([ + ... [1.2, 2.3, 3.4], [4.5, 5.6, 6.7], [7.8, 8.9, 9.0], [10.1, 11.2, 12.3] + ... ]) + >>> test_pca = PCA(2) + >>> test_pca.fit(test_data) + array([[4.41304280e+01, 2.58645300e-15, 1.52905333e-01], + [4.41304280e+01, 1.52905333e-01, 2.58645300e-15]]) + >>> test_pca.transform(test_data) + array([[-208.09344033, -208.13166667], + [ -61.95844033, -61.99666667], + [ 84.02365433, 84.13833333], + [ 186.02822633, 185.99 ]]) + """ + x = x - self.mean + return np.dot(x, np.transpose(self.components)) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + + X1 = np.random.normal(0, 1, 500) + X2 = np.random.normal(0, 1, 500) + X3 = np.random.normal(0, 1, 500) + X4 = np.random.normal(0, 1, 500) + + data = np.column_stack((X1, X2, X3, X4)) + + pca = PCA(2) + principal_components = pca.fit(data) + post_pca_data = pca.transform(data) + + print("Shape of X (Data Points) is: ", data.shape) + print("Shape of X after PCA is: ", post_pca_data.shape) From 2c8cc8e5a402ed06cb0f71d7ff561c87918ad846 Mon Sep 17 00:00:00 2001 From: kausthub-kannan Date: Tue, 3 Oct 2023 21:26:59 +0530 Subject: [PATCH 2/6] Added doctest for PCA/fit function --- machine_learning/principal_component_analysis.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/machine_learning/principal_component_analysis.py b/machine_learning/principal_component_analysis.py index 38d431f167eb..096219b20948 100644 --- a/machine_learning/principal_component_analysis.py +++ b/machine_learning/principal_component_analysis.py @@ -33,6 +33,13 @@ def fit(self, x: np.ndarray[float]) -> np.ndarray[float]: 3. Calculate the eigenvalues and eigenvectors of the covariance matrix 4. Sort the eigenvalues and eigenvectors in descending order of the eigenvalues 5. Choose the first n eigenvectors, where n is the number of components + >>> test_data = np.array([ + ... [1.2, 2.3, 3.4], [4.5, 5.6, 6.7], [7.8, 8.9, 9.0], [10.1, 11.2, 12.3] + ... ]) + >>> test_pca = PCA(2) + >>> test_pca.fit(test_data) + array([[4.41304280e+01, 2.58645300e-15, 1.52905333e-01], + [4.41304280e+01, 1.52905333e-01, 2.58645300e-15]]) """ self.mean = np.mean(x, axis=0) x = x - self.mean From 4ab89fee58d05bd5be363029f3cd79ca3d6ee8ee Mon Sep 17 00:00:00 2001 From: kausthub-kannan Date: Tue, 3 Oct 2023 21:31:27 +0530 Subject: [PATCH 3/6] Parameters description added --- .../principal_component_analysis.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/machine_learning/principal_component_analysis.py b/machine_learning/principal_component_analysis.py index 096219b20948..f3f762c6873f 100644 --- a/machine_learning/principal_component_analysis.py +++ b/machine_learning/principal_component_analysis.py @@ -18,14 +18,20 @@ class PCA: def __init__(self, n_components: int) -> None: """ + Parameters: + n_components: The number of components required after dimensionality reduction + Create a PCA object with the given number of components """ self.n = n_components self.mean = None self.components = None - def fit(self, x: np.ndarray[float]) -> np.ndarray[float]: + def fit(self, vector: np.ndarray[float]) -> np.ndarray[float]: """ + Parameters: + vector: The data to be fitted + Fit the PCA model to the given data and find the principal components The process of performing PCA involves the following steps: 1. Normalize the data by subtracting the mean from each data point @@ -41,10 +47,10 @@ def fit(self, x: np.ndarray[float]) -> np.ndarray[float]: array([[4.41304280e+01, 2.58645300e-15, 1.52905333e-01], [4.41304280e+01, 1.52905333e-01, 2.58645300e-15]]) """ - self.mean = np.mean(x, axis=0) - x = x - self.mean + self.mean = np.mean(vector, axis=0) + vector = vector - self.mean - cov = np.cov(x.T) + cov = np.cov(vector.T) eigen_vector, eigen_value = np.linalg.eig(cov) eigen_vector = eigen_vector.T @@ -55,8 +61,11 @@ def fit(self, x: np.ndarray[float]) -> np.ndarray[float]: self.components = eigen_vector[: self.n] return self.components - def transform(self, x: np.ndarray[float]) -> np.ndarray[float]: + def transform(self, vector: np.ndarray[float]) -> np.ndarray[float]: """ + Parameters: + vector: The data to be transformed + Transform the given data using the fitted PCA model >>> test_data = np.array([ @@ -72,8 +81,8 @@ def transform(self, x: np.ndarray[float]) -> np.ndarray[float]: [ 84.02365433, 84.13833333], [ 186.02822633, 185.99 ]]) """ - x = x - self.mean - return np.dot(x, np.transpose(self.components)) + vector = vector - self.mean + return np.dot(vector, np.transpose(self.components)) if __name__ == "__main__": From b850de9e0332f023ac91fea4322c366cf3fd1c33 Mon Sep 17 00:00:00 2001 From: kausthub-kannan Date: Tue, 3 Oct 2023 21:43:29 +0530 Subject: [PATCH 4/6] doctest fixed for fit function --- machine_learning/principal_component_analysis.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/machine_learning/principal_component_analysis.py b/machine_learning/principal_component_analysis.py index f3f762c6873f..73ee8f21bd26 100644 --- a/machine_learning/principal_component_analysis.py +++ b/machine_learning/principal_component_analysis.py @@ -27,25 +27,18 @@ def __init__(self, n_components: int) -> None: self.mean = None self.components = None - def fit(self, vector: np.ndarray[float]) -> np.ndarray[float]: + def fit(self, vector: np.ndarray[float]) -> None: """ Parameters: vector: The data to be fitted - Fit the PCA model to the given data and find the principal components + Fit the PCA model to the given data The process of performing PCA involves the following steps: 1. Normalize the data by subtracting the mean from each data point 2. Calculate the covariance matrix of the normalized data 3. Calculate the eigenvalues and eigenvectors of the covariance matrix 4. Sort the eigenvalues and eigenvectors in descending order of the eigenvalues 5. Choose the first n eigenvectors, where n is the number of components - >>> test_data = np.array([ - ... [1.2, 2.3, 3.4], [4.5, 5.6, 6.7], [7.8, 8.9, 9.0], [10.1, 11.2, 12.3] - ... ]) - >>> test_pca = PCA(2) - >>> test_pca.fit(test_data) - array([[4.41304280e+01, 2.58645300e-15, 1.52905333e-01], - [4.41304280e+01, 1.52905333e-01, 2.58645300e-15]]) """ self.mean = np.mean(vector, axis=0) vector = vector - self.mean @@ -59,7 +52,6 @@ def fit(self, vector: np.ndarray[float]) -> np.ndarray[float]: eigen_vector = eigen_vector[indexes] self.components = eigen_vector[: self.n] - return self.components def transform(self, vector: np.ndarray[float]) -> np.ndarray[float]: """ @@ -73,8 +65,6 @@ def transform(self, vector: np.ndarray[float]) -> np.ndarray[float]: ... ]) >>> test_pca = PCA(2) >>> test_pca.fit(test_data) - array([[4.41304280e+01, 2.58645300e-15, 1.52905333e-01], - [4.41304280e+01, 1.52905333e-01, 2.58645300e-15]]) >>> test_pca.transform(test_data) array([[-208.09344033, -208.13166667], [ -61.95844033, -61.99666667], @@ -98,7 +88,7 @@ def transform(self, vector: np.ndarray[float]) -> np.ndarray[float]: data = np.column_stack((X1, X2, X3, X4)) pca = PCA(2) - principal_components = pca.fit(data) + pca.fit(data) post_pca_data = pca.transform(data) print("Shape of X (Data Points) is: ", data.shape) From 739f389940bab8c51fa967bdba4ea16381b214d8 Mon Sep 17 00:00:00 2001 From: kausthub-kannan Date: Tue, 3 Oct 2023 21:45:00 +0530 Subject: [PATCH 5/6] doctest fixed for fit function --- machine_learning/principal_component_analysis.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/machine_learning/principal_component_analysis.py b/machine_learning/principal_component_analysis.py index 73ee8f21bd26..2a50a47b771d 100644 --- a/machine_learning/principal_component_analysis.py +++ b/machine_learning/principal_component_analysis.py @@ -39,6 +39,12 @@ def fit(self, vector: np.ndarray[float]) -> None: 3. Calculate the eigenvalues and eigenvectors of the covariance matrix 4. Sort the eigenvalues and eigenvectors in descending order of the eigenvalues 5. Choose the first n eigenvectors, where n is the number of components + + >>> test_data = np.array([ + ... [1.2, 2.3, 3.4], [4.5, 5.6, 6.7], [7.8, 8.9, 9.0], [10.1, 11.2, 12.3] + ... ]) + >>> test_pca = PCA(2) + >>> test_pca.fit(test_data) """ self.mean = np.mean(vector, axis=0) vector = vector - self.mean From 2d9401fda357f921cf1ae6234d4e16a5ab1ba4e0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:58:23 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../principal_component_analysis.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/machine_learning/principal_component_analysis.py b/machine_learning/principal_component_analysis.py index 2a50a47b771d..53b9b76f2122 100644 --- a/machine_learning/principal_component_analysis.py +++ b/machine_learning/principal_component_analysis.py @@ -1,17 +1,18 @@ """ - Principal Component Analysis (PCA) is an unsupervised learning - algorithm that is used for the dimensionality reduction in machine - learning. It is a statistical procedure that uses an orthogonal - transformation to convert a set of observations of possibly correlated - variables into a set of values of linearly uncorrelated variables called - principal components. +Principal Component Analysis (PCA) is an unsupervised learning +algorithm that is used for the dimensionality reduction in machine +learning. It is a statistical procedure that uses an orthogonal +transformation to convert a set of observations of possibly correlated +variables into a set of values of linearly uncorrelated variables called +principal components. - Data: The data used for PCA is a set of 500 data points, each with 4 - features. The data is assumed to be in normal form. +Data: The data used for PCA is a set of 500 data points, each with 4 +features. The data is assumed to be in normal form. - Reference: https://en.wikipedia.org/wiki/Principal_component_analysis +Reference: https://en.wikipedia.org/wiki/Principal_component_analysis """ + import numpy as np