"""
Module: K-Nearest Neighbors (KNN)
Catégorie : Apprentissage supervisé - Classification
Difficulté : Débutant

Généré depuis la plateforme ML Formation
"""

# Imports
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, mean_squared_error, r2_score

# Charger le dataset
df = pd.read_csv('iris_simple.csv')

# Explorer le dataset Iris
# Type: Code exécutable
print("=" * 70)
print("      EXPLORATION DU DATASET IRIS POUR KNN")
print("=" * 70)

print("\n" + "=" * 70)
print("1. APERCU DU DATASET")
print("=" * 70)
print("""
Le dataset Iris est un classique du Machine Learning!
Il contient des mesures de 150 fleurs de 3 especes differentes.

KNN va apprendre a classifier une nouvelle fleur en regardant
les k fleurs les plus similaires (les plus proches).
""")
display(df.head(10), title="Dataset Iris")

print("\n" + "=" * 70)
print("2. DISTRIBUTION DES ESPECES")
print("=" * 70)
species_counts = df['species'].value_counts()
print("\nRepartition des especes:")
print("-" * 40)
for species, count in species_counts.items():
    pct = count / len(df) * 100
    bar = "█" * int(pct / 3)
    print(f"  {species:12}: {count:3d} ({pct:.0f}%)  {bar}")

print(f"""
Interpretation:
  → Dataset parfaitement equilibre (50 de chaque espece)
  → Ideal pour l'apprentissage supervise
  → Pas besoin de techniques de resampling
""")

print("\n" + "=" * 70)
print("3. STATISTIQUES DES CARACTERISTIQUES")
print("=" * 70)
print("""
KNN utilise les distances entre points, donc les ECHELLES
des features sont cruciales!
""")
display(df.describe().round(2), title="Statistiques descriptives")

print("\n" + "-" * 40)
print("ANALYSE DES ECHELLES (CRUCIAL POUR KNN):")
print("-" * 40)
features = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
for feature in features:
    min_val = df[feature].min()
    max_val = df[feature].max()
    range_val = max_val - min_val
    print(f"  {feature:15}: [{min_val:.1f} - {max_val:.1f}], amplitude = {range_val:.1f}")

print(f"""
PROBLEME POTENTIEL:
  → sepal_length varie de 4.3 a 7.9 (amplitude 3.6)
  → petal_width varie de 0.1 a 2.5 (amplitude 2.4)

  Sans normalisation, sepal_length dominera le calcul de distance!
  La NORMALISATION est OBLIGATOIRE pour KNN.
""")


# Visualiser les données
# Type: Code exécutable
print("=" * 70)
print("    VISUALISATION DES DONNEES IRIS")
print("=" * 70)
print("""
Visualisons les donnees pour comprendre comment KNN va les separer.
Un bon algorithme KNN fonctionne mieux quand les classes
forment des groupes distincts dans l'espace des features.
""")

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

colors = {'setosa': '#9B7AC4', 'versicolor': '#C09CF0', 'virginica': '#F7E64D'}

# Petal length vs width
for species in df['species'].unique():
    mask = df['species'] == species
    axes[0].scatter(df[mask]['petal_length'], df[mask]['petal_width'],
                   c=colors[species], label=species, alpha=0.7, s=60, edgecolors='black')
axes[0].set_xlabel('Petal Length (cm)')
axes[0].set_ylabel('Petal Width (cm)')
axes[0].set_title('Petales: Longueur vs Largeur')
axes[0].legend()
axes[0].grid(True, alpha=0.3)

# Sepal length vs width
for species in df['species'].unique():
    mask = df['species'] == species
    axes[1].scatter(df[mask]['sepal_length'], df[mask]['sepal_width'],
                   c=colors[species], label=species, alpha=0.7, s=60, edgecolors='black')
axes[1].set_xlabel('Sepal Length (cm)')
axes[1].set_ylabel('Sepal Width (cm)')
axes[1].set_title('Sepales: Longueur vs Largeur')
axes[1].legend()
axes[1].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

print("\n" + "=" * 70)
print("INTERPRETATION DES VISUALISATIONS")
print("=" * 70)
print("""
GRAPHIQUE DE GAUCHE (Petales):
  → Setosa (violet) est clairement separee des autres
  → Versicolor et Virginica se chevauchent un peu
  → Les petales sont de bons discriminants!

GRAPHIQUE DE DROITE (Sepales):
  → Plus de chevauchement entre les especes
  → Moins discriminant que les petales
  → Utile en combinaison avec d'autres features

IMPLICATIONS POUR KNN:
  → Un nouveau point dans la zone violette sera facilement classe Setosa
  → Dans la zone de chevauchement, le resultat depend de k
  → Plus k est grand, plus la decision est "lissee"
""")


# ----------------------------------------------------------------------
# La suite de ce module demande un compte.
# Les cellules de code restantes ne sont pas dans ce fichier.
# ----------------------------------------------------------------------
