🎯 Trening Modelu Churn - Deployment Ready¶
📋 Kontekst projektu¶
⚠️ UWAGA: Model churn był już szczegółowo:
- Trenowany w projekcie 04 (churn_overfitting)
- Optymalizowany i tuningowany w projekcie 05 (churn_model_tuning)
- Analizowany w projekcie 06 (churn_recall_threshold)
Dlaczego trenujemy go ponownie tutaj?
- Przejrzystość - Projekt 07 pokazuje pełny proces deployment od A do Z
- Spójność - Wszystko w jednym miejscu (trening → predykcje)
- Samodzielność - Możesz używać tego projektu niezależnie od poprzednich
- Best practice - W produkcji masz pełną kontrolę nad treningiem i zapisem modelu
Ten notebook to wersja produkcyjna - prostsza, gotowa do użycia w realnym środowisku.
Krok 1: Import bibliotek¶
In [1]:
# Importujemy pandas - bibliotekę do pracy z danymi (jak Excel w Pythonie)
import pandas as pd
# Importujemy PyCaret - narzędzie AutoML do klasyfikacji
# To biblioteka która automatyzuje proces uczenia maszynowego
from pycaret.classification import *
# Importujemy json - do zapisywania ustawień modelu (threshold, itp.)
import json
print("✅ Biblioteki zaimportowane!")
✅ Biblioteki zaimportowane!
Krok 2: Wczytanie i przygotowanie danych¶
In [2]:
# Wczytujemy dane klientów z pliku CSV
# CSV = Comma Separated Values (plik tekstowy z danymi oddzielonymi przecinkami)
df = pd.read_csv('data/WA_Fn-UseC_-Telco-Customer-Churn.csv')
# Sprawdzamy ile mamy klientów i kolumn
print(f"📊 Liczba klientów: {len(df)}")
print(f"📋 Liczba kolumn: {len(df.columns)}")
# Wyświetlamy pierwsze 3 wiersze żeby zobaczyć jak wyglądają dane
print("\n🔍 Przykładowe dane:")
df.head(3)
📊 Liczba klientów: 7043 📋 Liczba kolumn: 21 🔍 Przykładowe dane:
Out[2]:
| customerID | gender | SeniorCitizen | Partner | Dependents | tenure | PhoneService | MultipleLines | InternetService | OnlineSecurity | ... | DeviceProtection | TechSupport | StreamingTV | StreamingMovies | Contract | PaperlessBilling | PaymentMethod | MonthlyCharges | TotalCharges | Churn | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 7590-VHVEG | Female | 0 | Yes | No | 1 | No | No phone service | DSL | No | ... | No | No | No | No | Month-to-month | Yes | Electronic check | 29.85 | 29.85 | No |
| 1 | 5575-GNVDE | Male | 0 | No | No | 34 | Yes | No | DSL | Yes | ... | Yes | No | No | No | One year | No | Mailed check | 56.95 | 1889.5 | No |
| 2 | 3668-QPYBK | Male | 0 | No | No | 2 | Yes | No | DSL | Yes | ... | No | No | No | No | Month-to-month | Yes | Mailed check | 53.85 | 108.15 | Yes |
3 rows × 21 columns
In [3]:
# CZYSZCZENIE DANYCH
# 1. Usuwamy kolumnę customerID
# To tylko identyfikator klienta (jak numer PESEL) - nie pomaga w przewidywaniu
df = df.drop('customerID', axis=1)
# 2. Naprawiamy kolumnę TotalCharges (łączne opłaty)
# Niektóre wartości są tekstem " " zamiast liczb - konwertujemy na liczby
# errors='coerce' oznacza: jak nie da się zamienić na liczbę, wpisz NaN (brak danych)
df['TotalCharges'] = pd.to_numeric(df['TotalCharges'], errors='coerce')
# 3. Wypełniamy brakujące wartości zerem
# Nowi klienci (tenure=0) mają 0 historii płatności - logicznie to ma sens
df['TotalCharges'].fillna(0, inplace=True)
# 4. Sprawdzamy rozkład churn (ile klientów odchodzi vs zostaje)
print("\n📊 Rozkład Churn (czy klient odszedł):")
print(df['Churn'].value_counts())
print(f"\n💡 Procent odchodzących: {(df['Churn'] == 'Yes').sum() / len(df) * 100:.1f}%")
print("\n✅ Dane przygotowane!")
📊 Rozkład Churn (czy klient odszedł): Churn No 5174 Yes 1869 Name: count, dtype: int64 💡 Procent odchodzących: 26.5% ✅ Dane przygotowane!
Krok 3: Konfiguracja PyCaret (przygotowanie do treningu)¶
In [4]:
# Inicjalizujemy PyCaret - przygotowujemy środowisko do uczenia maszynowego
# To jak przygotowanie kuchni przed gotowaniem - ustawiamy wszystkie narzędzia
clf_setup = setup(
data=df, # Nasze dane
target='Churn', # Co chcemy przewidzieć (czy klient odejdzie: Yes/No)
session_id=123, # "Ziarnko losowości" - dla powtarzalnych wyników
train_size=0.8, # 80% danych do treningu, 20% do testowania
fold=5, # 5-fold cross-validation (dzielimy dane na 5 części)
normalize=True, # Normalizacja - skalowanie liczb do podobnego zakresu
verbose=False # Nie pokazuj szczegółów konfiguracji (mniej tekstu)
)
print("\n✅ PyCaret skonfigurowany!")
print("📊 Dane podzielone: 80% trening, 20% test")
print("🎯 Target: Churn (Yes/No)")
✅ PyCaret skonfigurowany! 📊 Dane podzielone: 80% trening, 20% test 🎯 Target: Churn (Yes/No)
Krok 4: Wybór najlepszego modelu (optymalizacja pod Recall)¶
Co to jest Recall?¶
Recall = Ile % faktycznie odchodzących klientów wykrywamy
Przykład:
- Jest 100 klientów którzy faktycznie odejdą
- Model wykrywa 80 z nich
- Recall = 80%
Dlaczego optymalizujemy pod Recall?¶
W churn prediction gorsze jest przegapienie klienta, który odejdzie, niż fałszywy alarm. Najważniejsze dla nas jest przewidzenie ile będzie przypadków odejścia, dlatego metryka recall najbardziej nadaje się do tego.
In [7]:
# Porównujemy różne algorytmy uczenia maszynowego
# PyCaret automatycznie testuje ~15 różnych modeli (Gradient Boosting, Random Forest, itp.)
# sort='Recall' - wybieramy model który NAJLEPIEJ wykrywa odchodzących klientów
# n_select=1 - wybieramy tylko 1 najlepszy model
print("🔄 Porównywanie modeli...")
print("Szukamy modelu który wykryje NAJWIĘCEJ odchodzących klientów!\n")
# To może zająć 1-2 minuty - PyCaret testuje każdy model na 5-fold cross-validation
best_model = compare_models(sort='Recall', n_select=1)
print("\n✅ Najlepszy model wybrany!")
print(f"📊 Algorytm: {type(best_model).__name__}")
🔄 Porównywanie modeli... Szukamy modelu który wykryje NAJWIĘCEJ odchodzących klientów!
✅ Najlepszy model wybrany! 📊 Algorytm: LogisticRegression
Krok 5: Zapisanie modelu do pliku¶
In [8]:
# Zapisujemy wytrenowany model do pliku
# To jak zapisanie gry - później możemy go załadować i używać bez ponownego treningu
# PyCaret automatycznie tworzy plik .pkl (pickle) - spakowany model Python
print("💾 Zapisywanie modelu...")
# save_model zapisuje model do folderu models/
save_model(best_model, 'models/churn_model')
print(f"\n✅ Model zapisany jako: models/churn_model.pkl")
print("📦 Plik zawiera: wytrenowany model + preprocessing pipeline")
💾 Zapisywanie modelu... Transformation Pipeline and Model Successfully Saved ✅ Model zapisany jako: models/churn_model.pkl 📦 Plik zawiera: wytrenowany model + preprocessing pipeline
Krok 6: Zapisanie metadanych (ustawień modelu)¶
Co to są metadata?¶
Metadata = "dane o danych" - informacje opisujące nasz model
Po co zapisujemy metadata?¶
- Dokumentacja - Pamiętamy jak model był trenowany (threshold, optymalizacja)
- Reprodukowalność - Ktoś inny może zrozumieć ustawienia modelu
- Konsystencja - Predykcje używają tych samych ustawień co trening
- Wersjonowanie - Wiemy kiedy model był trenowany, jakie miał parametry
Co daje nam to w produkcji?¶
- ✅ Skrypt
predict.pyautomatycznie odczyta threshold z metadata - ✅ Nie trzeba pamiętać jakie były ustawienia
- ✅ Łatwa zmiana threshold bez zmiany kodu (tylko edycja JSON)
- ✅ Historia modelu - możesz mieć wiele wersji z różnymi metadata
In [9]:
# METADATA = informacje o modelu (nie sam model, ale jego "instrukcja obsługi")
# Zapisujemy: threshold, pod co optymalizowany, dlaczego takie ustawienia
metadata = {
"threshold": 0.5, # Próg decyzyjny: >= 0.5 = "klient odejdzie"
"optimized_for": "recall", # Model zoptymalizowany pod Recall
"business_reason": "false negatives are costly", # Dlaczego? Bo przegapienie klienta odchodzącego = strata pieniędzy
"model_type": type(best_model).__name__, # Jaki algorytm użyty (np. GradientBoostingClassifier)
"train_date": pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S") # Kiedy wytrenowany
}
# Zapisujemy metadata do pliku JSON
# JSON = prosty format tekstowy do przechowywania danych (jak słownik Python)
with open('models/metadata.json', 'w', encoding='utf-8') as f:
json.dump(metadata, f, indent=2, ensure_ascii=False)
print("💾 Zapisano metadata.json")
print("\n📋 Zawartość:")
print(json.dumps(metadata, indent=2, ensure_ascii=False))
print("\n✅ Model i metadata gotowe do użycia!")
💾 Zapisano metadata.json
📋 Zawartość:
{
"threshold": 0.5,
"optimized_for": "recall",
"business_reason": "false negatives are costly",
"model_type": "LogisticRegression",
"train_date": "2026-01-07 20:26:39"
}
✅ Model i metadata gotowe do użycia!
🎉 Podsumowanie¶
Co zrobiliśmy?¶
- ✅ Wczytaliśmy i oczyściliśmy dane (7,043 klientów)
- ✅ Skonfigurowaliśmy PyCaret (80/20 train/test split)
- ✅ Wybraliśmy najlepszy model pod kątem Recall
- ✅ Zapisaliśmy model do pliku
models/churn_model.pkl - ✅ Zapisaliśmy ustawienia do
models/metadata.json
Co dalej?¶
Teraz możemy użyć zapisanego modelu w notebooku predict.ipynb do:
- Przewidywania churn dla nowych klientów
- Stosowania threshold do podjęcia decyzji
- Wdrożenia modelu w produkcji
💡 Kluczowe pliki:¶
models/churn_model.pkl- wytrenowany modelmodels/metadata.json- ustawienia (threshold, optymalizacja)
Model jest gotowy do deployment! 🚀