Giới thiệu bài toán
Bài toán thêm dấu cho tiếng Việt là một bài toán khá hay và thú vị. Do đặc điểm thói quen của người dùng, do đặc điểm khác nhau của các bộ gõ, nhiều người dùng Việt Nam tạo nội dung không dấu trên internet. Đây là một thách thức lớn dành cho các nhà khoa học dữ liệu khi phải đồng bộ tất cả dữ liệu về cùng 1 dạng (tiếng Việt có dấu với cùng 1 chuẩn bộ gõ) để có thể khai thác được thông tin từ dữ liệu một cách chính xác và đầy đủ hơn.
Và bài toán này cũng là challenge thứ 3 của AIVIVN, một nền tảng giúp tổ chức các cuộc thi machine learning cho cộng đồng học sinh, sinh viên Việt Nam.
Thách thức đặt ra cho các đội là phải thêm dấu vào cho 8240 dòng tiếng Việt không dấu trong tập dữ liệu kiểm tra, mỗi dòng có thể là một câu hoặc một đoạn văn.
Trong bài viết này, mình sẽ giới thiệu tới các bạn một phương pháp đơn giản để giải quyết bài toàn này, đó là ứng dụng Machine Translation vào quá trình thêm dấu.
Giới thiệu về Machine Translation
Machine Translation là nhiệm vụ dịch một câu x ở một ngôn ngữ(ngôn ngữ nguồn) thành một câu y ở một ngôn ngữ khác(ngôn ngữ đích) mà ý nghĩa của câu không đổi.
Các hệ thống machine translation được bắt đầu nghiên cứu từ năm 1954. Trước đây, người ta giải quyết bài toán này dựa trên thống kê là chủ yếu, gọi là Statistical Machine Translation. Vài năm trở lại đây, với sự phát triển vượt bậc của các kĩ thuật học máy, Neural Machine Translation được đưa vào nghiên cứu và có những cải thiện vược bậc cho các hệ thống dịch máy. Đây là phương pháp dịch mà quá trình dịch được dựa trên 1 mạng neural duy nhất. Kiến trúc này được gọi là sequence-to-sequence( seq2seq) do đầu vào và đâu ra đều là các sequence(khác với các bài toán phân loại, hồi quy thông thường). Các kiến trúc mạng thường được sử dụng là các kiến trúc mạng cho dữ liệu dạng time-series như RNN, LSTM,… Trong bài viết này chúng ta sẽ không đi sâu vào giải thích về Machine Translation nên bạn có thể tim hiểu chi tiết về Machine translation bạn tại cs224n-2019-lecture08-nmt.
Ứng dụng Machine Translation vào bài toán thêm dấu cho tiếng Việt
Trong phần này, mình sẽ lần lượt giới thiệu tới các bạn hướng tiếp cận machine translation như thế nào, cách thức chuẩn bị dữ liệu, mã hóa dữ liệu và đưa vào mô hình training.
Chúng ta sẽ cùng bắt đầu.
Ứng dụng Machine Translation vào bài toán thêm dấuBài toán thêm dấu cho tiếng Việt được mình hiểu ở đây như một bài toán Sequence2Sequence, công việc được thực hiện tương tự như việc dịch từ một ngôn ngữ nguồn sang một ngôn ngữ đích(việc đọc dịch tiếng Việt không dấu còn mệt hơn cả đọc dịch tiếng Anh sang tiếng Việt.
Hiểu cơ bản là vậy, chúng ta bắt đầu thực hiện quá trình giải quyết bài toán.
Chuẩn bị dữ liệu dữ liệu huấn luyện
Một đặc điểm khá thú vị của bài toán này là chúng ta hoàn toàn có thể chủ động trong việc chuẩn bị dữ liệu huấn luyện, không mất quá nhiều công cho việc chuẩn bị và không phải mất công để gán nhãn cho chúng. Dữ liệu huấn luyện được sinh ra từ chính những văn bản thông thường trong tự nhiên, đầu vào là văn bản đã được xóa dấu, đầu ra của mô hình chính là văn bản gốc ban đầu( có dấu).
Trong bài hướng dấn này, mình sẽ sử dụng dữ liệu huấn luyện lấy từ Wikipedia của Việt Nam. Dữ liệu đã được kéo xuống lưu trữ theo chu kì 2 tuần 1 lần tại Wikimedia Downloads. Chọn tải về tệp viwiki-yyyymmdd-pages-articles.xml.bz2 chứa nội dung của các bài viết và giải nén bằng cách sử dụng WikiExtractor.
1 2 3 4 |
python WikiExtractor.py <path to XML wiki dump file> --processes 4 -o ./output/ --json |
Sau khi giải nén dữ liệu tải về từ Wikimedia Downloads, ta thu được 1 một tập hợp các file được lưu trữ dưới dạng jsonline(mỗi dòng trong file là một bài viết). Định dạng được lưu trữ là:
1 2 3 4 |
{"id": "", "revid": "", "url":"", "title": "", "text": "..."} |
Tất cả được lưu trữ trong thư mục output.
Nhiệm vụ của chúng ta bây giờ là từ những bài viết đó, tách ra thành các câu và lưu trữ thành file train_data.txt. Trong đó, mỗi dòng trong file train_data.txt là một câu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
PATH_DATA <span class="token operator">=</span> <span class="token string">"./output"</span> alphabet <span class="token operator">=</span> <span class="token string">'^[ _abcdefghijklmnopqrstuvwxyz0123456789áàảãạâấầẩẫậăắằẳẵặóòỏõọôốồổỗộơớờởỡợéèẻẽẹêếềểễệúùủũụưứừửữựíìỉĩịýỳỷỹỵđ!"',-.:;?_()]+$'</span> list_sub_folder <span class="token operator">=</span> os<span class="token punctuation">.</span>listdir<span class="token punctuation">(</span>PATH_DATA<span class="token punctuation">)</span> <span class="token keyword">for</span> sub_folder <span class="token keyword">in</span> <span class="token punctuation">(</span>list_sub_folder<span class="token punctuation">)</span><span class="token punctuation">:</span> path_sub_folder <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>PATH_DATA<span class="token punctuation">,</span> sub_folder<span class="token punctuation">)</span> list_file <span class="token operator">=</span> os<span class="token punctuation">.</span>listdir<span class="token punctuation">(</span>path_sub_folder<span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token builtin">file</span> <span class="token keyword">in</span> tqdm<span class="token punctuation">(</span>list_file<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>path_sub_folder<span class="token punctuation">,</span> <span class="token builtin">file</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"r"</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f_r<span class="token punctuation">:</span> contents <span class="token operator">=</span> f_r<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span> contents <span class="token operator">=</span> re<span class="token punctuation">.</span>sub<span class="token punctuation">(</span><span class="token string">"(s)+"</span><span class="token punctuation">,</span> r<span class="token string">"1"</span><span class="token punctuation">,</span> contents<span class="token punctuation">)</span> contents <span class="token operator">=</span> contents<span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">"
"</span><span class="token punctuation">)</span> <span class="token keyword">for</span> content <span class="token keyword">in</span> contents<span class="token punctuation">:</span> <span class="token keyword">try</span><span class="token punctuation">:</span> content <span class="token operator">=</span> <span class="token builtin">eval</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span> <span class="token keyword">except</span><span class="token punctuation">:</span> <span class="token keyword">continue</span> lines <span class="token operator">=</span> content<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">]</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">"
"</span><span class="token punctuation">)</span> <span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span><span class="token string">"./train_data.txt"</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f_w<span class="token punctuation">:</span> <span class="token keyword">for</span> line <span class="token keyword">in</span> lines<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">:</span> <span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>line<span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">2</span> <span class="token operato
Có thể bạn quan tâm
0
|