File size: 6,867 Bytes
33a31e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
"""
Lead.AI Fraud Shield β€” Live Demo
Explainable AI fraud detection for small business transactions.
Visit https://www.lead-ai.us for a custom deployment.
"""

import gradio as gr
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
import warnings
warnings.filterwarnings("ignore")

# ── Train a demo model on synthetic data ─────────────────────────────────────
np.random.seed(42)
n = 2000

amounts     = np.concatenate([np.random.uniform(1, 500, 1700), np.random.uniform(500, 5000, 300)])
hours       = np.concatenate([np.random.randint(8, 22, 1700), np.random.randint(0, 6, 300)])
freq_7d     = np.concatenate([np.random.randint(1, 8, 1700), np.random.randint(10, 30, 300)])
is_new      = np.concatenate([np.random.binomial(1, 0.2, 1700), np.random.binomial(1, 0.8, 300)])
intl        = np.concatenate([np.random.binomial(1, 0.05, 1700), np.random.binomial(1, 0.6, 300)])
labels      = np.concatenate([np.zeros(1700), np.ones(300)])

X = np.column_stack([amounts, hours, freq_7d, is_new, intl])
y = labels

model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X, y)

MERCHANT_TYPES = ["Retail", "Restaurant", "Online Store", "Gas Station",
                  "ATM / Cash", "Subscription Service", "Unknown"]

RISK_REASONS = {
    "amount":   ("Amount is unusually high for this merchant type",
                 "Transaction amount is within normal range"),
    "hour":     ("Transaction occurred outside normal business hours",
                 "Transaction time is within normal hours"),
    "freq_7d":  ("Unusually high transaction frequency in the last 7 days",
                 "Transaction frequency is normal"),
    "is_new":   ("Payment method was registered recently",
                 "Established payment method with history"),
    "intl":     ("International transaction detected",
                 "Domestic transaction"),
}

def analyze_transaction(amount, merchant_type, hour, freq_7d, is_new_card, is_international):
    features = np.array([[amount, hour, freq_7d,
                          int(is_new_card), int(is_international)]])
    prob      = model.predict_proba(features)[0][1]
    risk_pct  = round(prob * 100, 1)

    if risk_pct < 25:
        level, color, verdict = "LOW", "🟒", "APPROVED"
    elif risk_pct < 60:
        level, color, verdict = "MEDIUM", "🟑", "REVIEW RECOMMENDED"
    else:
        level, color, verdict = "HIGH", "πŸ”΄", "FLAG FOR INVESTIGATION"

    # Plain-English explanation
    thresholds = {
        "amount":  (amount > 800,   amount,    "$"),
        "hour":    (hour < 6 or hour > 22, hour, "h"),
        "freq_7d": (freq_7d > 8,    freq_7d,   " txns/7d"),
        "is_new":  (is_new_card,    "",        ""),
        "intl":    (is_international, "",      ""),
    }

    flags, clears = [], []
    for key, (triggered, val, unit) in thresholds.items():
        if triggered:
            flags.append(f"⚠️  {RISK_REASONS[key][0]}")
        else:
            clears.append(f"βœ“  {RISK_REASONS[key][1]}")

    explanation  = f"## {color} Risk Level: {level} ({risk_pct}%)\n\n"
    explanation += f"**Verdict: {verdict}**\n\n"
    explanation += "---\n\n"
    explanation += "### Why This Score?\n\n"

    if flags:
        explanation += "**Risk Factors Detected:**\n"
        explanation += "\n".join(flags) + "\n\n"
    if clears:
        explanation += "**Factors Within Normal Range:**\n"
        explanation += "\n".join(clears) + "\n\n"

    explanation += "---\n\n"
    explanation += "> ⚠️ This is a demo system. "
    explanation += "Your production Lead.AI Fraud Shield will be trained on your actual transaction history.\n\n"
    explanation += "**[β†’ Get a Custom Fraud Shield for Your Business](https://www.lead-ai.us)**"

    bar = f"Risk Score: {'β–ˆ' * int(risk_pct // 5)}{'β–‘' * (20 - int(risk_pct // 5))} {risk_pct}%"
    return bar, explanation


# ── Gradio UI ─────────────────────────────────────────────────────────────────
with gr.Blocks(
    title="Lead.AI Fraud Shield",
    theme=gr.themes.Soft(primary_hue="red"),
    css=".footer { text-align:center; margin-top:20px; color:#666; }"
) as demo:

    gr.Markdown("""
# πŸ›‘ Lead.AI Fraud Shield
### Explainable AI Fraud Detection for Small Businesses

Enter a transaction below. The AI will score it for risk and explain exactly why β€” in plain English.

> πŸ’Ό This is a live proof-of-concept. [Request a custom system β†’](https://www.lead-ai.us)
""")

    with gr.Row():
        with gr.Column():
            gr.Markdown("### Transaction Details")
            amount       = gr.Slider(1, 5000, value=120, step=1,
                                     label="Transaction Amount ($)")
            merchant     = gr.Dropdown(MERCHANT_TYPES, value="Retail",
                                       label="Merchant Type")
            hour         = gr.Slider(0, 23, value=14, step=1,
                                     label="Hour of Day (0=midnight, 14=2pm)")
            freq_7d_in   = gr.Slider(1, 30, value=3, step=1,
                                     label="Transactions in Last 7 Days (same card)")
            is_new_card  = gr.Checkbox(label="New Payment Method (registered < 7 days ago)")
            is_intl      = gr.Checkbox(label="International Transaction")
            btn          = gr.Button("πŸ” Analyze Transaction", variant="primary", size="lg")

        with gr.Column():
            gr.Markdown("### AI Analysis")
            score_bar  = gr.Textbox(label="Risk Score", lines=1)
            result_md  = gr.Markdown()

    btn.click(
        fn=analyze_transaction,
        inputs=[amount, merchant, hour, freq_7d_in, is_new_card, is_intl],
        outputs=[score_bar, result_md],
    )

    gr.Examples(
        examples=[
            [4800, "ATM / Cash",       2,  18, True,  True],
            [45,   "Restaurant",       12,  2, False, False],
            [299,  "Online Store",     20,  5, False, False],
            [1500, "Unknown",           3, 15, True,  True],
        ],
        inputs=[amount, merchant, hour, freq_7d_in, is_new_card, is_intl],
        label="Try These Examples",
    )

    gr.Markdown("""
---
<div class="footer">
🌐 <a href="https://www.lead-ai.us">www.lead-ai.us</a> &nbsp;|&nbsp;
πŸ’» <a href="https://github.com/Lead-AI-US/lead-ai-fraud-shield">GitHub</a> &nbsp;|&nbsp;
πŸ€— <a href="https://huggingface.co/lead-ai-labs">Hugging Face</a>
<br><br>
<strong>Need this customized for your business?</strong>
<a href="https://www.lead-ai.us">Request a Custom Lead.AI Setup β†’</a>
</div>
""")

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