Phần 2: Deep Learning cho Chatbot - Tạo một retrieval-based model Chatbot
Mở đầu Đây là bài dịch tiếp theo của phần 1 . Chúng ta sẽ cùng tạo một retrieval-based Model Chatbot. Nội dung Trong bài này chúng ta sẽ implement một retrieval-based bot. Retrieval-based model có một kho định nghĩa trước các câu trả lời chúng có thể sử dụng, không giống như generative ...
Mở đầu
Đây là bài dịch tiếp theo của phần 1 . Chúng ta sẽ cùng tạo một retrieval-based Model Chatbot.
Nội dung
Trong bài này chúng ta sẽ implement một retrieval-based bot.
Retrieval-based model có một kho định nghĩa trước các câu trả lời chúng có thể sử dụng, không giống như generative models cái mà có thể generate câu trả lời chúng không bao giờ nhìn thấy trước đây. Rõ hơn, từ một câu đầu vào tới retrieval-based model là một context c sẽ chọn ra một câu trả lời response r có khả năng nhất. Ouputs của model là câu trả lời tốt nhất. Để tìm ra câu trả lời tốt nhất bạn cần phải tính toán điểm cho tất cả các câu trả lời và chọn ra một với số điểm cao nhất.
Nhưng tại sao chúng ta lại tạo một retrieval-based model nếu chúng ta có thể tạo một generative model? Generative models dường như linh hoạt hơn bnowir vì chúng không cần kho câu trả lời định nghĩa trước, phải không các bạn? Vấn đề là generative models không hoạt động tốt trong thực tế. Ít nhất là cho tới bây giờ. Bởi vì chúng ta có quá nhiều tự do cho việc chúng có thể trả lời như thế nào, generative models có thể tạo ra các lỗi cú pháp, không có nghĩa, không nhất quán. Chúng cũng cần một số lượng dữ liệu training lớn và khó để tối ưu. Đa số hệ thống ngày nay là retrieval-based, hoặc kết hợp giữa retrieval-based và generative. Google's Smart Reply là một ví dụ. Generative models đang là lĩnh vực active trong nghiên cứu. Nhưng chúng ta không quan trọng, nếu chúng ta tạo một chatbot ngày nay, lựa chọn tốt nhất là tạo một retrieval-based model
The Ubuntu Dialog Corpus
Trong bài viết này chúng ta sẽ sử dụng Ubuntu Dialog Corpus (paper, github). Ubuntu Dialog Corpus (UDC) là một trong những tập dữ liệu hội thoại lớn nhất được public. Nó được dựa trên các lưu trữ chat từ các kênh Ubuntu trên public IRC network (ok là một dạng liên lạc cấp tốc qua mạng gì đó). Paper này sẽ đi vào chi tiết chính xác dữ liệu được tạo như thế nào, vì thế tôi không lặp lại nó ở đây. Tuy nhiên, việc hiểu được dữ liệu là quan trọng khi chúng ta làm việc với chúng, vì thế để tôi giải thích nó trước. Tập dữ liệu training bao gồm 1000000 mẫu, với 50% positive (label 1), 50% negative (label 0). Mỗi vĩ dụ bao gồm context, là điểm bắt đầu hội thoại, và một utterance, một câu phản hồi cho context trên. Positive với label 1 nghĩa là câu phản hồi là thực sự cho context đó, và negative label 0 nghĩa là không phải, Chọn ngẫu nhiên một số mẫu, đây là một vài mẫu dữ liệu. Các dữ liệu được generation script đã được tiền xử lý cho chúng ta (cái này mình không biết là bản thân dữ liệu UDC được tiền xử lý hay là script của bài viết này tiền xử lý, mình sẽ xem thử và trình bày rõ cho các bạn) - Tiền xử lý ở đây là tokenized, stemmed, and lemmatized sử dụng NLTK tool. Script này cũng đã thay thế các entities giống như tên, địa điểm, tổ chức, các url, các đường dẫn hệ thống bằng các ký tự đặc biệt. Việc tiền xử lý này không phải là phải làm, nhưng nó cũng sẽ giúp tăng hiệu quả một vài phần trăm. Trung bình context có 86 từ và utterance có 17 từ. Chúng ta có thể em chi tiết jupyter notebook. Tập dữ liệu còn bao gồm cả tập test sets và validation sets (Ngắn gọn thì đây là 2 tập không để đem đi train mà là tập chưa nhìn thấy để đánh giá model). Định dạng của chúng khác với tập dữ liệu train. Mỗi dữ liệu trong test/validation bao gồm một context, một utterance đúng và 9 utterance sai được gọi là distractors. Mục đích của model là gán điểm cao nhất cho đúng utterance, và thấp hơn cho các utterances sai (ok).
Có rất nhiều cách để đánh giá model. Cách thường sử dụng là recall@k. Recall@k nghĩa là model sẽ chọn ra k câu phản hồi tốt nhất trong 10 câu trả lời có thể (1 đúng và 10 sai). Nếu cái đúng nằm trong những cái mà chúng ta đã đánh dấu thì được coi là đúng (để dễ hiểu chọn k=3 ta chọn ra 3 câu phản hồi tốt nhất nếu trong 3 câu đó mà chứa câu đúng thì được coi là đúng). Vì thế k lớn hơn thì là dễ hơn. Nếu chúng ta set k=10 chúng ta sẽ có recall là 100% bởi vì chúng ta chỉ có 10 câu trả lời. Nếu chúng ta chọn k=1 thì model chỉ có một cơ hội để chọn ra câu trả lời đúng. Ở thời điểm này có lẽ bạn đang tự hỏi là 9 distractors(câu sai) được chọn như thế nào. Trong tập dữ liệu 9 câu sai được lấy ngẫu nhiên. Tuy nhiên trong thực tế bạn có cả triệu khả năng để chọn và bạn không biết được cái nào là đúng. Bạn không thể đánh giá cả triệu câu trả lời để lấy ra một cái có số điểm cao nhất - điều này là quá tốn kém (thời gian đôi khi hệ thống cần trả lời nhanh, ví dụ chatbot gửi câu yêu cầu là cần phản hồi nhanh không thể ngồi đợi đánh giá tất cả rồi chọn câu tốt nhất được, đến đây ta có thể mong ngóng bài viết sẽ đưa ra được mô hình tốt chứ không đơn giản như vậy). Google Smart Reply sử dụng kĩ thuật chia nhỏ các câu trả lời có thể chọn, hoặc nếu bạn chỉ có vài trăm câu trả lời thích hợp trong tất cả bạn có thể đánh giá tất. (Brute force được dùng ở mọi nơi phải không các bạn