CoolFace
Apppublic

ShynBui/Create_Vietnamese_spelling_errors

sourceHugging Faceapache-2.0updated 2y agoView on Hugging Face
0likes
utils.py626 linesDownload Raw Back to root
1import pandas as pd2import numpy as np3 4import random5import math6 7import fomula8 9##SER: Tỷ lệ lỗi đã thêm (mong muốn: < 15% - tối đa <= 30%)10SER_want = 0.1511SER_max = 0.312k_sigmoid = fomula.get_k_sigmoid(x=SER_max - SER_want)13print("k_sigmoid", k_sigmoid)14def character_replacement(text, SER, error_rate=0.03):15    '''16    :param text: Gồm 1 câu đúng chính tả17    :param error_rate: tỷ lệ lỗi sai muốn thêm18    :param C: hằng số để tính toán xác suất thay thế ký tự19    :SER: Tỷ lệ lỗi đã sửa / tổng lỗi20    :return: Gồm 1 câu sai chính tả21 22    Kết hợp phương pháp error_rate và augmentation_probability để tạo lỗi chính tả.23 24    Bàn phím QWERTY tiếng Việt:25 26    Tạo một từ điển (keyboard) chứa các ký tự và các ký tự gần đó trên bàn phím. Ví dụ, ký tự 'a' có thể được thay thế bằng 'â', 'ă', 'á',...27    Chuyển đổi văn bản thành danh sách ký tự:28 29    Sử dụng list(text) để chuyển chuỗi văn bản thành danh sách các ký tự riêng lẻ. Điều này giúp dễ dàng thay thế từng ký tự.30    Chọn ngẫu nhiên các vị trí để thay thế ký tự:31 32    Sử dụng random.sample để chọn ngẫu nhiên các vị trí dựa trên tỷ lệ lỗi. Điều này giúp tạo ra các lỗi chính tả ngẫu nhiên và đa dạng.33    Thực hiện thay thế ký tự:34 35    Với mỗi vị trí đã chọn, kiểm tra nếu ký tự đó có trong từ điển keyboard. Nếu có, chọn ngẫu nhiên một ký tự từ các ký tự gần đó trên bàn phím.36    Giữ nguyên kiểu chữ hoa hoặc chữ thường của ký tự gốc.37    Ghép lại thành chuỗi văn bản:38 39    Sử dụng ''.join(text) để ghép danh sách các ký tự lại thành chuỗi văn bản hoàn chỉnh.40    '''41 42 43    # Tính toán xác suất thay thế ký tự dựa trên error_rate sử dụng hàm logarit44    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)45 46    # Bàn phím QWERTY tiếng Việt47    keyboard = {48        'a': 'âăáàạảãấầậẩẫắằặẳẵ',49        'â': 'aăáàạảãấầậẩẫắằặẳẵ',50        'ă': 'aâáàạảãấầậẩẫắằặẳẵ',51        'á': 'aâăàạảãấầậẩẫắằặẳẵ',52        'à': 'aâăáạảãấầậẩẫắằặẳẵ',53        'ạ': 'aâăáàảãấầậẩẫắằặẳẵ',54        'ả': 'aâăáàạãấầậẩẫắằặẳẵ',55        'ã': 'aâăáàạảấầậẩẫắằặẳẵ',56        'â': 'aăáàạảãấầậẩẫắằặẳẵ',57        'b': 'vn',58        'c': 'xv',59        'd': 'đ',60        'đ': 'd',61        'e': 'êéèẹẻẽếềệểễ',62        'ê': 'eéèẹẻẽếềệểễ',63        'é': 'eêèẹẻẽếềệểễ',64        'è': 'eêéẹẻẽếềệểễ',65        'ẹ': 'eêéèẻẽếềệểễ',66        'ẻ': 'eêéèẹẽếềệểễ',67        'ẽ': 'eêéèẹẻếềệểễ',68        'ế': 'eêéèẹẻẽềệểễ',69        'ề': 'eêéèẹẻẽếệểễ',70        'ệ': 'eêéèẹẻẽếềểễ',71        'ể': 'eêéèẹẻẽếềệễ',72        'ễ': 'eêéèẹẻẽếềệ',73        'f': 'r',74        'g': 'hf',75        'h': 'g',76        'i': 'ìíỉĩị',77        'í': 'iìỉĩị',78        'ì': 'iíỉĩị',79        'ỉ': 'iíìĩị',80        'ĩ': 'iíìỉị',81        'ị': 'iíìỉĩ',82        'k': 'l',83        'l': 'k;',84        'm': 'n',85        'n': 'm',86        'o': 'ôơóòọỏõốồộổỗớờợởỡ',87        'ô': 'oơóòọỏõốồộổỗớờợởỡ',88        'ơ': 'oôóòọỏõốồộổỗớờợởỡ',89        'ó': 'oôơòọỏõốồộổỗớờợởỡ',90        'ò': 'oôơóọỏõốồộổỗớờợởỡ',91        'ọ': 'oôơóòỏõốồộổỗớờợởỡ',92        'ỏ': 'oôơóòọõốồộổỗớờợởỡ',93        'õ': 'oôơóòọỏốồộổỗớờợởỡ',94        'ố': 'oôơóòọỏõồộổỗớờợởỡ',95        'ồ': 'oôơóòọỏõốộổỗớờợởỡ',96        'ộ': 'oôơóòọỏõốồổỗớờợởỡ',97        'ổ': 'oôơóòọỏõốồộỗớờợởỡ',98        'ỗ': 'oôơóòọỏõốồộổỗớờợởỡ',99        'ớ': 'oôơóòọỏõốồộổỗờợởỡ',100        'ờ': 'oôơóòọỏõốồộổỗớờợởỡ',101        'ợ': 'oôơóòọỏõốồộổỗớờợởỡ',102        'ở': 'oôơóòọỏõốồộổỗớờợỡ',103        'ỡ': 'oôơóòọỏõốồộổỗớờợở',104        'p': 'q',105        'q': 'p',106        'r': 'f',107        's': 'd',108        't': 'y',109        'u': 'ưúùụủũứừựửữ',110        'ư': 'uúùụủũứừựửữ',111        'ú': 'uưùụủũứừựửữ',112        'ù': 'uưúụủũứừựửữ',113        'ụ': 'uưúùủũứừựửữ',114        'ủ': 'uưúùụũứừựửữ',115        'ũ': 'uưúùụủứừựửữ',116        'ứ': 'uưúùụủũừựửữ',117        'ừ': 'uưúùụủũứựửữ',118        'ự': 'uưúùụủũứừửữ',119        'ử': 'uưúùụủũứừựữ',120        'ữ': 'uưúùụủũứừựử',121        'v': 'b',122        'x': 'c',123        'y': 't',124        'z': 's'125    }126 127    # Chuyển đổi văn bản thành danh sách ký tự128    text = list(text)129 130    # Xác định số lượng ký tự cần thay thế dựa trên tỷ lệ lỗi131    num_errors = int(len(text) * error_rate)132    if num_errors < 1:133        num_errors = 1 if random.random() > 0.5 else 0134 135    # Chọn ngẫu nhiên các vị trí để thay thế ký tự136    indices = random.sample(range(len(text)), num_errors)137 138    num_of_change = 0139 140    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, - (SER - SER_want) * k_sigmoid))))141    print(sigmoid)142 143 144    for index in indices:145        if text[index].lower() in keyboard and random.random() <= augmentation_probability * sigmoid:146            num_of_change += 1147            # Lấy ngẫu nhiên một ký tự từ các ký tự gần trên bàn phím148            replacement_char = random.choice(keyboard[text[index].lower()])149            # Giữ nguyên kiểu chữ hoa hoặc chữ thường150            if text[index].isupper():151                replacement_char = replacement_char.upper()152            text[index] = replacement_char153 154    # Ghép các ký tự lại thành chuỗi văn bản hoàn chỉnh155    final_text = ''.join(text)156 157    print("character_replacement: ", num_of_change)158 159    return final_text, num_of_change160 161 162def character_insertion(text, SER, error_rate=0.03):163    '''164    :param text: Gồm 1 câu đúng chính tả165    :param error_rate: tỷ lệ lỗi sai muốn thêm166    :param C: hằng số để tính toán xác suất chèn ký tự167    :return: Gồm 1 câu sai chính tả168 169    Bàn phím QWERTY tiếng Việt:170 171    Một chuỗi ký tự bao gồm tất cả các ký tự chữ cái tiếng Việt và các ký tự dấu (â, ă, ê, ô, ơ, ư, đ).172    Chuyển đổi văn bản thành danh sách ký tự:173 174    Sử dụng list(text) để chuyển chuỗi văn bản thành danh sách các ký tự riêng lẻ. Điều này giúp dễ dàng thêm ký tự vào bất kỳ vị trí nào trong văn bản.175    Thực hiện thêm ký tự:176 177    Sử dụng vòng lặp for _ in range(num_errors) để thêm một số lượng ký tự ngẫu nhiên xác định (num_errors).178    Mỗi lần trong vòng lặp:179    Sử dụng random.randint(0, len(text)) để chọn ngẫu nhiên một vị trí trong văn bản nơi ký tự sẽ được thêm vào. Vị trí này có thể nằm ở bất kỳ đâu trong văn bản, bao gồm cả đầu và cuối văn bản.180    Sử dụng random.choice(keyboard) để chọn ngẫu nhiên một ký tự từ chuỗi keyboard.181    Sử dụng text.insert(index, char_to_insert) để thêm ký tự đã chọn vào vị trí đã chọn trong danh sách ký tự.182    Ghép lại thành chuỗi văn bản:183 184    Sử dụng ''.join(text) để ghép danh sách các ký tự lại thành chuỗi văn bản hoàn chỉnh.185    '''186 187    # Bàn phím QWERTY tiếng Việt với các ký tự gần nhau188    keyboard = 'abcdefghijklmnopqrstuvwxyzâăáàạảãấầậẩẫắằặẳẵêéèẹẻẽếềệểễìíỉĩịôơóòọỏõốồộổỗớờợởỡưúùụủũứừựửữđ'189 190    # Chuyển đổi văn bản thành danh sách ký tự để có thể thêm ký tự191    text = list(text)192 193    # Xác định số lượng ký tự cần thêm dựa trên tỷ lệ lỗi194    num_errors = int(len(text) * error_rate)195    if num_errors < 1:196        num_errors = 1 if random.random() > 0.5 else 0197 198    # Tính toán xác suất chèn ký tự dựa trên error_rate sử dụng hàm logarit199    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)200 201    num_of_change = 0202    # Thực hiện thêm ký tự tại các vị trí ngẫu nhiên203 204    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))205    print(sigmoid)206 207 208    for _ in range(num_errors):209        # Chọn ngẫu nhiên một vị trí trong văn bản để thêm ký tự210        if random.random() <= augmentation_probability * sigmoid:211            num_of_change += 1212            index = random.randint(0, len(text))213            # Chọn ngẫu nhiên một ký tự từ bàn phím214            char_to_insert = random.choice(keyboard)215            # Thêm ký tự vào vị trí đã chọn216            text.insert(index, char_to_insert)217 218    # Ghép các ký tự lại thành chuỗi văn bản219    print("character_insertion: ", num_of_change)220    return ''.join(text), num_of_change221 222 223def character_deletion(text, SER, error_rate=0.03):224    '''225    :param text: Gồm 1 câu đúng chính tả226    :param error_rate: tỷ lệ lỗi sai muốn thêm227    :param C: hằng số để tính toán xác suất xóa ký tự228    :return: Gồm 1 câu sai chính tả229 230    Thực hiện xóa ký tự:231    Sử dụng vòng lặp for _ in range(num_errors) để xóa một số lượng ký tự ngẫu nhiên xác định (num_errors).232    Mỗi lần trong vòng lặp:233    Sử dụng random.randint(0, len(text)-1) để chọn ngẫu nhiên một vị trí trong văn bản nơi ký tự sẽ bị xóa.234    Sử dụng text.pop(index) để xóa ký tự tại vị trí đã chọn.235    Ghép lại thành chuỗi văn bản:236    Sử dụng ''.join(text) để ghép danh sách các ký tự lại thành chuỗi văn bản hoàn chỉnh.237    '''238 239    # Chuyển đổi văn bản thành danh sách ký tự để có thể xóa ký tự240    text = list(text)241 242    # Xác định số lượng ký tự cần xóa dựa trên tỷ lệ lỗi243    num_errors = int(len(text) * error_rate)244    if num_errors < 1:245        num_errors = 1 if random.random() > 0.5 else 0246 247 248    # Tính toán xác suất xóa ký tự dựa trên error_rate sử dụng hàm logarit249    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)250 251    num_of_change = 0252 253    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))254    print(sigmoid)255 256    # Thực hiện xóa ký tự tại các vị trí ngẫu nhiên257    for _ in range(num_errors):258        # Chọn ngẫu nhiên một vị trí trong văn bản để xóa ký tự259        if random.random() <= augmentation_probability * sigmoid:260            if len(text) > 0:  # Đảm bảo rằng danh sách không trống261                num_of_change += 1262                index = random.randint(0, len(text) - 1)263                # Xóa ký tự tại vị trí đã chọn264                text.pop(index)265 266    # Ghép các ký tự lại thành chuỗi văn bản267    print("character_deletion: ", num_of_change)268    return ''.join(text), num_of_change269 270def character_transposition(text, SER, error_rate=0.03):271    '''272    :param text: Gồm 1 câu đúng chính tả273    :param error_rate: tỷ lệ lỗi sai muốn thêm274    :param C: hằng số để tính toán xác suất hoán đổi ký tự275    :return: Gồm 1 câu sai chính tả276 277    Thực hiện hoán đổi ký tự:278    Sử dụng vòng lặp for _ in range(num_errors) để hoán đổi một số lượng ký tự ngẫu nhiên xác định (num_errors).279    Mỗi lần trong vòng lặp:280    Sử dụng random.randint(0, len(text)-2) để chọn ngẫu nhiên một vị trí trong văn bản nơi ký tự sẽ bị hoán đổi.281    Hoán đổi hai ký tự liên tiếp tại vị trí đã chọn.282    Ghép lại thành chuỗi văn bản:283    Sử dụng ''.join(text) để ghép danh sách các ký tự lại thành chuỗi văn bản hoàn chỉnh.284    '''285 286    # Chuyển đổi văn bản thành danh sách ký tự để có thể hoán đổi ký tự287    text = list(text)288 289    # Xác định số lượng lần hoán đổi cần thực hiện dựa trên tỷ lệ lỗi290    num_errors = int(len(text) * error_rate)291    if num_errors < 1:292        num_errors = 1 if random.random() > 0.5 else 0293 294    # Tính toán xác suất hoán đổi ký tự dựa trên error_rate sử dụng hàm logarit295    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)296    num_of_change = 0297 298    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))299    print(sigmoid)300 301    # Thực hiện hoán đổi ký tự tại các vị trí ngẫu nhiên302    for _ in range(num_errors):303        # Chọn ngẫu nhiên một vị trí trong văn bản để hoán đổi ký tự304        if random.random() <= augmentation_probability * sigmoid:305            if len(text) > 1:  # Đảm bảo rằng danh sách có ít nhất 2 ký tự để hoán đổi306                num_of_change += 2307                index = random.randint(0, len(text) - 2)308                # Hoán đổi hai ký tự liên tiếp tại vị trí đã chọn309                text[index], text[index + 1] = text[index + 1], text[index]310 311    # Ghép các ký tự lại thành chuỗi văn bản312    print("character_transposition: ", num_of_change)313    return ''.join(text), num_of_change314 315def homophone_replacement(text, SER, error_rate=0.03):316    '''317    :param text: Gồm 1 câu đúng chính tả318    :param error_rate: tỷ lệ lỗi sai muốn thêm319    :param C: hằng số để tính toán xác suất thay thế từ đồng âm320    :return: Gồm 1 câu sai chính tả321 322    Thực hiện thay thế từ đồng âm:323    - Tìm các từ chứa homophones trước324    - Sử dụng augmentation_probability để xác định liệu từ đó có bị thay thế hay không325    Sử dụng ' '.join(words) để ghép danh sách các từ lại thành chuỗi văn bản hoàn chỉnh.326    '''327 328    homophones = {329        'gi': 'd',330        'd': 'gi',331        's': 'x',332        'x': 's',333        'tr': 'ch',334        'ch': 'tr',335        'r': 'd',336        'd': 'r',337        'l': 'n',338        'n': 'l',339        'c': 't',340        't': 'c',341        'v': 'b',342        'b': 'v',343        'ng': 'ngh',344        'ngh': 'ng',345        'v': 'z'346    }347 348    # Chuyển đổi văn bản thành danh sách từ để có thể thay thế từ349    words = text.split()350 351    # Xác định các từ có chứa homophones352    candidate_indices = []353    for i, word in enumerate(words):354        for key in homophones.keys():355            if key in word:356                candidate_indices.append(i)357                break358 359    # Tính toán xác suất thay thế từ dựa trên error_rate sử dụng hàm logarit360    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)361    num_of_change = 0362    # Thực hiện thay thế từ tại các vị trí ngẫu nhiên363    num_errors = int(len(text) * error_rate)364    if num_errors < 1:365        num_errors = 1 if random.random() > 0.5 else 0366 367    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))368    print(sigmoid)369 370    for _ in range(num_errors):371        if len(candidate_indices) > 0 and random.random() <= augmentation_probability * sigmoid:372            index = random.choice(candidate_indices)373            word = words[index]374            for key in homophones.keys():375                if key in word:376                    word = word.replace(key, homophones[key])377                    num_of_change += np.abs(len(key) - len(homophones[key]))378                    break  # Dừng lại sau khi thay thế lần đầu tiên để tránh thay thế nhiều lần379            words[index] = word380            candidate_indices.remove(index)  # Đảm bảo từ này không bị thay thế nhiều lần381 382    # Ghép các từ lại thành chuỗi văn bản383    print("homophone_replacement: ", num_of_change)384    return ' '.join(words), num_of_change385 386 387def common_misspelling_replacement(text, SER, error_rate=0.12):388    '''389    :param text: Gồm 1 câu đúng chính tả390    :param error_rate: tỷ lệ lỗi sai muốn thêm391    :param C: hằng số để tính toán xác suất thay thế từ sai chính tả phổ biến392    :return: Gồm 1 câu sai chính tả393 394    Thực hiện thay thế từ bằng các phiên bản sai chính tả phổ biến.395    - Tìm các từ có thể thay thế trước396    - Sử dụng augmentation_probability để xác định liệu từ đó có bị thay thế hay không397    '''398 399    # Từ điển các từ đúng chính tả và các phiên bản sai chính tả phổ biến của chúng, teen code400    common_misspellings = {401        'những': ['nhửng', 'nhừng'],402        'của': ['cuả', 'cũa'],403        'cái': ['cái', 'cã'],404        'giải': ['giãi', 'giải'],405        'pháp': ['pháp', 'fáp'],406        'đúng': ['dúng', 'đúng'],407        'rất': ['rất', 'rậc'],408        'sáng': ['sán', 'sáng'],409        'tạo': ['tạo', 'tạu']410    }411 412    # Chuyển đổi văn bản thành danh sách từ để có thể thay thế từ413    words = text.split()414 415    # Tìm các từ có thể thay thế416    candidate_indices = [i for i, word in enumerate(words) if word in common_misspellings]417 418    #Kiểm tra xem có thể thay không419    if len(candidate_indices) == 0:420        return ' '.join(words), 0421 422    # Tính toán xác suất thay thế từ dựa trên error_rate sử dụng hàm logarit423    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)424    num_of_change = 0425    # Thực hiện thay thế từ tại các vị trí ngẫu nhiên426    num_errors = int(len(text) * error_rate)427    if num_errors < 1:428        num_errors = 1 if random.random() > 0.5 else 0429 430    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))431    print(sigmoid)432 433    for _ in range(num_errors):434        if len(candidate_indices) > 0 and random.random() <= augmentation_probability * sigmoid:435            index = random.choice(candidate_indices)436            word = words[index]437            # Chọn ngẫu nhiên một phiên bản sai chính tả từ từ điển438            misspelled_word = random.choice(common_misspellings[word])439            words[index] = misspelled_word440            num_of_change += np.abs(len(misspelled_word) - len(word))441            candidate_indices.remove(index)  # Đảm bảo từ này không bị thay thế nhiều lần442 443    # Ghép các từ lại thành chuỗi văn bản444    print("common_misspelling_replacement: ", num_of_change)445    return ' '.join(words), num_of_change446 447 448def similar_character_replacement(text, SER, error_rate=0.03):449    '''450    :param text: Gồm 1 câu đúng chính tả451    :param error_rate: tỷ lệ lỗi sai muốn thêm452    :param C: hằng số để tính toán xác suất thay thế ký tự tương tự453    :return: Gồm 1 câu sai chính tả454 455    Thực hiện thay thế ký tự bằng ký tự tương tự trong bộ mã Unicode.456    - Tìm các ký tự có thể thay thế trước457    - Sử dụng augmentation_probability để xác định liệu ký tự đó có bị thay thế hay không458    '''459 460    # Từ điển các ký tự và các ký tự tương tự của chúng trong bộ mã Unicode461    similar_characters = {462        'a': ['á', 'à', 'ả', 'ã', 'ạ', 'â', 'ă'],463        'e': ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê'],464        'i': ['í', 'ì', 'ỉ', 'ĩ', 'ị'],465        'o': ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ơ'],466        'u': ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư'],467        'y': ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ'],468        'd': ['đ'],469        'A': ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Â', 'Ă'],470        'E': ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê'],471        'I': ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị'],472        'O': ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ơ'],473        'U': ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư'],474        'Y': ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ'],475        'D': ['Đ']476    }477 478    # Chuyển đổi văn bản thành danh sách ký tự để có thể thay thế ký tự479    characters = list(text)480 481    # Xác định các ký tự có thể thay thế482    candidate_indices = [i for i, char in enumerate(characters) if char in similar_characters]483 484    # Tính toán xác suất thay thế ký tự dựa trên error_rate sử dụng hàm logarit485    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)486    num_of_change = 0487    # Thực hiện thay thế ký tự tại các vị trí ngẫu nhiên488    num_errors = int(len(text) * error_rate)489    if num_errors < 1:490        num_errors = 1 if random.random() > 0.5 else 0491 492    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))493    print(sigmoid)494 495    for _ in range(num_errors):496        if len(candidate_indices) > 0 and random.random() <= augmentation_probability * sigmoid:497            num_of_change += 1498            index = random.choice(candidate_indices)499            char = characters[index]500            # Chọn ngẫu nhiên một ký tự tương tự từ từ điển501            similar_char = random.choice(similar_characters[char])502            characters[index] = similar_char503            candidate_indices.remove(index)  # Đảm bảo ký tự này không bị thay thế nhiều lần504 505    # Ghép các ký tự lại thành chuỗi văn bản506    print("similar_character_replacement: ", num_of_change)507    return ''.join(characters), num_of_change508 509 510def random_space_insertion(text, SER, error_rate=0.025):511    '''512    :param text: Gồm 1 câu đúng chính tả513    :param error_rate: tỷ lệ lỗi sai muốn thêm514    :param C: hằng số để tính toán xác suất chèn khoảng trắng ngẫu nhiên515    :return: Gồm 1 câu sai chính tả516 517    Thực hiện chèn khoảng trắng ngẫu nhiên vào giữa từ.518    '''519 520    # Chuyển đổi văn bản thành danh sách ký tự để có thể chèn khoảng trắng521    characters = list(text)522 523    # Tìm các vị trí có thể chèn khoảng trắng524    candidate_indices = [i for i in range(1, len(characters))]525 526    # Tính toán xác suất chèn khoảng trắng dựa trên error_rate sử dụng hàm logarit527    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)528    num_of_change = 0529    # Thực hiện chèn khoảng trắng tại các vị trí ngẫu nhiên530    num_errors = int(len(text) * error_rate)531    if num_errors < 1:532        num_errors = 1 if random.random() > 0.5 else 0533 534    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))535    print(sigmoid)536 537    for _ in range(num_errors):538        if len(candidate_indices) > 0 and random.random() <= augmentation_probability * sigmoid:539            num_of_change += 1540            index = random.choice(candidate_indices)541            characters.insert(index, ' ')542            candidate_indices.remove(index)  # Đảm bảo không chèn khoảng trắng nhiều lần tại cùng một vị trí543 544    # Ghép các ký tự lại thành chuỗi văn bản545    print("random_space_insertion: ", num_of_change)546    return ''.join(characters), num_of_change547 548def random_space_removal(text, SER, error_rate=0.01):549    '''550    :param text: Gồm 1 câu đúng chính tả551    :param error_rate: tỷ lệ lỗi sai muốn thêm552    :param C: hằng số để tính toán xác suất bỏ dấu cách553    :return: Gồm 1 câu bị thiếu dấu cách554 555    Thực hiện bỏ ngẫu nhiên một vài dấu cách giữa các từ.556    '''557 558    # Tính toán xác suất bỏ dấu cách dựa trên error_rate sử dụng hàm logarit559    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)560    num_of_change = 0561    # Tìm các vị trí có thể bỏ dấu cách (giữa các từ)562    words = text.split()563    candidate_indices = [i for i in range(len(words) - 1)]564 565    # Nếu num_errors không được cung cấp, tính toán số lượng dấu cách cần bỏ dựa trên error_rate566    num_errors = int(len(text) * error_rate)567    if num_errors < 1:568        num_errors = 1 if random.random() > 0.5 else 0569 570    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))571    print(sigmoid)572 573    # Thực hiện bỏ dấu cách tại các vị trí ngẫu nhiên574    selected_indices = random.sample(candidate_indices, min(num_errors, len(candidate_indices)))575    for index in selected_indices:576        if random.random() <= augmentation_probability * sigmoid:577            num_of_change += 1578            words[index] = words[index] + words[index + 1]579            words[index + 1] = ''  # Xóa từ đã ghép để tránh lặp lại580 581    # Ghép các từ lại thành chuỗi văn bản, bỏ qua các từ trống582    print("random_space_removal: ", num_of_change)583    return ' '.join([word for word in words if word]), num_of_change584 585 586 587import unidecode588 589def remove_vietnamese_accents(text, SER, error_rate=0.05):590    '''591    :param text: Gồm 1 câu có dấu tiếng Việt592    :param error_rate: tỷ lệ lỗi sai muốn thêm593    :param C: hằng số để tính toán xác suất chuyển đổi ký tự594    :param num_errors: số lượng lỗi sai muốn thêm (tuỳ chọn)595    :return: Gồm 1 câu không dấu tiếng Việt với một tỷ lệ lỗi nhất định596 597    Thực hiện chuyển đổi các ký tự có dấu thành các ký tự không dấu tương ứng với xác suất nhất định.598    '''599 600    # Tính toán xác suất chuyển đổi ký tự dựa trên error_rate sử dụng hàm logarit601    augmentation_probability = fomula.AP_fomula(error_rate=error_rate)602 603    # Chuyển đổi văn bản thành danh sách ký tự để có thể chuyển đổi ký tự604    characters = list(text)605 606    num_of_change = 0607    num_errors = int(len(text) * error_rate)608    if num_errors < 1:609        num_errors = 1 if random.random() > 0.5 else 0610 611    # Xác định các ký tự có thể chuyển đổi612    candidate_indices = [i for i, char in enumerate(characters) if unidecode.unidecode(char) != char]613 614    sigmoid = 1 if SER <= SER_want else (1 - (1 / (1 + pow(math.e, -(SER - SER_want) * k_sigmoid))))615    print(sigmoid)616 617    # Thực hiện chuyển đổi ký tự tại các vị trí ngẫu nhiên618    selected_indices = random.sample(candidate_indices, min(num_errors, len(candidate_indices)))619    for index in selected_indices:620        if random.random() <= augmentation_probability * sigmoid:621            num_of_change += 1622            characters[index] = unidecode.unidecode(characters[index])623 624    print("remove_vietnamese_accents: ", num_of_change)625    # Ghép các ký tự lại thành chuỗi văn bản626    return ''.join(characters), num_of_change