#Sekcja 1: Import Bibliotek

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import numpy as np

#Sekcja 2: Wczytywanie i zapoznanie z danymi

#Wczytanie zbioru danych Titanic z blibliteki seaborn
df = sns.load_dataset('titanic')
#Wyswietlenie pierwszych 10 wierszy danych
print("\nFirst 10 rows of the Titanic dateset:")
print(df.head(10))

print("\nLiczba brakujących wartości przed czyszczeniem: ")
print(df.isnull().sum())

#Usuniecie rekordów z brakującą daną w polu 'age i wysiwtlenie danych o liczbie wierszy
df = df.dropna(subset=['age'])

print("\nLiczba brakujących wartości po czyszczeniu (tylko age) :")
print(df.isnull().sum())

print(f"\nLiczba wierszy przed czyszczeniem: {len(sns.load_dataset('titanic'))}")
print(f"Liczba wierszy po czyszczeniu: {len(df)}")

# Sekcja 3: Kategoryzacja opłat za bilety

def categorize_fare(fare, fare_ranges):
    if fare <= fare_ranges[0]:
        return 0 # niska
    elif fare <= fare_ranges[1]:
        return 1 # średnia
    else:
        return 2 # wysoka

min_fare = df['fare'].min()
max_fare = df['fare'].max()
fare_step = (max_fare - min_fare) /3
fare_ranges = [min_fare + fare_step, min_fare + 2 *fare_step]

print("\nPrzedziały cenowe biletów:")
print(f"Niska: {min_fare:.2f} - {fare_ranges[0]:.2f}")
print(f"Średnia: {fare_ranges[0]:.2f} - {fare_ranges[1]:.2f}")
print(f"Wysoka: {fare_ranges[1]:.2f} - {max_fare:.2f}")

#Sekcja 4: Przygotowanie danych do modelowania
selected_features = ['sex', 'pclass', 'age', 'fare_category']
df_model = df.copy()
df_model['sex'] = df_model['sex'].map({'male': 0, 'female': 1})
df_model['fare_category'] = df_model['fare'].apply(lambda x: categorize_fare(x, fare_ranges))

#Sekcja numer 5: Podział danych i skalowanie
#Przygotowanie danych
x = df_model[selected_features]
y = df_model['survived']

#Podział na zbiór treningowy i testowy
X_train, X_test, y_train, y_test = train_test_split(x,y, test_size=0.2, random_state=42)

#Skalowanie danychs
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

#Sekcja 6: Trenowanie i ocena modelu
model = LogisticRegression (
    random_state = 42, #Zapewnia powtrzalność wyników
    C = 0.2 # Siła regularyzacji (Odwrotności)
)
model.fit(X_train_scaled, y_train)

y_pred = model.predict(X_test_scaled)
accuracy = accuracy_score(y_test, y_pred)

print("\nWynik modelu:")
print(f"Dokładność modelu: {accuracy:.3f}")

#Sekcja 7: Analiza metryk i macierzy pomyłek
print("\nRaport klasyfikacje:")
print(classification_report(y_test, y_pred))
conf_matrix = confusion_matrix(y_test, y_pred)

tn, fp, fn, tp = conf_matrix.ravel()
sensitivity = tp / (tp+fn)
precision = tp / (tp+fp)
f1 = 2 * (precision * sensitivity) / (precision + sensitivity)
                                      
print(f"\nDodatkowe metryki:")
print(f"Czułość (recall): {sensitivity:.3f}")
print(f"Precyzja: {precision:.3f}")
print(f"F1 Score: {f1:.3f}")

#Sekcja 8: Wizualizacja macierzy pomyłek
plt.figure(figsize=(10,8))
sns.heatmap(conf_matrix,
 annot = True,
 fmt = 'd',
 cmap = 'Blues',
 xticklabels=['Nie przeżył', "Przeżył"],
 yticklabels = ['Nie przeżył', 'Przeżył'])
 
plt.title("Macierz pomyłek")
plt.xlabel("Przewidywanie")
plt.ylabel("Rzeczywiste")
plt.tight_layout()
plt.show() 














    
    
