import dash
from dash import html, dcc, Input, Output, State, callback
import dash_bootstrap_components as dbc
import pandas as pd
import joblib
dash.register_page(__name__, path="/prediction")
# Load model
artifact = joblib.load("models/fraud_mlp_pipeline.joblib")
model = artifact["model"]
threshold = artifact["threshold"]
# Features
feature_names = ['Time'] + [f'V{i}' for i in range(1, 29)] + ['Amount']
layout = dbc.Container([
dbc.Row([
dbc.Col([
html.Div([
html.H4("TRANSACTION INPUTS", className="text-white mb-4 fw-bold"),
# Generate Inputs dynamically
*[
dbc.Input(id=f"feat-{feat}", placeholder=feat, type="number", className="mb-3 bg-dark-glass")
for feat in feature_names
],
dbc.Button("PREDICT FRAUD", id="predict-btn", className="w-100 py-3 mt-2 fw-bold border-0",
style={"background": "linear-gradient(90deg, #00d2ff 0%, #3a7bd5 100%)"}),
html.Div(id="predict-output", className="mt-4 p-3 result-display text-center")
], className="div-user-controls p-4")
], lg=6, md=8, sm=12)
], justify="center")
], fluid=True)
@callback(
Output("predict-output", "children"),
Input("predict-btn", "n_clicks"),
[State(f"feat-{feat}", "value") for feat in feature_names]
)
def predict_fraud(n, *values):
if n is None:
return ""
try:
df = pd.DataFrame([values], columns=feature_names)
proba = model.predict_proba(df)[:, 1][0]
prediction = "🔴 Fraud Detected!" if proba >= threshold else "🟢 Legit Transaction"
return html.Div([
html.H5(f"Fraud Probability: {proba:.2f}", className="text-info"),
html.H3(prediction, className="text-white fw-bold")
])
except Exception as e:
return html.Div([f"❌ Error: {str(e)}"], className="text-danger")