File size: 2,996 Bytes
1bb2414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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

import gradio as gr
import joblib
import pandas as pd
import shap
import xgboost as xgb
from xgboost import XGBClassifier
import numpy as np
import matplotlib
matplotlib.use('Agg')  
import matplotlib.pyplot as plt
import os

try:
    iso_forest = joblib.load("iso_forest.pkl")
    # Load XGBoost from JSON
    xgb = XGBClassifier()
    xgb.load_model("xgb_fraud.json")  

    # Load training columns
    train_cols = joblib.load("train_columns.pkl")

except FileNotFoundError as e:
    raise FileNotFoundError(f"File missing: {e}. Did you run fraud_model.py?")


explainer = shap.Explainer(xgb, pd.DataFrame(np.zeros((1, len(train_cols))), columns=train_cols))

def predict_fraud(amount, hour, country, merchant_category, is_weekend):
    try:
        amount = float(amount)
        hour = int(hour)
        is_weekend = int(is_weekend)
    except ValueError:
        return " Invalid input: Please enter valid numbers.", None

    input_data = pd.DataFrame({
        "amount": [amount],
        "hour": [hour],
        "is_weekend": [is_weekend],
        "country": [country],
        "merchant_category": [merchant_category]
    })

    input_data['amount_log'] = np.log1p(input_data['amount'])
    input_data = pd.get_dummies(input_data, columns=["country", "merchant_category"])
    input_data = input_data.reindex(columns=train_cols, fill_value=0)

    risk_score = iso_forest.score_samples(input_data)[0]
    prediction = xgb.predict(input_data)[0]

    
    shap_values = explainer(input_data)
    fig, ax = plt.subplots(figsize=(8, 5))
    shap.plots.waterfall(shap_values[0], max_display=6, show=False)
    plt.tight_layout()
    plt.close()

    if prediction == 1:
        return f" FRAUD DETECTED! Anomaly Score: {risk_score:.3f}", fig
    else:
        return f" No Fraud. Anomaly Score: {risk_score:.3f}", fig


# Gradio Interface
with gr.Blocks(title="FraudGuard", theme=gr.themes.Soft()) as demo:
    gr.Markdown("""
    #  FraudGuard  Real-Time Transaction Fraud Detector
    Enter transaction details below. FraudGuard uses AI to detect and **explain** fraud risk.
    """)
    
    with gr.Row():
        amount = gr.Number(label="Transaction Amount ($)", value=100.0)
        hour = gr.Slider(0, 23, step=1, label="Hour of Day", value=14)
        country = gr.Dropdown(["US", "Nigeria", "Russia", "China", "UK"], label="Country", value="US")
        merchant_category = gr.Dropdown(["Retail", "Health", "Crypto", "Gambling", "Travel"], 
                                        label="Merchant Category", value="Retail")
        is_weekend = gr.Checkbox(label="Is Weekend?")
    
    output = gr.Textbox(label="Risk Status")
    explanation = gr.Plot(label="Why This Decision? (SHAP Explanation)")
    
    submit_btn = gr.Button(" Analyze Transaction")
    submit_btn.click(
        fn=predict_fraud,
        inputs=[amount, hour, country, merchant_category, is_weekend],
        outputs=[output, explanation]
    )

if __name__ == "__main__":
    demo.launch(share=True)