# -*- coding: utf-8 -*-
"""P1-2-PCA Iris.ipynb

Automatically generated by Colab.

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

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()

def PCA(X , num_components):

    #Step-1
    # X_meaned = X - np.mean(X , axis = 0)
    X_meaned = sc.fit_transform(X)

    #Step-2
    cov_mat = np.cov(X_meaned , rowvar = False)

    #Step-3
    eigen_values , eigen_vectors = np.linalg.eigh(cov_mat)

    #Step-4
    sorted_index = np.argsort(eigen_values)[::-1]
    sorted_eigenvalue = eigen_values[sorted_index]
    sorted_eigenvectors = eigen_vectors[:,sorted_index]

    #Step-5
    eigenvector_subset = sorted_eigenvectors[:,0:num_components]

    #Step-6
    X_reduced = np.dot(eigenvector_subset.transpose() , X_meaned.transpose() ).transpose()

    return X_reduced

data = pd.read_csv("/content/iris.csv")
data.head()

#prepare the data
x = data.iloc[:,0:4]

#prepare the target
target = data.iloc[:,4]

x.head()

target.head()

#Applying it to PCA function
mat_reduced = PCA(x , 2)

#Creating a Pandas DataFrame of reduced Dataset
principal_df = pd.DataFrame(mat_reduced , columns = ['PC1','PC2'])

#Display the Principal Coponents
principal_df.head()

#Concat it with target variable to create a complete Dataset
principal_df = pd.concat([principal_df , pd.DataFrame(target)] , axis = 1)

principal_df.head()

import seaborn as sb
import matplotlib.pyplot as plt

plt.figure(figsize = (6,6))
sb.scatterplot(data = principal_df , x = 'PC1', y = 'PC2' , hue = "variety" , s = 60 , palette= 'icefire')
#sb.scatterplot(data = principal_df , x = 'PC1', y = 'PC2', s = 60 , palette= 'icefire')

#my coooode

# Import necessary libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler

# Initialize scaler
scaler = StandardScaler()

# Define PCA function
def PCA(X, num_components):
    # Step 1: Standardize the dataset
    X_scaled = scaler.fit_transform(X)

    # Step 2: Compute covariance matrix
    covariance_matrix = np.cov(X_scaled, rowvar=False)

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

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

    # Step 5: Select top components
    eigenvector_subset = eigen_vectors[:, :num_components]

    # Step 6: Project data onto principal components
    X_reduced = np.dot(X_scaled, eigenvector_subset)

    return X_reduced, eigen_values

# Load dataset
data = pd.read_csv(r"/content/iris.csv")

# Separate features and target
X = data.iloc[:, :-1]
y = data.iloc[:, -1]

# Apply PCA
X_reduced, eigen_values = PCA(X, 2)

# Create a DataFrame with principal components
pca_df = pd.DataFrame(X_reduced, columns=['PC1', 'PC2'])
pca_df['Variety'] = y

# Display first few rows
print(pca_df.head())

# Variance explained by each component
explained_variance = (eigen_values / np.sum(eigen_values)) * 100
print("\nExplained Variance (%):")
print(explained_variance[:2])

# Visualization
plt.figure(figsize=(7, 6))
sns.scatterplot(data=pca_df, x='PC1', y='PC2', hue='Variety', s=80, palette='viridis')
plt.title('PCA on Iris Dataset', fontsize=14)
plt.xlabel(f'PC1 ({explained_variance[0]:.2f}% variance)')
plt.ylabel(f'PC2 ({explained_variance[1]:.2f}% variance)')
plt.legend(title='Variety')
plt.grid(True, linestyle='--', alpha=0.6)
plt.show()

