Spaces:
Running
Running
| import regex | |
| import nltk | |
| from nltk.tokenize import RegexpTokenizer | |
| from nltk.corpus import stopwords as nltk_stopwords, wordnet | |
| from nltk.stem import PorterStemmer, WordNetLemmatizer | |
| from langdetect import detect, LangDetectException | |
| for pkg in ("stopwords", "punkt_tab", "wordnet", "averaged_perceptron_tagger_eng", "omw-1.4"): | |
| nltk.download(pkg, quiet=True) | |
| _tokenizer = RegexpTokenizer(r"(?u)\w+") | |
| _stemmer = PorterStemmer() | |
| _lemmatizer = WordNetLemmatizer() | |
| _stop_words = set(nltk_stopwords.words("english")) | |
| slang_map = { | |
| 'faggt': 'faggot', 'faggo': 'faggot', 'fagget': 'faggot', 'faggit': 'faggot', | |
| 'fagg': 'faggot', 'faggets': 'faggot', 'faggoty': 'faggot', 'faggish': 'faggot', | |
| 'fukk': 'fuck', 'fukken': 'fuck', 'fukking': 'fuck', 'fukker': 'fuck', | |
| 'fukkin': 'fuck', 'fukked': 'fuck', 'fuuck': 'fuck', 'fuucker': 'fuck', | |
| 'fuckk': 'fuck', 'fuckoff': 'fuck', 'fuckking': 'fuck', | |
| 'shiit': 'shit', 'shitt': 'shit', 'shitty': 'shit', 'shittin': 'shit', 'shitter': 'shit', | |
| 'niggaz': 'nigger', 'niggah': 'nigger', 'niggars': 'nigger', 'nigga': 'nigger', | |
| 'niggas': 'nigger', 'niggerlover': 'nigger', 'niggering': 'nigger', | |
| 'niggerism': 'nigger', 'niggerfaggot': 'nigger', 'sandnigger': 'nigger', | |
| 'sandniggers': 'nigger', | |
| 'dumbass': 'dumb', 'jackass': 'jerk', 'asshole': 'asshole', 'assholes': 'asshole', | |
| 'asshat': 'asshole', 'asswipe': 'asshole', 'assclown': 'asshole', | |
| 'assbitch': 'asshole', 'bitchass': 'asshole', 'cuntass': 'asshole', | |
| 'punkass': 'asshole', 'lameass': 'asshole', 'gayass': 'asshole', | |
| 'fatass': 'asshole', 'smartass': 'asshole', 'badass': 'asshole', | |
| 'pussyfuck': 'pussy', 'pussylicker': 'pussy', 'pussyass': 'pussy', | |
| 'goddamned': 'goddamn', 'goddamnit': 'goddamn', | |
| 'bullshitter': 'bullshit', 'bullshitting': 'bullshit', | |
| 'pissfuck': 'fuck', 'buttfuck': 'fuck', 'killyou': 'kill', | |
| } | |
| malayslangdict = { | |
| "2": "itu", "6be": "nombor", "abeh": "habis", "abes": "habis", "abih": "habis", | |
| "abg": "abang", "ade": "ada", "ader": "ada", "ado": "ada", "diaorg": "dia orang", | |
| "xtau": "tak tahu", "xde": "takde", "xnak": "tak nak", "siallah": "sial lah", | |
| "ape": "apa", "skrg": "sekarang", "wtf": "what the heck", "fucuk": "fuck", | |
| "cb": "cibai", "knl": "kenal", "bodohla": "bodoh la", "hado": "ada", | |
| "adk": "adik", "adek": "adik", "adeq": "adik", "adlh": "adalah", "agk": "agak", | |
| "aje": "sahaja", "ajer": "sahaja", "je": "sahaja", "shj": "sahaja", "ja": "sahaja", | |
| "jek": "sahaja", "jer": "sahaja", "saje": "sahaja", "ak": "aku", "ako": "aku", | |
| "aq": "aku", "akk": "kakak", "akn": "akan", "ambik": "ambil", "amek": "ambil", | |
| "hambek": "ambil", "ank": "anak", "antar": "hantar", "ap": "apa", "aper": "apa", | |
| "hapa": "apa", "haper": "apa", "apasal": "apa pasal", "apesal": "apa pasal", | |
| "apahal": "apa hal", "apehal": "apa hal", "apetah": "apa entah", "arap": "harap", | |
| "ari": "hari", "aritu": "hari itu", "asalkn": "asalkan", "aslkn": "asalkan", | |
| "asik": "asyik", "asl": "asal", "ati": "hati", "ats": "atas", "awat": "kenapa", | |
| "awt": "kenapa", "awk": "awak", "awl": "awal", "ayer": "air", "ayh": "ayah", | |
| "ayt": "ayat", "b": "ber", "br": "ber", "bagitau": "bagi tahu", | |
| "bgitau": "bagi tahu", "bgtu": "bagi tahu", "bgtaw": "bagi tahu", | |
| "bitau": "bagi tahu", "bapak": "bapa", "bape": "berapa", "baper": "berapa", | |
| "brp": "berapa", "bpe": "berapa", "braper": "berapa", "bby": "baby", "bc": "baca", | |
| "bca": "baca", "bdak": "budak", "dak": "budak", "bdn": "badan", "brd": "bandar", | |
| "bndar": "bandar", "bdoh": "bodoh", "beb": "babe", "beger": "burger", | |
| "bekfes": "breakfast", "belen": "balance", "beno": "benar", "benor": "benar", | |
| "bnr": "benar", "bbeno": "benar-benar", "bebeno": "benar-benar", | |
| "bebenor": "benar-benar", "benti": "berhenti", "bes": "best", "besaq": "besar", | |
| "beso": "besar", "besor": "besar", "bese": "biasa", "biase": "biasa", | |
| "betoi": "betul", "betol": "betul", "betui": "betul", "bg": "bagi", "bgi": "bagi", | |
| "bgai": "bagai", "bgini": "begini", "gini": "begini", "bgitu": "begitu", | |
| "gitu": "begitu", "bgkai": "bangkai", "bgkus": "bungkus", "bgn": "bangun", | |
| "bgs": "bagus", "bgus": "bagus", "bgsa": "bangsa", "bgun": "bangun", | |
| "bhasa": "bahasa", "bhs": "bahasa", "bhse": "bahasa", "bhgn": "bahagian", | |
| "bia": "biar", "biaq": "biar", "bile": "bila", "bla": "bila", "ble": "bila", | |
| "bior": "biar", "bj": "baju", "bju": "baju", "bjet": "bajet", "bjya": "berjaya", | |
| "bk": "buka", "bka": "buka", "bkak": "buka", "bkk": "buka", "bkn": "bukan", | |
| "blah": "pergi", "blaja": "belajar", "blja": "belajar", "bljar": "belajar", | |
| "bljr": "belajar", "blanja": "belanja", "blnj": "belanja", "bleh": "boleh", | |
| "blh": "boleh", "bley": "boleh", "blek": "balik", "blik": "balik", "blk": "balik", | |
| "blkg": "belakang", "blkng": "belakang", "blm": "belum", "blom": "belum", | |
| "blum": "belum", "bln": "bulan", "blj": "belanja", "blnja": "belanja", | |
| "bls": "balas", "bnd": "benda", "bnde": "benda", "bndg": "banding", | |
| "bngsa": "bangsa", "bntu": "bantu", "bnyk": "banyak", "byk": "banyak", | |
| "bodo": "bodoh", "borg": "borang", "borng": "borang", "brader": "bro", | |
| "brg": "barang", "brlku": "berlaku", "bru": "baru", "bsr": "besar", | |
| "bsar": "besar", "bt": "buat", "bwat": "buat", "wat": "buat", "wt": "buat", | |
| "btl": "betul", "btpe": "buat apa", "watpe": "buat apa", "wtpe": "buat apa", | |
| "bw": "bawa", "bwa": "bawa", "bwak": "bawa", "bwh": "bawah", "byak": "banyak", | |
| "byr": "bayar", "camna": "macam mana", "camne": "macam mana", | |
| "camner": "macam mana", "cmna": "macam mana", "cmne": "macam mana", | |
| "cmner": "macam mana", "cmana": "macam mana", "cmane": "macam mana", | |
| "cmaner": "macam mana", "camni": "macam ni", "cmnie": "macam ni", | |
| "cbe": "cuba", "ce": "cuba", "cer": "cuba", "cbok": "sibuk", "cdgn": "cadangan", | |
| "cdgan": "cadangan", "cdgkn": "cadangkan", "cdgkan": "cadangkan", | |
| "chat": "sihat", "cite": "cerita", "citer": "cerita", "crita": "cerita", | |
| "crite": "cerita", "crta": "cerita", "cter": "cerita", "cket": "sikit", | |
| "ckit": "sikit", "skit": "sikit", "ckp": "cakap", "ckap": "cakap", | |
| "ckup": "cukup", "cm": "macam", "mcm": "macam", "cmburu": "cemburu", | |
| "cme": "cuma", "cmpur": "campur", "cmtu": "camtu", "cna": "sana", "cni": "sini", | |
| "cnta": "cinta", "cntik": "cantik", "cntk": "cantik", "come": "comel", | |
| "comei": "comel", "comolot": "cium mulut", "cpt": "cepat", "cepat": "cepat", | |
| "cr": "cara", "cri": "cari", "crik": "cari", "ct": "siti", "cth": "contoh", | |
| "cntoh": "contoh", "ctu": "situ", "stu": "situ", "d": "di", "da": "sudah", | |
| "dah": "sudah", "dh": "sudah", "ddk": "duduk", "dduk": "duduk", "duk": "duduk", | |
| "de": "ada", "dea": "dia", "dek": "adik", "deq": "adik", "dik": "adik", | |
| "derg": "dia orang", "dorg": "dia orang", "diorg": "dia orang", | |
| "dorng": "dia orang", "dgn": "dengan", "dgan": "dengan", "dgr": "dengar", | |
| "dgar": "dengar", "die": "dia", "dier": "dia", "dkt": "dekat", "dkat": "dekat", | |
| "dl": "dahulu", "dlu": "dahulu", "dlm": "dalam", "dlam": "dalam", "dn": "dan", | |
| "dpt": "dapat", "dpat": "dapat", "dpn": "depan", "dpan": "depan", "dr": "dari", | |
| "dari": "dari", "drpd": "daripada", "dtg": "datang", "ekceli": "actually", | |
| "fhm": "faham", "fkir": "fikir", "pk": "fikir", "fmly": "family", "g": "pergi", | |
| "gado": "gaduh", "gdh": "gaduh", "gak": "juga", "giler": "gila", "gle": "gila", | |
| "gler": "gila", "gtuh": "begitu", "gtu": "begitu", "gmba": "gambar", | |
| "gmbar": "gambar", "gmbor": "gambar", "gmbr": "gambar", "gna": "guna", | |
| "gne": "guna", "hbgn": "hubungan", "hbs": "habis", "hdp": "hadap", | |
| "hdup": "hidup", "hepi": "happy", "heran": "hairan", "hg": "hang", | |
| "hgpa": "hangpa", "hjg": "hujung", "hlg": "hilang", "hmpa": "hampa", | |
| "hmpir": "hampir", "hntr": "hantar", "hny": "hanya", "hnya": "hanya", | |
| "hnye": "hanya", "hosp": "hospital", "i": "saya", "spital": "hospital", | |
| "hrga": "harga", "hri": "hari", "hrp": "harap", "hrap": "harap", | |
| "hutg": "hutang", "hutng": "hutang", "igt": "ingat", "jap": "sekejap", | |
| "jd": "jadi", "jdi": "jadi", "jeles": "jealous", "jg": "juga", "jga": "juga", | |
| "jgk": "juga", "jgak": "juga", "jugak": "juga", "juge": "juga", "jgn": "jangan", | |
| "jilake": "celaka", "jln": "jalan", "jmp": "jumpa", "jmpa": "jumpa", | |
| "jnis": "jenis", "jnji": "janji", "jntn": "jantan", "jwb": "jawab", | |
| "jawab": "jawab", "jwpn": "jawapan", "jwtn": "jawatan", "k": "okay", "ka": "ke", | |
| "kabo": "khabar", "kate": "kata", "kawen": "kahwin", "kawin": "kahwin", | |
| "kcik": "kecil", "kecik": "kecil", "kechik": "kecil", "kcuali": "kecuali", | |
| "kdg2": "kadang-kadang", "kekadang": "kadang-kadang", "keja": "kerja", | |
| "keje": "kerja", "kejer": "kerja", "kje": "kerja", "krja": "kerja", | |
| "kg": "kampung", "kite": "kita", "kte": "kita", "kjaan": "kerajaan", | |
| "krjaan": "kerajaan", "klu": "kalau", "kn": "kan", "knp": "kenapa", | |
| "ko": "kau", "korg": "kau orang", "kpd": "kepada", "krn": "kerana", | |
| "kat": "dekat", "kt": "dekat", "ktorg": "kita orang", "kuar": "keluar", | |
| "kwn": "kawan", "kwsn": "kawasan", "lbh": "lebih", "lbih": "lebih", | |
| "lg": "lagi", "lgi": "lagi", "lgpun": "lagipun", "lgsg": "langsung", | |
| "lh": "lah", "lmbt": "lambat", "lme": "lama", "lncr": "lancar", "lyn": "layan", | |
| "mane": "mana", "mbe": "member", "mcmne": "macam mana", "mcmner": "macam mana", | |
| "mcmni": "macam ini", "mcmnie": "macam ini", "mcmtu": "macam itu", | |
| "mcmtue": "macam itu", "men": "main", "mende": "benda", "mggu": "minggu", | |
| "mgkin": "mungkin", "mgkn": "mungkin", "mkn": "makan", "mksd": "maksud", | |
| "mmg": "memang", "mmng": "memang", "mmpu": "mampu", "mn": "mana", "mne": "mana", | |
| "mnx": "minta", "mintak": "minta", "mtk": "minta", "mrk": "mereka", | |
| "msk": "masuk", "mslh": "masalah", "msti": "mesti", "nak": "hendak", | |
| "nk": "hendak", "ne": "mana", "ngan": "dengan", "ngn": "dengan", "ni": "ini", | |
| "nie": "ini", "nih": "ini", "nmpk": "nampak", "nmpak": "nampak", "nnt": "nanti", | |
| "nnti": "nanti", "t": "nanti", "ntah": "entah", "tah": "entah", "nye": "punya", | |
| "org": "orang", "olh": "oleh", "p": "pergi", "pd": "pada", "pdhal": "padahal", | |
| "pebenda": "apa benda", "pg": "pagi", "pgi": "pagi", "pggl": "panggil", | |
| "pjg": "panjang", "pnjg": "panjang", "plak": "pula", "plg": "paling", | |
| "plk": "pelik", "pn": "pun", "pndai": "pandai", "pnh": "penuh", | |
| "prnah": "pernah", "pntg": "penting", "pnting": "penting", "pnye": "punya", | |
| "ppuan": "perempuan", "psl": "fasal", "pstu": "lepas itu", "ptg": "petang", | |
| "ptt": "patut", "pyh": "payah", "retis": "artis", "rkn": "rakan", | |
| "rkyat": "rakyat", "rkyt": "rakyat", "rmai": "ramai", "rmh": "rumah", | |
| "rs": "rasa", "rsa": "rasa", "rse": "rasa", "sado": "sasa", "sape": "siapa", | |
| "sbb": "sebab", "sbg": "sebagai", "sbr": "sabar", "scr": "secara", | |
| "sdar": "sedar", "sdp": "sedap", "sdr": "sedar", "sg": "sungai", | |
| "sgala": "segala", "sggh": "singgah", "sggp": "sanggup", "snggup": "sanggup", | |
| "sgguh": "sungguh", "sgka": "sangka", "sgt": "sangat", "shbt": "sahabat", | |
| "skg": "sekarang", "skang": "sekarang", "skunk": "sekarang", | |
| "skrang": "sekarang", "sknx": "sekarang", "ske": "suka", "suke": "suka", | |
| "sklh": "sekolah", "slh": "salah", "sllu": "selalu", "slmt": "selamat", | |
| "slamat": "selamat", "sme": "sama", "smlm": "semalam", "smp": "sampai", | |
| "smpai": "sampai", "smpi": "sampai", "sndiri": "sendiri", "sne": "sana", | |
| "sng": "senang", "sorg": "seorang", "spt": "seperti", "spy": "supaya", | |
| "ssh": "susah", "sume": "semua", "sy": "saya", "syg": "sayang", "tau": "tahu", | |
| "taw": "tahu", "tawu": "tahu", "tdo": "tidur", "tido": "tidur", | |
| "tggi": "tinggi", "tnggi": "tinggi", "tggjwb": "tanggungjawab", | |
| "tggl": "tinggal", "tgu": "tunggu", "tggu": "tunggu", "tgh": "tengah", | |
| "tgk": "tengok", "tgok": "tengok", "tngk": "tengok", "tgn": "tangan", | |
| "thn": "tahun", "tkt": "tingkat", "tkut": "takut", "tlg": "tolong", | |
| "tmbah": "tambah", "tmbh": "tambah", "tmpat": "tempat", "tmpt": "tempat", | |
| "tntg": "tentang", "ttg": "tentang", "tp": "tapi", "tpi": "tapi", | |
| "tpt": "tepat", "trs": "terus", "trus": "terus", "ttp": "tetap", | |
| "ttpi": "tetapi", "tu": "itu", "tue": "itu", "utk": "untuk", "uol": "you all", | |
| "uols": "you all", "uolls": "you all", "wlu": "walau", "wlpn": "walaupun", | |
| "wlpun": "walaupun", "wpun": "walaupun", "wslm": "waalaikumsalam", | |
| "x": "tak", "xde": "tak ada", "xder": "tak ada", "takde": "tak ada", | |
| "takder": "tak ada", "xkn": "tak akan", "xkan": "tak akan", | |
| "takkan": "tak akan", "xle": "tak boleh", "xleh": "tak boleh", | |
| "takleh": "tak boleh", "xmau": "tak mahu", "xnk": "tak nak", "xnak": "tak nak", | |
| "taknak": "tak nak", "xpe": "tak apa", "xper": "tak apa", "takpe": "tak apa", | |
| "takper": "tak apa", "y": "yang", "yg": "yang", "zmn": "zaman", | |
| } | |
| def _clean_text(text: str) -> str: | |
| text = regex.sub(r'https?://\S+', '', text) | |
| text = regex.sub(r'\{\|.*?\|\}', '', text, flags=regex.DOTALL) | |
| text = regex.sub(r'\|[\w\s=""""#;:]+', '', text) | |
| text = regex.sub(r'style="""".*?""""', '', text) | |
| text = regex.sub(r'<.*?>', '', text) | |
| text = regex.sub(r'#[0-9a-fA-F]{3,6}', '', text) | |
| text = regex.sub(r'\b(background-color|vertical-align|padding|border|font-size|rowspan|colspan|height|width)\b.*?;', '', text) | |
| words = text.split() | |
| words = [w for w in words if not (len(w) > 25 and regex.search(r'[^aeiou]{10,}', w.lower()))] | |
| text = " ".join(words) | |
| text = regex.sub(r'\b\d+[\d.,]+\b', '', text) | |
| text = regex.sub(r'[^\w\s]', ' ', text) | |
| text = regex.sub(r'\s+', ' ', text).strip() | |
| return text | |
| def _get_wordnet_pos(tag: str): | |
| if tag.startswith("J"): | |
| return wordnet.ADJ | |
| elif tag.startswith("V"): | |
| return wordnet.VERB | |
| elif tag.startswith("N"): | |
| return wordnet.NOUN | |
| elif tag.startswith("R"): | |
| return wordnet.ADV | |
| return wordnet.NOUN | |
| def detect_language(text: str) -> str: | |
| """Returns 'ms' for Malay, 'en' for everything else.""" | |
| try: | |
| lang = detect(text) | |
| return "ms" if lang == "ms" else "en" | |
| except LangDetectException: | |
| return "en" | |
| def preprocess(text: str, lang: str) -> str: | |
| """ | |
| Preprocess text to match training pipeline. | |
| lang: 'en' or 'ms' | |
| """ | |
| cleaned = _clean_text(text) | |
| tokens = _tokenizer.tokenize(cleaned.lower()) | |
| if lang == "ms": | |
| tokens = [malayslangdict.get(t, t) for t in tokens] | |
| return " ".join(tokens) | |
| tokens = [slang_map.get(t, t) for t in tokens] | |
| tokens = [t for t in tokens if t not in _stop_words] | |
| tokens = [_stemmer.stem(t) for t in tokens] | |
| pos_tags = nltk.pos_tag(tokens) | |
| tokens = [_lemmatizer.lemmatize(t, _get_wordnet_pos(pos)) for t, pos in pos_tags] | |
| return " ".join(tokens) | |