sentimarttt / src /views /batch.py
myreport12's picture
Upload 23 files
6acab55 verified
Raw
History Blame Contribute Delete
3.66 kB
import io
import pandas as pd
import streamlit as st
import plotly.express as px
from utils.model_loader import predict_batch, model_is_available
st.markdown("## 📊 Analisis Batch")
st.caption("Unggah file CSV berisi ulasan produk untuk memproses sentimen secara massal.")
with st.container(border=True):
uploaded = st.file_uploader(
"Seret & letakkan file CSV di sini, atau klik untuk memilih file dari komputer",
type=["csv"],
help="Format: CSV · Maks: 20MB · Kolom teks harus ada",
)
st.caption("📄 Format: CSV · Maks: 20MB · Kolom teks (Butuh 1 kolom berisi teks ulasan)")
st.caption("Belum ada file? [unduh contoh data](https://example.com) — atau gunakan `sample_data/contoh_ulasan.csv` di repo ini.")
if uploaded is not None:
try:
df = pd.read_csv(uploaded)
except Exception as e:
st.error(f"Gagal membaca CSV: {e}")
st.stop()
if df.empty:
st.warning("File CSV kosong.")
st.stop()
st.write("")
text_col = st.selectbox(
"Pilih kolom yang berisi teks ulasan:",
options=list(df.columns),
index=0,
)
max_rows = st.slider("Jumlah baris yang diproses (batasi untuk demo cepat)", 1, len(df), min(len(df), 200))
run = st.button("🚀 Jalankan Analisis Batch", type="primary")
if run:
subset = df.head(max_rows).copy()
texts = subset[text_col].astype(str).tolist()
progress_bar = st.progress(0.0, text="Memproses ulasan...")
def _cb(frac):
progress_bar.progress(frac, text=f"Memproses ulasan... {int(frac*100)}%")
results = predict_batch(texts, progress_callback=_cb)
progress_bar.empty()
subset["Sentimen"] = [r[0] for r in results]
subset["Confidence"] = [round(r[1] * 100, 2) for r in results]
st.success(f"Selesai! {len(subset)} ulasan berhasil dianalisis.")
st.markdown("#### Hasil Analisis")
st.dataframe(subset, use_container_width=True, height=320)
st.write("")
col_pie, col_bar = st.columns(2)
sent_counts = subset["Sentimen"].value_counts().reindex(["Positive", "Negative"]).fillna(0)
with col_pie:
fig_pie = px.pie(
names=sent_counts.index, values=sent_counts.values,
color=sent_counts.index,
color_discrete_map={"Positive": "#2ecc71", "Negative": "#e74c3c"},
title="Proporsi Sentimen",
hole=0.35,
)
st.plotly_chart(fig_pie, use_container_width=True)
with col_bar:
fig_bar = px.bar(
x=sent_counts.index, y=sent_counts.values,
color=sent_counts.index,
color_discrete_map={"Positive": "#2ecc71", "Negative": "#e74c3c"},
labels={"x": "Sentimen", "y": "Jumlah Ulasan"},
title="Distribusi Sentimen",
)
fig_bar.update_layout(showlegend=False)
st.plotly_chart(fig_bar, use_container_width=True)
csv_buffer = io.StringIO()
subset.to_csv(csv_buffer, index=False)
st.download_button(
"⬇️ Unduh Hasil Analisis (CSV)",
data=csv_buffer.getvalue(),
file_name="hasil_analisis_sentimen.csv",
mime="text/csv",
)
else:
st.info("Unggah file CSV untuk mulai menganalisis banyak ulasan sekaligus.")
if not model_is_available():
st.caption(
"⚠️ Model IndoBERT belum ditemukan — hasil batch di atas menggunakan mode demo "
"(heuristik kata kunci). Lihat README.md untuk cara memasang model asli."
)