Spaces:
Build error
Build error
Duplicate from bright1/Customer-Churn-App
Browse filesCo-authored-by: Bright Eshun <[email protected]>
- .gitattributes +34 -0
- README.md +13 -0
- app.py +139 -0
- full_pipeline.pkl +3 -0
- history.csv +11 -0
- logistic_reg_class_model.pkl +3 -0
- requirements.txt +6 -0
- utils.py +35 -0
.gitattributes
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
29 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
30 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
31 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
32 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
33 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
34 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: Customer Churn App
|
3 |
+
emoji: 💻
|
4 |
+
colorFrom: indigo
|
5 |
+
colorTo: indigo
|
6 |
+
sdk: gradio
|
7 |
+
sdk_version: 3.29.0
|
8 |
+
app_file: app.py
|
9 |
+
pinned: false
|
10 |
+
duplicated_from: bright1/Customer-Churn-App
|
11 |
+
---
|
12 |
+
|
13 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pickle
|
3 |
+
# import time
|
4 |
+
import pandas as pd
|
5 |
+
import numpy as np
|
6 |
+
from utils import create_new_columns, create_processed_dataframe
|
7 |
+
import os
|
8 |
+
|
9 |
+
|
10 |
+
|
11 |
+
pipeline_pkl = "full_pipeline.pkl"
|
12 |
+
log_reg = "logistic_reg_class_model.pkl"
|
13 |
+
|
14 |
+
# hist_df = "history.csv"
|
15 |
+
|
16 |
+
# def check_csv(csv_file, data):
|
17 |
+
# if os.path.isfile(csv_file):
|
18 |
+
# data.to_csv(csv_file, mode='a', header=False, index=False, encoding='utf-8')
|
19 |
+
# else:
|
20 |
+
# history = data.copy()
|
21 |
+
# history.to_csv(csv_file, index=False)
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
def tenure_values():
|
30 |
+
cols = ['0-2', '3-5', '6-8', '9-11', '12-14', '15-17', '18-20', '21-23', '24-26', '27-29', '30-32', '33-35', '36-38', '39-41', '42-44', '45-47', '48-50', '51-53', '54-56', '57-59', '60-62', '63-65', '66-68', '69-71', '72-74']
|
31 |
+
return cols
|
32 |
+
|
33 |
+
def predict_churn(gender, SeniorCitizen, Partner, Dependents, Tenure, PhoneService, MultipleLines, InternetService,
|
34 |
+
OnlineSecurity, OnlineBackup, DeviceProtection,TechSupport,StreamingTV, StreamingMovies,
|
35 |
+
Contract, PaperlessBilling, PaymentMethod, MonthlyCharges, TotalCharges):
|
36 |
+
|
37 |
+
data = [gender, SeniorCitizen, Partner, Dependents, Tenure, PhoneService, MultipleLines, InternetService,
|
38 |
+
OnlineSecurity, OnlineBackup, DeviceProtection,TechSupport,StreamingTV, StreamingMovies,
|
39 |
+
Contract, PaperlessBilling, PaymentMethod, MonthlyCharges, TotalCharges]
|
40 |
+
|
41 |
+
x = np.array([data])
|
42 |
+
dataframe = pd.DataFrame(x, columns=train_features)
|
43 |
+
dataframe = dataframe.astype({'MonthlyCharges': 'float', 'TotalCharges': 'float', 'tenure': 'float'})
|
44 |
+
dataframe_ = create_new_columns(dataframe)
|
45 |
+
try:
|
46 |
+
processed_data = pipeline.transform(dataframe_)
|
47 |
+
except Exception as e:
|
48 |
+
raise gr.gradio('Kindly make sure to check/select all')
|
49 |
+
else:
|
50 |
+
# check_csv(hist_df, dataframe)
|
51 |
+
# history = pd.read_csv(hist_df)
|
52 |
+
|
53 |
+
processed_dataframe = create_processed_dataframe(processed_data, dataframe)
|
54 |
+
predictions = model.predict_proba(processed_dataframe)
|
55 |
+
return round(predictions[0][0], 3), round(predictions[0][1], 3)
|
56 |
+
|
57 |
+
|
58 |
+
|
59 |
+
theme = gr.themes.Default().set(body_background_fill="#0E1117",
|
60 |
+
background_fill_secondary="#FFFFFF",
|
61 |
+
background_fill_primary="#262730",
|
62 |
+
body_text_color="#FF4B4B",
|
63 |
+
checkbox_background_color='#FFFFFF',
|
64 |
+
button_secondary_background_fill="#FF4B4B")
|
65 |
+
|
66 |
+
|
67 |
+
def load_pickle(filename):
|
68 |
+
with open(filename, 'rb') as file:
|
69 |
+
data = pickle.load(file)
|
70 |
+
return data
|
71 |
+
|
72 |
+
pipeline = load_pickle(pipeline_pkl)
|
73 |
+
model = load_pickle(log_reg)
|
74 |
+
|
75 |
+
train_features = ['gender', 'SeniorCitizen', 'Partner', 'Dependents','tenure', 'PhoneService', 'MultipleLines', 'InternetService',
|
76 |
+
'OnlineSecurity', 'OnlineBackup', 'DeviceProtection','TechSupport','StreamingTV', 'StreamingMovies',
|
77 |
+
'Contract', 'PaperlessBilling', 'PaymentMethod', 'MonthlyCharges', 'TotalCharges']
|
78 |
+
|
79 |
+
|
80 |
+
# theme = gr.themes.Base()
|
81 |
+
with gr.Blocks(theme=theme) as demo:
|
82 |
+
gr.HTML("""
|
83 |
+
<h1 style="color:white; text-align:center">Customer Churn Classification App</h1>
|
84 |
+
<h2 style="color:white;">Welcome Cherished User 👋 </h2>
|
85 |
+
<h4 style="color:white;">Start predicting customer churn.</h4>
|
86 |
+
|
87 |
+
""")
|
88 |
+
with gr.Row():
|
89 |
+
gender = gr.Dropdown(label='Gender', choices=['Female', 'Male'])
|
90 |
+
Contract = gr.Dropdown(label='Contract', choices=['Month-to-month', 'One year', 'Two year'])
|
91 |
+
InternetService = gr.Dropdown(label='Internet Service', choices=['DSL', 'Fiber optic', 'No'])
|
92 |
+
|
93 |
+
with gr.Accordion('Yes or no'):
|
94 |
+
|
95 |
+
with gr.Row():
|
96 |
+
OnlineSecurity = gr.Radio(label="Online Security", choices=["Yes", "No", "No internet service"])
|
97 |
+
OnlineBackup = gr.Radio(label="Online Backup", choices=["Yes", "No", "No internet service"])
|
98 |
+
DeviceProtection = gr.Radio(label="Device Protection", choices=["Yes", "No", "No internet service"])
|
99 |
+
TechSupport = gr.Radio(label="Tech Support", choices=["Yes", "No", "No internet service"])
|
100 |
+
StreamingTV = gr.Radio(label="TV Streaming", choices=["Yes", "No", "No internet service"])
|
101 |
+
StreamingMovies = gr.Radio(label="Movie Streaming", choices=["Yes", "No", "No internet service"])
|
102 |
+
with gr.Row():
|
103 |
+
SeniorCitizen = gr.Radio(label="Senior Citizen", choices=["Yes", "No"])
|
104 |
+
Partner = gr.Radio(label="Partner", choices=["Yes", "No"])
|
105 |
+
Dependents = gr.Radio(label="Dependents", choices=["Yes", "No"])
|
106 |
+
PaperlessBilling = gr.Radio(label="Paperless Billing", choices=["Yes", "No"])
|
107 |
+
PhoneService = gr.Radio(label="Phone Service", choices=["Yes", "No"])
|
108 |
+
MultipleLines = gr.Radio(label="Multiple Lines", choices=["No phone service", "Yes", "No"])
|
109 |
+
|
110 |
+
with gr.Row():
|
111 |
+
MonthlyCharges = gr.Number(label="Monthly Charges")
|
112 |
+
TotalCharges = gr.Number(label="Total Charges")
|
113 |
+
Tenure = gr.Number(label='Months of Tenure')
|
114 |
+
PaymentMethod = gr.Dropdown(label="Payment Method", choices=["Electronic check", "Mailed check", "Bank transfer (automatic)", "Credit card (automatic)"])
|
115 |
+
|
116 |
+
submit_button = gr.Button('Prediction')
|
117 |
+
# print(type([[122, 456]]))
|
118 |
+
|
119 |
+
with gr.Row():
|
120 |
+
with gr.Accordion('Churn Prediction'):
|
121 |
+
output1 = gr.Slider(maximum=1,
|
122 |
+
minimum=0,
|
123 |
+
value=0.0,
|
124 |
+
label='Yes')
|
125 |
+
output2 = gr.Slider(maximum=1,
|
126 |
+
minimum=0,
|
127 |
+
value=0.0,
|
128 |
+
label='No')
|
129 |
+
# with gr.Accordion('Input History'):
|
130 |
+
# output3 = gr.Dataframe()
|
131 |
+
|
132 |
+
submit_button.click(fn=predict_churn, inputs=[gender, SeniorCitizen, Partner, Dependents, Tenure, PhoneService, MultipleLines,
|
133 |
+
InternetService, OnlineSecurity, OnlineBackup, DeviceProtection,TechSupport,StreamingTV, StreamingMovies, Contract, PaperlessBilling, PaymentMethod, MonthlyCharges, TotalCharges], outputs=[output1, output2])
|
134 |
+
|
135 |
+
|
136 |
+
# demo = gr.Interface(fn=predict_churn, inputs=[gender, SeniorCitizen, Partner, Dependents, Tenure, PhoneService, MultipleLines,
|
137 |
+
# InternetService, OnlineSecurity, OnlineBackup, DeviceProtection,TechSupport,StreamingTV, StreamingMovies, Contract, PaperlessBilling, PaymentMethod, MonthlyCharges, TotalCharges], outputs=['slider', 'slider'], theme=theme)
|
138 |
+
|
139 |
+
demo.launch(debug=True)
|
full_pipeline.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:8258008cf92ff5e5446c62b85547661f5139b8034dd3408cb61224b44fdf7c1b
|
3 |
+
size 3517
|
history.csv
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gender,SeniorCitizen,Partner,Dependents,PhoneService,MultipleLines,InternetService,OnlineSecurity,OnlineBackup,DeviceProtection,TechSupport,StreamingTV,StreamingMovies,Contract,PaperlessBilling,PaymentMethod,MonthlyCharges,TotalCharges,Monthly Variations,tenure_group
|
2 |
+
Female,Yes,Yes,Yes,No,Yes,Fiber optic,Yes,Yes,Yes,No internet service,Yes,Yes,Month-to-month,No,Bank transfer (automatic),123.0,1345.0,-131.0,12-14
|
3 |
+
Female,Yes,Yes,Yes,No,Yes,Fiber optic,Yes,Yes,Yes,No internet service,Yes,Yes,Month-to-month,No,Bank transfer (automatic),123.0,1345.0,-131.0,12-14
|
4 |
+
Female,Yes,Yes,No,No,Yes,Fiber optic,Yes,Yes,Yes,No internet service,Yes,Yes,Month-to-month,No,Bank transfer (automatic),123.0,5677.0,4201.0,12-14
|
5 |
+
Male,Yes,Yes,Yes,Yes,No phone service,Fiber optic,No internet service,Yes,Yes,No,Yes,No internet service,Two year,Yes,Bank transfer (automatic),123.0,1200.0,-276.0,12-14
|
6 |
+
Male,Yes,No,Yes,No,Yes,Fiber optic,No internet service,Yes,Yes,No,Yes,No internet service,Two year,No,Mailed check,123.0,1200.0,-276.0,12-14
|
7 |
+
Female,No,Yes,Yes,Yes,No phone service,Fiber optic,Yes,Yes,Yes,Yes,No internet service,No internet service,One year,Yes,Credit card (automatic),128.0,1234.0,-1710.0,21-23
|
8 |
+
Female,No,Yes,Yes,Yes,No phone service,Fiber optic,No internet service,No internet service,No internet service,No internet service,No internet service,No internet service,One year,Yes,Credit card (automatic),128.0,1234.0,-1710.0,21-23
|
9 |
+
Female,No,Yes,Yes,Yes,Yes,Fiber optic,No internet service,Yes,Yes,Yes,Yes,Yes,One year,Yes,Credit card (automatic),128.0,1234.0,-1710.0,21-23
|
10 |
+
Male,Yes,Yes,Yes,Yes,No phone service,Fiber optic,No,Yes,No internet service,Yes,Yes,Yes,One year,Yes,Mailed check,120.0,12003.0,10923.0,9-11
|
11 |
+
Female,Yes,Yes,Yes,Yes,Yes,DSL,Yes,Yes,Yes,Yes,No internet service,No internet service,One year,No,Bank transfer (automatic),167.0,2000.0,497.0,9-11
|
logistic_reg_class_model.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:909c3db0e63bc22cacd72f7bd76e53e978f8667b32123fb543ff66831b0e9d1a
|
3 |
+
size 1301
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
matplotlib==3.3.4
|
3 |
+
numpy==1.20.1
|
4 |
+
pandas==1.2.4
|
5 |
+
seaborn==0.11.1
|
6 |
+
scikit-learn==0.24.1
|
utils.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
import pickle
|
4 |
+
import os
|
5 |
+
|
6 |
+
|
7 |
+
|
8 |
+
# DIRPATH = os.path.dirname(os.path.realpath(__file__))
|
9 |
+
|
10 |
+
pipeline_pkl = "full_pipeline.pkl"
|
11 |
+
|
12 |
+
def load_pickle(filename):
|
13 |
+
with open(filename, 'rb') as file:
|
14 |
+
data = pickle.load(file)
|
15 |
+
return data
|
16 |
+
|
17 |
+
preprocessor = load_pickle(pipeline_pkl)
|
18 |
+
|
19 |
+
|
20 |
+
def create_new_columns(train_data):
|
21 |
+
train_data['Monthly Variations'] = (train_data.loc[:, 'TotalCharges']) -((train_data.loc[:, 'tenure'] * train_data.loc[:, 'MonthlyCharges']))
|
22 |
+
labels =['{0}-{1}'.format(i, i+2) for i in range(0, 73, 3)]
|
23 |
+
train_data['tenure_group'] = pd.cut(train_data['tenure'], bins=(range(0, 78, 3)), right=False, labels=labels)
|
24 |
+
train_data.drop(columns=['tenure'], inplace=True)
|
25 |
+
return train_data
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
def create_processed_dataframe(processed_data, train_data):
|
31 |
+
train_num_cols=train_data.select_dtypes(exclude=['object', 'category']).columns
|
32 |
+
cat_features = preprocessor.named_transformers_['categorical']['cat_encoder'].get_feature_names()
|
33 |
+
labels = np.concatenate([train_num_cols, cat_features])
|
34 |
+
processed_dataframe = pd.DataFrame(processed_data.toarray(), columns=labels)
|
35 |
+
return processed_dataframe
|