Spaces:
Sleeping
Sleeping
| 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 --- | |
| 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 ----- | |
| 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}") |