Spaces:
Sleeping
Sleeping
Upload app.py with huggingface_hub
Browse files
app.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Lead.AI Fraud Shield β Live Demo
|
| 3 |
+
Explainable AI fraud detection for small business transactions.
|
| 4 |
+
Visit https://www.lead-ai.us for a custom deployment.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import gradio as gr
|
| 8 |
+
import numpy as np
|
| 9 |
+
import pandas as pd
|
| 10 |
+
from sklearn.ensemble import RandomForestClassifier
|
| 11 |
+
from sklearn.preprocessing import LabelEncoder
|
| 12 |
+
import warnings
|
| 13 |
+
warnings.filterwarnings("ignore")
|
| 14 |
+
|
| 15 |
+
# ββ Train a demo model on synthetic data βββββββββββββββββββββββββββββββββββββ
|
| 16 |
+
np.random.seed(42)
|
| 17 |
+
n = 2000
|
| 18 |
+
|
| 19 |
+
amounts = np.concatenate([np.random.uniform(1, 500, 1700), np.random.uniform(500, 5000, 300)])
|
| 20 |
+
hours = np.concatenate([np.random.randint(8, 22, 1700), np.random.randint(0, 6, 300)])
|
| 21 |
+
freq_7d = np.concatenate([np.random.randint(1, 8, 1700), np.random.randint(10, 30, 300)])
|
| 22 |
+
is_new = np.concatenate([np.random.binomial(1, 0.2, 1700), np.random.binomial(1, 0.8, 300)])
|
| 23 |
+
intl = np.concatenate([np.random.binomial(1, 0.05, 1700), np.random.binomial(1, 0.6, 300)])
|
| 24 |
+
labels = np.concatenate([np.zeros(1700), np.ones(300)])
|
| 25 |
+
|
| 26 |
+
X = np.column_stack([amounts, hours, freq_7d, is_new, intl])
|
| 27 |
+
y = labels
|
| 28 |
+
|
| 29 |
+
model = RandomForestClassifier(n_estimators=100, random_state=42)
|
| 30 |
+
model.fit(X, y)
|
| 31 |
+
|
| 32 |
+
MERCHANT_TYPES = ["Retail", "Restaurant", "Online Store", "Gas Station",
|
| 33 |
+
"ATM / Cash", "Subscription Service", "Unknown"]
|
| 34 |
+
|
| 35 |
+
RISK_REASONS = {
|
| 36 |
+
"amount": ("Amount is unusually high for this merchant type",
|
| 37 |
+
"Transaction amount is within normal range"),
|
| 38 |
+
"hour": ("Transaction occurred outside normal business hours",
|
| 39 |
+
"Transaction time is within normal hours"),
|
| 40 |
+
"freq_7d": ("Unusually high transaction frequency in the last 7 days",
|
| 41 |
+
"Transaction frequency is normal"),
|
| 42 |
+
"is_new": ("Payment method was registered recently",
|
| 43 |
+
"Established payment method with history"),
|
| 44 |
+
"intl": ("International transaction detected",
|
| 45 |
+
"Domestic transaction"),
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
def analyze_transaction(amount, merchant_type, hour, freq_7d, is_new_card, is_international):
|
| 49 |
+
features = np.array([[amount, hour, freq_7d,
|
| 50 |
+
int(is_new_card), int(is_international)]])
|
| 51 |
+
prob = model.predict_proba(features)[0][1]
|
| 52 |
+
risk_pct = round(prob * 100, 1)
|
| 53 |
+
|
| 54 |
+
if risk_pct < 25:
|
| 55 |
+
level, color, verdict = "LOW", "π’", "APPROVED"
|
| 56 |
+
elif risk_pct < 60:
|
| 57 |
+
level, color, verdict = "MEDIUM", "π‘", "REVIEW RECOMMENDED"
|
| 58 |
+
else:
|
| 59 |
+
level, color, verdict = "HIGH", "π΄", "FLAG FOR INVESTIGATION"
|
| 60 |
+
|
| 61 |
+
# Plain-English explanation
|
| 62 |
+
thresholds = {
|
| 63 |
+
"amount": (amount > 800, amount, "$"),
|
| 64 |
+
"hour": (hour < 6 or hour > 22, hour, "h"),
|
| 65 |
+
"freq_7d": (freq_7d > 8, freq_7d, " txns/7d"),
|
| 66 |
+
"is_new": (is_new_card, "", ""),
|
| 67 |
+
"intl": (is_international, "", ""),
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
flags, clears = [], []
|
| 71 |
+
for key, (triggered, val, unit) in thresholds.items():
|
| 72 |
+
if triggered:
|
| 73 |
+
flags.append(f"β οΈ {RISK_REASONS[key][0]}")
|
| 74 |
+
else:
|
| 75 |
+
clears.append(f"β {RISK_REASONS[key][1]}")
|
| 76 |
+
|
| 77 |
+
explanation = f"## {color} Risk Level: {level} ({risk_pct}%)\n\n"
|
| 78 |
+
explanation += f"**Verdict: {verdict}**\n\n"
|
| 79 |
+
explanation += "---\n\n"
|
| 80 |
+
explanation += "### Why This Score?\n\n"
|
| 81 |
+
|
| 82 |
+
if flags:
|
| 83 |
+
explanation += "**Risk Factors Detected:**\n"
|
| 84 |
+
explanation += "\n".join(flags) + "\n\n"
|
| 85 |
+
if clears:
|
| 86 |
+
explanation += "**Factors Within Normal Range:**\n"
|
| 87 |
+
explanation += "\n".join(clears) + "\n\n"
|
| 88 |
+
|
| 89 |
+
explanation += "---\n\n"
|
| 90 |
+
explanation += "> β οΈ This is a demo system. "
|
| 91 |
+
explanation += "Your production Lead.AI Fraud Shield will be trained on your actual transaction history.\n\n"
|
| 92 |
+
explanation += "**[β Get a Custom Fraud Shield for Your Business](https://www.lead-ai.us)**"
|
| 93 |
+
|
| 94 |
+
bar = f"Risk Score: {'β' * int(risk_pct // 5)}{'β' * (20 - int(risk_pct // 5))} {risk_pct}%"
|
| 95 |
+
return bar, explanation
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
# ββ Gradio UI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 99 |
+
with gr.Blocks(
|
| 100 |
+
title="Lead.AI Fraud Shield",
|
| 101 |
+
theme=gr.themes.Soft(primary_hue="red"),
|
| 102 |
+
css=".footer { text-align:center; margin-top:20px; color:#666; }"
|
| 103 |
+
) as demo:
|
| 104 |
+
|
| 105 |
+
gr.Markdown("""
|
| 106 |
+
# π‘ Lead.AI Fraud Shield
|
| 107 |
+
### Explainable AI Fraud Detection for Small Businesses
|
| 108 |
+
|
| 109 |
+
Enter a transaction below. The AI will score it for risk and explain exactly why β in plain English.
|
| 110 |
+
|
| 111 |
+
> πΌ This is a live proof-of-concept. [Request a custom system β](https://www.lead-ai.us)
|
| 112 |
+
""")
|
| 113 |
+
|
| 114 |
+
with gr.Row():
|
| 115 |
+
with gr.Column():
|
| 116 |
+
gr.Markdown("### Transaction Details")
|
| 117 |
+
amount = gr.Slider(1, 5000, value=120, step=1,
|
| 118 |
+
label="Transaction Amount ($)")
|
| 119 |
+
merchant = gr.Dropdown(MERCHANT_TYPES, value="Retail",
|
| 120 |
+
label="Merchant Type")
|
| 121 |
+
hour = gr.Slider(0, 23, value=14, step=1,
|
| 122 |
+
label="Hour of Day (0=midnight, 14=2pm)")
|
| 123 |
+
freq_7d_in = gr.Slider(1, 30, value=3, step=1,
|
| 124 |
+
label="Transactions in Last 7 Days (same card)")
|
| 125 |
+
is_new_card = gr.Checkbox(label="New Payment Method (registered < 7 days ago)")
|
| 126 |
+
is_intl = gr.Checkbox(label="International Transaction")
|
| 127 |
+
btn = gr.Button("π Analyze Transaction", variant="primary", size="lg")
|
| 128 |
+
|
| 129 |
+
with gr.Column():
|
| 130 |
+
gr.Markdown("### AI Analysis")
|
| 131 |
+
score_bar = gr.Textbox(label="Risk Score", lines=1)
|
| 132 |
+
result_md = gr.Markdown()
|
| 133 |
+
|
| 134 |
+
btn.click(
|
| 135 |
+
fn=analyze_transaction,
|
| 136 |
+
inputs=[amount, merchant, hour, freq_7d_in, is_new_card, is_intl],
|
| 137 |
+
outputs=[score_bar, result_md],
|
| 138 |
+
)
|
| 139 |
+
|
| 140 |
+
gr.Examples(
|
| 141 |
+
examples=[
|
| 142 |
+
[4800, "ATM / Cash", 2, 18, True, True],
|
| 143 |
+
[45, "Restaurant", 12, 2, False, False],
|
| 144 |
+
[299, "Online Store", 20, 5, False, False],
|
| 145 |
+
[1500, "Unknown", 3, 15, True, True],
|
| 146 |
+
],
|
| 147 |
+
inputs=[amount, merchant, hour, freq_7d_in, is_new_card, is_intl],
|
| 148 |
+
label="Try These Examples",
|
| 149 |
+
)
|
| 150 |
+
|
| 151 |
+
gr.Markdown("""
|
| 152 |
+
---
|
| 153 |
+
<div class="footer">
|
| 154 |
+
π <a href="https://www.lead-ai.us">www.lead-ai.us</a> |
|
| 155 |
+
π» <a href="https://github.com/Lead-AI-US/lead-ai-fraud-shield">GitHub</a> |
|
| 156 |
+
π€ <a href="https://huggingface.co/lead-ai-labs">Hugging Face</a>
|
| 157 |
+
<br><br>
|
| 158 |
+
<strong>Need this customized for your business?</strong>
|
| 159 |
+
<a href="https://www.lead-ai.us">Request a Custom Lead.AI Setup β</a>
|
| 160 |
+
</div>
|
| 161 |
+
""")
|
| 162 |
+
|
| 163 |
+
if __name__ == "__main__":
|
| 164 |
+
demo.launch()
|