import pandas as pd
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix

# 1. LOAD DATASET
# Objective: Predict Titanic passenger survival

df = pd.read_csv("titanic.csv")

# 2. EDA AND DATA QUALITY

print(df.head())
print("Data Types:\n", df.dtypes)
print("Missing Values:\n", df.isnull().sum())
print("Statistics:\n", df.describe())
print("Target Distribution:\n", df["Survived"].value_counts())

df["Survived"].value_counts().plot(kind="bar")
plt.title("Survival Distribution")
plt.show()

# 3. SELECT FEATURES AND ENCODE SEX

df = df.dropna(subset=["Survived"])

X = df[["Pclass", "Age", "Fare", "Sex"]].copy()
y = df["Survived"]

X["Sex"] = X["Sex"].map({"male": 0, "female": 1})

print("Target: Survived")
print("Features:", X.columns)

# 4. TRAIN-TEST SPLIT

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 5. CREATE ML PIPELINE

pipe = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("scaler", StandardScaler()),
    ("knn", KNeighborsClassifier())
])

# 6. HYPERPARAMETER TUNING USING CROSS-VALIDATION

search = GridSearchCV(
    pipe,
    {"knn__n_neighbors": [3, 5, 7]},
    cv=5,
    scoring="f1"
)

search.fit(X_train, y_train)

print("Best K:", search.best_params_)
print("Cross-Validation F1:", search.best_score_)

# 7. PREDICT AND EVALUATE

y_pred = search.predict(X_test)

print("Accuracy:", accuracy_score(y_test, y_pred))
print("Precision:", precision_score(y_test, y_pred))
print("Recall:", recall_score(y_test, y_pred))
print("F1 Score:", f1_score(y_test, y_pred))
print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))
