# -*- coding: utf-8 -*-
"""different Distance methods (Euclidean) with Prediction, Test Score and Confusion Matrix1.ipynb

Automatically generated by Colab.

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

# Importing required libraries
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report

# Load the dataset
data = pd.read_csv("/content/Irisdata.csv")

# Selecting features and target
X = data.iloc[:, [1, 2, 3, 4]].values
y = data.iloc[:, 5].values

# Encoding target labels
le = LabelEncoder()
y = le.fit_transform(y)

# Splitting data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Creating KNN model using Euclidean distance
model = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
model.fit(X_train, y_train)

# Making predictions
y_pred = model.predict(X_test)

# Evaluating model performance
cm = confusion_matrix(y_test, y_pred)
acc = accuracy_score(y_test, y_pred)

print("Confusion Matrix:\n", cm)
print("\nAccuracy Score:", round(acc * 100, 2), "%")
print("\nClassification Report:\n", classification_report(y_test, y_pred, target_names=le.classes_))

# Example prediction
sample = [[5.1, 3.5, 1.4, 0.2]]
predicted_class = model.predict(sample)
print("\nPredicted Class for", sample, ":", le.inverse_transform(predicted_class)[0])

# ---- Visualization of KNN Results ----
import matplotlib.pyplot as plt
import numpy as np

# Only for 2D plotting (we'll use the first two features: SepalLength and SepalWidth)
X_plot = X_train[:, :2]
y_plot = y_train

# Train again using only first 2 features (for visualization)
model_2d = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
model_2d.fit(X_plot, y_plot)

# Create a meshgrid for background decision boundary
x_min, x_max = X_plot[:, 0].min() - 1, X_plot[:, 0].max() + 1
y_min, y_max = X_plot[:, 1].min() - 1, X_plot[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
                     np.arange(y_min, y_max, 0.1))

# Predict for each point in meshgrid
Z = model_2d.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# Plot decision boundary and training points
plt.figure(figsize=(8,6))
plt.contourf(xx, yy, Z, alpha=0.3)
plt.scatter(X_plot[:, 0], X_plot[:, 1], c=y_plot, s=40, edgecolor='k')
plt.title("KNN Classification (Euclidean Distance)")
plt.xlabel("Sepal Length")
plt.ylabel("Sepal Width")
plt.show()



#second code 

4.a Euclidean
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score

# --- Step 1: Sample dataset ---
# For simplicity, use an example dataset
from sklearn.datasets import load_iris
data = load_iris()
X = data.data
y = data.target

# --- Step 2: Split into training and testing ---
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# --- Step 3: Define a function for Euclidean distance ---
def euclidean_distance(x1, x2):
    return np.sqrt(np.sum((x1 - x2)**2))

# --- Step 4: Implement KNN manually using Euclidean distance ---
def knn_predict(X_train, y_train, X_test, k=3):
    predictions = []
    for test_point in X_test:
        # Calculate all distances
        distances = [euclidean_distance(test_point, x_train) for x_train in X_train]
        # Get indices of k nearest neighbors
        k_indices = np.argsort(distances)[:k]
        # Get the labels of k nearest points
        k_neighbor_labels = [y_train[i] for i in k_indices]
        # Take the majority vote
        most_common = max(set(k_neighbor_labels), key=k_neighbor_labels.count)
        predictions.append(most_common)
    return np.array(predictions)

# --- Step 5: Make predictions ---
y_pred = knn_predict(X_train, y_train, X_test, k=3)

# --- Step 6: Evaluate model ---
acc = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)

print("Predictions:", y_pred)
print("\nTest Accuracy:", acc)
print("\nConfusion Matrix:\n", cm)

