File size: 5,614 Bytes
db11cf1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import streamlit as st
import numpy as np
import pickle  # Değişiklik: 'joblib' yerine 'pickle' import edildi
from tensorflow.keras.models import load_model

# --- Model ve Scaler Yükleme ---
@st.cache_resource
def load_keras_model():
    """Kayıtlı Keras modelini yükler."""
    try:
        model = load_model("model_churn.keras")
        return model
    except Exception as e:
        st.error(f"Keras modeli (model_churn.keras) yüklenirken hata oluştu: {e}")
        return None

# ----- BAŞLANGIÇ: GÜNCELLENEN BÖLÜM -----
@st.cache_resource
def load_scaler_model():
    """Kayıtlı Scaler'ı (pickle) yükler."""
    try:
        # Pickle dosyaları 'rb' (read binary) modu ile açılmalıdır
        with open("scaler_churn", "rb") as f:
            scaler = pickle.load(f)
        return scaler
    except FileNotFoundError:
        st.error("Hata: 'scaler_churn' dosyası bulunamadı. Lütfen dosyayı yüklediğinizden emin olun.")
        return None
    except Exception as e:
        st.error(f"Scaler (scaler_churn) yüklenirken hata oluştu: {e}")
        return None
# ----- BİTİŞ: GÜNCELLENEN BÖLÜM -----

# Modelleri yükle
model = load_keras_model()
scaler = load_scaler_model()

# Modelinizin/Scaler'ınızın beklediği 11 özelliğin sırası
MODEL_INPUT_COLUMNS_ORDER = [
    'CreditScore', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'HasCrCard',
    'IsActiveMember', 'EstimatedSalary', 'Geography_Germany', 'Geography_Spain',
    'Gender_Male'
]

# --- Arayüz (UI) ---
st.set_page_config(page_title="Müşteri Churn Tahmini", layout="wide")
st.title("🏦 Müşteri Churn Tahmin Modeli")

col1, col2 = st.columns([1, 1])

with col1:
    st.header("Müşteri Bilgileri")
    st.caption("Lütfen müşterinin bilgilerini girin.")
    
    geography = st.selectbox("Ülke", ("France", "Spain", "Germany"), index=0)
    gender = st.radio("Cinsiyet", ("Female", "Male"), index=0)
    has_cr_card = st.radio("Kredi Kartı Var mı?", ("Var", "Yok"), index=0)
    is_active_member = st.radio("Aktif Üye mi?", ("Evet", "Hayır"), index=0)
    
    credit_score = st.number_input("Kredi Skoru", min_value=300, max_value=900, value=619)
    age = st.number_input("Yaş", min_value=18, max_value=100, value=42)
    tenure = st.number_input("Banka Müşterisi Olma Süresi (Yıl)", min_value=0, max_value=10, value=2)
    balance = st.number_input("Bakiye", value=0.00, format="%.2f")
    num_of_products = st.number_input("Ürün Sayısı", min_value=1, max_value=4, value=1)
    estimated_salary = st.number_input("Tahmini Maaş", value=101348.88, format="%.2f")

    predict_button = st.button("Riski Hesapla", type="primary")

with col2:
    st.header("Tahmin Sonucu")
    st.caption("Modelin churn (ayrılma) olasılığı tahmini.")

    if predict_button:
        if model is None or scaler is None:
            st.error("Modeller yüklenemedi. Lütfen yönetici ile iletişime geçin.")
        else:
            try:
                # --- 1. Adım: Tüm Ham Girdileri Bir Sözlükte Topla ---
                raw_data_dict = {
                    'CreditScore': credit_score,
                    'Age': age,
                    'Tenure': tenure,
                    'Balance': balance,
                    'NumOfProducts': float(num_of_products),
                    'HasCrCard': 1.0 if has_cr_card == "Var" else 0.0,
                    'IsActiveMember': 1.0 if is_active_member == "Evet" else 0.0,
                    'EstimatedSalary': estimated_salary,
                    'Geography_Germany': 1.0 if geography == "Germany" else 0.0,
                    'Geography_Spain': 1.0 if geography == "Spain" else 0.0,
                    'Gender_Male': 1.0 if gender == "Male" else 0.0
                }
                
                # --- 2. Adım: Veriyi Modelin Sırasına Göre Diz ---
                raw_input_features = [raw_data_dict[col] for col in MODEL_INPUT_COLUMNS_ORDER]
                raw_input_array = np.array(raw_input_features).reshape(1, -1)
                
                # --- 3. Adım: Ölçekleme (Scaling) ---
                scaled_input_array = scaler.transform(raw_input_array)
                
                # --- 4. Adım: Tahmin Yapma ---
                with st.spinner("Model çalışıyor, tahmin yapılıyor..."):
                    prediction_proba = model.predict(scaled_input_array)[0][0]
                    churn_probability_percent = prediction_proba * 100
                    threshold = 50.0

                    # --- 5. Adım: Sonucu Gösterme ---
                    if churn_probability_percent > threshold:
                        st.error(f"Müşterinin Churn Olma Olasılığı: {churn_probability_percent:.2f}%")
                        st.warning("Bu müşterinin ayrılma riski YÜKSEK. 🚨")
                    else:
                        st.success(f"Müşterinin Churn Olma Olasılığı: {churn_probability_percent:.2f}%")
                        st.info("Bu müşterinin ayrılma riski DÜŞÜK. ✅")
                
                with st.expander("Modelin Gördüğü İşlenmiş (Scaled) Veri"):
                    scaled_features_list = scaled_input_array.flatten().tolist()
                    st.json({col: val for col, val in zip(MODEL_INPUT_COLUMNS_ORDER, scaled_features_list)})
                
                with st.expander("Scalera Giren Ham Veri (Kontrol amaçlı)"):
                    st.json({col: val for col, val in zip(MODEL_INPUT_COLUMNS_ORDER, raw_input_features)})

            except Exception as e:
                st.error(f"Tahmin sırasında bir hata oluştu: {e}")