yogie27 commited on
Commit
38119cf
·
verified ·
1 Parent(s): 714617c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +191 -0
app.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import numpy as np
3
+ from transformers import AutoTokenizer, RobertaTokenizerFast, AutoModelForSequenceClassification, RobertaForSequenceClassification
4
+ import torch
5
+ from collections import Counter
6
+ from langdetect import detect, LangDetectException
7
+ import re
8
+
9
+ # Definisi huruf vokal
10
+ def has_vowel(word):
11
+ vowels = 'aeiouAEIOU'
12
+ return any(char in vowels for char in word)
13
+
14
+ # Definisi huruf sama berurutan
15
+ def has_consecutive_letters(word):
16
+ count = 1
17
+ for i in range(1, len(word)):
18
+ if word[i] == word[i - 1]:
19
+ count += 1
20
+ if count >= 3:
21
+ return True
22
+ else:
23
+ count = 1
24
+ return False
25
+
26
+ # Fungsi untuk mengecek apakah suatu kata hanya terdiri dari angka atau tanda baca
27
+ def is_number_or_punctuation(word):
28
+ return word.isdigit() or re.match(r'^[\W_]+$', word)
29
+
30
+ # Definisi model Transformers
31
+ @st.cache_resource()
32
+ def get_model():
33
+ tokenizer = AutoTokenizer.from_pretrained("flax-community/indonesian-roberta-base")
34
+ model1 = AutoModelForSequenceClassification.from_pretrained("yogie27/IndoRoBERTa-Base-Sentiment-Indonesian-Social-Media")
35
+ model2 = AutoModelForSequenceClassification.from_pretrained("yogie27/IndoRoBERTa-Base-Emotion-Indonesian-Social-Media")
36
+
37
+ return tokenizer, model1, model2
38
+ #model2, model3
39
+
40
+ tokenizer, model1, model2 = get_model()
41
+
42
+ st.image("banner_edit.png", use_container_width=True)
43
+ header = st.title("IndoRoBERTa: Klasifikasi Sentimen dan Emosi Berbasis Teks Bahasa Indonesia.")
44
+ note1 = st.caption("**Author: Yogie Oktavianus Sihombing**")
45
+ note2 = st.write(
46
+ #"EMOSI dan SENTIMEN adalah dua konsep yang berbeda meskipun saling terkait. EMOSI adalah keadaan psikologis yang kompleks dan alami, seperti kebahagiaan atau kemarahan, yang terdiri dari pengalaman subjektif, respons fisiologis, dan respons perilaku. Emosi bersifat mentah dan dapat dipicu oleh berbagai situasi atau kondisi individu.
47
+ "SENTIMEN adalah sikap mental atau pemikiran yang dipengaruhi oleh emosi, dan lebih terorganisir serta sering kali mencerminkan hubungan dengan objek sosial tertentu, seperti cinta atau kebencian. Sentimen menggabungkan aspek kognitif, fisiologis, dan sosial budaya, menjadikannya lebih dari sekadar respons emosional. (Ivanov, 2023)​")
48
+ #note3 = st.write("Ujaran kebencian (HATE SPEECH) adalah tindakan komunikasi dalam bentuk provokasi, hasutan, atau penghinaan terhadap individu atau kelompok berdasarkan aspek seperti ras, warna kulit, etnis, gender, cacat, orientasi seksual, kewarganegaraan, agama, dan lain-lain. Hal ini dapat berupa perkataan, tulisan, atau tindakan yang dilarang karena berpotensi memicu tindakan kekerasan atau prasangka​.(Dictionary.com).")
49
+ st.info("Input teks Anda di kolom bawah dan tekan 'ANALISIS' untuk mulai prediksi. Tekan 'RESET' untuk atur ulang halaman.")
50
+
51
+ # Klasifikasi sentimen
52
+ sentimen = {
53
+ 2: 'POSITIVE',
54
+ 1: 'NEUTRAL',
55
+ 0: 'NEGATIVE'
56
+ }
57
+
58
+ # Klasifikasi emosi
59
+ emosi = {
60
+ 4: 'SADNESS',
61
+ 3: 'LOVE',
62
+ 2: 'HAPPY',
63
+ 1: 'FEAR',
64
+ 0: 'ANGER'
65
+ }
66
+
67
+ # Klasifikasi hatespeech
68
+ hate = {
69
+ 1: 'BUKAN HATE SPEECH',
70
+ 0: 'HATE SPEECH'
71
+ }
72
+
73
+ # Definisi kategori prediksi
74
+ def get_confidence_level(prob):
75
+ if prob >= 0.90:
76
+ return "**Excellent**"
77
+ elif prob >= 0.80:
78
+ return "**Very High**"
79
+ elif prob >= 0.70:
80
+ return "**High**"
81
+ elif prob >= 0.60:
82
+ return "**Moderate**"
83
+ else:
84
+ return "**Low**"
85
+
86
+ # Membuat form
87
+ user_input = st.text_area('**MASUKKAN / SALIN TEKS DARI MEDIA SOSIAL:**')
88
+ with st.form(key='my_form'):
89
+ button = st.form_submit_button("ANALISIS")
90
+ reset_button = st.form_submit_button("RESET")
91
+
92
+ if button and user_input:
93
+ if len(user_input.split()) > 2:
94
+ english_word_count = 0
95
+ indonesian_word_count = 0
96
+ warning_count = 0
97
+ for word in user_input.split():
98
+ # Mengabaikan angka dan tanda baca
99
+ if is_number_or_punctuation(word):
100
+ continue
101
+ try:
102
+ lang = detect(word)
103
+ if lang == 'en':
104
+ english_word_count += 1
105
+ elif lang == 'id':
106
+ indonesian_word_count += 1
107
+ if has_consecutive_letters(word):
108
+ st.warning(f"Kata '{word}' memiliki tiga atau lebih huruf yang sama berurutan, mungkin mempengaruhi konteks dan prediksi.")
109
+ warning_count += 1
110
+ if not has_vowel(word):
111
+ st.warning(f"Kata '{word}' tidak memiliki huruf vokal, mungkin mempengaruhi konteks dan prediksi.")
112
+ warning_count += 1
113
+ except LangDetectException:
114
+ # Tidak menampilkan peringatan jika kata hanya angka atau tanda baca
115
+ continue
116
+
117
+ if warning_count > 7:
118
+ st.error("Warning lebih dari 7, analisis prediksi dihentikan, perbaiki kembali kalimat Anda.")
119
+ else:
120
+ if english_word_count > indonesian_word_count:
121
+ st.warning("Kalimat ini dominan dalam bahasa Inggris, mungkin mempengaruhi konteks dan prediksi.")
122
+
123
+ inputs = tokenizer([user_input], padding=True, truncation=True, max_length=512, return_tensors='pt')
124
+
125
+ output1 = model1(**inputs)
126
+ output2 = model2(**inputs)
127
+ #output3 = model3(**inputs)
128
+
129
+ logits1 = output1.logits
130
+ logits2 = output2.logits
131
+ #logits3 = output3.logits
132
+
133
+ max_sentiment_index = torch.argmax(logits1, dim=1).item()
134
+ max_sentiment_prob = torch.softmax(logits1, dim=1).squeeze()[max_sentiment_index].item()
135
+
136
+ max_emotion_index = torch.argmax(logits2, dim=1).item()
137
+ max_emotion_prob = torch.softmax(logits2, dim=1).squeeze()[max_emotion_index].item()
138
+
139
+ #max_hatespeech_index = torch.argmax(logits3, dim=1).item()
140
+ #max_hatespeech_prob = torch.softmax(logits3, dim=1).squeeze()[max_hatespeech_index].item()
141
+
142
+ sentiment_confidence = get_confidence_level(max_sentiment_prob)
143
+ emotion_confidence = get_confidence_level(max_emotion_prob)
144
+ #hatespeech_confidence = get_confidence_level(max_hatespeech_prob)
145
+
146
+ st.write("Sentimen =", f"**{sentimen[max_sentiment_index]}**", ": Score =", f"**{max_sentiment_prob:.2%}**", f"({sentiment_confidence})")
147
+ st.write("Emosi =", f"**{emosi[max_emotion_index]}**", ": Score =", f"**{max_emotion_prob:.2%}**", f"({emotion_confidence})")
148
+ #st.write("Hate Speech =", f"**{hate[max_hatespeech_index]}**", ": Prediksi =", f"**{max_hatespeech_prob:.2%}**", f"({hatespeech_confidence})")
149
+ else:
150
+ st.error("Kalimat kurang dari 3 kata, input kembali pada kolom teks.")
151
+
152
+ if reset_button:
153
+ st.experimental_rerun()
154
+
155
+ st.markdown("""
156
+ <style>
157
+ div.stButton > button:first-child {
158
+ background-color: green;
159
+ color: white;
160
+ }
161
+ div.stButton > button:last-child {
162
+ background-color: red;
163
+ color: white;
164
+ }
165
+ .stForm {
166
+ border: 2px solid blue;
167
+ padding: 1em;
168
+ }
169
+ </style>
170
+ """, unsafe_allow_html=True)
171
+
172
+ # Menggabungkan beberapa catatan info
173
+ st.markdown("""
174
+ <div style="background-color: #002060; padding: 10px; border-radius: 5px; border: 1px solid #003399;">
175
+ <h3 style="color: white;">Catatan:</h3>
176
+ <ol style="color: white;">
177
+ <li><strong>Analisis selain menggunakan bahasa Indonesia tidak disarankan.</strong></li>
178
+ <li><strong>Peringatan berwarna <span style="color: yellow;">KUNING</span> muncul saat analisis sebagai reminder.</strong></li>
179
+ <ul style="margin-left: 25px;">
180
+ <li><strong>Jika <span style="color: yellow;">peringatan</span> muncul < 7, kalimat tetap dapat diprediksi. </strong></li>
181
+ <li><strong>Jika <span style="color: yellow;">peringatan</span> muncul > 7, prediksi tidak berjalan, sesuaikan kembali input teks.</strong></li>
182
+ </ul>
183
+ <li><strong>Input teks minimal 3 kata.</strong></li>
184
+ </ol>
185
+
186
+ """, unsafe_allow_html=True)
187
+
188
+ # margin HTML
189
+ st.markdown("<div style='margin-top: 20px;'></div>", unsafe_allow_html=True)
190
+
191
+ st.info("**Disclaimer** : Program ini masih dalam tahap uji coba.")