Professional Documents
Culture Documents
Lab3. SỬA LỖI TỰ ĐỘNG CHO VĂN BẢN TIẾNG VIỆT
Lab3. SỬA LỖI TỰ ĐỘNG CHO VĂN BẢN TIẾNG VIỆT
Bước 1. Tách văn bản inpT thành mảng các đơn vị ati (bằng dấu cách).
Bước 2. Nếu ati chứa nguyên âm có dấu, và ati từ điển âm tiết (lỗi) thì
tách ra 4 phần: dấu thanh, phụ âm đầu, âm giữa và phụ âm cuối.
Bước 3. Tạo lại âm tiết ati mới với các thông tin cũ (gồm có phụ âm đầu,
âm giữa và phụ âm cuối) với dấu thanh đặt theo quy tắc đã nêu.
Bước 4. Ghép mảng các đơn vị ati lại thành văn bản mới outT.
Độ phức tạp thuật toán là O(n), với n là số lượng âm tiết trong văn bản.
2. Tách các dấu trong câu
Đây là một trong những nhiệm vụ tiền xử lý văn bản tiếng Việt. Do có sự nhập
nhằng giữa việc tách hay không tách một số dấu câu khi đi kèm với âm tiết, chữ viết
tắt, số,... Hơn nữa, các dấu câu chiếm tỉ lệ khá lớn trong văn bản (14.34 - 15.02%) nên
cần phải được phân tách đúng.
Trước hết, sử dụng dấu cách để tách câu đầu vào thành một mảng các đơn vị âm
tiết ai. Với mỗi đơn vị âm tiết ai đó, tách theo 3 trường hợp như sau (Hình 3.2):
+ Kí tự đặc biệt (kt) ở bên trái âm tiết (amtiet) ai, có dạng: (kt)(amtiet)
+ Kí tự đặc biệt ở bên phải ai, có dạng: (amtiet)(kt)
+ Kí tự đặc biệt ở giữa của ai, có dạng: (am)(kt)(tiet)
Thuật toán 3.2. Tách kí tự đặc biệt dựa vào cây quyết định nhị phân.
Hình 3.2. Cây quyết định nhị phân để tách các kí tự đặc biệt
Kí tự dấu câu: _ | ` ^ ~ ! @ # $ % & * ( ) - + = { } [ ] < > \ / ; : . , .. " ... '
- Thay các kí tự "|" và "_" bằng dấu cách.
- Cắt bỏ các dấu cách thừa, chỉ để lại 1 dấu cách.
- Tách dấu câu: | ... | .. | . | ? | ! | : | ; | , | ( | ) | { | } | [ | ] | < | > | " | ~ | ` |
- Không tách dấu nháy đơn (') vì phải dùng như: T'rưng, K'Ho, it's
- Không tách dấu chấm (.) sau chữ viết tắt: | Q. |, | TP. |, | TS. |, | Th. |,...
- Một số kí tự đặc biệt { - & % $ ^ # * + . } được xử lý riêng:
+ Kí tự "-" giữa 2 kí tự kề nhau, trước chữ in thường: không tách.
Ví dụ: | a-xit |, | Lê-nin |, | bê-tông |,...
+ Nếu có 1 dấu cách, hoặc dấu "-" trước âm tiết viết Hoa thì tách.
Ví dụ: Mác-Lê-nin : có 1 đơn vị âm tiết: Mác-Lê-nin
Thừa Thiên-Huế : có 2 đơn vị âm tiết: Thừa, Thiên-Huế
Cần tách ra: Mác - Lê-nin, Thừa Thiên - Huế, Bà Rịa - Vũng Tàu
Các trường hợp khác đi kèm với 1 dấu cách thì tách ra, chẳng hạn:
Mác– Lê-nin, Mác –Lê-nin => Mác – Lê-nin
+ Với các kí tự &, %, $, # thì tách ra khi đứng trước/sau kí tự
GD&ĐT, GD& ĐT, GD &ĐT => GD & ĐT
Tỉ lệ% => Tỉ lệ %, 45% => 45 %, 25$ => 25 $, dấu# => dấu #
+ Không tách dấu {# + - .} đứng trước số: #65, .5, -6, +20,...
Ngoài các kí tự dấu câu đã nêu, có thể sẽ gặp các kí tự unicode đặc biệt khác
như: , ,... và các kí tự nước ngoài thì ta sẽ thực hiện tách ra.
3. Tách các từ dính tiếng Việt
Đây là một trong những nhiệm vụ tiền xử lý văn bản tiếng Việt. Hầu hết các văn
bản được lấy tự động về từ Internet (website), có nhiều trường hợp các âm tiết tại biên
phải trên Web khi căn lề Justify thường bị dính với nhau. Chẳng hạn như "vănbản",
"hoàbình", "hànội", "cácâm",... Do vậy trước khi xử lý, cần phải tách ra cho đúng.
Đặc điểm này tương tự như trong tiếng Trung, Lào, Khmer,... có các con chữ viết liền
nhau, cần phải tách ra cho đúng mới xử lý được.
Tổng quát, xét ví dụ gồm dãy âm tiết bị dính:
Táchcáctừdính
Yêu cầu tách ra cho đúng như sau:
Tách các từ dính
Cách giải quyết:
- Cần xác định vị trí để ngắt các âm tiết ra (chèn dấu cách - space): Dùng so khớp
cực đại dựa vào từ điển âm tiết tiếng Việt để tách.
+ Xác định cửa sổ âm tiết cực đại là 7 (chữ "nghiêng" trong từ điển)
+ Duyệt từ trái sang phải hay ngược lại để tìm các ứng viên theo cửa sổ.
- Khi có từ 02 phương án tách trở lên ta gọi là nhập nhằng ranh giới. Chẳng hạn:
"hànội" => "hàn ội" / "hà nội", "cácâm" => "các âm" / "cá câm". Ta có thể dùng mô
hình n-gram mức ký tự hay mức âm tiết học từ kho ngữ liệu để tách.
Với mô hình n-gram mức âm tiết được học từ kho ngữ liệu thô âm tiết tiếng Việt,
ta sẽ có các xác suất bigram như sau:
P(nội | hà) >> P(ội | hàn) => chọn phương án tách "hà nội"
P(âm | các) >> P(cá | câm) => chọn phương án tách "các âm"
Thuật toán tổng quát tách từ dính: theo 2 bước chính sau:
Bước 1. Sinh các ứng viên dựa vào từ điển âm tiết tiếng Việt.
(Gán điểm cho các ứng viên theo nhập nhằng và ngữ cảnh).
Bước 2. Tìm dãy tách âm tiết tối ưu.
3.1. Sinh các ứng viên dựa vào từ điển âm tiết tiếng Việt
Bước này sinh ra mạng từ tiếng Việt dựa vào so khớp cực đại theo từ điển từ
vựng. Việc sinh các ứng viên từ hay tìm dãy tách từ tối ưu có thời gian phụ thuộc cửa
sổ ký tự. Trong tiếng Việt, các âm tiết có độ dài từ 1 đến 7 ký tự. Do vậy, việc chọn
cửa sổ 7 âm tiết đảm bảo yêu cầu về độ chính xác, thuật toán thực hiện nhanh và tiết
kiệm bộ nhớ.
Dùng một mảng hai chiều score[1..n, 1..7] (như một mạng ký tự) để ghi điểm cho
mỗi ứng viên aij theo cửa sổ 7 ký tự (1 ≤ i ≤ n, 1 ≤ j ≤ 7). Nếu một dãy ký tự (ci...ci-1+j)
có thể là một âm tiết (aij) trong từ điển hay ngữ liệu huấn luyện hay theo quy tắc ngôn
ngữ học thì ghi điểm cho nó bằng 1 hoặc tỉ lệ ngịch với số lượng ký tự của âm tiết,
ngược lại là +∞ như sau:
Minh hoạ sinh ứng viên mạng từ bằng đồ thị: với 2 câu ví dụ mẫu như sau:
Dãy 1. "Táchcáctừdính"
Dãy 2. "dínhcácâmtiết"
Biểu diễn đồ thị của mảng điểm số cho hai câu trên như hình 3.3 và 3.4.
7
6
5
4
3
2
1
Cửa sổ 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Dãy 1 T á c h c á c t ừ d í n h
Hình 3.3. Minh hoạ sơ đồ mạng từ được sinh theo từ điển cho Dãy 1
7
6
5
4
3
2
1
Cửa sổ 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Dãy 2 d í n h c á c â m t í ế t
Hình 3.4. Minh hoạ sơ đồ mạng từ được sinh theo từ điển cho Dãy 2
Trên đồ thị Hình 3.3, các đường liền nét (mũi tên đỏ) mô tả các âm tiết thuộc từ
điển có điểm số ở trên cạnh (mũi tên xanh) ra (≤1), ngược lại, các đường đứt nét
(màu xanh) mô tả không phải âm tiết với điểm số bằng +∞. Với mô tả đồ thị như vậy,
bài toán tách từ dính trở thành bài toán tìm đường đi ngắn nhất trên đồ thị có hướng.
(i) Dãy 1 có n = 13 ký tự, mạng ký tự được sinh theo từ điển như Hình 3.3.
Trường hợp này, chỉ có 1 phương án với tổng điểm số nhỏ nhất là 6:
(1) => (4) | (5) => (7) | (8) => (9) | (10) => (13) | (14)
Kết quả tách: Tách các từ dính
(ii) Dãy 2 có n = 13 ký tự, mạng ký tự được sinh theo từ điển như Hình 3.4.
Trường hợp này, có hai phương án có điểm số bằng nhau và bằng 6:
+ Phương án 1: (1) => (4) | (5) => (7) | (8) => (9) | (10) => (13) | (14)
Kết quả: dính các âm tiết
+ Phương án 2: (1) => (4) | (5) => (6) | (7) => (9) | (10) => (13) | (14)
Kết quả: dính cá câm tiết
Đây là trường hợp nhập nhằng chồng lấp ký tự c: (là ký tự cuối của âm tiết
trước hoặc là ký tự đầu của âm tiết sau) khi điểm số bằng nhau. Nhập nhằng này
có thể được giải quyết bằng n-gram mức âm tiết.
Thuật toán 3.3. Sinh ứng viên có cửa sổ ký tự dựa vào từ điển âm tiết.
+ Đầu vào: dãy n ký tự: a1, a2, a3, ..., an.
+ Đầu ra : mảng điểm số (mạng ký tự): score[1..n, 1..7]
B1. Lặp với mỗi ký tự ci (1 ≤ i ≤ n) {
1) Điểm số ký tự ci (j = 1): score[i, 1] 1; //ký tự luôn tồn tại.
2) Lặp với 6 ký tự kế tiếp ci: 2 ≤ j ≤ 7, (i + 1 ≤ i + j - 1 ≤ i + 6) {
a) Nếu (aij = (ci...ci+j-1) Từđiển) thì: score[i, j] 1;
ngượclại thì score[i, j] +;
}//kết thúc vòng lặp cửa sổ con 6 ký tự
} //kết thúc vòng lặp n ký tự.
B2. Trả về score; // trả về mảng điểm số của mạng ký tự.
Độ phức tạp thuật toán: Có 2 vòng lặp lồng nhau và lồng với việc tìm kiếm âm
tiết trong từ điển: B1) lặp n lần, 1) và 2) thực hiện 7 lần, a) tìm kiếm âm tiết dùng
Automat tối thiểu (MinDFA) với thời gian là O(1). Vì vậy, thuật toán 3.3 có độ phức
tạp tổng hợp là O(n), với n là số ký tự trong dãy vào.
3.2. Tìm dãy tách từ dính tối ưu
Trên cơ sở điểm số của mỗi âm tiết trong mạng: score[1..n, 1..7], ta sẽ tìm đường
đi ngắn nhất (có tổng số điểm nhỏ nhất) từ nút 1 đến nút n trên đồ thị có hướng như
mô tả trong Hình 3.3 và 3.4. Theo so khớp cực đại, số lượng m âm tiết được tách là tối
thiểu. Mỗi âm tiết có một điểm số tối đa là 1, vì thế tổng điểm số của chúng là nhỏ
nhất (≤ m). Đây là hàm mục tiêu để xác định dãy âm tiết tối ưu trong mạng ký tự theo
điểm số score[i, j].
Gọi SC(S(m)) là tổng điểm số theo phương án tách m âm tiết của dãy S. Vì thế,
phương án tối ưu thoả mãn tiêu chuẩn sau:
m
min{SC ( S ( m ) )} min score(ai ) (3.2)
m m
i 1
Trong đó, ai là âm tiết thứ i được tách, m là số lượng âm tiết được tách của S.
Từ mảng điểm số score[1..n, 1..7] và phương án tối ưu theo (3.2), tác giả đưa ra
thuật toán quy hoạch động tìm kiếm dãy âm tiết được tách tối ưu như sau:
Thuật toán 3.4. Tìm dãy tách âm tiết tối ưu.
+ Đầu vào: dãy n ký tự (c1, c2, c3, ..., cn) và mảng điểm: score[1..n,1..7]
+ Đầu ra : dãy âm tiết được tách tối ưu: SegOut.
B1. SC[0] 0; //mảng SC có n+1 phần từ bắt đầu từ 0.
B2. Lặp với mỗi i trong dãy ký tự (1 ≤ i ≤ n) {
21) SC[i] +;
22) Lặp với mỗi j từ 7 xuống 1 (j = 7 .. 1) { // cửa sổ 7 ký tự
a) Nếu (i ≥ j) thì {
a1) a c[i – j+1]; // ký tự đầu tiên của âm tiết
a2) Nếu (SC[i] > SC[i - j] + score[i – j+1, j]) thì { // tìm SC min
a21) SC[i] SC[i - j] + score[i – j+1, j];
a22) Lặp với các ký tự k từ vị trí (i – j+2) đến (i) {
i) a a & c[k]; //lấy âm tiết
} //kết thúc vòng lặp a22)
} //kết thúc a2)
a3) q[i] a; // lưu vết kết quả tách âm tiết tối ưu
} // kết thúc a)
} // kết thúc vòng lặp 22 (7 ký tự)
} // kết thúc vòng lặp B2 (n ký tự)
B3. Truy vết ngược tìm dãy âm tiết được tách từ cuối n về đầu 1, (i = n .. 1)
31) i n;
32) SegOut "";
33) Lặp {
b1) demKT len(q[i]); // đếm số ký tự của âm tiết tại q[i]
b2) SegOut q[i] & " " & SegOut; // dấu cách " " để tách âm tiết
b3) i i – demKT;
}ChoĐếnKhi (i < 1); //kết thúc vòng lặp 33.
B4. Trả về SegOut; // trả về dãy âm tiết được tách
Độ phức tạp của thuật toán:
Tại B1, cần thời gian thực hiện là O(n); Tại B2, có 3 vòng lặp lồng nhau: vòng
21 với n lần lặp, vòng lặp 22 với 7 lần lặp, và vòng lặp a22 với 6 lần lặp. Vì vậy, thời
gian thực hiện bước B2 là O(n); Tại bước B3: có 1 vòng lặp 33 duyệt các ký tự của
mỗi âm tiết trong dãy kết quả lưu vết q[i] với tổng số ký tự là n, nên cần thời gian thực
hiện là O(n). Như vậy, thuật toán 3.4 tìm dãy tách âm tiết tối ưu cần thời gian thực
hiện là O(n), với n là số ký tự của dãy vào.
3.3. Thử nghiệm tách từ dính với các kho ngữ liệu mẫu
Sự kết hợp thuật toán 3.3 sinh ứng viên dựa vào từ điển âm tiết và thuật toán 3.4
tìm dãy tách âm tiết tối ưu tạo thành thuật toán so khớp cực đại tách từ dính tiếng Việt.
Hai thuật toán 3.3 và 3.4. đều có độ phức tạp O(n), nên thuật toán kết hợp tách từ
dính AMM (thuật toán 3.3 và 3.4) cũng có độ phức tạp O(n).
Thực hiện thử nghiệm bằng cách dùng từ điển 7015 âm tiết tiếng Việt và:
+ Tạo kho ngữ liệu dính âm tiết là charVnCorpus từ kho ngữ liệu thô tiếng Việt
rawVnCorpus bằng cách loại bỏ tất cả dấu cách cho từng câu (dòng).
+ Tách âm tiết trên kho ngữ liệu charVnCorpus bằng thuật toán AMM, n-gram
+ Đánh giá kết quả thử nghiệm:
Kí hiệu: + Nm: là số đơn vị âm tiết trong văn bản mẫu (rawVnCorpus).
+ Nt : là số đơn vị âm tiết trong văn bản kết quả tách.
+ Nđ: là số đơn vị âm tiết tách đúng so với mẫu.
+ Độ hồi tưởng R (Recall) : R = Nđ/Nm (3.3)
+ Độ chính xác P (Precision) : P = Nđ/Nt (3.4)
+ Độ đo F1-score : F1 = 2RP/(R+P) (3.5)
Bảng 3.1. Thử nghiệm tách âm tiết với thuật toán AMM và ngram
Model Nm Nt Nđ R(%) P(%) F1(%)
AMM
AMM & ngram