Akki2228 commited on
Commit
308d819
Β·
verified Β·
1 Parent(s): c2380b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +189 -87
app.py CHANGED
@@ -1,12 +1,13 @@
1
  import gradio as gr
2
  import pickle
3
  import numpy as np
 
4
  import matplotlib.pyplot as plt
5
  import matplotlib
6
  matplotlib.use("Agg")
7
 
8
  # =========================
9
- # Load model
10
  # =========================
11
  try:
12
  with open("DecisionTreeClassifier.pkl", "rb") as f:
@@ -14,18 +15,116 @@ try:
14
  except:
15
  model = None
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  # =========================
19
- # Prediction + Full Analysis
20
  # =========================
21
- def analyze_customer(age, gender, tenure, usage, support, delay,
22
- subscription, contract, spend, interaction):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  try:
25
  if model is None:
26
- return "Model not loaded ❌", "", "", None, None, None
27
 
28
- # Encoding
29
  gender_val = 1 if gender == "Female" else 0
30
 
31
  sub_premium = 1 if subscription == "Premium" else 0
@@ -50,7 +149,6 @@ def analyze_customer(age, gender, tenure, usage, support, delay,
50
 
51
  result = "⚠️ Likely to Churn" if pred == 1 else "βœ… Stable Customer"
52
 
53
- # Risk level
54
  if prob > 0.7:
55
  risk = "πŸ”΄ High Risk"
56
  elif prob > 0.4:
@@ -58,51 +156,14 @@ def analyze_customer(age, gender, tenure, usage, support, delay,
58
  else:
59
  risk = "🟒 Low Risk"
60
 
61
- # =========================
62
- # πŸ“Š Chart 1: Probability
63
- # =========================
64
- fig1, ax1 = plt.subplots()
65
- ax1.bar(["No Churn", "Churn"], [1-prob, prob])
66
- ax1.set_ylim(0, 1)
67
- ax1.set_title("Churn Probability")
68
- plt.close(fig1)
69
-
70
- # =========================
71
- # πŸ“Š Chart 2: Feature Values
72
- # =========================
73
- features = [
74
- "Age","Tenure","Usage","Support",
75
- "Delay","Spend","Interaction"
76
- ]
77
- values = [
78
- age, tenure, usage, support,
79
- delay, spend, interaction
80
- ]
81
-
82
- fig2, ax2 = plt.subplots()
83
- ax2.barh(features, values)
84
- ax2.set_title("Customer Profile")
85
- plt.close(fig2)
86
-
87
- # =========================
88
- # πŸ“Š Chart 3: Risk Indicators
89
- # =========================
90
- risk_scores = [
91
- delay/30,
92
- support/20,
93
- (6-tenure)/6 if tenure < 6 else 0
94
- ]
95
-
96
- labels = ["Payment Delay", "Support Calls", "Low Tenure"]
97
-
98
- fig3, ax3 = plt.subplots()
99
- ax3.bar(labels, risk_scores)
100
- ax3.set_title("Risk Factors")
101
- plt.close(fig3)
102
-
103
- # =========================
104
- # 🧠 Explanation
105
- # =========================
106
  reasons = []
107
  if delay > 15: reasons.append("High payment delay")
108
  if tenure < 6: reasons.append("Low tenure")
@@ -110,54 +171,95 @@ def analyze_customer(age, gender, tenure, usage, support, delay,
110
 
111
  explanation = "\n".join(reasons) if reasons else "No strong risk indicators"
112
 
113
- return result, f"{prob*100:.2f}%", risk, fig1, fig2, fig3, explanation
114
 
115
  except Exception as e:
116
- return f"Error: {str(e)}", "", "", None, None, None, ""
117
-
118
 
119
  # =========================
120
- # UI
121
  # =========================
122
  with gr.Blocks() as demo:
123
 
124
- gr.Markdown("# πŸš€ Customer Churn Interactive Analyzer")
125
-
126
- with gr.Row():
127
- with gr.Column():
128
- age = gr.Slider(18, 80, value=30, label="Age")
129
- gender = gr.Radio(["Male", "Female"], value="Male")
130
- tenure = gr.Slider(0, 60, value=12, label="Tenure")
131
- usage = gr.Slider(0, 50, value=10, label="Usage")
132
-
133
- with gr.Column():
134
- support = gr.Slider(0, 20, value=2, label="Support Calls")
135
- delay = gr.Slider(0, 30, value=5, label="Payment Delay")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  subscription = gr.Radio(["Basic","Standard","Premium"], value="Basic")
137
  contract = gr.Radio(["Monthly","Quarterly","Yearly"], value="Monthly")
138
 
139
- spend = gr.Slider(0, 10000, value=2000)
140
- interaction = gr.Slider(0, 100, value=20)
141
-
142
- btn = gr.Button("Analyze Customer")
143
 
144
- gr.Markdown("## πŸ“Š Results")
145
 
146
- result = gr.Textbox(label="Prediction")
147
- prob = gr.Textbox(label="Probability")
148
- risk = gr.Textbox(label="Risk Level")
 
 
149
 
150
- graph1 = gr.Plot(label="Churn Probability")
151
- graph2 = gr.Plot(label="Customer Profile")
152
- graph3 = gr.Plot(label="Risk Factors")
 
 
 
153
 
154
- explanation = gr.Textbox(label="Why this prediction?")
155
-
156
- btn.click(
157
- analyze_customer,
158
- inputs=[age, gender, tenure, usage, support, delay,
159
- subscription, contract, spend, interaction],
160
- outputs=[result, prob, risk, graph1, graph2, graph3, explanation]
161
- )
162
 
 
 
 
163
  demo.launch(debug=True)
 
1
  import gradio as gr
2
  import pickle
3
  import numpy as np
4
+ import pandas as pd
5
  import matplotlib.pyplot as plt
6
  import matplotlib
7
  matplotlib.use("Agg")
8
 
9
  # =========================
10
+ # πŸ”Ή Load Model
11
  # =========================
12
  try:
13
  with open("DecisionTreeClassifier.pkl", "rb") as f:
 
15
  except:
16
  model = None
17
 
18
+ # =========================
19
+ # πŸ”Ή Load Dataset (REAL or DUMMY)
20
+ # =========================
21
+ try:
22
+ data = pd.read_csv("churn_data.csv") # πŸ”₯ Replace with your dataset
23
+ except:
24
+ # fallback dummy dataset
25
+ np.random.seed(42)
26
+ data = pd.DataFrame({
27
+ "gender": np.random.choice(["Male","Female"], 300),
28
+ "tenure": np.random.randint(1, 60, 300),
29
+ "MonthlyCharges": np.random.randint(500, 8000, 300),
30
+ "Contract": np.random.choice(["Monthly","Quarterly","Yearly"], 300),
31
+ "Churn": np.random.choice([0,1], 300)
32
+ })
33
+
34
+ # =========================
35
+ # πŸ”Ή KPI FUNCTION
36
+ # =========================
37
+ def get_kpis(df):
38
+ total = len(df)
39
+ churn_rate = df["Churn"].mean() * 100
40
+ avg_spend = df["MonthlyCharges"].mean()
41
+ avg_tenure = df["tenure"].mean()
42
+
43
+ return f"""
44
+ ### πŸ“Š Key Metrics
45
+ - Total Customers: **{total}**
46
+ - Churn Rate: **{churn_rate:.2f}%**
47
+ - Avg Spend: **β‚Ή{avg_spend:.0f}**
48
+ - Avg Tenure: **{avg_tenure:.1f} months**
49
+ """
50
 
51
  # =========================
52
+ # πŸ”Ή FILTER FUNCTION
53
  # =========================
54
+ def apply_filters(gender, contract):
55
+ df = data.copy()
56
+
57
+ if gender != "All":
58
+ df = df[df["gender"] == gender]
59
+
60
+ if contract != "All":
61
+ df = df[df["Contract"] == contract]
62
+
63
+ return df
64
+
65
+ # =========================
66
+ # πŸ”Ή CHARTS
67
+ # =========================
68
+ def churn_dist(df):
69
+ fig, ax = plt.subplots()
70
+ counts = df["Churn"].value_counts()
71
+ ax.bar(["No Churn","Churn"], counts)
72
+ ax.set_title("Churn Distribution")
73
+ plt.close(fig)
74
+ return fig
75
+
76
+ def contract_chart(df):
77
+ fig, ax = plt.subplots()
78
+ pd.crosstab(df["Contract"], df["Churn"]).plot(kind="bar", ax=ax)
79
+ ax.set_title("Churn by Contract")
80
+ plt.close(fig)
81
+ return fig
82
+
83
+ def tenure_chart(df):
84
+ fig, ax = plt.subplots()
85
+ ax.scatter(df["tenure"], df["Churn"])
86
+ ax.set_title("Tenure vs Churn")
87
+ plt.close(fig)
88
+ return fig
89
+
90
+ def risk_pie(df):
91
+ fig, ax = plt.subplots()
92
+ counts = df["Churn"].value_counts()
93
+ ax.pie(counts, labels=["No Churn","Churn"], autopct="%1.1f%%")
94
+ ax.set_title("Risk Segmentation")
95
+ plt.close(fig)
96
+ return fig
97
+
98
+ # =========================
99
+ # πŸ”Ή FEATURE IMPORTANCE
100
+ # =========================
101
+ def feature_importance():
102
+ if model is None or not hasattr(model, "feature_importances_"):
103
+ return None
104
+
105
+ features = [
106
+ "age","gender","tenure","usage","support","delay",
107
+ "spend","interaction",
108
+ "sub_premium","sub_standard",
109
+ "contract_monthly","contract_quarterly"
110
+ ]
111
+
112
+ fig, ax = plt.subplots()
113
+ ax.barh(features, model.feature_importances_)
114
+ ax.set_title("Feature Importance")
115
+ plt.close(fig)
116
+ return fig
117
+
118
+ # =========================
119
+ # πŸ”Ή PREDICTION
120
+ # =========================
121
+ def predict_churn(age, gender, tenure, usage, support, delay,
122
+ subscription, contract, spend, interaction):
123
 
124
  try:
125
  if model is None:
126
+ return "Model not loaded ❌", "", "", None, ""
127
 
 
128
  gender_val = 1 if gender == "Female" else 0
129
 
130
  sub_premium = 1 if subscription == "Premium" else 0
 
149
 
150
  result = "⚠️ Likely to Churn" if pred == 1 else "βœ… Stable Customer"
151
 
 
152
  if prob > 0.7:
153
  risk = "πŸ”΄ High Risk"
154
  elif prob > 0.4:
 
156
  else:
157
  risk = "🟒 Low Risk"
158
 
159
+ # probability chart
160
+ fig, ax = plt.subplots()
161
+ ax.bar(["No Churn","Churn"], [1-prob, prob])
162
+ ax.set_ylim(0,1)
163
+ ax.set_title("Prediction Probability")
164
+ plt.close(fig)
165
+
166
+ # explanation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  reasons = []
168
  if delay > 15: reasons.append("High payment delay")
169
  if tenure < 6: reasons.append("Low tenure")
 
171
 
172
  explanation = "\n".join(reasons) if reasons else "No strong risk indicators"
173
 
174
+ return result, f"{prob*100:.2f}%", risk, fig, explanation
175
 
176
  except Exception as e:
177
+ return f"Error: {str(e)}", "", "", None, ""
 
178
 
179
  # =========================
180
+ # 🎨 UI
181
  # =========================
182
  with gr.Blocks() as demo:
183
 
184
+ gr.Markdown("# πŸš€ Customer Churn Analytics Dashboard")
185
+
186
+ # ---------------------
187
+ # πŸ“Š DASHBOARD TAB
188
+ # ---------------------
189
+ with gr.Tab("πŸ“Š Dashboard"):
190
+
191
+ gender_filter = gr.Dropdown(["All","Male","Female"], value="All", label="Filter by Gender")
192
+ contract_filter = gr.Dropdown(["All","Monthly","Quarterly","Yearly"], value="All", label="Filter by Contract")
193
+
194
+ kpi_text = gr.Markdown()
195
+ chart1 = gr.Plot()
196
+ chart2 = gr.Plot()
197
+ chart3 = gr.Plot()
198
+ chart4 = gr.Plot()
199
+
200
+ def update_dashboard(g, c):
201
+ df = apply_filters(g, c)
202
+ return (
203
+ get_kpis(df),
204
+ churn_dist(df),
205
+ contract_chart(df),
206
+ tenure_chart(df),
207
+ risk_pie(df)
208
+ )
209
+
210
+ gender_filter.change(update_dashboard, [gender_filter, contract_filter],
211
+ [kpi_text, chart1, chart2, chart3, chart4])
212
+
213
+ contract_filter.change(update_dashboard, [gender_filter, contract_filter],
214
+ [kpi_text, chart1, chart2, chart3, chart4])
215
+
216
+ # initial load
217
+ demo.load(update_dashboard, [gender_filter, contract_filter],
218
+ [kpi_text, chart1, chart2, chart3, chart4])
219
+
220
+ # ---------------------
221
+ # πŸ” PREDICTION TAB
222
+ # ---------------------
223
+ with gr.Tab("πŸ” Prediction"):
224
+
225
+ with gr.Row():
226
+ age = gr.Slider(18,80,value=30)
227
+ gender = gr.Radio(["Male","Female"], value="Male")
228
+ tenure = gr.Slider(0,60,value=12)
229
+ usage = gr.Slider(0,50,value=10)
230
+
231
+ with gr.Row():
232
+ support = gr.Slider(0,20,value=2)
233
+ delay = gr.Slider(0,30,value=5)
234
  subscription = gr.Radio(["Basic","Standard","Premium"], value="Basic")
235
  contract = gr.Radio(["Monthly","Quarterly","Yearly"], value="Monthly")
236
 
237
+ spend = gr.Slider(0,10000,value=2000)
238
+ interaction = gr.Slider(0,100,value=20)
 
 
239
 
240
+ btn = gr.Button("Predict")
241
 
242
+ result = gr.Textbox(label="Prediction")
243
+ prob = gr.Textbox(label="Probability")
244
+ risk = gr.Textbox(label="Risk Level")
245
+ graph = gr.Plot()
246
+ explanation = gr.Textbox(label="Why this prediction?")
247
 
248
+ btn.click(
249
+ predict_churn,
250
+ inputs=[age, gender, tenure, usage, support, delay,
251
+ subscription, contract, spend, interaction],
252
+ outputs=[result, prob, risk, graph, explanation]
253
+ )
254
 
255
+ # ---------------------
256
+ # πŸ“ˆ INSIGHTS TAB
257
+ # ---------------------
258
+ with gr.Tab("πŸ“ˆ Insights"):
259
+ gr.Markdown("### Feature Importance")
260
+ gr.Plot(feature_importance())
 
 
261
 
262
+ # =========================
263
+ # πŸš€ LAUNCH
264
+ # =========================
265
  demo.launch(debug=True)