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 : 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 :
""", 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")