diff --git a/Phase 2/dim_reduction_methods.py b/Phase 2/dim_reduction_methods.py new file mode 100644 index 0000000..67d8b0c --- /dev/null +++ b/Phase 2/dim_reduction_methods.py @@ -0,0 +1,51 @@ +import numpy as np + +def svd(matrix, k): + # Step 1: Compute the covariance matrix + cov_matrix = np.dot(matrix.T, matrix) + + # Step 2: Compute the eigenvalues and eigenvectors of the covariance matrix + eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) + + # Step 3: Sort the eigenvalues and corresponding eigenvectors + sort_indices = eigenvalues.argsort()[::-1] + eigenvalues = eigenvalues[sort_indices] + eigenvectors = eigenvectors[:, sort_indices] + + # Step 4: Compute the singular values and the left and right singular vectors + singular_values = np.sqrt(eigenvalues) + left_singular_vectors = np.dot(matrix, eigenvectors) + right_singular_vectors = eigenvectors + + # Step 5: Normalize the singular vectors + for i in range(left_singular_vectors.shape[1]): + left_singular_vectors[:, i] /= singular_values[i] + + for i in range(right_singular_vectors.shape[1]): + right_singular_vectors[:, i] /= singular_values[i] + + # Keep only the top k singular values and their corresponding vectors + singular_values = singular_values[:k] + left_singular_vectors = left_singular_vectors[:, :k] + right_singular_vectors = right_singular_vectors[:, :k] + + return left_singular_vectors, np.diag(singular_values), right_singular_vectors.T + +def nmf(matrix, k, num_iterations = 100): + d1, d2 = matrix.shape + # Initialize W and H matrices with random non-negative values + W = np.random.rand(d1, k) + H = np.random.rand(k, d2) + + for iteration in range(num_iterations): + # Update H matrix + numerator_h = np.dot(W.T, matrix) + denominator_h = np.dot(np.dot(W.T, W), H) + H *= numerator_h / denominator_h + + # Update W matrix + numerator_w = np.dot(matrix, H.T) + denominator_w = np.dot(W, np.dot(H, H.T)) + W *= numerator_w / denominator_w + + return W, H \ No newline at end of file