# -*- coding: utf-8 -*-
"""Huynh_Do_Lab3.ipynb

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/1FHA5TbIDs5UJoCuJ39yBOoHOaBWcmTCT
"""

# Import required Python packages
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import sklearn
from sklearn.preprocessing import scale
from sklearn.decomposition import PCA
import seaborn as sns  # Optional for better visuals
from google.colab import files
from sklearn.preprocessing import StandardScaler

# Upload 'b5.csv' file
uploaded = files.upload()

# Load the dataset
df = pd.read_csv("b5.csv")
df.head()

# Step 1: Standardize the dataset
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df)

# Step 2: Calculate covariance matrix
cov_matrix = np.cov(df_scaled.T)

# Step 3: Compute eigenvalues and eigenvectors
eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)

# Step 4: Sort eigenvalues and eigenvectors in descending order
sorted_indices = np.argsort(eigenvalues)[::-1]
eigenvalues_sorted = eigenvalues[sorted_indices]
eigenvectors_sorted = eigenvectors[:, sorted_indices]

# Step 5: Select top k eigenvectors and project the data (2D)
k2 = 2
top_k2_eigenvectors = eigenvectors_sorted[:, :k2]
df_pca_2d = df_scaled.dot(top_k2_eigenvectors)
df_pca_2d = pd.DataFrame(df_pca_2d, columns=[f'PC{i+1}' for i in range(k2)])

# Step 6: Visualize 2D PCA
plt.figure(figsize=(8, 6))
plt.scatter(df_pca_2d['PC1'], df_pca_2d['PC2'], alpha=0.5, s=10)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.title('PCA Projection (2D)')
plt.grid(True)
plt.tight_layout()
plt.show()

# Total sum of all eigenvalues
total_variance = np.sum(eigenvalues_sorted)

# Variance explained by each principal component
variance_explained = eigenvalues_sorted / total_variance

# Print variance explained by PC1, PC2, PC3
for i in range(3):
    print(f"PC{i+1} explains {variance_explained[i]*100:.2f}% of the total variance.")