sentimarttt / src /views /performance.py
myreport12's picture
Upload 23 files
6acab55 verified
Raw
History Blame Contribute Delete
3.95 kB
import pandas as pd
import streamlit as st
import plotly.graph_objects as go
import plotly.express as px
from utils.metrics_data import load_metrics
st.markdown("## 📈 Performa Model")
st.caption("Evaluasi komprehensif model IndoBERT yang telah di-fine-tune pada dataset PRDECT-ID.")
metrics = load_metrics()
if metrics.get("is_demo"):
st.warning(
"Menampilkan data demo (hasil aktual dari Progress Proposal). "
"Letakkan `metrics.json` hasil training di `model/metrics.json` untuk data real-time. "
"Lihat `export_metrics_snippet.py`."
)
cm = metrics["confusion_matrix"]
# ---- 4 kartu metrik ----
c1, c2, c3, c4 = st.columns(4)
card_specs = [
("ACCURACY", metrics["accuracy"], "Persentase prediksi benar dari seluruh data uji", c1),
("PRECISION", metrics["precision"], "Ketepatan prediksi positif dari semua prediksi positif", c2),
("RECALL", metrics["recall"], "Kemampuan menemukan semua sampel positif aktual", c3),
("F1-SCORE", metrics["f1"], "Harmonic mean dari Precision dan Recall", c4),
]
for label, val, desc, col in card_specs:
with col:
with st.container(border=True):
st.caption(f"⭐ {label}")
st.markdown(f"### {val*100:.1f}%")
st.caption(desc)
st.write("")
col_cm, col_curve = st.columns(2)
with col_cm:
with st.container(border=True):
st.markdown(f"**Confusion Matrix**")
st.caption(f"Test set · {metrics.get('n_test', cm['tn']+cm['fp']+cm['fn']+cm['tp'])} sampel")
z = [[cm["tp"], cm["fn"]], [cm["fp"], cm["tn"]]]
x_labels = ["Pred: Positive", "Pred: Negative"]
y_labels = ["Actual: Positive", "Actual: Negative"]
fig_cm = go.Figure(data=go.Heatmap(
z=z, x=x_labels, y=y_labels,
colorscale=[[0, "#eef2ff"], [1, "#4338ca"]],
text=z, texttemplate="%{text}", textfont={"size": 20},
showscale=False,
))
fig_cm.update_layout(margin=dict(l=10, r=10, t=10, b=10), height=320)
st.plotly_chart(fig_cm, use_container_width=True)
m1, m2 = st.columns(2)
m1.metric("True Positive + True Negative", cm["tp"] + cm["tn"])
m2.metric("False Positive + False Negative", cm["fp"] + cm["fn"])
with col_curve:
with st.container(border=True):
st.markdown("**Kurva Pelatihan**")
st.caption("Training & validation loss per epoch")
epochs = list(range(1, len(metrics["train_loss"]) + 1))
fig_curve = go.Figure()
fig_curve.add_trace(go.Scatter(
x=epochs, y=metrics["train_loss"], mode="lines+markers",
name="Training Loss", line=dict(color="#4338ca"),
))
fig_curve.add_trace(go.Scatter(
x=epochs, y=metrics["val_loss"], mode="lines+markers",
name="Validation Loss", line=dict(color="#e74c3c"),
))
fig_curve.update_layout(
margin=dict(l=10, r=10, t=10, b=10), height=280,
xaxis_title="Epoch", yaxis_title="Loss",
legend=dict(orientation="h", yanchor="bottom", y=1.02),
)
st.plotly_chart(fig_curve, use_container_width=True)
bcol1, bcol2 = st.columns(2)
bcol1.metric("Best Val Loss", f"{min(metrics['val_loss']):.3f}")
bcol2.metric("Total Epoch", len(metrics["train_loss"]))
st.write("")
with st.expander("Lihat akurasi training vs validation per epoch"):
df_acc = pd.DataFrame({
"Epoch": list(range(1, len(metrics["train_acc"]) + 1)),
"Train Accuracy": metrics["train_acc"],
"Val Accuracy": metrics["val_acc"],
})
fig_acc = px.line(
df_acc, x="Epoch", y=["Train Accuracy", "Val Accuracy"],
markers=True, color_discrete_sequence=["#4338ca", "#e74c3c"],
)
fig_acc.update_layout(yaxis_title="Accuracy", legend_title="")
st.plotly_chart(fig_acc, use_container_width=True)
st.dataframe(df_acc, use_container_width=True, hide_index=True)