FinRiskGuard / app.py
Sarvarbek13's picture
Update app.py
ca9af3c verified
Raw
History Blame Contribute Delete
10.2 kB
import os
import json
import joblib
import numpy as np
import pandas as pd
import gradio as gr
from pathlib import Path
# Modellarning lokal manzili
MODELS_DIR = Path("/home/user/app/outputs/models")
_fraud_predictor = None
_credit_predictor = None
def load_predictors():
global _fraud_predictor, _credit_predictor
if _fraud_predictor is None:
# Modellarni to'g'ridan-to'g'ri ko'rsatilgan papkadan yuklaymiz
fraud_dir = MODELS_DIR / "fraud"
credit_dir = MODELS_DIR / "credit"
_fraud_predictor = SimpleFraudPredictor(fraud_dir)
_credit_predictor = SimpleCreditPredictor(credit_dir)
class SimpleFraudPredictor:
def __init__(self, model_dir):
self.fe_artifacts = joblib.load(model_dir / "fe_artifacts.pkl")
self.prep_artifacts = joblib.load(model_dir / "prep_artifacts.pkl")
self.fs_artifacts = joblib.load(model_dir / "fs_artifacts.pkl")
self.model = joblib.load(model_dir / "fraud_model.pkl")
self.xgb = joblib.load(model_dir / "tuned_xgb.pkl")
self.lgb = joblib.load(model_dir / "tuned_lgb.pkl")
self.cat = joblib.load(model_dir / "tuned_cat.pkl")
with open(model_dir / "fraud_model_metadata.json") as f:
meta = json.load(f)
self.threshold = meta["threshold"]
self.model_name = meta["model_name"]
self.final_feats = self.fs_artifacts["final_features"]
def predict(self, transaction: dict) -> dict:
import sys
sys.path.insert(0, "/home/user/app")
from src.features.ieee_cis.feature_engineer import feature_engineer_test
from src.data.ieee_cis.preprocessor import preprocess_test
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
df = pd.DataFrame([transaction])
df = feature_engineer_test(df, self.fe_artifacts)
df = preprocess_test(df, self.prep_artifacts)
df = df.apply(pd.to_numeric, errors="coerce").fillna(0.0)
missing = [c for c in self.final_feats if c not in df.columns]
for col in missing:
df[col] = 0.0
X = df[self.final_feats]
if isinstance(self.model, (LogisticRegression, Pipeline)):
meta_input = np.column_stack([
self.xgb.predict_proba(X)[:, 1],
self.lgb.predict_proba(X)[:, 1],
self.cat.predict_proba(X)[:, 1],
])
prob = self.model.predict_proba(meta_input)[:, 1][0]
else:
prob = self.model.predict_proba(X)[:, 1][0]
return {
"fraud_probability": round(float(prob), 4),
"is_fraud": bool(prob >= self.threshold),
"threshold": self.threshold,
"model": self.model_name,
}
class SimpleCreditPredictor:
def __init__(self, model_dir):
self.fe_artifacts = joblib.load(model_dir / "fe_artifacts.pkl")
self.prep_artifacts = joblib.load(model_dir / "prep_artifacts.pkl")
self.fs_artifacts = joblib.load(model_dir / "fs_artifacts.pkl")
self.model = joblib.load(model_dir / "credit_model.pkl")
self.xgb = joblib.load(model_dir / "tuned_xgb.pkl")
self.lgb = joblib.load(model_dir / "tuned_lgb.pkl")
self.cat = joblib.load(model_dir / "tuned_cat.pkl")
with open(model_dir / "credit_model_metadata.json") as f:
meta = json.load(f)
self.threshold = meta["threshold"]
self.model_name = meta["model_name"]
self.final_feats = self.fs_artifacts["final_features"]
def predict(self, applicant: dict) -> dict:
import sys
sys.path.insert(0, "/home/user/app")
from src.features.home_credit.feature_engineer import feature_engineer_test
from src.data.home_credit.preprocessor import preprocess_test
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
df = pd.DataFrame([applicant])
empty_tables = {
"bureau": pd.DataFrame(), "bureau_balance": pd.DataFrame(),
"previous_app": pd.DataFrame(), "pos_cash": pd.DataFrame(),
"installments": pd.DataFrame(), "credit_card": pd.DataFrame(),
}
df = feature_engineer_test(df, empty_tables, self.fe_artifacts)
df = preprocess_test(df, self.prep_artifacts)
df = df.apply(pd.to_numeric, errors="coerce").fillna(0.0)
missing = [c for c in self.final_feats if c not in df.columns]
for col in missing:
df[col] = 0.0
X = df[self.final_feats]
if isinstance(self.model, (LogisticRegression, Pipeline)):
meta_input = np.column_stack([
self.xgb.predict_proba(X)[:, 1],
self.lgb.predict_proba(X)[:, 1],
self.cat.predict_proba(X)[:, 1],
])
prob = self.model.predict_proba(meta_input)[:, 1][0]
else:
prob = self.model.predict_proba(X)[:, 1][0]
return {
"default_probability": round(float(prob), 4),
"will_default": bool(prob >= self.threshold),
"threshold": self.threshold,
"model": self.model_name,
}
def predict_fraud(txn_id, txn_dt, txn_amt, prod_cd, card4, card6, p_email, r_email, dev_type):
load_predictors()
payload = {
"TransactionID": int(txn_id), "TransactionDT": int(txn_dt),
"TransactionAmt": float(txn_amt), "ProductCD": prod_cd,
"card4": card4, "card6": card6,
"P_emaildomain": p_email, "R_emaildomain": r_email,
"DeviceType": dev_type,
}
result = _fraud_predictor.predict(payload)
color = "RED — FRAUD" if result["is_fraud"] else "GREEN — LEGITIMATE"
output = f"Decision: {color}\nFraud Probability: {result['fraud_probability']}\nThreshold: {result['threshold']}\nModel: {result['model']}"
return output, round(result["fraud_probability"] * 100, 2)
def predict_credit(sk_id, amt_credit, amt_income, amt_annuity, days_birth, days_employed, ext1, ext2, ext3):
load_predictors()
payload = {
"SK_ID_CURR": int(sk_id), "AMT_CREDIT": float(amt_credit),
"AMT_INCOME_TOTAL": float(amt_income), "AMT_ANNUITY": float(amt_annuity),
"DAYS_BIRTH": int(days_birth), "DAYS_EMPLOYED": int(days_employed),
}
if ext1: payload["EXT_SOURCE_1"] = float(ext1)
if ext2: payload["EXT_SOURCE_2"] = float(ext2)
if ext3: payload["EXT_SOURCE_3"] = float(ext3)
result = _credit_predictor.predict(payload)
color = "RED — HIGH RISK" if result["will_default"] else "GREEN — LOW RISK"
output = f"Decision: {color}\nDefault Probability: {result['default_probability']}\nThreshold: {result['threshold']}\nModel: {result['model']}"
return output, round(result["default_probability"] * 100, 2)
# Gradio Interfeysi
with gr.Blocks(title="FinRiskGuard", theme=gr.themes.Soft()) as demo:
gr.Markdown("# FinRiskGuard\n### Fraud Detection and Credit Default Scoring")
with gr.Tabs():
with gr.Tab("Fraud Detection"):
gr.Markdown("#### IEEE-CIS | AUC-ROC: 0.9258 | Threshold: 0.44")
with gr.Row():
with gr.Column():
txn_id = gr.Number(label="TransactionID", value=2987004, precision=0)
txn_dt = gr.Number(label="TransactionDT", value=86400, precision=0)
txn_amt = gr.Number(label="TransactionAmt", value=117.5)
prod_cd = gr.Dropdown(["W","H","C","S","R"], label="ProductCD", value="W")
card4 = gr.Dropdown(["visa","mastercard","american express","discover"], label="card4", value="visa")
card6 = gr.Dropdown(["debit","credit","debit or credit","charge card"], label="card6", value="debit")
p_email = gr.Textbox(label="P_emaildomain", value="gmail.com")
r_email = gr.Textbox(label="R_emaildomain", value="gmail.com")
dev_type = gr.Dropdown(["desktop","mobile"], label="DeviceType", value="desktop")
btn_f = gr.Button("Predict", variant="primary")
with gr.Column():
fraud_result = gr.Textbox(label="Result")
fraud_gauge = gr.Number(label="Fraud Probability (%)")
btn_f.click(predict_fraud,
inputs=[txn_id, txn_dt, txn_amt, prod_cd, card4, card6, p_email, r_email, dev_type],
outputs=[fraud_result, fraud_gauge])
with gr.Tab("Credit Scoring"):
gr.Markdown("#### Home Credit | AUC-ROC: 0.7849 | Threshold: 0.50")
with gr.Row():
with gr.Column():
sk_id = gr.Number(label="SK_ID_CURR", value=100002, precision=0)
amt_cred = gr.Number(label="AMT_CREDIT", value=406597.5)
amt_inc = gr.Number(label="AMT_INCOME_TOTAL", value=202500.0)
amt_ann = gr.Number(label="AMT_ANNUITY", value=24700.5)
d_birth = gr.Number(label="DAYS_BIRTH", value=-9461, precision=0)
d_emp = gr.Number(label="DAYS_EMPLOYED", value=-637, precision=0)
ext1 = gr.Number(label="EXT_SOURCE_1", value=None)
ext2 = gr.Number(label="EXT_SOURCE_2", value=0.651)
ext3 = gr.Number(label="EXT_SOURCE_3", value=0.493)
btn_c = gr.Button("Predict", variant="primary")
with gr.Column():
credit_result = gr.Textbox(label="Result")
credit_gauge = gr.Number(label="Default Probability (%)")
btn_c.click(predict_credit,
inputs=[sk_id, amt_cred, amt_inc, amt_ann, d_birth, d_emp, ext1, ext2, ext3],
outputs=[credit_result, credit_gauge])
gr.Markdown("---\nFinRiskGuard | XGBoost · LightGBM · CatBoost · Stacking · SHAP")
if __name__ == "__main__":
demo.launch()