add cleaned_text for response
Browse files
main.py
CHANGED
|
@@ -10,33 +10,70 @@ from typing import Dict, List
|
|
| 10 |
# 1. KELAS LOGIKA ANDA (Tidak ada perubahan)
|
| 11 |
# ====================================================================
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
class TextCleaner:
|
|
|
|
| 14 |
def __init__(self):
|
|
|
|
|
|
|
| 15 |
self.character = ['.', ',', ';', ':', '?', '!', '(', ')', '[', ']', '{', '}', '<', '>', '"', '/', '\'', '-', '@']
|
|
|
|
| 16 |
self.character.extend([chr(i) for i in range(ord('a'), ord('z') + 1)])
|
| 17 |
|
|
|
|
| 18 |
def repeatcharClean(self, text):
|
|
|
|
| 19 |
for char_to_clean in self.character:
|
|
|
|
|
|
|
| 20 |
pattern = re.compile(re.escape(char_to_clean) + r'{3,}')
|
|
|
|
|
|
|
| 21 |
text = pattern.sub(char_to_clean, text)
|
| 22 |
return text
|
| 23 |
|
|
|
|
| 24 |
def clean_review(self, text):
|
|
|
|
| 25 |
text = text.lower()
|
|
|
|
| 26 |
text = re.sub(r'\s+', ' ', text)
|
|
|
|
| 27 |
text = re.sub(r'[^\x00-\x7F]+', ' ', text)
|
|
|
|
|
|
|
| 28 |
new_text = []
|
|
|
|
| 29 |
for word in text.split(" "):
|
|
|
|
| 30 |
word = '@USER' if word.startswith('@') and len(word) > 1 else word
|
|
|
|
| 31 |
word = 'HTTPURL' if word.startswith('http') else word
|
| 32 |
new_text.append(word)
|
|
|
|
| 33 |
text = " ".join(new_text)
|
|
|
|
|
|
|
| 34 |
text = emoji.demojize(text)
|
|
|
|
| 35 |
text = re.sub(r':[A-Za-z_-]+:', ' ', text)
|
|
|
|
|
|
|
| 36 |
text = re.sub(r"([xX;:]'?[dDpPvVoO3)(])", ' ', text)
|
|
|
|
| 37 |
text = re.sub(r'["#$%&()*+,./:;<=>\[\]\\^_`{|}~]', ' ', text)
|
|
|
|
|
|
|
| 38 |
text = self.repeatcharClean(text)
|
|
|
|
|
|
|
| 39 |
text = re.sub(r'\s+', ' ', text).strip()
|
|
|
|
|
|
|
| 40 |
return text
|
| 41 |
|
| 42 |
class SentimentPredictor:
|
|
@@ -100,6 +137,7 @@ class BatchTextInput(BaseModel):
|
|
| 100 |
# -----------------------------------------------------------
|
| 101 |
|
| 102 |
class PredictionOutput(BaseModel):
|
|
|
|
| 103 |
sentiment: str
|
| 104 |
confidence: float
|
| 105 |
all_scores: Dict[str, float]
|
|
@@ -129,6 +167,7 @@ def predict_sentiment_batch(request: BatchTextInput):
|
|
| 129 |
cleaned_text = text_cleaner.clean_review(text)
|
| 130 |
sentiment, confidence, all_scores = sentiment_predictor.predict(cleaned_text)
|
| 131 |
results.append(PredictionOutput(
|
|
|
|
| 132 |
sentiment=sentiment,
|
| 133 |
confidence=confidence,
|
| 134 |
all_scores=all_scores
|
|
|
|
| 10 |
# 1. KELAS LOGIKA ANDA (Tidak ada perubahan)
|
| 11 |
# ====================================================================
|
| 12 |
|
| 13 |
+
# Impor library yang dibutuhkan
|
| 14 |
+
import re # Untuk operasi regular expression
|
| 15 |
+
import emoji # Untuk menangani emoji
|
| 16 |
+
|
| 17 |
+
# Definisikan sebuah kelas untuk mengelompokkan semua fungsi pembersihan teks
|
| 18 |
class TextCleaner:
|
| 19 |
+
# Metode constructor, dieksekusi saat objek TextCleaner dibuat
|
| 20 |
def __init__(self):
|
| 21 |
+
# Inisialisasi daftar karakter yang akan diperiksa untuk pengulangan.
|
| 22 |
+
# Daftar ini berisi berbagai tanda baca dan simbol.
|
| 23 |
self.character = ['.', ',', ';', ':', '?', '!', '(', ')', '[', ']', '{', '}', '<', '>', '"', '/', '\'', '-', '@']
|
| 24 |
+
# Tambahkan semua huruf abjad (a-z) ke dalam daftar karakter di atas.
|
| 25 |
self.character.extend([chr(i) for i in range(ord('a'), ord('z') + 1)])
|
| 26 |
|
| 27 |
+
# Metode untuk membersihkan karakter yang berulang lebih dari 2 kali (misal: "haaiiii" -> "haai").
|
| 28 |
def repeatcharClean(self, text):
|
| 29 |
+
# Ulangi untuk setiap karakter dalam daftar 'self.character'
|
| 30 |
for char_to_clean in self.character:
|
| 31 |
+
# Buat pola regex untuk menemukan karakter yang berulang 3 kali atau lebih secara berurutan.
|
| 32 |
+
# Contoh: jika char_to_clean adalah 'a', polanya akan mencari 'aaa' atau 'aaaa', dst.
|
| 33 |
pattern = re.compile(re.escape(char_to_clean) + r'{3,}')
|
| 34 |
+
# Ganti urutan karakter yang berulang tersebut dengan satu karakter saja.
|
| 35 |
+
# Contoh: "good moooorning" menjadi "good morning".
|
| 36 |
text = pattern.sub(char_to_clean, text)
|
| 37 |
return text
|
| 38 |
|
| 39 |
+
# Metode utama untuk menjalankan seluruh proses pembersihan teks
|
| 40 |
def clean_review(self, text):
|
| 41 |
+
# 1. Ubah semua teks menjadi huruf kecil (lowercase) untuk konsistensi.
|
| 42 |
text = text.lower()
|
| 43 |
+
# 2. Ganti spasi, tab, atau baris baru yang berlebih dengan satu spasi saja.
|
| 44 |
text = re.sub(r'\s+', ' ', text)
|
| 45 |
+
# 3. Hapus karakter non-ASCII (seperti karakter Cina, Arab, atau beberapa emoji kompleks).
|
| 46 |
text = re.sub(r'[^\x00-\x7F]+', ' ', text)
|
| 47 |
+
|
| 48 |
+
# 4. Ganti @mention dan URL dengan token placeholder.
|
| 49 |
new_text = []
|
| 50 |
+
# Pecah teks menjadi kata-kata
|
| 51 |
for word in text.split(" "):
|
| 52 |
+
# Jika kata diawali dengan '@' dan lebih dari 1 karakter, ganti dengan '@USER'.
|
| 53 |
word = '@USER' if word.startswith('@') and len(word) > 1 else word
|
| 54 |
+
# Jika kata diawali dengan 'http', ganti dengan 'HTTPURL'.
|
| 55 |
word = 'HTTPURL' if word.startswith('http') else word
|
| 56 |
new_text.append(word)
|
| 57 |
+
# Gabungkan kembali kata-kata menjadi satu kalimat.
|
| 58 |
text = " ".join(new_text)
|
| 59 |
+
|
| 60 |
+
# 5. Ubah emoji menjadi representasi teksnya (misal: 😊 -> ':smiling_face:').
|
| 61 |
text = emoji.demojize(text)
|
| 62 |
+
# 6. Hapus representasi teks emoji yang polanya seperti ':nama_emoji:'.
|
| 63 |
text = re.sub(r':[A-Za-z_-]+:', ' ', text)
|
| 64 |
+
|
| 65 |
+
# 7. Hapus emoticon umum berbasis teks seperti :), :D, :(, xD, dll.
|
| 66 |
text = re.sub(r"([xX;:]'?[dDpPvVoO3)(])", ' ', text)
|
| 67 |
+
# 8. Hapus semua tanda baca dan simbol yang tersisa.
|
| 68 |
text = re.sub(r'["#$%&()*+,./:;<=>\[\]\\^_`{|}~]', ' ', text)
|
| 69 |
+
|
| 70 |
+
# 9. Panggil metode 'repeatcharClean' untuk membersihkan karakter yang berulang.
|
| 71 |
text = self.repeatcharClean(text)
|
| 72 |
+
|
| 73 |
+
# 10. Lakukan pembersihan spasi terakhir dan hapus spasi di awal/akhir kalimat.
|
| 74 |
text = re.sub(r'\s+', ' ', text).strip()
|
| 75 |
+
|
| 76 |
+
# Kembalikan teks yang sudah bersih
|
| 77 |
return text
|
| 78 |
|
| 79 |
class SentimentPredictor:
|
|
|
|
| 137 |
# -----------------------------------------------------------
|
| 138 |
|
| 139 |
class PredictionOutput(BaseModel):
|
| 140 |
+
cleaned_text: str = None # Optional, hanya diisi pada batch
|
| 141 |
sentiment: str
|
| 142 |
confidence: float
|
| 143 |
all_scores: Dict[str, float]
|
|
|
|
| 167 |
cleaned_text = text_cleaner.clean_review(text)
|
| 168 |
sentiment, confidence, all_scores = sentiment_predictor.predict(cleaned_text)
|
| 169 |
results.append(PredictionOutput(
|
| 170 |
+
cleaned_text=cleaned_text,
|
| 171 |
sentiment=sentiment,
|
| 172 |
confidence=confidence,
|
| 173 |
all_scores=all_scores
|