1. Mở đầu

Hằng ngày ở các trang thương mại điện tử có rất nhiều comment về sản phẩm được người dùng đưa ra đánh giá về những sản phẩm đó. Việc phân tích thống kê lại xem những bình luận đó là tích cực hay tiêu cực sẽ giúp cho doanh nghiệp biết được chất lượng sản phẩm, tâm lý khách hàng và từ đó đưa ra những thay đổi hợp lý trong kinh doanh. Vì có rất nhiều lượt comment, trên các trang thương mại điện tử lớn có thể lên tới hàng chục triệu lượt comment trong 1 ngày nên việc phân tích bằng tay truyền thống là điều không thể. Đây là lúc các model machine learning thể hiện sức mạnh của mình.
Trong blog này mình sẽ xây dựng 1 model machine learning kết hợp giữa Tfidf và SVM để giải quyết bài toán tích sắc thái bình luận trong tiếng việt. Do bản thân không có căn bản tốt về toán cho nên trong blog này sẽ không nói sâu về bản chất của các thuật toán thay vào đó mình chỉ nói về tư tưởng của các thuật toán này, cách điều chỉnh tham số và tại sao lại áp dụng các thuật toán này cho bài toán phân tích sắc thái bình luận tiếng việt. Chi tiết cơ bản hơn về các thuật toán bạn đọc có thể tham khảo tại blog machinelearningcoban.com của anh Vũ Hữu Tiệp.

2. Yêu cầu bài toán.

  • Yêu cầu bài toán
    • Xác định 1 câu bình luận là tích cực hay tiêu cực.
  • Tổng quan về Dataset
    uc?id=1V1YNefG0zTPIGE69FJS7UOFUzPu04LrI&export=download
    • dataset được cung cấp bởi aivivn.com về các câu bình luận trong tiếng Việt trong đó bộ training dataset gồm 16087 câu bình luận đã được gắn nhãn, bộ testing dataset gồm 10981 câu bình luận.
      • Dataset gồm bình luận và nhãn của bình luận.
      • Bình luận tích cực vd: "sản phẩm đẹp quá", "giao hàng hơi trẽ 1 chút, nhưng sp toet vời" được gắn nhãn 0.
      • Bình luận tiêu cực vd: "quá thất vọng","sản phẩm quá đắt mà chất lượng bình thường" được gắn nhãn 1.

3. Xây dựng model

  • Phân tích training dataset.
    Phân tích training dataset rất quan trọng trong việc xây dựng các model machine learning, việc phân tích training dataset chính xác sẽ giúp chúng ta đưa ra được model chính xác để giải quyết bài toán. Những điều rút ra được khi phân tích training dataset:

    • Sự phân bố dữ liệu giữa các class trong training dataset,nếu quá mất cân bằng thì phải tiến hành sinh thêm dữ liệu để cân bằng hơn, vì nếu 1 class quá ít dữ liệu rất dễ dẫn tới overfit. Ta dùng maplotlib để visualize dữ liệu như hình bên dưới. Nhận thấy dataset gồm 2 class khá cân bằng nên ta không cần sinh thêm dữ liệu nữa.
      uc?id=1g0d7D-NePt_nQTTbKXP33mwgHzPpB8yA&export=download
    • Khi quan sát bộ dữ liệu này mình nhận thấy nó khá sạch tức dữ liệu hầu hết đã được gắn nhãn đúng nên mình sẽ không gắn nhãn lại dữ liệu nữa. Với nhưng bộ dữ liệu không sạch thì bạn phải tiến hành gắn lại nhãn dữ liệu, đây là 1 công việc tốn thời gian nhưng thường xuyên phải làm với 1 người làm về machine learning.
    • Ta nhận thấy trong bộ training dataset có những câu bình luận như sau:" sp đẹp quáa","tks shop, qá toẹt vời","sp đẹp dc cái hơi đắt". Đây là những câu bình luận thường thấy trên mạng xã hội. Về mặt ý nghĩa thì vd: "sp đẹp quáa" và "sản phẩm đẹp quá" hay "tks shop","thanks shop","cảm ơn shop" sẽ giống nhau hoàn toàn nhưng máy tính thì không biết điều đó. Lúc trích xuất vector đặc trưng cho mỗi bình luận thì những câu bình luận như vậy sẽ có vector khác nhau. Vậy ta phải tiến hành chuẩn hóa lại dữ liệu, những từ có ý nghĩa giống nhau vd: "thanks","tks","thaks.." sẽ được chuyển về "cảm ơn"...Việc chuẩn hóa dữ liệu này được mình viết trong file utils.py của source code các bạn có thể xem. Sau khi chuẩn hóa lại dữ liệu độ chính xác model của mình tăng lên 3% và quan trong hơn là giải quyết được nhiều bình luận teen thường gặp.
    • Trong bộ dữ liệu ta sẽ gặp những bình luận rất khó để biết nó là tích cực hay tiêu cực vd: "giao hàng nhanh nhưng sản phẩm không tốt","hơi đắt nhưng sản phẩm quá tốt,đúng là tiền nào của đấy". Những câu bình luận kiểu này khá khó để model biết là tích cực hay tiêu cực nên mình sẽ có những xử lý riêng được viết tại file exception.py của source code.
  • Lựa chọn thuật toán để trích xuất vector và phân loại.

    • Mình sẽ dùng Tfidf để trích xuất vector và SVM để phân loại, chi tiết về 2 thuật toán này bạn có thể đọc tại rất nhiều tài liệu có cả tiếng Anh lẫn tiếng Việt.
    • Tại sao chọn SVM ?
      • Như chúng ta biết có rất nhiều thuật toán để phân loại như logistic regression, softmax, naive bayes, random forest, SVM .... Nhưng ở đây ta nhận thấy ở bài toán này số lượng chiều của mỗi vector sau khi được trích xuất bằng Tfidf là rất lớn ( trong code của mình là 100000) mà chỉ có 2 class mà thôi. Trong những trường hợp như vậy thì SVM phân loại hiệu quả hơn hẳn những thuật toán khác. Giải thích tại sao các bạn có thể xem tại links sau: https://www.quora.com/Why-does-SVM-work-well-in-practice-even-if-the-reproduced-space-is-very-high-dimensional

      • Cách tối ưu các tham số phù hợp để đạt kết quả cao nhất. Việc tối ưu các tham số trong Tfidf và SVM là rất quan trọng, nếu tham số không phù hợp với dữ liệu sẽ cho ra kết quả rất thấp và ngược lại. Với những bạn hiểu cặn kẽ nền tảng toán học của Tfidf và SVM thì có thể chọn lựa dễ dàng. Còn nếu những bạn không hiểu rõ lắm thì Sklearn đã cung cấp cho bạn GridSearchCV() để làm việc đó, hàm này sẽ giúp bạn thử từng bộ tham số 1 và chọn ra bộ tham số cho kết quả tốt nhất. Tất nhiên cũng sẽ tốn thời gian hơn rất nhiều và với những bộ dataset lớn hoặc model training phức tạp, thời gian training lâu thì cách này gần như là không thể vì với 1 bộ tham số thôi nó cũng mấy nhiều tiếng đồng hồ rồi, vậy mới thấy việc nắm được tốt kiến thức cơ bản về toán trong machine learning là quan trọng như thế nào đúng không. Mình đã code file optimize_params.py để tìm bộ tham số phù hợp cho model.

  • Cách chia validation và training model

  • Đánh giá model

    • Model này đạt được 90,008% f1_score trên tập dữ liệu testing dataset của cuộc thi do aivivn tổ chức, một con số khá ổn với 1 model không dùng đến deeplearning.

4. Tổng kết

  • Đánh giá điểm hạn chế của model, và những phương hướng để cải tiến
    • Mode khá nhanh,nhẹ nhàng, dùng tốt trong những trường hợp bình luận thông thường nhưng vẫn còn phân tích sai trong những trường hợp câu khó, phức tạp về ý nghĩa.
    • Mặc dù việc dùng Tfidf để trích xuất vector đặc trừng đã có để ý đến thứ tự sắp xếp các từ trong câu nhưng Tfidf vẫn chủ yếu là để đánh trọng số những từ quan trọng là chính nên có thể sai những câu bình luận kiểu như: "Không làm tôi thất vọng" sẽ được xếp vào nhóm tiêu cực. Giải pháp:
      • Liệt kê ra những loại câu như vậy,những câu chứa nhiều từ tiêu cực nhưng ghép lại là 1 câu tích cực rồi cho nó vào bộ data training.
      • Sử dụng mạng LSTM để trích xuất vector đặc trưng.
    • Bộ dữ liêu vẫn có nhiều câu bình luận chưa có dấu, sai chính tả nếu xử lý chuẩn hóa lại dữ liệu theo hướng này chắc chắn chất lượng model sẽ tăng lên. Nhưng do trong thời gian ngắn vừa code vừa viết blog nên tạm thời mình chưa thể làm được vấn đề này :D.
  • Hướng dẫn sử dụng source code
    • Các bạn có thể tải source code về và dùng được ngay tại: https://github.com/nhatthanh123bk/sentiment-analysis

      • Môi trường python3.6.
      • sử dụng câu lệnh pip3 install -r requitments.txt để cài đặt các pakage cần thiết.
      • Để train lại model chạy: python3 training.py.
      • Có thể sử dụng trực tiếp: python3 classify.py -t "câu bình luận".
    • Mọi ý kiến đánh giá của mọi người về xin được gửi về tại email: thanhtn@vietnamlab.vn.