Spaces:
Build error
Build error
| """ | |
| 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() | |