Spaces:
Running
Running
# pages/Statistics.py | |
import streamlit as st | |
import pandas as pd | |
import plotly.express as px | |
import plotly.graph_objects as go | |
import re | |
from datetime import datetime | |
from utils.functions import ( | |
get_stats, | |
get_history | |
) | |
# Definiowanie t艂umacze艅 dla zak艂adki "Statystyki" | |
page_translations = { | |
'Polish': { | |
'page_title': "馃搳 Statystyki", | |
'page_icon': "馃搱", | |
'header': "馃搳 Statystyki Aplikacji", | |
'description': "Poni偶ej znajduj膮 si臋 statystyki analizy wiadomo艣ci w aplikacji.", | |
'total_analyses': "Liczba przeanalizowanych wiadomo艣ci", | |
'total_frauds_detected': "Wykryte oszustwa", | |
'fraud_percentage': "Procent oszustw", | |
'history_title': "Historia analizowanych wiadomo艣ci", | |
'frauds_over_time': "Liczba wykrytych oszustw w czasie", | |
'risk_distribution': "Rozk艂ad ocen ryzyka oszustwa", | |
'fraud_country_distribution': "Rozk艂ad oszustw wed艂ug kraj贸w", | |
'heatmap_title': "Mapa ciep艂a oszustw w czasie", | |
'fraud_vs_nonfraud': "Procentowy podzia艂: Oszustwa vs Bezpieczne", | |
'no_data': "Brak dost臋pnych danych do wy艣wietlenia." | |
}, | |
'German': { | |
'page_title': "馃搳 Statistiken", | |
'page_icon': "馃搱", | |
'header': "馃搳 Anwendungsstatistiken", | |
'description': "Nachfolgend finden Sie die Statistiken zur Nachrichtenanalyse in der Anwendung.", | |
'total_analyses': "Anzahl der analysierten Nachrichten", | |
'total_frauds_detected': "Erkannte Betr眉gereien", | |
'fraud_percentage': "Betrugsprozentsatz", | |
'history_title': "Analyseverlauf der Nachrichten", | |
'frauds_over_time': "Anzahl der erkannten Betr眉gereien im Laufe der Zeit", | |
'risk_distribution': "Verteilung der Betrugsrisikobewertungen", | |
'fraud_country_distribution': "Betrug nach L盲ndern", | |
'heatmap_title': "Heatmap der Betr眉gereien im Laufe der Zeit", | |
'fraud_vs_nonfraud': "Prozentanteil: Betrug vs Sichere Nachrichten", | |
'no_data': "Keine Daten zur Anzeige verf眉gbar." | |
}, | |
'English': { | |
'page_title': "馃搳 Statistics", | |
'page_icon': "馃搱", | |
'header': "馃搳 Application Statistics", | |
'description': "Below are the statistics of message analysis in the app.", | |
'total_analyses': "Total Messages Analyzed", | |
'total_frauds_detected': "Frauds Detected", | |
'fraud_percentage': "Fraud Percentage", | |
'history_title': "History of Analyzed Messages", | |
'frauds_over_time': "Number of Detected Frauds Over Time", | |
'risk_distribution': "Distribution of Fraud Risk Scores", | |
'fraud_country_distribution': "Fraud Distribution by Countries", | |
'heatmap_title': "Fraud Heatmap Over Time", | |
'fraud_vs_nonfraud': "Fraud vs Safe Messages Percentage", | |
'no_data': "No data available to display." | |
} | |
} | |
# G艂贸wna funkcja zak艂adki "Statystyki" | |
def main(language): | |
translations = page_translations[language] | |
# Pobieranie danych z bazy danych | |
stats = get_stats() | |
history = get_history() | |
# Kluczowe metryki | |
total_analyses = stats["total_analyses"] | |
total_frauds_detected = stats["total_frauds_detected"] | |
# Wy艣wietlenie metryk | |
st.title(translations['header']) | |
st.markdown(translations['description']) | |
col1, col2, col3 = st.columns(3) | |
col1.metric(label=translations['total_analyses'], value=total_analyses) | |
col2.metric(label=translations['total_frauds_detected'], value=total_frauds_detected) | |
# Obs艂uga dzielenia przez zero | |
if total_analyses > 0: | |
fraud_percentage = (total_frauds_detected / total_analyses) * 100 | |
else: | |
fraud_percentage = 0 # Ustawienie na 0% w przypadku braku analiz | |
col3.metric(label=translations['fraud_percentage'], value=f"{fraud_percentage:.2f}%") | |
# Wizualizacja procentowego podzia艂u oszustw | |
fraud_data = [total_frauds_detected, total_analyses - total_frauds_detected] | |
fraud_labels = ['Fraud', 'Non-Fraud'] | |
fig_fraud_pie = go.Figure(data=[go.Pie(labels=fraud_labels, values=fraud_data, hole=.3, marker_colors=['#FF6347', '#4682B4'])]) | |
fig_fraud_pie.update_layout(title_text=translations['fraud_vs_nonfraud']) | |
st.plotly_chart(fig_fraud_pie, use_container_width=True) | |
# Wy艣wietlenie historii analiz w tabeli | |
if history: | |
st.markdown(f"### {translations['history_title']}") | |
# Tworzenie DataFrame z listy s艂ownik贸w | |
df_history = pd.DataFrame(history) | |
# Upewnij si臋, 偶e 'timestamp' jest w formacie datetime | |
df_history['timestamp'] = pd.to_datetime(df_history['timestamp']) | |
# Dodanie kolumny 'date' dla wizualizacji | |
df_history['date'] = df_history['timestamp'].dt.date | |
# Wy艣wietlenie tabeli historii | |
st.dataframe(df_history[['timestamp', 'phone_number', 'risk_assessment']], height=300) | |
# Wykres ko艂owy dla ocen ryzyka | |
st.markdown(f"### {translations['risk_distribution']}") | |
# Wyodr臋bnienie ocen ryzyka | |
def extract_risk_score(risk_assessment): | |
match = re.search(r'(\d+)/10', risk_assessment) | |
return int(match.group(1)) if match else 0 | |
df_history['risk_score'] = df_history['risk_assessment'].apply(extract_risk_score) | |
risk_data = df_history['risk_score'].value_counts().sort_index() | |
risk_labels = [f'Risk {i}/10' for i in risk_data.index] | |
fig_risk_pie = go.Figure(data=[go.Pie(labels=risk_labels, values=risk_data, hole=.3, marker_colors=px.colors.sequential.RdBu)]) | |
fig_risk_pie.update_layout(title_text=translations['risk_distribution']) | |
st.plotly_chart(fig_risk_pie, use_container_width=True) | |
# Wizualizacja mapy ciep艂a (heatmap) | |
st.markdown(f"### {translations['heatmap_title']}") | |
heatmap_data = df_history.groupby('date').size().reset_index(name='count') | |
fig_heatmap = px.density_heatmap( | |
heatmap_data, | |
x='date', | |
y='count', | |
nbinsx=20, | |
nbinsy=20, | |
title=translations['heatmap_title'], | |
color_continuous_scale='Blues' | |
) | |
st.plotly_chart(fig_heatmap, use_container_width=True) | |
# Wizualizacja rozk艂adu oszustw wed艂ug kraj贸w | |
st.markdown(f"### {translations['fraud_country_distribution']}") | |
# Dodanie informacji o kraju do historii (je艣li dost臋pne) | |
# Je艣li nie masz danych o kraju, mo偶esz je doda膰 poprzez pobranie informacji o numerze telefonu | |
# Dodamy teraz prost膮 funkcj臋, kt贸ra doda kraj na podstawie numeru telefonu | |
from utils.functions import get_phone_info | |
def add_country_info(row): | |
country, _ = get_phone_info(row['phone_number']) | |
return country | |
df_history['country'] = df_history.apply(add_country_info, axis=1) | |
if 'country' in df_history.columns and df_history['country'].notnull().any(): | |
country_data = df_history['country'].value_counts().reset_index() | |
country_data.columns = ['country', 'counts'] | |
fig_map = px.choropleth( | |
country_data, | |
locations='country', | |
locationmode='country names', | |
color='counts', | |
title=translations['fraud_country_distribution'], | |
color_continuous_scale=px.colors.sequential.Plasma | |
) | |
st.plotly_chart(fig_map, use_container_width=True) | |
else: | |
st.info(translations['no_data']) | |
else: | |
st.info(translations['no_data']) | |