import streamlit as st
import pandas as pd
import boto3
import os
from datetime import datetime
from dotenv import load_dotenv
import plotly.express as px
# --- CHARGEMENT DES SECRETS ---
load_dotenv()
# S3 / Hugging Face secrets
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
AWS_DEFAULT_REGION = os.getenv("AWS_DEFAULT_REGION", "eu-west-3")
S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME")
HF_API_TOKEN = os.getenv("HF_API_TOKEN")
# --- INITIALISATION CLIENT S3 ---
s3 = None
if AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and S3_BUCKET_NAME:
s3 = boto3.client(
"s3",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=AWS_DEFAULT_REGION
)
# --- CACHE POUR LES DONNÉES ---
@st.cache_data(ttl=600)
def load_csv_from_s3(_s3_client, bucket_name, key):
local_path = f"/tmp/{key.split('/')[-1]}"
try:
_s3_client.download_file(bucket_name, key, local_path)
return pd.read_csv(local_path)
except Exception as e:
st.error(f"Erreur lors du téléchargement depuis S3 : {e}")
return pd.DataFrame()
# --- CACHE POUR LES IMAGES ---
@st.cache_resource(ttl=3600)
def load_image_from_s3(_s3_client, bucket_name, key):
local_path = f"/tmp/{key.split('/')[-1]}"
try:
_s3_client.download_file(bucket_name, key, local_path)
return local_path
except Exception as e:
st.warning(f"Impossible de charger l'image depuis S3 : {e}")
return None
# --- CONFIG PAGE ---
st.set_page_config(page_title="Dashboard Fraude", page_icon="🚨", layout="wide")
# --- SIDEBAR NAVIGATION ---
pages = ["Accueil", "Dataset principal", "Suivi des fraudes"]
selected_page = st.sidebar.radio("Navigation", pages)
# --- PAGE 1 : ACCUEIL / ARCHITECTURE ---
if selected_page == "Accueil":
st.title("🚨 Dashboard de suivi du projet de détection de fraude")
st.markdown(
"""
Bienvenue sur le dashboard de suivi du projet de détection automatisée des fraudes bancaires.
Ce dashboard a pour objectif de présenter le contexte et les chiffres relatifs aux fraudes, ainsi que
la démarche de détection automatisée mise en place.
📊 En janvier 2025, le
Sous-Gouverneur de la Banque de France a présenté les chiffres officiels
de la fraude sur le premier semestre 2024.
👉 Consultez le rapport complet
ici.
Chiffres clés :
- Montant total fraudé : 584,6 millions d'euros sur le premier semestre
- Part des paiements et retraits par carte : 43% des montants totaux fraudés (en légère progression par rapport à 2023 : 41,5%)
- Tendance générale : légère baisse de 1% par rapport à l’année précédente
L'enjeu est crucial pour les institutions financières afin de protéger leurs clients
et de minimiser les pertes financières liées à ces activités frauduleuses.
Ce projet vise à développer un système de détection automatisée des paiements frauduleux
afin de proposer des solutions complémentaires aux systèmes existants et ce tableau de bord vous permettra de suivre la démarche initiée
et de visualiser les paiements frauduleux au fil du temps.
""",
unsafe_allow_html=True
)
st.markdown("### Architecture du projet")
architecture_img = None
if s3:
architecture_img = load_image_from_s3(s3, S3_BUCKET_NAME, "images/architecture.png")
if architecture_img:
st.image(architecture_img, use_container_width=False)
else:
st.info("Placez `architecture.png` en local ou sur S3 pour affichage.")
st.markdown("---")
st.markdown(
"""
Les principes clés de l'architecture mise en place :
- Entraînement initial du modèle sur le dataset fourni par Jedha, permettant de disposer d'un modèle de base fiable.
- Stockage et gestion des modèles avec MLflow et AWS S3, garantissant la traçabilité et la persistance des artefacts.
- Déploiement du modèle via FastAPI, offrant des prédictions en temps réel pour les transactions entrantes.
- Conteneurisation avec Docker, permettant d'isoler l'environnement, garantir la reproductibilité et faciliter le déploiement du modèle sur différents environnements (local, cloud, Hugging Face Spaces, etc.).
- Orchestration avec Airflow, exécutant les tâches de prédiction 5 fois par minute pour assurer une détection quasi instantanée.
- Stockage des prédictions et des requêtes API dans une base de données PostgreSQL, permettant un audit et une analyse historique.
- Notification quotidienne par email des fraudes détectées la veille, fournissant aux équipes métier un résumé et les transactions concernées.
- Stockage hebdomadaire des données de prédiction dans un bucket S3, assurant la sauvegarde et la disponibilité des données pour des analyses futures.
""",
unsafe_allow_html=True
)
# --- PAGE 2 : DATASET PRINCIPAL ---
elif selected_page == "Dataset principal":
st.header("Exploration du dataset principal")
# Chargement du dataset
try:
df = load_csv_from_s3(s3, S3_BUCKET_NAME, "data/fraudTest.csv")
st.subheader("Aperçu des données")
st.dataframe(df.head(5))
except Exception as e:
st.error(f"Erreur lors du chargement du dataset : {e}")
st.markdown("---")
# Répartition des paiements frauduleux
try:
fraud_counts = df["is_fraud"].value_counts()
fraud_percent = df["is_fraud"].value_counts(normalize=True) * 100
df_plot = pd.DataFrame({
"Fraude": fraud_counts.index.astype(str),
"Nombre": fraud_counts.values,
"Pourcentage": fraud_percent.values
})
color_map = {'0': 'royalblue', '1': 'crimson'}
fig = px.pie(
df_plot, names='Fraude', values='Nombre', color='Fraude', color_discrete_map=color_map
)
fig.update_traces(textinfo='label+percent+value', pull=[0.05]*len(df_plot))
st.plotly_chart(fig, use_container_width=True)
st.subheader(f"👉 Taux de fraude : **{df['is_fraud'].mean()*100:.2f}%**")
except Exception as e:
st.error(f"Erreur lors de la visualisation de la répartition des fraudes : {e}")
st.markdown("---")
# Image des performances du modèle
st.subheader("Voici les performances du modèle de prédiction utilisé")
try:
perf_img = load_image_from_s3(s3, S3_BUCKET_NAME, "images/aucpr.png")
if perf_img:
st.image(perf_img, use_container_width=False)
except Exception as e:
st.error(f"Erreur lors du chargement de l'image des performances : {e}")
st.markdown("---")
# Image des features principales
st.subheader("Regardons également les principales features prises en compte par le modèle prédictif")
try:
features_img = load_image_from_s3(s3, S3_BUCKET_NAME, "images/features.png")
if features_img:
st.image(features_img, use_container_width=False)
except Exception as e:
st.error(f"Erreur lors du chargement de l'image des features : {e}")
# --- PAGE 3 : REPORTING S3 ---
elif selected_page == "Suivi des fraudes":
st.header("Reporting des fraudes détectées")
s3_key = "backups/all_payments.csv"
if s3:
try:
df_s3 = load_csv_from_s3(s3, S3_BUCKET_NAME, s3_key)
if not df_s3.empty:
# Filtrer les fraudes
df_fraudes = df_s3[df_s3["predicted_fraud"] == 1]
if not df_fraudes.empty:
st.subheader("Visualisation")
st.dataframe(df_fraudes)
total_fraudes = df_fraudes.shape[0]
montant_total = df_fraudes["amt"].sum()
st.markdown(
f"Grâce au modèle, un total de {total_fraudes} fraudes a été détecté à ce jour pour un montant de {montant_total:,.2f} €
",
unsafe_allow_html=True
)
else:
st.info("Aucune fraude détectée dans le dataset.")
else:
st.warning("Le fichier S3 est vide.")
except Exception as e:
st.error(f"Impossible de charger le fichier S3 : {e}")
else:
st.error("Connexion S3 non configurée")