# -*- coding: utf-8 -*-
"""P5-1 Hierarchical Clustering.ipynb

Automatically generated by Colab.

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

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster import hierarchy

#load the Penguins dataset
data = pd.read_csv("/content/penguins.csv")
data.head()

data['species'].value_counts()

print(data.shape) # (344, 9)

#trimming the dataset to the chosen columns and dropping rows with missing data
df = data[['bill_length_mm', 'flipper_length_mm']]
df = df.dropna(axis=0)

df.head()

#use Scipy's hierarchy.linkage() to form clusters and plot them with hierarchy.dendrogram()

clusters = hierarchy.linkage(df, method="ward")

plt.figure(figsize=(8, 6))
dendrogram = hierarchy.dendrogram(clusters)
# Plotting a horizontal line based on the first biggest distance between clusters
plt.axhline(150, color='red', linestyle='--');
# Plotting a horizontal line based on the second biggest distance between clusters
plt.axhline(100, color='crimson');

#perform Agglomerative Clustering with Scikit-Learn to find cluster labels for the three types of penguins
clustering_model = AgglomerativeClustering(n_clusters=3, linkage="ward")
clustering_model.fit(df)
labels = clustering_model.labels_

#plot the data before and after Agglomerative Clustering with 3 clusters
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15,5))
sns.scatterplot(ax=axes[0], data=df, x='bill_length_mm', y='flipper_length_mm').set_title('Without cliustering')
sns.scatterplot(ax=axes[1], data=df, x='bill_length_mm', y='flipper_length_mm', hue=clustering_model.labels_).set_title('With clustering');

#Agglomerative Clustering without specifying the number of clusters
clustering_model_no_clusters = AgglomerativeClustering(linkage="ward")
clustering_model_no_clusters.fit(df)
labels_no_clusters = clustering_model_no_clusters.labels_

# plot the data without Agglomerative Clustering, with 3 clusters and with no pre defined clusters
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15,5))
sns.scatterplot(ax=axes[0], data=df, x='bill_length_mm', y='flipper_length_mm').set_title('Without cliustering')
sns.scatterplot(ax=axes[1], data=df, x='bill_length_mm', y='flipper_length_mm', hue=clustering_model.labels_).set_title('With 3 clusters')
sns.scatterplot(ax=axes[2], data=df, x='bill_length_mm', y='flipper_length_mm', hue=clustering_model_no_clusters.labels_).set_title('Without choosing number of clusters');

# my cooode

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster import hierarchy

# ============================
# 1️⃣ Load & Prepare Dataset
# ============================
data = pd.read_csv("/content/penguins.csv")

print("Dataset shape:", data.shape)
print("\nSpecies count:\n", data['species'].value_counts())

# Select relevant numerical features and drop missing rows
df = data[['bill_length_mm', 'flipper_length_mm']].dropna()
print("\nCleaned dataset shape:", df.shape)
print(df.head())

# ============================
# 2️⃣ Create Dendrogram (Hierarchical Tree)
# ============================
plt.figure(figsize=(10, 6))
clusters = hierarchy.linkage(df, method="ward")

# Plot the dendrogram
dendrogram = hierarchy.dendrogram(clusters, color_threshold=100)
plt.axhline(150, color='red', linestyle='--', label='Threshold 150')
plt.axhline(100, color='orange', linestyle='--', label='Threshold 100')
plt.title("Hierarchical Clustering Dendrogram (Ward’s Method)")
plt.xlabel("Data Points")
plt.ylabel("Euclidean Distance")
plt.legend()
plt.grid(True)
plt.show()

# ============================
# 3️⃣ Agglomerative Clustering (with 3 clusters)
# ============================
agg3 = AgglomerativeClustering(n_clusters=3, linkage="ward")
labels_3 = agg3.fit_predict(df)

# Add cluster labels to dataframe
df['Cluster_3'] = labels_3

# ============================
# 4️⃣ Visualization — With and Without Clustering
# ============================
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.scatterplot(ax=axes[0], data=df, x='bill_length_mm', y='flipper_length_mm', color='gray')
axes[0].set_title("Without Clustering")

sns.scatterplot(ax=axes[1], data=df, x='bill_length_mm', y='flipper_length_mm', hue='Cluster_3', palette='viridis', s=70)
axes[1].set_title("With 3 Clusters")
plt.tight_layout()
plt.show()

# ============================
# 5️⃣ Agglomerative Clustering (without predefined clusters)
# ============================
agg_auto = AgglomerativeClustering(linkage="ward")
labels_auto = agg_auto.fit_predict(df[['bill_length_mm', 'flipper_length_mm']])
df['Cluster_auto'] = labels_auto

# ============================
# 6️⃣ Compare — No Clustering vs 3 Clusters vs Auto
# ============================
fig, axes = plt.subplots(1, 3, figsize=(18, 5))

sns.scatterplot(ax=axes[0], data=df, x='bill_length_mm', y='flipper_length_mm', color='gray')
axes[0].set_title("Without Clustering")

sns.scatterplot(ax=axes[1], data=df, x='bill_length_mm', y='flipper_length_mm', hue='Cluster_3', palette='cool', s=70)
axes[1].set_title("With 3 Clusters")

sns.scatterplot(ax=axes[2], data=df, x='bill_length_mm', y='flipper_length_mm', hue='Cluster_auto', palette='plasma', s=70)
axes[2].set_title("Auto Clustering (No Predefined k)")

plt.tight_layout()
plt.show()