File size: 9,199 Bytes
c110ac6 2bf4ab3 c110ac6 2bf4ab3 c110ac6 d465628 2bf4ab3 c110ac6 2bf4ab3 c110ac6 2bf4ab3 2d6c451 c110ac6 2bf4ab3 c110ac6 2bf4ab3 ce9d6de 2d6c451 ce9d6de 2bf4ab3 ce9d6de 2bf4ab3 c110ac6 2bf4ab3 35f63b4 2bf4ab3 35f63b4 2bf4ab3 b02a11d 2bf4ab3 c110ac6 2bf4ab3 |
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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
import streamlit as st
import pandas as pd
import pickle
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc
from io import StringIO
# Sayfa ayarları
st.set_page_config(page_title="Müşteri Kaybı Tahmin Uygulaması", page_icon=":telephone_receiver:", layout="wide")
# Veriyi yükle (sadece bir kere yüklemek için @st.cache kullanıyoruz)
@st.cache_data()
def load_data():
df = pd.read_csv('churn.csv')
return df
df = load_data()
# --- Arayüz ---
st.title("Müşteri Kaybı Tahmin Uygulaması")
# --- Sidebar (Sol Menü) ---
st.sidebar.header("Navigasyon")
page = st.sidebar.radio("Sayfa Seçin:", ["Veri İnceleme", "Model ve Tahmin"])
# --- Veri İnceleme Sayfası ---
if page == "Veri İnceleme":
st.header("Veri Seti İnceleme")
if st.checkbox("Veri Setini Göster"):
st.subheader("Veri Seti")
st.dataframe(df)
if st.checkbox("Özet İstatistikleri Göster"):
st.subheader("Özet İstatistikler")
st.write(df.describe())
if st.checkbox("Sütun Bilgilerini Göster"):
st.subheader("Sütun Bilgileri")
buffer = StringIO()
df.info(buf=buffer)
s = buffer.getvalue()
st.text(s)
# --- Görselleştirme ---
st.header("Veri Görselleştirme")
if st.checkbox("Sayısal Değişken Dağılımları"):
st.subheader("Sayısal Değişken Dağılımları")
for col in ['tenure', 'MonthlyCharges', 'TotalCharges']:
fig, ax = plt.subplots()
sns.histplot(df[col], kde=True, ax=ax)
st.pyplot(fig)
if st.checkbox("Kategorik Değişken Dağılımları"):
st.subheader("Kategorik Değişken Dağılımları")
for col in ['gender', 'SeniorCitizen', 'Partner', 'Dependents', 'PhoneService', 'MultipleLines',
'InternetService', 'OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport',
'StreamingTV', 'StreamingMovies', 'Contract', 'PaperlessBilling', 'PaymentMethod', "Churn"]:
fig, ax = plt.subplots()
sns.countplot(x=col, data=df, ax=ax)
st.pyplot(fig)
if st.checkbox("Churn Dağılımı"):
st.subheader("Churn Dağılımı")
fig, ax = plt.subplots()
sns.countplot(x='Churn', data=df, ax=ax)
st.pyplot(fig)
if st.checkbox("Cinsiyete Göre Churn Dağılımı"):
st.subheader("Cinsiyete Göre Churn Dağılımı")
fig, ax = plt.subplots()
sns.countplot(x='gender', hue='Churn', data=df, ax=ax)
st.pyplot(fig)
# --- Model ve Tahmin Sayfası ---
elif page == "Model ve Tahmin":
st.header("Müşteri Kaybı Tahmini")
# Preprocess the data
df_model = df.copy()
# TotalCharges sütununu sayısal yap ve eksik değerleri doldur
df_model['TotalCharges'] = pd.to_numeric(df_model['TotalCharges'], errors='coerce')
df_model['TotalCharges'].fillna(df_model['TotalCharges'].median(), inplace=True)
# Kategorik sütunları Label Encoding ile sayısal hale getir
label_enc = LabelEncoder()
for col in df_model.select_dtypes(include=['object']).columns:
if col != 'customerID':
df_model[col] = label_enc.fit_transform(df_model[col])
# --- Kullanıcıdan girdi al ---
def user_input_features():
features = {}
col1, col2 = st.columns(2)
# 'TotalCharges' sütununu sayısal yap ve boş değerleri 0 ile doldur (geçici çözüm)
df['TotalCharges'] = pd.to_numeric(df['TotalCharges'], errors='coerce')
df['TotalCharges'] = df['TotalCharges'].fillna(0)
with col1:
features['gender'] = st.selectbox("Cinsiyet", df['gender'].unique())
features['SeniorCitizen'] = st.selectbox("Yaşlı Mı?", df['SeniorCitizen'].unique())
features['Partner'] = st.selectbox("Partneri Var Mı?", df['Partner'].unique())
features['Dependents'] = st.selectbox("Bağımlı Kişi Var Mı?", df['Dependents'].unique())
features['PhoneService'] = st.selectbox("Telefon Hizmeti Var Mı?", df['PhoneService'].unique())
# MultipleLines için özel durum (PhoneService'e göre seçenekleri güncelle)
if features['PhoneService'] == 'Yes':
features['MultipleLines'] = st.selectbox("Çoklu Hat Var Mı?", ['Yes', 'No'])
else:
features['MultipleLines'] = st.selectbox("Çoklu Hat Var Mı?", ['No phone service'])
features['OnlineSecurity'] = st.selectbox("Çevrimiçi Güvenlik Var Mı?", df['OnlineSecurity'].unique())
features['OnlineBackup'] = st.selectbox("Çevrimiçi Yedekleme Var Mı?", df['OnlineBackup'].unique())
with col2:
features['DeviceProtection'] = st.selectbox("Cihaz Koruması Var Mı?", df['DeviceProtection'].unique())
features['TechSupport'] = st.selectbox("Teknik Destek Var Mı?", df['TechSupport'].unique())
features['StreamingTV'] = st.selectbox("TV Yayını Var Mı?", df['StreamingTV'].unique())
features['StreamingMovies'] = st.selectbox("Film Yayını Var Mı?", df['StreamingMovies'].unique())
features['Contract'] = st.selectbox("Sözleşme Türü", df['Contract'].unique())
features['PaperlessBilling'] = st.selectbox("Kağıtsız Fatura Var Mı?", df['PaperlessBilling'].unique())
features['PaymentMethod'] = st.selectbox("Ödeme Yöntemi", df['PaymentMethod'].unique())
features['tenure'] = st.slider("Müşteri Olma Süresi (Ay)", 0, 72, 12)
features['MonthlyCharges'] = st.slider("Aylık Ücret", 0, 150, 50)
features['TotalCharges'] = st.slider("Toplam Ücret", 0, int(df['TotalCharges'].max()), int(df['TotalCharges'].median()))
# InternetService'i sona ekle, çünkü diğer özelliklerin seçimine bağlı
features['InternetService'] = st.selectbox("İnternet Servisi", df['InternetService'].unique())
return pd.DataFrame(features, index=[0])
input_df = user_input_features()
# --- Modeli Eğit ve Tahmin Yap ---
X = df_model.drop(columns=['Churn', 'customerID'])
y = df_model['Churn']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# --- Değişiklikler ---
# 1. Eğitim verisinin sütun sırasını kaydet
column_order = X.columns
for col in input_df.select_dtypes(include=['object']).columns:
input_df[col] = input_df[col].astype(str) # Her ihtimale karşı, object tipindeki sütunları stringe çevir
for col in input_df.columns:
if input_df[col].dtype == object or input_df[col].dtype == str :
input_df[col] = pd.Categorical(input_df[col], categories=df[col].unique())
input_df[col] = input_df[col].cat.codes
# 2. Girdi verisini eğitim verisinin sütun sırasına göre düzenle
input_df = input_df.reindex(columns=column_order)
# --- Değişiklikler Son ---
input_df = scaler.transform(input_df)
input_df = pd.DataFrame(input_df, columns=column_order) # scaler.transform sonrası tekrar isimlendir
# Modeli yükle
model = LogisticRegression()
model.fit(X_train, y_train) # Modeli tekrar burada eğitiyoruz
if st.button('Tahmin Yap'):
prediction = model.predict(input_df)
prediction_proba = model.predict_proba(input_df)
st.subheader("Tahmin Sonucu:")
if prediction[0] == 0:
st.success("Bu müşterinin kayıp **OLMAYACAĞI** tahmin ediliyor. :thumbsup:")
else:
st.error("Bu müşterinin kayıp **OLACAĞI** tahmin ediliyor. :thumbsdown:")
st.subheader("Tahmin Olasılıkları:")
st.write(f"Kayıp Olmama Olasılığı: **{prediction_proba[0][0]:.2f}**")
st.write(f"Kayıp Olma Olasılığı: **{prediction_proba[0][1]:.2f}**")
# --- Model Performansı ---
st.header("Model Performansı")
y_pred = model.predict(X_test)
st.subheader("Sınıflandırma Raporu")
st.text(classification_report(y_test, y_pred))
st.subheader("Karışıklık Matrisi")
fig, ax = plt.subplots()
sns.heatmap(confusion_matrix(y_test, y_pred), annot=True, fmt='d', cmap='Blues', ax=ax)
st.pyplot(fig)
st.subheader("ROC Eğrisi")
y_prob = model.predict_proba(X_test)[:, 1]
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)
fig, ax = plt.subplots()
ax.plot(fpr, tpr, color='blue', lw=2, label=f"ROC Curve (AUC = {roc_auc:.2f})")
ax.plot([0, 1], [0, 1], color='red', lw=2, linestyle='--')
ax.set_xlabel("False Positive Rate")
ax.set_ylabel("True Positive Rate")
ax.set_title("Receiver Operating Characteristic (ROC) Curve")
ax.legend(loc="lower right")
st.pyplot(fig) |