Tamagodji/text_preprocessing
1
1import gradio as gr2import regex as re # ใช้ regex module ที่รองรับ Unicode properties3from pythainlp.tokenize import word_tokenize4 5# =============================================================================6# Section 1: Utility Functions7# =============================================================================8 9def remove_skin_tone_modifiers(text):10 """11 ลบตัวดัดแปลงสีผิวออกจากอีโมจิ รวมถึง Variation Selector (FE0F)12 """13 skin_tone_pattern = re.compile(r'[\U0001F3FB-\U0001F3FF️]')14 return skin_tone_pattern.sub('', text)15 16# =============================================================================17# Section 2: Text Adjustment Functions18# =============================================================================19 20def adjust_text_intensity(text):21 """22 ปรับระดับความเข้มของคำที่มีการซ้ำตัวอักษร เช่น23 'มากกกก' → 'มากจริง ๆ'24 แต่ถ้าซ้ำกันแค่สองตัว เช่น 'มากก' ให้คงไว้เป็นเดิม25 """26 intensity_mapping = {27 1: "{word}",28 2: "{word} ๆ",29 3: "{word} จริง ๆ",30 4: "{word} สุด ๆ",31 5: "{word} ที่สุดเลย"32 }33 34 def replacement(match):35 if len(match.group()) == 2:36 return match.group()37 word = match.group(1)38 count = len(match.group()) - len(word)39 return intensity_mapping.get(count, "{word} ที่สุดเลย").format(word=word)40 41 pattern = re.compile(r"(\w)\1{1,}")42 return pattern.sub(replacement, text)43 44def adjust_word_repetition(text):45 """46 ปรับระดับความเข้มของคำที่มีการซ้ำติดกัน เช่น47 'โอเค โอเค' → 'โอเค ๆ'48 'ดี ดี ดี' → 'ดี จริง ๆ'49 """50 intensity_mapping = {51 1: "{word}",52 2: "{word} ๆ",53 3: "{word} จริง ๆ",54 4: "{word} สุด ๆ",55 5: "{word} ที่สุดเลย",56 10: "{word} อย่างมากที่สุด"57 }58 59 def replacement(match):60 word = match.group(1)61 count = len(match.group(0).split())62 if count > 10:63 return "{word} อย่างมากที่สุด".format(word=word)64 return intensity_mapping.get(count, "{word} ที่สุดเลย").format(word=word)65 66 pattern = re.compile(r"\b(\w+)(?: \1)+\b")67 return pattern.sub(replacement, text)68 69# =============================================================================70# Section 3: Emoji Mapping Functions71# =============================================================================72 73def adjust_emoji_intensity(text, emoji_char, base_mapping):74 """75 ตรวจจับและปรับระดับความเข้มของอีโมจิที่ซ้ำกันในข้อความ76 """77 pattern = re.compile(r'(' + re.escape(emoji_char) + r'){1,}')78 79 def replacement(match):80 count = len(match.group())81 if count == 1:82 return base_mapping83 elif count == 2:84 return base_mapping + " ดี"85 elif count <= 4:86 return base_mapping + " ดีมาก"87 elif count <= 9:88 return base_mapping + " อย่างมาก"89 else:90 return base_mapping + " อย่างมากที่สุด"91 92 return pattern.sub(replacement, text)93 94def adjust_text(text, emoji_dict):95 """96 แทนที่อีโมจิด้วยคำอธิบายที่เหมาะสมจาก emoji_dict97 หากอีโมจิไม่อยู่ใน emoji_dict ให้แทนที่ด้วยคำว่า "อีโมจิ"98 """99 text = remove_skin_tone_modifiers(text)100 found_emojis = set(re.findall(r'[\U0001F300-\U0001F6FF\U0001F900-\U0001F9FF\U0001FA70-\U0001FAFF\U00002B50]', text))101 unknown_emojis = found_emojis - set(emoji_dict.keys())102 for emoji_char, mapping in emoji_dict.items():103 if emoji_char in text:104 text = adjust_emoji_intensity(text, emoji_char, mapping)105 for unknown in unknown_emojis:106 text = text.replace(unknown, "อีโมจิ")107 return text108 109# =============================================================================110# Section 4: Cleaning & Tokenizing111# =============================================================================112 113def clean_text(text, emoji_dict):114 """115 ทำความสะอาดข้อความ:116 - ปรับข้อความอีโมจิตาม emoji_dict117 - ปรับระดับความเข้มของคำที่ซ้ำตัวอักษร118 - ปรับระดับความเข้มของคำที่ซ้ำกันติดกัน119 - ลบ HTML, URL, แท็กพิเศษ และอักขระที่ไม่จำเป็น120 - ลบวงเล็บออก (โดยคงเฉพาะเนื้อหาภายใน)121 - รักษาตัวอักษร, สระ, ตัวเลข, และสัญลักษณ์ที่เกี่ยวข้อง (เช่น & / , .)122 """123 text = adjust_text(text, emoji_dict)124 text = adjust_text_intensity(text)125 text = adjust_word_repetition(text)126 text = re.sub(r"\s+", " ", text).strip()127 text = re.sub(r"<.*?>", "", text)128 text = re.sub(r"http\S+|www\S+", "", text)129 text = re.sub(r"#(\S+)", r"\1", text)130 text = re.sub(r"[\t\n\r\f\v]", " ", text)131 text = re.sub(r"[^\p{L}\p{M}\p{N}\s&/(),.]", "", text)132 text = re.sub(r"\((.*?)\)", r"\1", text)133 text = re.sub(r"\.{2,}", ".", text)134 text = re.sub(r"(,)", r" \1 ", text)135 text = re.sub(r"\s+", " ", text).strip()136 return text137 138def tokenize_text(text):139 """140 ตัดคำภาษาไทยโดยใช้ Attacut ผ่านฟังก์ชัน word_tokenize141 """142 tokens = word_tokenize(text, engine="attacut", keep_whitespace=False)143 return tokens144 145# =============================================================================146# Section 5: Gradio Interface Function147# =============================================================================148 149# กำหนดค่า emoji mapping ตัวอย่าง150# พจนานุกรมสำหรับแทนที่อีโมจิด้วยคำที่มีความหมายในภาษาไทย151emoji_dict = {152 '🤧': 'อาจสื่อถึงความผิดหวังหรือรู้สึกไม่ดีเกี่ยวกับสินค้า',153 '😚': 'แสดงความพึงพอใจหรือชื่นชอบ',154 '😃': 'ดีใจ พอใจกับสินค้า',155 '😂': 'หัวเราะ หรืออาจหมายถึงตกใจปนขำ',156 '?': 'อาจแสดงถึงข้อสงสัยเกี่ยวกับสินค้า',157 '🏽': 'อาจเป็นส่วนหนึ่งของอิโมจิสีผิว',158 '🐱': 'น่ารัก อาจเกี่ยวกับสินค้าแนวสัตว์เลี้ยง',159 'T_T': 'เสียใจ ผิดหวังกับสินค้า',160 '😣': 'รู้สึกไม่พอใจหรือผิดหวังเล็กน้อย',161 '🙁': 'ไม่ค่อยพอใจ',162 '😩': 'ผิดหวังหรือเหนื่อยใจกับสินค้า',163 '💎': 'สินค้าดูมีคุณค่า ดูพรีเมียม',164 '🤬': 'โกรธหรือไม่พอใจมาก',165 '❤': 'รักหรือชอบสินค้ามาก',166 '😀': 'พึงพอใจ',167 '😉': 'พอใจแบบขี้เล่น อาจหมายถึงแอบชอบ',168 '👑': 'สินค้าดี มีคุณภาพเหมือนของราชา',169 '👍': 'ถูกใจ ยอมรับในคุณภาพ',170 '🎉': 'ตื่นเต้นหรือดีใจที่ได้รับสินค้า',171 '🙏': 'ขอบคุณ',172 '😐': 'รู้สึกเฉย ๆ',173 '😇': 'รู้สึกดีใจหรือพึงพอใจ',174 '😵': 'ตกใจหรือผิดหวังกับสินค้า',175 '!!': 'เน้นอารมณ์ เช่น ตื่นเต้นหรือผิดหวัง',176 '??': 'แสดงความสงสัย',177 '😿': 'เศร้า ผิดหวัง',178 '🤣': 'ขำขัน หรืออาจรู้สึกงง',179 '🤐': 'ไม่อยากพูดถึงสินค้า อาจไม่พอใจ',180 '✨': 'สินค้าดูดี มีประกาย',181 '😆': 'พึงพอใจแบบขำ ๆ',182 '😕': 'สับสนหรือไม่แน่ใจเกี่ยวกับสินค้า',183 '😘': 'ชอบมากถึงขั้นส่งจุ๊บ',184 '😖': 'ผิดหวังหรือไม่ชอบสินค้า',185 '💕': 'รักหรือชอบสินค้ามาก',186 '🤜': 'แสดงถึงการยอมรับหรือเชียร์สินค้า',187 '🥰': 'รักและชอบสินค้าสุด ๆ',188 '☺': 'พึงพอใจ',189 '🤦': 'รู้สึกผิดหวังหรือเซ็ง',190 '???': 'ข้อสงสัยมาก ๆ',191 '😧': 'กังวลหรือไม่แน่ใจ',192 '😔': 'เสียใจหรือผิดหวังเล็กน้อย',193 '😯': 'ตกใจหรือคาดไม่ถึง',194 '?!': 'ตกใจและสงสัยในเวลาเดียวกัน',195 '🤲': 'ขอบคุณหรือขอร้อง',196 '😢': 'เสียใจมาก',197 '😠': 'โกรธ',198 ':(': 'ไม่พอใจ',199 '😍': 'รักหรือชอบสินค้ามาก',200 '😪': 'เบื่อหรือผิดหวัง',201 '🥺': 'อ้อนวอน หรือรู้สึกอยากได้มาก',202 '!!!!': 'ตื่นเต้นหรือแสดงอารมณ์มากขึ้น',203 '😏': 'รู้สึกดีใจแบบมีเลศนัย',204 '??????': 'ข้อสงสัยอย่างมาก',205 '😒': 'ไม่พอใจหรือเบื่อ',206 '💛': 'รักและชอบ',207 '🏻': 'อาจเป็นส่วนของอิโมจิสีผิว',208 '🚚': 'เกี่ยวกับการจัดส่ง',209 '💖': 'รักหรือชอบมาก',210 '😨': 'กลัวหรือกังวล',211 '👎': 'ไม่พอใจ',212 '😡': 'โกรธมาก',213 '😭': 'เสียใจมาก',214 '😞': 'ผิดหวัง',215 '⭐': 'ให้คะแนน เช่น 5 ดาว',216 ':)': 'ยิ้ม พอใจ',217 '♀': 'อาจเกี่ยวข้องกับเพศหญิง',218 '😥': 'กังวลหรือผิดหวัง',219 '😲': 'ตกใจ',220 '🚀': 'รวดเร็วหรือทันสมัย',221 '😅': 'รู้สึกเก้อเขินหรือขำ ๆ',222 '😑': 'ไม่พอใจ',223 '😓': 'เครียดหรือกังวล',224 '👌': 'ยอดเยี่ยม',225 '👏': 'ชื่นชม',226 '🙂': 'พึงพอใจเล็กน้อย',227 '🙄': 'รำคาญ',228 '🏼': 'อาจเป็นส่วนของอิโมจิสีผิว',229 '🖕': 'แสดงความไม่พอใจรุนแรง',230 '😊': 'รู้สึกดี',231 '😁': 'พอใจมาก',232 '😱': 'ตกใจมาก',233 '☹': 'ไม่พอใจ',234 '😄': 'พึงพอใจ',235 '😤': 'โกรธหรือไม่พอใจ',236 '🤗': 'อบอุ่นใจ',237 '!': 'เน้นอารมณ์',238 '!!!': 'ตื่นเต้นหรือเน้นอารมณ์',239 '👹': 'อาจหมายถึงสิ่งที่แย่',240 '😮': 'แปลกใจหรือตกใจ',241 '⭐': 'ให้คะแนน เช่น 5 ดาว',242 '⭐️': 'ให้คะแนน เช่น 5 ดาว, สินค้าดี มีคุณภาพ',243 ':D': 'หน้ายิ้ม'244}245 246def process_text(text):247 """248 ฟังก์ชันสำหรับประมวลผลข้อความ: ทำความสะอาดและตัดคำ249 """250 cleaned = clean_text(text, emoji_dict)251 tokens = tokenize_text(cleaned)252 return cleaned, " ".join(tokens)253 254# สร้าง Gradio Interface ด้วย widget ใหม่255iface = gr.Interface(256 fn=process_text,257 inputs=gr.Textbox(lines=5, placeholder="ป้อนข้อความที่ต้องการประมวลผล..."),258 outputs=[gr.Textbox(label="Cleaned Text"), gr.Textbox(label="Tokenized Text")],259 title="Text Preprocessing Demo",260 description="ป้อนข้อความแล้วดูผลลัพธ์หลังจากทำความสะอาดและตัดคำ"261)262 263 264if __name__ == "__main__":265 iface.launch(share=True)