Djohell commited on
Commit
4877f61
·
verified ·
1 Parent(s): 47b15bb

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +112 -166
src/streamlit_app.py CHANGED
@@ -1,23 +1,19 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
5
- import os
6
- import matplotlib.pyplot as plt
7
  import boto3
8
- import seaborn as sns
9
- import plotly.express as px
10
- from datetime import datetime, timedelta
11
  from dotenv import load_dotenv
 
12
 
13
  load_dotenv()
14
 
 
15
  AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
16
  AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
17
  AWS_DEFAULT_REGION = os.getenv("AWS_DEFAULT_REGION", "eu-west-3")
18
  S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME")
19
 
20
-
21
  s3 = None
22
  if AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and S3_BUCKET_NAME:
23
  s3 = boto3.client(
@@ -27,163 +23,113 @@ if AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and S3_BUCKET_NAME:
27
  region_name=AWS_DEFAULT_REGION
28
  )
29
 
30
- # CONFIGURATION DE LA PAGE
31
-
32
- st.set_page_config(
33
- page_title="Dashboard de détection de fraude",
34
- page_icon="🚨",
35
- layout="wide"
36
- )
37
-
38
- local_path = "/tmp/fraudTest.csv"
39
- s3.download_file(os.getenv("S3_BUCKET_NAME"), "data/fraudTest.csv", local_path)
40
-
41
- df = pd.read_csv(local_path)
42
-
43
- # TITRE & INTRODUCTION
44
-
45
- st.title("🚨 Dashboard de suivi du projet de détection automatisée des paiements frauduleux")
46
-
47
- st.markdown(
48
- """
49
- <div style='font-size:18px; line-height:1.6;'>
50
- <b>Bienvenue sur le dashboard de suivi du projet de détection automatisée des fraudes bancaires</b>.<br><br>
51
-
52
- Ce dashboard a pour objectif de présenter le contexte et les chiffres relatifs aux fraudes, ainsi que
53
- la démarche de détection automatisée mise en place.<br><br>
54
-
55
- 📊 En janvier 2025, le <b>Sous-Gouverneur de la Banque de France</b> a présenté les chiffres officiels
56
- de la fraude sur le premier semestre 2024.
57
- 👉 Consultez le rapport complet <a href='https://www.banque-france.fr/fr/interventions-gouverneur/presentation-des-statistiques-de-fraude-au-1er-semestre-2024-par-losmp#:~:text=Dans%20ce%20contexte%20de%20progression,fraude%20au%20premier%20semestre%202023' target='_blank' style='color:#1E90FF; text-decoration:none;'>ici</a>.<br><br>
58
-
59
- <b>Chiffres clés :</b>
60
- <ul>
61
- <li>Montant total fraudé : <b>584,6 millions d'euros</b> sur le premier semestre</li>
62
- <li>Part des paiements et retraits par carte : <b>43%</b> des montants totaux fraudés (en légère progression par rapport à 2023 : 41,5%)</li>
63
- <li>Tendance générale : légère baisse de <b>1%</b> par rapport à l’année précédente</li>
64
- </ul>
65
-
66
- L'enjeu est crucial pour les institutions financières afin de protéger leurs clients
67
- et de minimiser les pertes financières liées à ces activités frauduleuses.<br><br>
68
-
69
- Ce projet vise à développer un système de détection automatisée des paiements frauduleux
70
- 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
71
- et de visualiser les paiements frauduleux au fil du temps.
72
- </div>
73
- """,
74
- unsafe_allow_html=True
75
- )
76
-
77
- st.markdown("---")
78
- st.subheader("Les choix d'architecture du projet :")
79
-
80
-
81
- local_img_path = os.path.join(os.getcwd(), "architecture.png")
82
- image_displayed = False
83
-
84
- if s3:
85
- try:
86
-
87
- temp_path = "/tmp/architecture.png"
88
- s3.download_file(S3_BUCKET_NAME, "images/architecture.png", temp_path)
89
- st.image(temp_path, use_container_width=False)
90
- image_displayed = True
91
- except Exception as e:
92
- st.warning(f"Impossible de récupérer l'image depuis S3 : {e}")
93
-
94
- if not image_displayed:
95
- # fallback local
96
- if os.path.exists(local_img_path):
97
- st.image(local_img_path, use_container_width=False)
98
  else:
99
- st.error("Image architecture introuvable ! Placez-la en local ou sur S3.")
100
-
101
- st.markdown("---")
102
-
103
- st.markdown(
104
- """
105
- ### Les principes clés de l'architecture mise en place :
106
-
107
- - **Entraînement initial du modèle** sur le dataset fourni par Jedha, permettant de disposer d'un modèle de base fiable.
108
- - **Stockage et gestion des modèles** avec MLflow et AWS S3, garantissant la traçabilité et la persistance des artefacts.
109
- - **Déploiement du modèle via FastAPI**, offrant des prédictions en temps réel pour les transactions entrantes.
110
- - **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.).
111
- - **Orchestration avec Airflow**, exécutant les tâches de prédiction 5 fois par minute pour assurer une détection quasi instantanée.
112
- - **Stockage des prédictions et des requêtes API** dans une base de données PostgreSQL, permettant un audit et une analyse historique.
113
- - **Notification quotidienne par email** des fraudes détectées la veille, fournissant aux équipes métier un résumé et les transactions concernées.
114
- """
115
- )
116
-
117
- st.markdown("---")
118
-
119
- st.subheader(
120
- "Le dataset utilisé pour entraîner le modèle :"
121
- )
122
-
123
- st.subheader("Aperçu des données")
124
- st.dataframe(df.head(5))
125
-
126
- st.subheader("Répartition des paiements frauduleux")
127
-
128
- # --- Calculs ---
129
- fraud_counts = df["is_fraud"].value_counts()
130
- fraud_percent = df["is_fraud"].value_counts(normalize=True) * 100
131
-
132
- # Préparer le DataFrame pour Plotly
133
- df_plot = pd.DataFrame({
134
- "Fraude": fraud_counts.index.astype(str),
135
- "Nombre": fraud_counts.values,
136
- "Pourcentage": fraud_percent.values
137
- })
138
-
139
- # --- Couleurs personnalisées : bleu pour 0, rouge pour 1 ---
140
- color_map = {'0': 'royalblue', '1': 'crimson'}
141
-
142
- # --- Graphique interactif ---
143
- fig = px.pie(
144
- df_plot,
145
- names='Fraude',
146
- values='Nombre',
147
- color='Fraude',
148
- color_discrete_map=color_map,
149
- )
150
-
151
- # Ajouter hover template avec valeurs absolues et pourcentage
152
- fig.update_traces(
153
- textinfo='label+percent+value', # label + pourcentage + nombre absolu
154
- pull=[0.05]*len(df_plot),
155
- hovertemplate="<b>%{label}</b><br>Nombre : %{value}<br>Pourcentage : %{percent:.2%}"
156
- )
157
-
158
- fig.update_layout(width=500, height=500, margin=dict(l=20, r=20, t=40, b=20))
159
-
160
- # Affichage dans Streamlit
161
- st.plotly_chart(fig, use_container_width=True)
162
-
163
- fraud_rate = df["is_fraud"].mean() * 100
164
- st.markdown(f"👉 Comme vous pouvez le constater, le dataset a un taux de fraudes de **{fraud_rate:.2f}%**")
165
-
166
- st.markdown("---")
167
-
168
- st.subheader("Les principales features prises en compte par le modèle")
169
-
170
- local_img_path = os.path.join(os.getcwd(), "features.png")
171
- image_displayed = False
172
-
173
- if s3:
174
  try:
175
-
176
- temp_path = "/tmp/features.png"
177
- s3.download_file(S3_BUCKET_NAME, "images/features.png", temp_path)
178
- st.image(temp_path, use_container_width=False)
179
- image_displayed = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  except Exception as e:
181
- st.warning(f"Impossible de récupérer l'image depuis S3 : {e}")
182
-
183
- if not image_displayed:
184
- # fallback local
185
- if os.path.exists(local_img_path):
186
- st.image(local_img_path, use_container_width=False)
187
- else:
188
- st.error("Image features introuvable ! Placez-la en local ou sur S3.")
189
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import pandas as pd
 
3
  import boto3
4
+ import os
5
+ from datetime import datetime
 
6
  from dotenv import load_dotenv
7
+ import plotly.express as px
8
 
9
  load_dotenv()
10
 
11
+ # --- CONFIG S3 ---
12
  AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
13
  AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
14
  AWS_DEFAULT_REGION = os.getenv("AWS_DEFAULT_REGION", "eu-west-3")
15
  S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME")
16
 
 
17
  s3 = None
18
  if AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and S3_BUCKET_NAME:
19
  s3 = boto3.client(
 
23
  region_name=AWS_DEFAULT_REGION
24
  )
25
 
26
+ # --- CACHE POUR LES DONNÉES ---
27
+ @st.cache_data(ttl=600)
28
+ def load_csv_from_s3(s3_client, bucket_name, key):
29
+ local_path = f"/tmp/{key.split('/')[-1]}"
30
+ s3_client.download_file(bucket_name, key, local_path)
31
+ return pd.read_csv(local_path)
32
+
33
+ # --- CACHE POUR LES IMAGES ---
34
+ @st.cache_resource(ttl=3600)
35
+ def load_image_from_s3(s3_client, bucket_name, key):
36
+ local_path = f"/tmp/{key.split('/')[-1]}"
37
+ s3_client.download_file(bucket_name, key, local_path)
38
+ return local_path
39
+
40
+ # --- CONFIG PAGE ---
41
+ st.set_page_config(page_title="Dashboard Fraude", page_icon="🚨", layout="wide")
42
+
43
+ # --- SIDEBAR NAVIGATION ---
44
+ pages = ["Accueil", "Dataset principal", "Reporting S3"]
45
+ selected_page = st.sidebar.radio("Navigation", pages)
46
+
47
+ # --- PAGE 1 : ACCUEIL / ARCHITECTURE ---
48
+ if selected_page == "Accueil":
49
+ st.title("🚨 Dashboard de suivi du projet de détection de fraude")
50
+ st.markdown(
51
+ """
52
+ Bienvenue sur le dashboard de suivi du projet de détection automatisée des fraudes bancaires.
53
+ """
54
+ )
55
+ st.markdown("### Architecture du projet")
56
+
57
+ # Affichage image architecture
58
+ architecture_img = None
59
+ if s3:
60
+ try:
61
+ architecture_img = load_image_from_s3(s3, S3_BUCKET_NAME, "images/architecture.png")
62
+ except:
63
+ st.warning("Impossible de charger l'image depuis S3")
64
+
65
+ if architecture_img:
66
+ st.image(architecture_img, use_container_width=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  else:
68
+ st.info("Placez `architecture.png` en local ou sur S3 pour affichage.")
69
+
70
+ st.markdown("---")
71
+ st.markdown("""
72
+ **Principes clés de l'architecture :**
73
+ - Entraînement initial du modèle sur dataset de base
74
+ - Stockage des modèles avec MLflow et S3
75
+ - Déploiement via FastAPI
76
+ - Orchestration avec Airflow
77
+ - Notifications email quotidiennes
78
+ """)
79
+
80
+ # --- PAGE 2 : DATASET PRINCIPAL ---
81
+ elif selected_page == "Dataset principal":
82
+ st.header("Exploration du dataset principal")
83
+
84
+ # Chargement dataset
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  try:
86
+ df = load_csv_from_s3(s3, S3_BUCKET_NAME, "data/fraudTest.csv")
87
+ st.subheader("Aperçu des données")
88
+ st.dataframe(df.head(5))
89
+
90
+ # Répartition des paiements frauduleux
91
+ fraud_counts = df["is_fraud"].value_counts()
92
+ fraud_percent = df["is_fraud"].value_counts(normalize=True) * 100
93
+ df_plot = pd.DataFrame({
94
+ "Fraude": fraud_counts.index.astype(str),
95
+ "Nombre": fraud_counts.values,
96
+ "Pourcentage": fraud_percent.values
97
+ })
98
+ color_map = {'0': 'royalblue', '1': 'crimson'}
99
+ fig = px.pie(
100
+ df_plot, names='Fraude', values='Nombre', color='Fraude', color_discrete_map=color_map
101
+ )
102
+ fig.update_traces(textinfo='label+percent+value', pull=[0.05]*len(df_plot))
103
+ st.plotly_chart(fig, use_container_width=True)
104
+ st.markdown(f"👉 Taux de fraude : **{df['is_fraud'].mean()*100:.2f}%**")
105
+
106
+ # Image des features principales
107
+ features_img = None
108
+ if s3:
109
+ try:
110
+ features_img = load_image_from_s3(s3, S3_BUCKET_NAME, "images/features.png")
111
+ except:
112
+ st.warning("Impossible de charger l'image features depuis S3")
113
+ if features_img:
114
+ st.image(features_img, use_container_width=False)
115
  except Exception as e:
116
+ st.error(f"Erreur lors du chargement du dataset : {e}")
117
+
118
+ # --- PAGE 3 : REPORTING S3 ---
119
+ elif selected_page == "Reporting S3":
120
+ st.header("Reporting sur un dataset S3")
121
+ st.info("Téléversez le dataset ou renseignez le chemin S3")
122
+
123
+ s3_key_input = st.text_input("Nom du fichier dans S3 (ex: data/transactions.csv)")
124
+ if s3_key_input:
125
+ try:
126
+ df_s3 = load_csv_from_s3(s3, S3_BUCKET_NAME, s3_key_input)
127
+ st.subheader("Aperçu des données")
128
+ st.dataframe(df_s3.head(5))
129
+
130
+ # Exemple simple : histogramme des montants
131
+ if "amt" in df_s3.columns:
132
+ fig = px.histogram(df_s3, x="amt", nbins=50, title="Distribution des montants")
133
+ st.plotly_chart(fig, use_container_width=True)
134
+ except Exception as e:
135
+ st.error(f"Impossible de charger le fichier S3 : {e}")