TukangSapu commited on
Commit
7b918ec
Β·
verified Β·
1 Parent(s): 573f085

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +140 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,142 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import torch
3
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
4
+ import torch.nn as nn
5
 
6
+ st.set_page_config(page_title="Dasbor Analisis Berita", page_icon="πŸš€", layout="wide")
7
+
8
+ # --- Fungsi Pemuatan Model (Menggunakan Cache untuk Efisiensi) ---
9
+
10
+ @st.cache_resource
11
+ def load_fakenews_model():
12
+ """Memuat model dan tokenizer untuk deteksi berita palsu."""
13
+ st.info("Memuat model Deteksi Berita Palsu...")
14
+ tokenizer = AutoTokenizer.from_pretrained("vikram71198/distilroberta-base-finetuned-fake-news-detection")
15
+ model = AutoModelForSequenceClassification.from_pretrained("vikram71198/distilroberta-base-finetuned-fake-news-detection")
16
+ return tokenizer, model
17
+
18
+ @st.cache_resource
19
+ def load_topic_classifier():
20
+ """Memuat pipeline untuk klasifikasi topik berita."""
21
+ st.info("Memuat model Klasifikasi Topik...")
22
+ device = 0 if torch.cuda.is_available() else -1
23
+ classifier = pipeline("text-classification", model="classla/multilingual-IPTC-news-topic-classifier", device=device, max_length=512, truncation=True)
24
+ return classifier
25
+
26
+ @st.cache_resource
27
+ def load_summarizer():
28
+ """Memuat pipeline untuk peringkasan teks."""
29
+ st.info("Memuat model Peringkas Teks...")
30
+ device = 0 if torch.cuda.is_available() else -1
31
+ summarizer = pipeline("summarization", model="Falconsai/text_summarization", device=device)
32
+ return summarizer
33
+
34
+ # --- Memuat semua model di awal ---
35
+ # Menampilkan pesan loading saat model diunduh/dimuat untuk pertama kali
36
+ with st.spinner("Mempersiapkan semua model AI... Ini mungkin memakan waktu beberapa saat pada pemuatan pertama."):
37
+ fakenews_tokenizer, fakenews_model = load_fakenews_model()
38
+ topic_classifier = load_topic_classifier()
39
+ summarizer = load_summarizer()
40
+
41
+ # --- Antarmuka Pengguna (UI) Streamlit ---
42
+ st.title("πŸš€ Dasbor Analisis Berita Cerdas")
43
+ st.markdown("Analisis berita secara komprehensif: deteksi keaslian, identifikasi topik, dan dapatkan ringkasan instan.")
44
+
45
+ st.markdown("---")
46
+
47
+ user_input = st.text_area("Masukkan teks artikel berita yang ingin Anda analisis:", height=250, placeholder="Salin dan tempel artikel berita lengkap di sini...")
48
+
49
+ analyze_button = st.button("✨ Analisis Sekarang!", type="primary")
50
+
51
+ # --- Logika Backend dan Tampilan Hasil ---
52
+ if analyze_button and user_input:
53
+ # Memastikan input tidak terlalu pendek
54
+ if len(user_input.split()) < 40:
55
+ st.warning("Teks terlalu pendek. Harap masukkan artikel yang lebih panjang untuk hasil yang akurat.")
56
+ else:
57
+ with st.spinner("Menganalisis keaslian, topik, dan membuat ringkasan..."):
58
+
59
+ # --- Proses 1: Deteksi Berita Palsu ---
60
+ encoded_input = fakenews_tokenizer(user_input, truncation=True, padding="max_length", max_length=512, return_tensors='pt')
61
+ output_logits = fakenews_model(**encoded_input)["logits"]
62
+ softmax = nn.Softmax(dim=1)
63
+ probs = softmax(output_logits.detach())
64
+ prob_real, prob_fake = probs.squeeze().tolist()
65
+
66
+ jenis_berita_label = "Berita Nyata" if prob_real > prob_fake else "Berita Palsu"
67
+ jenis_berita_score = prob_real if prob_real > prob_fake else prob_fake
68
+
69
+ # --- Proses 2: Klasifikasi Topik ---
70
+ topic_result = topic_classifier(user_input)[0]
71
+ tema_label = topic_result['label'].title()
72
+ tema_score = topic_result['score']
73
+
74
+ # --- Proses 3: Peringkasan Teks ---
75
+ try:
76
+ # 1. Hitung jumlah token pada teks input.
77
+ input_token_count = len(fakenews_tokenizer.encode(user_input))
78
+
79
+ # 2. Tentukan target panjang ringkasan (misal, 20% dari input)
80
+ # dan batasi (clamp) dalam rentang yang aman (minimal 70, maksimal 250 token).
81
+ target_length = input_token_count // 5 # Target 20% dari panjang input
82
+
83
+ # Pastikan target tidak kurang dari 70 dan tidak lebih dari 250
84
+ safe_max_length = max(70, min(250, target_length))
85
+ safe_min_length = max(50, safe_max_length // 2) # min_length = setengah dari max_length
86
+
87
+ st.info(f"Panjang Input: {input_token_count} token. Target ringkasan: ~{safe_max_length} token.")
88
+
89
+ # 3. Panggil summarizer dengan parameter yang sudah dihitung dan aman
90
+ summary_result = summarizer(
91
+ user_input,
92
+ max_length=safe_max_length,
93
+ min_length=safe_min_length,
94
+ do_sample=False
95
+ )[0]
96
+ ringkasan_teks = summary_result['summary_text']
97
+
98
+ except Exception as e:
99
+ st.error(f"Gagal membuat ringkasan: {e}")
100
+ ringkasan_teks = "Model tidak dapat memproses teks ini untuk diringkas."
101
+
102
+ # --- Menampilkan Hasil Sesuai Format yang Diminta ---
103
+ st.markdown("---")
104
+ st.header("Hasil Analisis Komprehensif")
105
+
106
+ # Baris 1: Jenis Berita
107
+ st.markdown("#### 1. Jenis Berita")
108
+ if jenis_berita_label == "Berita Nyata":
109
+ st.success(f"**{jenis_berita_label}**")
110
+ else:
111
+ st.error(f"**{jenis_berita_label}**")
112
+
113
+ # Baris 2: Tema
114
+ st.markdown("#### 2. Tema")
115
+ st.info(f"**{tema_label}**")
116
+
117
+ # Baris 3: Ringkasan
118
+ st.markdown("#### 3. Ringkasan")
119
+ st.markdown(f"> {ringkasan_teks}")
120
+
121
+ # Bagian Akurasi di Bawah
122
+ st.markdown("---")
123
+ st.subheader("πŸ“Š Tingkat Keyakinan Model")
124
+
125
+ col1, col2, col3 = st.columns(3)
126
+ with col1:
127
+ st.markdown("**Keaslian**")
128
+ st.progress(jenis_berita_score)
129
+ st.write(f"{jenis_berita_score:.2%}")
130
+
131
+ with col2:
132
+ st.markdown("**Topik**")
133
+ st.progress(tema_score)
134
+ st.write(f"{tema_score:.2%}")
135
+
136
+ with col3:
137
+ st.markdown("**Ringkasan**")
138
+ st.info("Tidak Berlaku (Model Generatif)")
139
+
140
+
141
+ elif analyze_button and not user_input:
142
+ st.error("Mohon masukkan teks berita terlebih dahulu untuk dianalisis.")