Ferdinann commited on
Commit
ab72c0d
Β·
verified Β·
1 Parent(s): bd99d2b

Update sentiment_app.py

Browse files
Files changed (1) hide show
  1. sentiment_app.py +57 -65
sentiment_app.py CHANGED
@@ -12,8 +12,16 @@ MODEL_NAME = "w11wo/indonesian-roberta-base-sentiment-classifier"
12
  device = 0 if torch.cuda.is_available() else -1
13
  sentiment_pipeline = pipeline("sentiment-analysis", model=MODEL_NAME, device=device)
14
 
 
15
  all_messages = []
16
 
 
 
 
 
 
 
 
17
  def process_submission(text):
18
  if not text or text.strip() == "":
19
  return "⚠️ Mohon isi komentar Anda terlebih dahulu.", gr.update()
@@ -22,102 +30,86 @@ def process_submission(text):
22
  result = sentiment_pipeline(text)[0]
23
  label = result['label'].upper()
24
 
25
- # 2. Simpan ke "Database"
26
  new_entry = {
27
- "Waktu": datetime.now().strftime("%H:%M:%S"),
28
  "Pesan": text.strip(),
29
  "Sentimen": label
30
  }
31
  all_messages.append(new_entry)
32
 
33
  # 3. Respons untuk User
34
- thanks_msg = f"""
35
- ### πŸ™ Terima kasih atas pesan Anda!
36
- Masukan Anda sangat berharga bagi kami di Posko. Pesan Anda telah kami terima dan akan segera diproses oleh tim admin.
37
- """
38
-
39
- return thanks_msg, gr.update(value="") # Clear input box
40
 
41
- def get_admin_dashboard():
42
  if not all_messages:
43
- return None, "Belum ada data pesan yang masuk."
44
 
45
- df = pd.DataFrame(all_messages)
46
 
47
- # --- VISUALISASI 1: Grafik Jenis Pesan Terbanyak ---
 
 
 
 
 
 
 
 
 
 
 
 
48
  fig, ax = plt.subplots(figsize=(8, 5))
49
  color_map = {"POSITIVE": "#4CAF50", "NEGATIVE": "#F44336", "NEUTRAL": "#FFC107"}
50
- label_map = {"POSITIVE": "Pujian/Apresiasi", "NEGATIVE": "Keluhan/Kritik", "NEUTRAL": "Pertanyaan/Info"}
51
-
52
- counts = df['Sentimen'].value_counts()
53
  counts.index = [label_map.get(i, i) for i in counts.index]
54
 
55
- sns.barplot(x=counts.index, y=counts.values, palette=[color_map.get(i.split('/')[0].upper(), "#999999") for i in counts.index], ax=ax)
56
- ax.set_title("Distribusi Jenis Pesan di Posko", fontsize=14, fontweight='bold')
57
- ax.set_ylabel("Jumlah Pesan")
58
-
59
- # --- TABEL 2: Top 10 Pesan Terbanyak (Informasi Serupa) ---
60
- # Kita mengelompokkan pesan yang mirip atau identik
61
- counter = collections.Counter([m['Pesan'].lower() for m in all_messages])
62
- top_10 = counter.most_common(10)
63
 
64
- df_top = pd.DataFrame(top_10, columns=["Isi Pesan", "Jumlah Orang"])
 
 
 
65
 
66
- return fig, df_top
67
 
68
  # --- INTERFACE GRADIO ---
69
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="emerald"), title="PoskoLog - Sistem Aspirasi Pengungsi") as demo:
70
- gr.Markdown("""
71
- # πŸ“¦ PoskoLog: Suara Pengungsi
72
- Selamat datang di layanan aspirasi digital posko. Silakan sampaikan keluhan, kebutuhan, atau pertanyaan Anda.
73
- """)
74
 
75
  with gr.Tabs():
76
- # --- TAB USER: FORM KOMENTAR ---
77
  with gr.Tab("πŸ“ Sampaikan Pesan"):
78
  with gr.Column(variant="panel"):
79
- gr.Markdown("### Formulir Aspirasi Pengungsi")
80
- user_input = gr.Textbox(
81
- label="Komentar / Masukan Anda",
82
- placeholder="Tuliskan kebutuhan atau keluhan Anda di sini (Contoh: Air bersih habis di tenda C)...",
83
- lines=4
84
- )
85
  submit_btn = gr.Button("Kirim Pesan", variant="primary")
86
-
87
- # Output area untuk ucapan terima kasih
88
  user_feedback = gr.Markdown("")
89
-
90
- gr.Markdown("""
91
- ---
92
- *Catatan: Pesan Anda akan dianalisis secara otomatis untuk memprioritaskan bantuan yang paling mendesak.*
93
- """)
94
 
95
- # --- TAB ADMIN: DASHBOARD MONITORING ---
96
- with gr.Tab("πŸ“Š Dashboard Admin (Real-time)"):
97
- gr.Markdown("### Ringkasan Informasi Posko")
98
- refresh_btn = gr.Button("πŸ”„ Perbarui Data Dashboard", variant="secondary")
 
 
 
 
 
99
 
100
  with gr.Row():
101
  with gr.Column():
102
- plot_output = gr.Plot(label="Grafik Sentimen")
103
  with gr.Column():
104
- gr.Markdown("#### πŸ“ˆ Top 10 Masukan Terbanyak")
105
- table_output = gr.Dataframe(
106
- headers=["Isi Pesan", "Jumlah Orang"],
107
- interactive=False
108
- )
109
 
110
- # Logic Interaksi
111
- submit_btn.click(
112
- fn=process_submission,
113
- inputs=user_input,
114
- outputs=[user_feedback, user_input]
115
- )
116
-
117
- refresh_btn.click(
118
- fn=get_admin_dashboard,
119
- outputs=[plot_output, table_output]
120
- )
121
 
122
  if __name__ == "__main__":
123
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
12
  device = 0 if torch.cuda.is_available() else -1
13
  sentiment_pipeline = pipeline("sentiment-analysis", model=MODEL_NAME, device=device)
14
 
15
+ # --- DATABASE SEDERHANA (In-Memory) ---
16
  all_messages = []
17
 
18
+ # Mapping Label untuk Tampilan UI
19
+ label_map = {
20
+ "POSITIVE": "Pujian/Apresiasi",
21
+ "NEGATIVE": "Keluhan/Kritik",
22
+ "NEUTRAL": "Pertanyaan/Info"
23
+ }
24
+
25
  def process_submission(text):
26
  if not text or text.strip() == "":
27
  return "⚠️ Mohon isi komentar Anda terlebih dahulu.", gr.update()
 
30
  result = sentiment_pipeline(text)[0]
31
  label = result['label'].upper()
32
 
33
+ # 2. Simpan ke Database Lokal
34
  new_entry = {
35
+ "Waktu": datetime.now().strftime("%Y-%m-%d %H:%M"),
36
  "Pesan": text.strip(),
37
  "Sentimen": label
38
  }
39
  all_messages.append(new_entry)
40
 
41
  # 3. Respons untuk User
42
+ thanks_msg = "### πŸ™ Terima kasih atas pesan Anda!\nMasukan Anda telah kami terima dan akan segera ditinjau oleh tim admin posko."
43
+ return thanks_msg, gr.update(value="")
 
 
 
 
44
 
45
+ def get_admin_dashboard(filter_val):
46
  if not all_messages:
47
+ return None, pd.DataFrame(columns=["Pesan", "Sentimen", "Jumlah"]), "Belum ada data."
48
 
49
+ df_all = pd.DataFrame(all_messages)
50
 
51
+ # --- LOGIKA FILTER ---
52
+ if filter_val != "SEMUA":
53
+ # Balik mapping untuk filter data asli
54
+ rev_map = {v: k for k, v in label_map.items()}
55
+ target = rev_map.get(filter_val)
56
+ df_filtered = df_all[df_all['Sentimen'] == target]
57
+ else:
58
+ df_filtered = df_all
59
+
60
+ if df_filtered.empty:
61
+ return None, pd.DataFrame(columns=["Pesan", "Sentimen", "Jumlah"]), f"Tidak ada data untuk kategori: {filter_val}"
62
+
63
+ # --- VISUALISASI TOTAL ---
64
  fig, ax = plt.subplots(figsize=(8, 5))
65
  color_map = {"POSITIVE": "#4CAF50", "NEGATIVE": "#F44336", "NEUTRAL": "#FFC107"}
66
+ counts = df_all['Sentimen'].value_counts()
 
 
67
  counts.index = [label_map.get(i, i) for i in counts.index]
68
 
69
+ sns.barplot(x=counts.index, y=counts.values, palette="viridis", ax=ax)
70
+ ax.set_title("Proporsi Pesan Masuk (Total)", fontsize=12, fontweight='bold')
 
 
 
 
 
 
71
 
72
+ # --- TABEL TOP 10 DENGAN KOLOM SENTIMEN ---
73
+ top_df = df_filtered.groupby(['Pesan', 'Sentimen']).size().reset_index(name='Jumlah')
74
+ top_df = top_df.sort_values(by='Jumlah', ascending=False).head(10)
75
+ top_df['Sentimen'] = top_df['Sentimen'].map(label_map) # Percantik label di tabel
76
 
77
+ return fig, top_df, f"Menampilkan {len(df_filtered)} pesan ({filter_val})"
78
 
79
  # --- INTERFACE GRADIO ---
80
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="emerald"), title="PoskoLog Dashboard") as demo:
81
+ gr.Markdown("# πŸ“¦ PoskoLog: Suara Pengungsi")
 
 
 
82
 
83
  with gr.Tabs():
84
+ # TAB USER
85
  with gr.Tab("πŸ“ Sampaikan Pesan"):
86
  with gr.Column(variant="panel"):
87
+ user_input = gr.Textbox(label="Komentar Anda", placeholder="Tulis masukan di sini...", lines=4)
 
 
 
 
 
88
  submit_btn = gr.Button("Kirim Pesan", variant="primary")
 
 
89
  user_feedback = gr.Markdown("")
 
 
 
 
 
90
 
91
+ # TAB ADMIN
92
+ with gr.Tab("πŸ“Š Dashboard Admin"):
93
+ with gr.Row():
94
+ sentiment_filter = gr.Dropdown(
95
+ choices=["SEMUA"] + list(label_map.values()),
96
+ value="SEMUA",
97
+ label="Filter Sentimen"
98
+ )
99
+ refresh_btn = gr.Button("πŸ”„ Refresh & Filter", variant="secondary")
100
 
101
  with gr.Row():
102
  with gr.Column():
103
+ plot_output = gr.Plot(label="Grafik Distribusi")
104
  with gr.Column():
105
+ gr.Markdown("#### πŸ“ˆ Top 10 Pesan Berdasarkan Filter")
106
+ table_output = gr.Dataframe(headers=["Pesan", "Sentimen", "Jumlah"], interactive=False)
107
+
108
+ status_txt = gr.Markdown("")
 
109
 
110
+ # Binding Events
111
+ submit_btn.click(fn=process_submission, inputs=user_input, outputs=[user_feedback, user_input])
112
+ refresh_btn.click(fn=get_admin_dashboard, inputs=sentiment_filter, outputs=[plot_output, table_output, status_txt])
 
 
 
 
 
 
 
 
113
 
114
  if __name__ == "__main__":
115
  demo.launch(server_name="0.0.0.0", server_port=7860)