GenAICoder commited on
Commit
9366f7a
·
verified ·
1 Parent(s): bd0729b

Update appv1.py

Browse files
Files changed (1) hide show
  1. appv1.py +390 -50
appv1.py CHANGED
@@ -1,111 +1,451 @@
 
 
1
  import pandas as pd
2
  import gradio as gr
3
 
4
- from analytics.monitoring_analysis import generate_monitoring_table
 
 
5
 
6
- from helper.vintage_helpers import(
7
  create_booking_vintage
8
  )
9
 
10
- from helper.data_merger import(
11
  merge_acq_perf
12
  )
13
 
 
 
 
 
14
  from metrics.mix_metrics import (
15
- calculate_count_mix,
16
  calculate_limit_mix
17
  )
18
 
19
- # ------------------------
20
- # Load Data
21
- # ------------------------
22
- acq = pd.read_csv("data/acquisition.csv")
23
- perf = pd.read_csv("data/performance.csv")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- acq= create_booking_vintage(
26
  acq,
27
  booking_date_col="booking_date"
28
  )
29
 
30
- perf = merge_acq_perf(
31
- acq,
32
- perf
 
 
 
 
33
  )
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- # ------------------------
37
- # Core Engine
38
- # ------------------------
39
- def run_analysis(dataset, analysis_type, group_col):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  if dataset == "Acquisition":
42
 
43
- df = acq
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
- if analysis_type == "Count Mix":
46
- return calculate_count_mix(df, group_col)
47
 
48
- elif analysis_type == "Limit Mix":
49
- return calculate_limit_mix(df, group_col)
 
50
 
51
- else:
52
- return "Invalid analysis type for Acquisition dataset"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  elif dataset == "Performance":
55
 
56
- df = perf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
- if analysis_type == "Vintage Monitoring Table":
59
- return generate_monitoring_table(df)
60
 
61
- else:
62
- return "Invalid analysis type for Performance dataset"
 
 
63
 
64
  else:
65
- return "Invalid dataset selection"
66
 
 
 
 
 
 
67
 
68
- # ------------------------
69
- # Gradio UI
70
- # ------------------------
71
  with gr.Blocks() as app:
72
 
73
- gr.Markdown("# 📊 Risk Analytics Manager Agent (V1)")
 
 
74
 
75
  with gr.Row():
76
 
77
- dataset = gr.Dropdown(
78
- choices=["Acquisition", "Performance"],
79
- label="Select Dataset"
 
 
 
 
80
  )
81
 
82
- analysis_type = gr.Dropdown(
83
  choices=[
84
- "Count Mix",
85
- "Limit Mix",
86
- "Vintage Monitoring Table"
87
  ],
88
- label="Select Analysis"
 
89
  )
90
 
91
- group_col = gr.Dropdown(
92
  choices=[
93
- "sourcing_channel",
94
  "fico_band",
 
95
  "city_tier",
96
  "occupation_type"
97
  ],
98
- label="Group Column (for Mix)"
 
99
  )
100
 
101
- run_btn = gr.Button("Run Analysis")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
- output = gr.Dataframe()
104
 
105
- run_btn.click(
106
  fn=run_analysis,
107
- inputs=[dataset, analysis_type, group_col],
108
- outputs=output
 
 
 
 
109
  )
110
 
111
  app.launch()
 
1
+ # app.py
2
+
3
  import pandas as pd
4
  import gradio as gr
5
 
6
+ # ---------------------------------------------------
7
+ # HELPERS
8
+ # ---------------------------------------------------
9
 
10
+ from helper.vintage_helpers import (
11
  create_booking_vintage
12
  )
13
 
14
+ from helper.data_merger import (
15
  merge_acq_perf
16
  )
17
 
18
+ # ---------------------------------------------------
19
+ # METRICS
20
+ # ---------------------------------------------------
21
+
22
  from metrics.mix_metrics import (
23
+ calculate_vintage_mix,
24
  calculate_limit_mix
25
  )
26
 
27
+ # ---------------------------------------------------
28
+ # ANALYTICS
29
+ # ---------------------------------------------------
30
+
31
+ from analytics.performance_analysis import (
32
+ generate_metric_view
33
+ )
34
+
35
+ # ---------------------------------------------------
36
+ # LOAD DATA
37
+ # ---------------------------------------------------
38
+
39
+ acq = pd.read_csv(
40
+ "data/acquisition.csv"
41
+ )
42
+
43
+ perf = pd.read_csv(
44
+ "data/performance.csv"
45
+ )
46
+
47
+ # ---------------------------------------------------
48
+ # CREATE BOOKING VINTAGE
49
+ # ---------------------------------------------------
50
 
51
+ acq = create_booking_vintage(
52
  acq,
53
  booking_date_col="booking_date"
54
  )
55
 
56
+ # ---------------------------------------------------
57
+ # CREATE MASTER PERFORMANCE DATASET
58
+ # ---------------------------------------------------
59
+
60
+ master_df = merge_acq_perf(
61
+ acq_df=acq,
62
+ perf_df=perf
63
  )
64
 
65
+ # ---------------------------------------------------
66
+ # ACQUISITION ANALYSIS
67
+ # ---------------------------------------------------
68
+
69
+ def run_acquisition_analysis(
70
+ analysis_type,
71
+ category
72
+ ):
73
+
74
+ # -----------------------------------------
75
+ # PORTFOLIO MIX
76
+ # -----------------------------------------
77
+
78
+ if analysis_type == "Portfolio Mix":
79
+
80
+ result = (
81
+ acq.groupby(
82
+ ["booking_vintage", category]
83
+ )
84
+ .agg(
85
+ count=("account_id", "nunique"),
86
+ balance=("credit_limit", "sum")
87
+ )
88
+ .reset_index()
89
+ )
90
+
91
+ vintage_total = (
92
+ result.groupby("booking_vintage")["count"]
93
+ .transform("sum")
94
+ )
95
+
96
+ result["rate"] = (
97
+ result["count"] / vintage_total
98
+ ) * 100
99
+
100
+ result["rate"] = (
101
+ result["rate"]
102
+ .round(2)
103
+ )
104
+
105
+ # -----------------------------------------
106
+ # CREDIT LINE CONCENTRATION
107
+ # -----------------------------------------
108
+
109
+ elif analysis_type == "Credit Line Concentration":
110
+
111
+ result = (
112
+ acq.groupby(
113
+ ["booking_vintage", category]
114
+ )
115
+ .agg(
116
+ count=("account_id", "nunique"),
117
+ balance=("credit_limit", "sum")
118
+ )
119
+ .reset_index()
120
+ )
121
+
122
+ vintage_total = (
123
+ result.groupby("booking_vintage")["balance"]
124
+ .transform("sum")
125
+ )
126
+
127
+ result["rate"] = (
128
+ result["balance"] / vintage_total
129
+ ) * 100
130
+
131
+ result["rate"] = (
132
+ result["rate"]
133
+ .round(2)
134
+ )
135
+
136
+ else:
137
+
138
+ return pd.DataFrame()
139
+
140
+ # -----------------------------------------
141
+ # STANDARDIZED OUTPUT
142
+ # -----------------------------------------
143
+
144
+ result = result.rename(
145
+ columns={
146
+ "booking_vintage": "Vintage",
147
+ category: "Category",
148
+ "count": "Count",
149
+ "balance": "Balance",
150
+ "rate": "Rate"
151
+ }
152
+ )
153
+
154
+ return result[
155
+ [
156
+ "Vintage",
157
+ "Category",
158
+ "Count",
159
+ "Balance",
160
+ "Rate"
161
+ ]
162
+ ]
163
+
164
+ # ---------------------------------------------------
165
+ # PERFORMANCE ANALYSIS
166
+ # ---------------------------------------------------
167
+
168
+ def run_performance_analysis(
169
+ metric_name,
170
+ view_level
171
+ ):
172
+
173
+ # -----------------------------------------
174
+ # VIEW MAPPING
175
+ # -----------------------------------------
176
+
177
+ view_mapping = {
178
+
179
+ "Overall": None,
180
+
181
+ "Channel":
182
+ "sourcing_channel",
183
+
184
+ "FICO":
185
+ "fico_band",
186
+
187
+ "City Tier":
188
+ "city_tier",
189
+
190
+ "Occupation":
191
+ "occupation_type"
192
+ }
193
+
194
+ group_col = view_mapping[
195
+ view_level
196
+ ]
197
+
198
+ # -----------------------------------------
199
+ # CALL ANALYTICS ENGINE
200
+ # -----------------------------------------
201
+
202
+ result = generate_metric_view(
203
+ df=master_df,
204
+ metric_name=metric_name,
205
+ group_col=group_col
206
+ )
207
+
208
+ # -----------------------------------------
209
+ # STANDARDIZE OUTPUT
210
+ # -----------------------------------------
211
+
212
+ if group_col is not None:
213
+
214
+ result = result.rename(
215
+ columns={
216
+ group_col: "Category"
217
+ }
218
+ )
219
+
220
+ else:
221
+
222
+ result["Category"] = "Overall"
223
+
224
+ # -----------------------------------------
225
+ # IDENTIFY RATE COLUMN
226
+ # -----------------------------------------
227
+
228
+ rate_col = [
229
+ col for col in result.columns
230
+ if "rate" in col.lower()
231
+ ][0]
232
+
233
+ # -----------------------------------------
234
+ # OUTPUT FORMAT
235
+ # -----------------------------------------
236
 
237
+ final_result = pd.DataFrame()
238
+
239
+ final_result["Vintage"] = (
240
+ result["booking_vintage"]
241
+ )
242
+
243
+ final_result["Category"] = (
244
+ result["Category"]
245
+ )
246
+
247
+ final_result["Count"] = (
248
+ result["total_accounts"]
249
+ )
250
+
251
+ final_result["Balance"] = (
252
+ result["total_balance"]
253
+ )
254
+
255
+ final_result["Rate"] = (
256
+ result[rate_col]
257
+ .round(2)
258
+ )
259
+
260
+ return final_result
261
+
262
+ # ---------------------------------------------------
263
+ # DYNAMIC DROPDOWNS
264
+ # ---------------------------------------------------
265
+
266
+ def update_analysis_dropdown(
267
+ dataset
268
+ ):
269
+
270
+ # -----------------------------------------
271
+ # ACQUISITION
272
+ # -----------------------------------------
273
 
274
  if dataset == "Acquisition":
275
 
276
+ return gr.update(
277
+ choices=[
278
+ "Portfolio Mix",
279
+ "Credit Line Concentration"
280
+ ],
281
+ value="Portfolio Mix"
282
+ )
283
+
284
+ # -----------------------------------------
285
+ # PERFORMANCE
286
+ # -----------------------------------------
287
+
288
+ elif dataset == "Performance":
289
+
290
+ return gr.update(
291
+ choices=[
292
+ "30+@3",
293
+ "30+@6",
294
+ "30+@9",
295
+ "Yr1 NCL"
296
+ ],
297
+ value="30+@6"
298
+ )
299
 
 
 
300
 
301
+ def update_category_dropdown(
302
+ dataset
303
+ ):
304
 
305
+ # -----------------------------------------
306
+ # ACQUISITION
307
+ # -----------------------------------------
308
+
309
+ if dataset == "Acquisition":
310
+
311
+ return gr.update(
312
+ choices=[
313
+ "fico_band",
314
+ "sourcing_channel",
315
+ "city_tier",
316
+ "occupation_type"
317
+ ],
318
+ value="fico_band"
319
+ )
320
+
321
+ # -----------------------------------------
322
+ # PERFORMANCE
323
+ # -----------------------------------------
324
 
325
  elif dataset == "Performance":
326
 
327
+ return gr.update(
328
+ choices=[
329
+ "Overall",
330
+ "Channel",
331
+ "FICO",
332
+ "City Tier",
333
+ "Occupation"
334
+ ],
335
+ value="Overall"
336
+ )
337
+
338
+ # ---------------------------------------------------
339
+ # MASTER ROUTER
340
+ # ---------------------------------------------------
341
+
342
+ def run_analysis(
343
+ dataset,
344
+ analysis,
345
+ category
346
+ ):
347
+
348
+ # -----------------------------------------
349
+ # ACQUISITION
350
+ # -----------------------------------------
351
+
352
+ if dataset == "Acquisition":
353
+
354
+ return run_acquisition_analysis(
355
+ analysis_type=analysis,
356
+ category=category
357
+ )
358
+
359
+ # -----------------------------------------
360
+ # PERFORMANCE
361
+ # -----------------------------------------
362
 
363
+ elif dataset == "Performance":
 
364
 
365
+ return run_performance_analysis(
366
+ metric_name=analysis,
367
+ view_level=category
368
+ )
369
 
370
  else:
 
371
 
372
+ return pd.DataFrame()
373
+
374
+ # ---------------------------------------------------
375
+ # GRADIO UI
376
+ # ---------------------------------------------------
377
 
 
 
 
378
  with gr.Blocks() as app:
379
 
380
+ gr.Markdown(
381
+ "# Risk Analytics Manager Agent"
382
+ )
383
 
384
  with gr.Row():
385
 
386
+ dataset_dropdown = gr.Dropdown(
387
+ choices=[
388
+ "Acquisition",
389
+ "Performance"
390
+ ],
391
+ value="Acquisition",
392
+ label="Dataset"
393
  )
394
 
395
+ analysis_dropdown = gr.Dropdown(
396
  choices=[
397
+ "Portfolio Mix",
398
+ "Credit Line Concentration"
 
399
  ],
400
+ value="Portfolio Mix",
401
+ label="Analysis"
402
  )
403
 
404
+ category_dropdown = gr.Dropdown(
405
  choices=[
 
406
  "fico_band",
407
+ "sourcing_channel",
408
  "city_tier",
409
  "occupation_type"
410
  ],
411
+ value="fico_band",
412
+ label="Category / View"
413
  )
414
 
415
+ # -----------------------------------------
416
+ # DYNAMIC DROPDOWNS
417
+ # -----------------------------------------
418
+
419
+ dataset_dropdown.change(
420
+ fn=update_analysis_dropdown,
421
+ inputs=dataset_dropdown,
422
+ outputs=analysis_dropdown
423
+ )
424
+
425
+ dataset_dropdown.change(
426
+ fn=update_category_dropdown,
427
+ inputs=dataset_dropdown,
428
+ outputs=category_dropdown
429
+ )
430
+
431
+ # -----------------------------------------
432
+ # RUN BUTTON
433
+ # -----------------------------------------
434
+
435
+ run_button = gr.Button(
436
+ "Run Analysis"
437
+ )
438
 
439
+ output_table = gr.Dataframe()
440
 
441
+ run_button.click(
442
  fn=run_analysis,
443
+ inputs=[
444
+ dataset_dropdown,
445
+ analysis_dropdown,
446
+ category_dropdown
447
+ ],
448
+ outputs=output_table
449
  )
450
 
451
  app.launch()