dineth554's picture
Upload app.py with huggingface_hub
488b3d4 verified
"""
Death Legion Fraud Detection - Gradio Space
Real-time fraud detection interface powered by Best Teams.
"""
import os
import gradio as gr
import numpy as np
from safetensors.numpy import load_file
from huggingface_hub import hf_hub_download
# Death Legion Branding
TITLE = "🔥 Death Legion Fraud Detection System"
DESCRIPTION = """
### Powered by Best Teams | Elite ML Division
Real-time credit card fraud detection using advanced Random Forest technology.
**AUPRC: 0.8177** | **Model Size: 6.12 MB**
Enter transaction features (V1-V28, Time, Amount) to get instant fraud predictions.
"""
# Load model from Hub
REPO_ID = "Pnny13/fraud-detection-model"
class SafetensorsRFClassifier:
"""Random Forest classifier from Safetensors."""
def __init__(self, tensors):
self.n_estimators = int(tensors['metadata/n_estimators'][0])
self.n_features = int(tensors['metadata/n_features'][0])
self.n_classes = int(tensors['metadata/n_classes'][0])
self.classes_ = tensors['metadata/classes']
self.trees = []
for i in range(self.n_estimators):
prefix = f'tree_{i:03d}'
tree = {
'node_count': int(tensors[f'{prefix}/node_count'][0]),
'children_left': tensors[f'{prefix}/children_left'],
'children_right': tensors[f'{prefix}/children_right'],
'feature': tensors[f'{prefix}/feature'],
'threshold': tensors[f'{prefix}/threshold'],
'value': tensors[f'{prefix}/value'],
'value_shape': tensors[f'{prefix}/value_shape'],
}
self.trees.append(tree)
def _predict_proba_tree(self, tree, X):
n_samples = X.shape[0]
probas = np.zeros((n_samples, self.n_classes), dtype=np.float32)
for i in range(n_samples):
node = 0
while tree['children_left'][node] != tree['children_right'][node]:
if X[i, tree['feature'][node]] <= tree['threshold'][node]:
node = tree['children_left'][node]
else:
node = tree['children_right'][node]
value_shape = tree['value_shape']
value = tree['value'].reshape(value_shape)
class_counts = value[node, 0]
total = class_counts.sum()
probas[i] = class_counts / total if total > 0 else [0.5, 0.5]
return probas
def predict_proba(self, X):
X = np.asarray(X, dtype=np.float32)
probas = np.zeros((X.shape[0], self.n_classes), dtype=np.float32)
for tree in self.trees:
probas += self._predict_proba_tree(tree, X)
probas /= self.n_estimators
return probas
class SafetensorsScaler:
"""RobustScaler from Safetensors."""
def __init__(self, tensors):
self.center_ = tensors['scaler/center']
self.scale_ = tensors['scaler/scale']
def transform(self, X):
X = np.asarray(X, dtype=np.float32)
X_scaled = X.copy()
for i in range(len(self.center_)):
X_scaled[:, i] = (X[:, i] - self.center_[i]) / self.scale_[i]
return X_scaled
# Global model cache
_model = None
_scaler = None
def load_model():
"""Load model from Hugging Face Hub."""
global _model, _scaler
if _model is None:
model_path = hf_hub_download(repo_id=REPO_ID, filename="model/fraud_detector.safetensors")
tensors = load_file(model_path)
_model = SafetensorsRFClassifier(tensors)
_scaler = SafetensorsScaler(tensors)
return _model, _scaler
def predict_fraud(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
v11, v12, v13, v14, v15, v16, v17, v18, v19, v20,
v21, v22, v23, v24, v25, v26, v27, v28, time, amount):
"""Make fraud prediction from input features."""
try:
model, scaler = load_model()
# Build feature vector
features = np.array([[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
v11, v12, v13, v14, v15, v16, v17, v18, v19, v20,
v21, v22, v23, v24, v25, v26, v27, v28, time, amount]],
dtype=np.float32)
# Scale Time and Amount
features_scaled = features.copy()
features_scaled[:, 0] = (features[:, 0] - scaler.center_[0]) / scaler.scale_[0] # Time
features_scaled[:, 29] = (features[:, 29] - scaler.center_[1]) / scaler.scale_[1] # Amount
# Predict
probas = model.predict_proba(features_scaled)[0]
fraud_prob = probas[1]
# Determine result
is_fraud = fraud_prob > 0.5
# Create result display
if is_fraud:
result = f"""
## 🚨 FRAUD DETECTED
**Fraud Probability: {fraud_prob:.2%}**
⚠️ This transaction shows suspicious patterns consistent with fraudulent activity.
**Recommendation:** Block transaction and flag for review.
"""
else:
result = f"""
## ✅ LEGITIMATE TRANSACTION
**Fraud Probability: {fraud_prob:.2%}**
✓ This transaction appears normal and safe to process.
**Recommendation:** Approve transaction.
"""
return result, fraud_prob
except Exception as e:
return f"Error: {str(e)}", 0.0
# Create Gradio interface
inputs = [
gr.Number(label=f"V{i}", value=0.0) for i in range(1, 29)
] + [
gr.Number(label="Time (seconds)", value=0.0),
gr.Number(label="Amount ($)", value=100.0)
]
outputs = [
gr.Markdown(label="Prediction Result"),
gr.Number(label="Fraud Probability", visible=False)
]
interface = gr.Interface(
fn=predict_fraud,
inputs=inputs,
outputs=outputs,
title=TITLE,
description=DESCRIPTION,
theme=gr.themes.Soft(),
examples=[
# Example 1: Normal transaction
[0.1, -0.2, 0.5, 0.3, -0.1, 0.2, -0.3, 0.1, 0.0, 0.2,
-0.1, 0.3, -0.2, 0.1, 0.0, 0.2, -0.1, 0.1, 0.0, 0.0,
0.1, -0.1, 0.0, 0.0, 0.1, -0.1, 0.0, 0.1, 3600, 50.0],
# Example 2: Suspicious transaction
[-2.5, 3.2, -1.8, 2.1, -0.5, 1.2, -2.1, 0.8, -1.5, 2.3,
-0.8, 1.5, -2.0, 0.5, -1.2, 2.0, -0.6, 1.8, -1.0, 0.3,
-1.5, 2.2, -0.9, 1.1, -1.8, 0.4, -1.2, 0.8, 7200, 999.99],
],
cache_examples=False,
)
if __name__ == "__main__":
interface.launch()