Ujeshhh commited on
Commit
4881b97
·
verified ·
1 Parent(s): c41e114

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -40
app.py CHANGED
@@ -1,57 +1,107 @@
1
- # app.py
2
  import gradio as gr
3
  import pandas as pd
4
- import numpy as np
5
- import pickle
6
- from datetime import datetime
 
7
 
8
- # Load model
9
- with open("anomaly_detector_rf_model.pkl", "rb") as f:
10
- model = pickle.load(f)
11
 
 
 
 
 
 
 
 
 
12
  def detect_anomalies(df):
13
- df["log_amount"] = np.log1p(df["amount"])
14
- df["amount_zscore"] = (df["amount"] - df["amount"].mean()) / df["amount"].std()
15
- df["transaction_date"] = pd.to_datetime(df["transaction_date"])
16
- df["day_of_week"] = df["transaction_date"].dt.dayofweek
17
- df["hour"] = df["transaction_date"].dt.hour
18
- df["is_weekend"] = df["day_of_week"].isin([5, 6]).astype(int)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- features = ["amount", "log_amount", "amount_zscore", "day_of_week", "hour", "is_weekend"]
21
- df["is_anomalous"] = model.predict(df[features])
 
 
 
22
 
23
- anomalies = df[df["is_anomalous"] == 1][["transaction_id", "amount", "merchant", "location", "transaction_date"]]
 
 
 
 
 
24
 
25
- # Save anomalies to CSV
26
- csv_path = "/tmp/anomalies.csv"
27
- anomalies.to_csv(csv_path, index=False)
28
 
29
- return anomalies, csv_path
 
 
 
30
 
31
- # Summary function
32
- def generate_summary(df):
33
- total = len(df)
34
- anomalous = df["is_anomalous"].sum()
35
- return f"Total Transactions: {total} | 🚨 Anomalies: {anomalous} | ⚠️ Rate: {anomalous/total:.2%}"
36
 
37
- # Gradio UI
38
- with gr.Blocks() as app:
39
- gr.Markdown("## 💸 Financial Transaction Anomaly Detector")
40
- gr.Markdown("Upload your CSV with columns: `transaction_id`, `amount`, `merchant`, `location`, `transaction_date`")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  with gr.Row():
43
- file_input = gr.File(file_types=[".csv"], label="📁 Upload Transaction File")
44
- download_button = gr.File(label="⬇️ Download Anomalies CSV")
45
 
46
- summary_text = gr.Textbox(label="📊 Summary", interactive=False)
47
- output_table = gr.Dataframe(label="🚨 Detected Anomalies")
 
48
 
49
- def app_interface(file):
50
- df = pd.read_csv(file.name)
51
- anomalies, csv_path = detect_anomalies(df)
52
- summary = generate_summary(df)
53
- return summary, anomalies, csv_path
54
 
55
- file_input.change(fn=app_interface, inputs=[file_input], outputs=[summary_text, output_table, download_button])
 
56
 
57
- app.launch()
 
 
1
  import gradio as gr
2
  import pandas as pd
3
+ import joblib
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ import io
7
 
8
+ # Load trained model
9
+ model = joblib.load("anomaly_detector_rf_model.pkl")
 
10
 
11
+ # Features used during training
12
+ feature_cols = [
13
+ "amount", "hour", "day_of_week", "is_weekend", "merchant_avg_amount",
14
+ "amount_zscore", "log_amount", "type_atm_withdrawal", "type_credit",
15
+ "type_debit", "merchant_encoded"
16
+ ]
17
+
18
+ # Function to detect anomalies
19
  def detect_anomalies(df):
20
+ original_df = df.copy()
21
+
22
+ for col in ["transaction_id", "merchant", "location", "amount"]:
23
+ if col not in original_df.columns:
24
+ original_df[col] = "N/A" if col != "amount" else 0.0
25
+
26
+ model_input = df.reindex(columns=feature_cols, fill_value=0)
27
+ preds = model.predict(model_input)
28
+ original_df["is_anomalous"] = preds
29
+
30
+ anomalies = original_df[original_df["is_anomalous"] == 1]
31
+ return original_df, anomalies[["transaction_id", "merchant", "location", "amount", "is_anomalous"]]
32
+
33
+ # Function to plot charts
34
+ def plot_charts(df):
35
+ fig, axes = plt.subplots(2, 2, figsize=(12, 10))
36
+
37
+ if "amount" in df.columns:
38
+ sns.histplot(df["amount"], bins=30, kde=True, ax=axes[0, 0])
39
+ axes[0, 0].set_title("Amount Distribution")
40
+ sns.boxplot(x=df["amount"], ax=axes[0, 1])
41
+ axes[0, 1].set_title("Amount Box Plot")
42
+ else:
43
+ axes[0, 0].text(0.5, 0.5, "No 'amount' column", ha='center')
44
+ axes[0, 1].text(0.5, 0.5, "No 'amount' column", ha='center')
45
 
46
+ if "day_of_week" in df.columns:
47
+ sns.countplot(x=df["day_of_week"], ax=axes[1, 0])
48
+ axes[1, 0].set_title("Transactions by Day of Week")
49
+ else:
50
+ axes[1, 0].text(0.5, 0.5, "No 'day_of_week' column", ha='center')
51
 
52
+ if "merchant" in df.columns:
53
+ top_merchants = df.groupby("merchant")["amount"].sum().nlargest(5).reset_index()
54
+ sns.barplot(data=top_merchants, x="merchant", y="amount", ax=axes[1, 1])
55
+ axes[1, 1].set_title("Top 5 Merchants by Amount")
56
+ else:
57
+ axes[1, 1].text(0.5, 0.5, "No 'merchant' column", ha='center')
58
 
59
+ plt.tight_layout()
60
+ return fig
 
61
 
62
+ # Function to generate summary + charts + file
63
+ def app_interface(csv_file):
64
+ df = pd.read_csv(csv_file)
65
+ full_df, anomalies = detect_anomalies(df)
66
 
67
+ total = len(full_df)
68
+ anom_count = len(anomalies)
69
+ percent = (anom_count / total) * 100 if total > 0 else 0
 
 
70
 
71
+ summary = (
72
+ f"🔢 **Total Transactions**: {total}\n"
73
+ f"⚠️ **Anomalies Detected**: {anom_count}\n"
74
+ f"📊 **Anomaly Percentage**: {percent:.2f}%"
75
+ )
76
+
77
+ # Convert anomalies to CSV bytes for download
78
+ csv_bytes = anomalies.to_csv(index=False).encode()
79
+ download = io.BytesIO(csv_bytes)
80
+
81
+ fig = plot_charts(full_df)
82
+
83
+ return summary, anomalies, fig, download
84
+
85
+ # Gradio App with UI
86
+ with gr.Blocks(theme=gr.themes.Soft()) as interface:
87
+ gr.Markdown("# 🛡️ Financial Abuse & Anomaly Detection App")
88
+ gr.Markdown("Upload your **transaction CSV** to detect anomalies and view insights.")
89
+
90
+ with gr.Row():
91
+ file_input = gr.File(label="📁 Upload CSV File", file_types=[".csv"])
92
+ detect_button = gr.Button("🚨 Run Detection", variant="primary")
93
 
94
  with gr.Row():
95
+ summary_box = gr.Markdown("")
 
96
 
97
+ with gr.Tab("��� Anomalies Detected"):
98
+ result_table = gr.Dataframe(label="🔴 Anomalies")
99
+ download_btn = gr.File(label="⬇️ Download Detected Anomalies")
100
 
101
+ with gr.Tab("📊 Transaction Charts"):
102
+ chart_output = gr.Plot()
 
 
 
103
 
104
+ detect_button.click(fn=app_interface, inputs=file_input,
105
+ outputs=[summary_box, result_table, chart_output, download_btn])
106
 
107
+ interface.launch(share=True)