Spaces:
Running
Running
Update pages/Statistics.py
Browse files- pages/Statistics.py +69 -39
pages/Statistics.py
CHANGED
@@ -7,11 +7,13 @@ import plotly.graph_objects as go
|
|
7 |
import json
|
8 |
import os
|
9 |
import re
|
10 |
-
from datetime import datetime
|
11 |
import pycountry
|
12 |
|
|
|
13 |
from streamlit_extras.metric_cards import style_metric_cards
|
14 |
-
|
|
|
15 |
|
16 |
# Definiowanie 艣cie偶ek do plik贸w JSON
|
17 |
FAKE_NUMBERS_FILE = os.path.join('data', 'fake_numbers.json')
|
@@ -32,10 +34,10 @@ page_translations = {
|
|
32 |
'frauds_over_time': "Liczba Wykrytych Oszustw w Czasie",
|
33 |
'risk_distribution_title': "Rozk艂ad Ocen Ryzyka Oszustwa",
|
34 |
'fraud_country_distribution_title': "Rozk艂ad Oszustw Wed艂ug Kraj贸w",
|
|
|
35 |
'fraud_trend_title': "Trendy Oszustw w Czasie",
|
36 |
'risk_distribution': "Rozk艂ad Ocen Ryzyka Oszustwa",
|
37 |
'fraud_country_distribution': "Rozk艂ad Oszustw Wed艂ug Kraj贸w",
|
38 |
-
'heatmap_title': "Heatmapa Oszustw w Czasie",
|
39 |
'fraud_vs_nonfraud': "Procentowy Podzia艂: Oszustwa vs Bezpieczne",
|
40 |
'no_data': "Brak dost臋pnych danych do wy艣wietlenia.",
|
41 |
'download_button': "馃摜 Pobierz dane jako CSV",
|
@@ -54,10 +56,10 @@ page_translations = {
|
|
54 |
'frauds_over_time': "Anzahl der erkannten Betr眉gereien im Laufe der Zeit",
|
55 |
'risk_distribution_title': "Verteilung der Betrugsrisikobewertungen",
|
56 |
'fraud_country_distribution_title': "Betrug nach L盲ndern",
|
|
|
57 |
'fraud_trend_title': "Betrugstrends im Laufe der Zeit",
|
58 |
'risk_distribution': "Verteilung der Betrugsrisikobewertungen",
|
59 |
'fraud_country_distribution': "Betrug nach L盲ndern",
|
60 |
-
'heatmap_title': "Heatmap der Betr眉gereien im Laufe der Zeit",
|
61 |
'fraud_vs_nonfraud': "Prozentanteil: Betrug vs Sichere Nachrichten",
|
62 |
'no_data': "Keine Daten zur Anzeige verf眉gbar.",
|
63 |
'download_button': "馃摜 Daten als CSV herunterladen",
|
@@ -76,10 +78,10 @@ page_translations = {
|
|
76 |
'frauds_over_time': "Number of Detected Frauds Over Time",
|
77 |
'risk_distribution_title': "Distribution of Fraud Risk Scores",
|
78 |
'fraud_country_distribution_title': "Fraud Distribution by Countries",
|
|
|
79 |
'fraud_trend_title': "Fraud Trends Over Time",
|
80 |
'risk_distribution': "Distribution of Fraud Risk Scores",
|
81 |
'fraud_country_distribution': "Fraud Distribution by Countries",
|
82 |
-
'heatmap_title': "Fraud Heatmap Over Time",
|
83 |
'fraud_vs_nonfraud': "Fraud vs Safe Messages Percentage",
|
84 |
'no_data': "No data available to display.",
|
85 |
'download_button': "馃摜 Download data as CSV",
|
@@ -109,7 +111,7 @@ def save_json(file_path, data):
|
|
109 |
"""Zapisuje dane do pliku JSON."""
|
110 |
with open(file_path, 'w', encoding='utf-8') as file:
|
111 |
json.dump(data, file, ensure_ascii=False, indent=4)
|
112 |
-
|
113 |
|
114 |
def get_stats_from_json():
|
115 |
"""Pobiera statystyki z pliku stats.json."""
|
@@ -146,26 +148,38 @@ def main(language):
|
|
146 |
# Stylizacja kart metryk
|
147 |
style_metric_cards()
|
148 |
|
149 |
-
#
|
150 |
-
st.
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
)
|
163 |
-
|
164 |
-
# Filtracja historii na podstawie daty
|
165 |
if history:
|
166 |
df_history = pd.DataFrame(history)
|
167 |
# Upewnij si臋, 偶e 'timestamp' jest w formacie datetime
|
168 |
df_history['timestamp'] = pd.to_datetime(df_history['timestamp'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
# Filtracja na podstawie daty
|
170 |
mask = (df_history['timestamp'].dt.date >= start_date) & (df_history['timestamp'].dt.date <= end_date)
|
171 |
df_filtered = df_history.loc[mask]
|
@@ -176,10 +190,13 @@ def main(language):
|
|
176 |
fraud_percentage_filtered = (frauds_filtered / total_filtered) * 100 if total_filtered > 0 else 0
|
177 |
|
178 |
# Wy艣wietlenie metryk dla filtrowanej historii
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
|
|
|
|
|
|
183 |
|
184 |
# Wizualizacja procentowego podzia艂u oszustw
|
185 |
st.markdown("### " + translations['fraud_vs_nonfraud'])
|
@@ -190,6 +207,8 @@ def main(language):
|
|
190 |
fig_fraud_pie.update_layout(title_text=translations['fraud_vs_nonfraud'])
|
191 |
st.plotly_chart(fig_fraud_pie, use_container_width=True)
|
192 |
|
|
|
|
|
193 |
# Trend oszustw w czasie
|
194 |
st.markdown("### " + translations['frauds_over_time'])
|
195 |
fraud_over_time = df_filtered.groupby(df_filtered['timestamp'].dt.date)['phone_number'].count().reset_index()
|
@@ -199,6 +218,8 @@ def main(language):
|
|
199 |
fig_trend.update_traces(line=dict(color='firebrick'))
|
200 |
st.plotly_chart(fig_trend, use_container_width=True)
|
201 |
|
|
|
|
|
202 |
# Rozk艂ad ocen ryzyka
|
203 |
st.markdown("### " + translations['risk_distribution_title'])
|
204 |
def extract_risk_score(risk_assessment):
|
@@ -213,6 +234,8 @@ def main(language):
|
|
213 |
color='risk_score', color_continuous_scale=px.colors.sequential.RdBu)
|
214 |
st.plotly_chart(fig_risk, use_container_width=True)
|
215 |
|
|
|
|
|
216 |
# Rozk艂ad oszustw wed艂ug kraj贸w
|
217 |
st.markdown("### " + translations['fraud_country_distribution_title'])
|
218 |
def get_country(row):
|
@@ -241,27 +264,32 @@ def main(language):
|
|
241 |
else:
|
242 |
st.info(translations['no_data'])
|
243 |
|
244 |
-
|
|
|
|
|
245 |
st.markdown("### " + translations['heatmap_title'])
|
246 |
-
# Heatmapa oszustw na podstawie lokalizacji
|
247 |
if not fraud_countries.empty:
|
248 |
-
# Przygotowanie danych geograficznych
|
249 |
-
|
|
|
|
|
250 |
fraud_countries,
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
)
|
260 |
-
fig_heatmap.
|
261 |
st.plotly_chart(fig_heatmap, use_container_width=True)
|
262 |
else:
|
263 |
st.info(translations['no_data'])
|
264 |
|
|
|
|
|
265 |
# Gauge Chart - Procentowy udzia艂 oszustw
|
266 |
st.markdown("### " + translations['fraud_percentage'])
|
267 |
fig_gauge = go.Figure(go.Indicator(
|
@@ -286,3 +314,5 @@ def main(language):
|
|
286 |
}
|
287 |
))
|
288 |
st.plotly_chart(fig_gauge, use_container_width=True)
|
|
|
|
|
|
7 |
import json
|
8 |
import os
|
9 |
import re
|
10 |
+
from datetime import datetime, timedelta
|
11 |
import pycountry
|
12 |
|
13 |
+
# Opcjonalne: Importowanie dodatkowych komponent贸w
|
14 |
from streamlit_extras.metric_cards import style_metric_cards
|
15 |
+
# Je艣li korzystasz z streamlit_elements, upewnij si臋, 偶e jest zainstalowany
|
16 |
+
# from streamlit_elements import elements, mui, html
|
17 |
|
18 |
# Definiowanie 艣cie偶ek do plik贸w JSON
|
19 |
FAKE_NUMBERS_FILE = os.path.join('data', 'fake_numbers.json')
|
|
|
34 |
'frauds_over_time': "Liczba Wykrytych Oszustw w Czasie",
|
35 |
'risk_distribution_title': "Rozk艂ad Ocen Ryzyka Oszustwa",
|
36 |
'fraud_country_distribution_title': "Rozk艂ad Oszustw Wed艂ug Kraj贸w",
|
37 |
+
'heatmap_title': "Heatmapa Oszustw w Czasie",
|
38 |
'fraud_trend_title': "Trendy Oszustw w Czasie",
|
39 |
'risk_distribution': "Rozk艂ad Ocen Ryzyka Oszustwa",
|
40 |
'fraud_country_distribution': "Rozk艂ad Oszustw Wed艂ug Kraj贸w",
|
|
|
41 |
'fraud_vs_nonfraud': "Procentowy Podzia艂: Oszustwa vs Bezpieczne",
|
42 |
'no_data': "Brak dost臋pnych danych do wy艣wietlenia.",
|
43 |
'download_button': "馃摜 Pobierz dane jako CSV",
|
|
|
56 |
'frauds_over_time': "Anzahl der erkannten Betr眉gereien im Laufe der Zeit",
|
57 |
'risk_distribution_title': "Verteilung der Betrugsrisikobewertungen",
|
58 |
'fraud_country_distribution_title': "Betrug nach L盲ndern",
|
59 |
+
'heatmap_title': "Heatmap der Betr眉gereien im Laufe der Zeit",
|
60 |
'fraud_trend_title': "Betrugstrends im Laufe der Zeit",
|
61 |
'risk_distribution': "Verteilung der Betrugsrisikobewertungen",
|
62 |
'fraud_country_distribution': "Betrug nach L盲ndern",
|
|
|
63 |
'fraud_vs_nonfraud': "Prozentanteil: Betrug vs Sichere Nachrichten",
|
64 |
'no_data': "Keine Daten zur Anzeige verf眉gbar.",
|
65 |
'download_button': "馃摜 Daten als CSV herunterladen",
|
|
|
78 |
'frauds_over_time': "Number of Detected Frauds Over Time",
|
79 |
'risk_distribution_title': "Distribution of Fraud Risk Scores",
|
80 |
'fraud_country_distribution_title': "Fraud Distribution by Countries",
|
81 |
+
'heatmap_title': "Fraud Heatmap Over Time",
|
82 |
'fraud_trend_title': "Fraud Trends Over Time",
|
83 |
'risk_distribution': "Distribution of Fraud Risk Scores",
|
84 |
'fraud_country_distribution': "Fraud Distribution by Countries",
|
|
|
85 |
'fraud_vs_nonfraud': "Fraud vs Safe Messages Percentage",
|
86 |
'no_data': "No data available to display.",
|
87 |
'download_button': "馃摜 Download data as CSV",
|
|
|
111 |
"""Zapisuje dane do pliku JSON."""
|
112 |
with open(file_path, 'w', encoding='utf-8') as file:
|
113 |
json.dump(data, file, ensure_ascii=False, indent=4)
|
114 |
+
st.success(f"Dane zosta艂y zapisane do {file_path}.")
|
115 |
|
116 |
def get_stats_from_json():
|
117 |
"""Pobiera statystyki z pliku stats.json."""
|
|
|
148 |
# Stylizacja kart metryk
|
149 |
style_metric_cards()
|
150 |
|
151 |
+
# Wy艣wietlenie metryk
|
152 |
+
col1, col2, col3 = st.columns(3)
|
153 |
+
col1.metric(label=translations['total_analyses'], value=total_analyses)
|
154 |
+
col2.metric(label=translations['total_frauds_detected'], value=total_frauds_detected)
|
155 |
+
if total_analyses > 0:
|
156 |
+
fraud_percentage = (total_frauds_detected / total_analyses) * 100
|
157 |
+
else:
|
158 |
+
fraud_percentage = 0 # Ustawienie na 0% w przypadku braku analiz
|
159 |
+
col3.metric(label=translations['fraud_percentage'], value=f"{fraud_percentage:.2f}%")
|
160 |
+
|
161 |
+
st.markdown("---")
|
162 |
+
|
163 |
+
# Dodanie interaktywnego filtra daty w g艂贸wnym obszarze strony
|
164 |
+
st.header(translations['history_title'])
|
165 |
+
|
|
|
166 |
if history:
|
167 |
df_history = pd.DataFrame(history)
|
168 |
# Upewnij si臋, 偶e 'timestamp' jest w formacie datetime
|
169 |
df_history['timestamp'] = pd.to_datetime(df_history['timestamp'])
|
170 |
+
|
171 |
+
# Definiowanie domy艣lnego zakresu dat
|
172 |
+
default_start_date = datetime.now().date() - timedelta(days=translations['recent_days'])
|
173 |
+
default_end_date = datetime.now().date()
|
174 |
+
|
175 |
+
# Filtry daty
|
176 |
+
start_date, end_date = st.date_input(
|
177 |
+
translations['select_date_range'],
|
178 |
+
value=(default_start_date, default_end_date),
|
179 |
+
min_value=df_history['timestamp'].dt.date.min(),
|
180 |
+
max_value=df_history['timestamp'].dt.date.max()
|
181 |
+
)
|
182 |
+
|
183 |
# Filtracja na podstawie daty
|
184 |
mask = (df_history['timestamp'].dt.date >= start_date) & (df_history['timestamp'].dt.date <= end_date)
|
185 |
df_filtered = df_history.loc[mask]
|
|
|
190 |
fraud_percentage_filtered = (frauds_filtered / total_filtered) * 100 if total_filtered > 0 else 0
|
191 |
|
192 |
# Wy艣wietlenie metryk dla filtrowanej historii
|
193 |
+
st.subheader(translations['fraud_trend_title'])
|
194 |
+
col4, col5, col6 = st.columns(3)
|
195 |
+
col4.metric(label=translations['total_analyses'], value=total_filtered)
|
196 |
+
col5.metric(label=translations['total_frauds_detected'], value=frauds_filtered)
|
197 |
+
col6.metric(label=translations['fraud_percentage'], value=f"{fraud_percentage_filtered:.2f}%")
|
198 |
+
|
199 |
+
st.markdown("---")
|
200 |
|
201 |
# Wizualizacja procentowego podzia艂u oszustw
|
202 |
st.markdown("### " + translations['fraud_vs_nonfraud'])
|
|
|
207 |
fig_fraud_pie.update_layout(title_text=translations['fraud_vs_nonfraud'])
|
208 |
st.plotly_chart(fig_fraud_pie, use_container_width=True)
|
209 |
|
210 |
+
st.markdown("---")
|
211 |
+
|
212 |
# Trend oszustw w czasie
|
213 |
st.markdown("### " + translations['frauds_over_time'])
|
214 |
fraud_over_time = df_filtered.groupby(df_filtered['timestamp'].dt.date)['phone_number'].count().reset_index()
|
|
|
218 |
fig_trend.update_traces(line=dict(color='firebrick'))
|
219 |
st.plotly_chart(fig_trend, use_container_width=True)
|
220 |
|
221 |
+
st.markdown("---")
|
222 |
+
|
223 |
# Rozk艂ad ocen ryzyka
|
224 |
st.markdown("### " + translations['risk_distribution_title'])
|
225 |
def extract_risk_score(risk_assessment):
|
|
|
234 |
color='risk_score', color_continuous_scale=px.colors.sequential.RdBu)
|
235 |
st.plotly_chart(fig_risk, use_container_width=True)
|
236 |
|
237 |
+
st.markdown("---")
|
238 |
+
|
239 |
# Rozk艂ad oszustw wed艂ug kraj贸w
|
240 |
st.markdown("### " + translations['fraud_country_distribution_title'])
|
241 |
def get_country(row):
|
|
|
264 |
else:
|
265 |
st.info(translations['no_data'])
|
266 |
|
267 |
+
st.markdown("---")
|
268 |
+
|
269 |
+
# Heatmapa oszustw w czasie (opcjonalnie)
|
270 |
st.markdown("### " + translations['heatmap_title'])
|
|
|
271 |
if not fraud_countries.empty:
|
272 |
+
# Przygotowanie danych geograficznych
|
273 |
+
# U偶yjemy szeroko艣ci i d艂ugo艣ci geograficznej kraj贸w
|
274 |
+
# Tworzenie mapy g臋sto艣ci oszustw
|
275 |
+
fig_heatmap = px.scatter_geo(
|
276 |
fraud_countries,
|
277 |
+
locations='iso_alpha',
|
278 |
+
color='counts',
|
279 |
+
hover_name='country',
|
280 |
+
size='counts',
|
281 |
+
projection="natural earth",
|
282 |
+
title=translations['heatmap_title'],
|
283 |
+
color_continuous_scale=px.colors.sequential.Plasma,
|
284 |
+
size_max=50
|
285 |
)
|
286 |
+
fig_heatmap.update_geos(showcountries=True, showcoastlines=True, showcountries=True)
|
287 |
st.plotly_chart(fig_heatmap, use_container_width=True)
|
288 |
else:
|
289 |
st.info(translations['no_data'])
|
290 |
|
291 |
+
st.markdown("---")
|
292 |
+
|
293 |
# Gauge Chart - Procentowy udzia艂 oszustw
|
294 |
st.markdown("### " + translations['fraud_percentage'])
|
295 |
fig_gauge = go.Figure(go.Indicator(
|
|
|
314 |
}
|
315 |
))
|
316 |
st.plotly_chart(fig_gauge, use_container_width=True)
|
317 |
+
|
318 |
+
st.markdown("---")
|