ShynBui/Create_Vietnamese_spelling_errors
0
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