Skip to content
Mì AI Mì AI Mì AI

Học AI theo cách Mì ăn liền!

Mì AI Mì AI Mì AI

Học AI theo cách Mì ăn liền!

  • Trang chủ
  • Kênh Youtube
  • Facebook Group
  • Nói về chủ tiệm Mì
  • Trang chủ
  • Kênh Youtube
  • Facebook Group
  • Nói về chủ tiệm Mì
Close

Search

  • Trang chủ
  • Kênh Youtube
  • Facebook Group
  • Nói về chủ tiệm Mì
Mì AI Mì AI Mì AI

Học AI theo cách Mì ăn liền!

Mì AI Mì AI Mì AI

Học AI theo cách Mì ăn liền!

  • Trang chủ
  • Kênh Youtube
  • Facebook Group
  • Nói về chủ tiệm Mì
  • Trang chủ
  • Kênh Youtube
  • Facebook Group
  • Nói về chủ tiệm Mì
Close

Search

  • Trang chủ
  • Kênh Youtube
  • Facebook Group
  • Nói về chủ tiệm Mì
Natural Language Processing

[BERT Series] Chương 3. Thử nhận diện cảm xúc văn bản Tiếng Việt với PhoBert (Cách #1)

By Chủ tiệm Mì
December 29, 2020 6 Min Read
27

Hi anh em, hôm nay chúng ta sẽ trở lại với series về BERT với bài toán Thử nhận diện cảm xúc văn bản Tiếng Việt với PhoBert.

Trong 2 bài trước, mình đã cùng các bạn tìm hiểu về BERT. Bạn nào chưa xem thì có thể xem lại tại đây [BERT Series] Chương 1. BERT là cái chi chi? và [BERT Series] Chương 2. Nghịch một chút với Hugging Face

Trong các bài tiếp theo chúng ta sẽ cùng sử dụng thư viện Hugging Face để làm các Task khác nhau trong “môn võ công” BERT này. Và bắt đầu sẽ là tak thân quên “Nhận diện cảm xúc”

Phần 1 – Đặt vấn đề bài toán nhận diện cảm xúc văn bản với PhoBert.

Bài toán nhận diện cảm xúc này thì nhiều bạn làm, nhiều trang viết rồi, các bạn có thể search thoải mái trên mạng.

Nguồn: Tại đây

Tóm lại , bài toán này là ta sẽ cần xây dựng một model nhận vào một câu văn bản và trả ra được cảm xúc của câu văn bản đó. Cảm xúc ở đây có thể là tích cực, tiêu cực, trung tính hoặc đơn giản là Tốt/Xấu…. tuỳ bài toán.

Ví dụ:

  • “Nhà hàng này rất ngon” thì là Tích cực
  • “Nhà hàng này ăn cũng tạm” thì là Trung tính
  • “Nhà hàng này lừa đảo” thì là Tiêu cực

Lớp bài toán này thì các làm là chúng ta sẽ vector hoá câu văn bản, sau đó đưa vào một mạng LSTM để lấy ra vector output, sau đó ta đưa qua một mạng neural đơn giản hoặc SVM để phân lớp.

Và hôm nay chúng ta sẽ làm cách tương tự đó là sử dụng BERT, đưa câu văn bản vào pretrain PhoBERT, lấy output đầu ra và sử dụng SVM để phân lớp nhé.

Phần 2 – Cách thức thực hiện

Rồi, chúng ta sẽ cùng vạch ra cách thức thực hiện bài toán này với pretrain PhoBert của VinAI ( https://github.com/VinAIResearch/PhoBERT).

Như chúng ta đã biết, BERT là một nửa của Transformer (cụ thể là nửa Encoder) với một loạt các Block Encoder chồng lên nhau (nhiều hay ít tuỳ model Base hay Large):

Nguồn: Tại đây

Nếu chúng ta feed 1 câu văn bản qua PhoBERT thì sẽ lấy ra được embedding output của cả câu sau block encoder cuối cùng. Và đấy, chúng ta sẽ sử dụng output đó để làm đặc trưng classify nhá!

Cụ thể sẽ bao gồm các bước như sau:

  • Bước 1: Tiền xử lý câu văn bản
  • Bước 2: Word segment câu văn bản trước khi đưa vào PhoBert (do PhoBert yêu cầu)
  • Bước 3: Tokenize bằng bộ Tokenizer của PhoBert. Chú ý rằng khi tokenize ta sẽ thêm 2 token đặc biệt là [CLS] và [SEP] vào đầu và cuối câu.
  • Bước 4: Đưa câu văn bản đã được tokenize vào model kèm theo attention mask.
  • Bước 5: Lấy output đầu ra và lấy vector output đầu tiên (chính là ở vị trí token đặc biệt [CLS]) làm đặc trưng cho câu để train hoặc để predict (tuỳ phase).

Chú ý: Chỗ này mình nhấn mạnh đây là cách lazy, còn nếu làm sâu hơn thì nên fine tune lại model BERT nha (mình sẽ nói vào bài sau). Vì chắc sẽ có bạn comment chỗ này nên mình nói luôn để các bạn đỡ tìm.

Đó, đại khái cách làm là như vậy, bạn nào chưa rõ có thể post lên Group trao đổi, chia sẻ: https://facebook.com/groups/miaigroup để cùng thảo luận cho vui nhé!

Phần 3 – Viết code cho chương trình nhận diện cảm xúc văn bản với PhoBert.

Cài đặt thư viện

Đầu tiên chúng ta cùng cài bằng lệnh pip thần thánh:

# Cài đặt hugging face
pip install transformer
# Cài đặt thư viện underthesea để thực hiện word segment
pip install underthesea
# Cài đặt pytorch
pip install torch
# Cài đặt sklearn
pip install scikit-learn

Chú ý ở đây là transformer hugging face sử dụng framework pytorch nên chúng ta phải cài đặt torch nhé.

Load model PhoBERT

Chúng ta sẽ load bằng đoạn code sau:

# Hàm load model BERT
def load_bert():
    v_phobert = AutoModel.from_pretrained("vinai/phobert-base")
    v_tokenizer = AutoTokenizer.from_pretrained("vinai/phobert-base", use_fast=False)
    return v_phobert, v_tokenizer

Chú ý model sẽ được load từ cloud về nên lần chạy đầu tiên sẽ khá chậm nhé.

Chuẩn hoá dữ liệu

Dữ liệu thu thập từ trên mạng thường rất sạn. Sạn ở đây cụ thể là: từ viết tắt, dấu câu, sai chính tả, từ không dấu….và chúng ta phải xử lý để chuẩn hoá dữ liệu thì model mới cho ra kết quả tốt được.

Việc chuẩn hoá này tốn nhiều công sức và thời gian xử lý lắm luôn! Ở đây chỉ để demo nên mình chỉ làm thao tác remove dấu câu thôi nhé:

# Hàm chuẩn hoá câu
def standardize_data(row):
    # Xóa dấu chấm, phẩy, hỏi ở cuối câu
    row = re.sub(r"[\.,\?]+$-", "", row)
    # Xóa tất cả dấu chấm, phẩy, chấm phẩy, chấm thang, ... trong câu
    row = row.replace(",", " ").replace(".", " ") \
        .replace(";", " ").replace("“", " ") \
        .replace(":", " ").replace("”", " ") \
        .replace('"', " ").replace("'", " ") \
        .replace("!", " ").replace("?", " ") \
        .replace("-", " ").replace("?", " ")
    row = row.strip().lower()
    return row

Word segmentation và Tokenize

Rồi, sau khi đã chuẩn hoá xong, ta sẽ word segment (phân tách từ) bằng Underthesea (các bạn có thể dùng VnCoreNLP cũng okie nhé, mình cài sẵn Underthesea nên xài luôn)

line = underthesea.word_tokenize(line, format="text")

Và đưa vào tokenizer của PhoBert:

line = tokenizer.encode(line)

Padding và đưa vào model PhoBERT trích đặc trưng

Ở đây các bạn chú ý là chúng ta phải padding để đảm bảo các input có cùng độ dài như nhau nhé:

max_len = 100
# Chèn thêm số 1 vào cuối câu nếu như không đủ 100 từ
    padded = numpy.array([i + [1] * (max_len - len(i)) for i in v_tokenized])

Tuy nhiên, khi padding thế thì ta phải thêm một attention_mask đẻ model chỉ focus vào các từ trong câu và bỏ qua các từ được padding thêm:

# Đánh dấu các từ thêm vào = 0 để không tính vào quá trình lấy features
attention_mask = numpy.where(padded == 1, 0, 1)

Và cuối cùng là tống nó vào model và lấy ra output

# Chuyển thành tensor
    padded = torch.tensor(padded).to(torch.long)
    print("Padd = ",padded.size())
    attention_mask = torch.tensor(attention_mask)

    # Lấy features dầu ra từ BERT
    with torch.no_grad():
        last_hidden_states = phobert(input_ids= padded, attention_mask=attention_mask)

    v_features = last_hidden_states[0][:, 0, :].numpy()

Các bạn để ý dòng cuối, cái chỗ [:,0,:] chính là lấy vector embedding của token đầu tiên. Để mình vẽ cho các bạn dễ hình dung chỗ này:

Train model SVM

Vâng, và sau khi có đầy đủ các vector đặc trưng của từng câu thì ta chỉ cần nhét vào một model SVM đơn giản mà thôi. Thông số của SVM thì các bạn có thể sử dụng GridSearch để tìm nhé. Ở đây mình hardcode vài thông số cho nhanh.

cl = SVC(kernel='linear', probability=True, gamma=0.125)
cl.fit(features, label)

sc = cl.score(X_test, y_test)
print('Kết quả train model, độ chính xác = ', sc*100, '%')

Predict câu văn bản mới

Với câu mới, ta cũng thực hiện tương tự các bước: chuẩn hoá, word segment rồi thì cũng tokenize, lấy embeđing rồi đưa vào model SVM là ra class của nó:

# Lấy features từ BERT
    with torch.no_grad():
        last_hidden_states = phobert(padded, attention_mask=attention_mask)
    
    v_features = last_hidden_states[0][:, 0, :].numpy()
    # Đưa vào model predict lấy kết quả
    sc = svm_model.predict_proba(v_features)

    cv = numpy.max(sc) # Đây là giá trị probality
    cb = numpy.argmax(sc) # Đây là giá trị index đạt max

Vậy thôi, đó là các bước khá đơn giản để làm một bài sentiment analysis theo cách số 1 – không finetune model. Trong bài tiếp theo mình sẽ cùng các bạn làm theo cách có finetune nhé.

Tips: Có một số bạn nói rằng trích xuất vector embedding của token [CLS] trong vài layer cuối sau đó concat lại làm đặc trưng sẽ mang lại kết quả tốt hơn.

Hẹn gặp lại các bạn! Mình xin tặng bạn nào đọc đến đây link github thay lời cảm ơn nha: Tại đây.

Chúc các bạn thành công!

#MìAI

Fanpage: http://facebook.com/miaiblog
Group trao đổi, chia sẻ: https://www.facebook.com/groups/miaigroup
Website: https://miai.vn/
Youtube: http://bit.ly/miaiyoutube

Tài liệu tham khảo: https://viblo.asia/p/su-dung-ai-danh-gia-san-pham-tren-lazadatiki-dua-tren-comment-aWj53b9ol6m

Tags:

berthugging facenatural language processingNature Language Processingnhận diện cảm xúcNLPsentiment analysistransformerXử lý ngôn ngữ tự nhiên
Author

Chủ tiệm Mì

Follow Me
Other Articles
Previous

[BERT Series] Chương 2. Nghịch một chút với Hugging Face

Next

Nhìn đời theo cách của mạng CNN (visualize feature maps- heatmap)

27 Comments
  1. Vũ Tuấn Linh says:
    January 2, 2021 at 4:19 pm

    file data_1.csv ở đâu vậy ạ ?

    Reply
    1. Nguyễn Chiến Thắng says:
      January 6, 2021 at 3:35 am

      File đó là file private nên anh ko share được. Em có thể tự tạo ra bằng cách như sau:
      – Mỗi dòng gồm có câu văn bản và rating của nó (1-5)
      – Phân tách nhau bởi dấu |

      Reply
      1. Kiet Tran says:
        March 7, 2022 at 3:20 pm

        Dạ em chào anh Thắng, em thấy anh có đăng data để train bài này trên thư viện rồi mà không rõ cách sử dụng ạ. Mình cần sửa hay thêm gì không ạ? Mong anh sớm trả lời. Em cảm ơn a!

        Reply
        1. Nguyễn Chiến Thắng says:
          March 14, 2022 at 8:47 am

          Em post lên https://facebook.com/groups/miaigroup thảo luận cho tiện nha!

          Reply
  2. jimei says:
    January 3, 2021 at 11:18 am

    mong anh ra sớm m7 này e phải nộp bc rồi ạ cám ơn a nhiều

    Reply
    1. Nguyễn Chiến Thắng says:
      January 6, 2021 at 3:34 am

      Cảm ơn em dã quan tâm. Ra gì em nhỉ?

      Reply
      1. jimei says:
        January 18, 2021 at 3:08 pm

        mong a ra cách 2 ạ

        Reply
        1. Nguyễn Chiến Thắng says:
          January 20, 2021 at 3:09 am

          Thanks em. Đợi việc đỡ bận chút anh sẽ ra nhé!

          Reply
  3. Thanh says:
    January 16, 2021 at 11:57 pm

    Anh ơi, cái phần thư viện của Hugging face là pip install transformers ạ ( của a thiếu s á a).

    Reply
    1. Nguyễn Chiến Thắng says:
      January 17, 2021 at 2:42 pm

      Thanks em. Chắc typing sót kaka 😀

      Reply
  4. jimei says:
    January 24, 2021 at 3:31 pm

    a cho e hỏi BPE là gì được k ạ và nó có giống chức năng của w2v k ak

    Reply
    1. Nguyễn Chiến Thắng says:
      January 27, 2021 at 3:33 am

      Em post lên Group trao đổi, chia sẻ: https://facebook.com/groups/miaigroup trao đổi cho dễ nhé. Trên này khó vì ko up hình được.

      Reply
  5. ngoan says:
    March 24, 2021 at 2:42 am

    mình uốn chạy trên local host thì làm s anh

    Reply
    1. Nguyễn Chiến Thắng says:
      March 24, 2021 at 2:53 am

      Anh chưa hiểu ý em. Chạy trên Localhost là như nào. Em post lên Group: https://www.facebook.com/groups/miaigroup cho tiện trao đổi thêm nhé!

      Reply
  6. Cam Vinh Banh says:
    September 21, 2021 at 8:13 pm

    HÓng bài mới ạ

    Reply
    1. Nguyễn Chiến Thắng says:
      October 2, 2021 at 8:55 pm

      Thanks em!

      Reply
  7. sơn says:
    December 16, 2021 at 9:20 pm

    Anh ơi cho e hói chút à có video hướng dẫn không ạ

    Reply
    1. Nguyễn Chiến Thắng says:
      December 21, 2021 at 10:19 am

      Cái này anh viết chi tiết rồi nên chưa có em ạ.

      Reply
  8. Tran Dinh Lam says:
    May 25, 2022 at 10:21 am

    Hi anh, chỗ train trong code là “cl.fit(X_train, label)” mới đúng chứ anh nhỉ? Em thấy mình đang train luôn nguyên tập features

    Reply
    1. Nguyễn Chiến Thắng says:
      June 29, 2022 at 10:33 pm

      Có thể anh đang làm ví dụ. Em post lên Group trao đổi, chia sẻ: https://facebook.com/groups/miaigroup trao đổi thêm nhé!

      Reply
  9. Nam says:
    June 1, 2022 at 3:24 pm

    Mong anh hướng dẫn cách dùng PhoBert để phát hiện trùng lặp văn bản ạ.

    Reply
    1. Nguyễn Chiến Thắng says:
      June 29, 2022 at 10:30 pm

      Okie em. Anh sẽ bố trí nhé.

      Reply
  10. hoàng says:
    June 26, 2022 at 10:22 am

    cho e hỏi đối với bài toán multilabel dùng phobert nó có khác biệt nhiều với cách sử dụng bert với multiclass k ạ?

    Reply
    1. Nguyễn Chiến Thắng says:
      June 29, 2022 at 10:30 pm

      Anh cũng chưa thử món này., Em post lên Group trao đổi, chia sẻ: https://facebook.com/groups/miaigroup cho tiện trao đổi nhé!

      Reply
  11. Mạnh Quang says:
    July 14, 2022 at 9:52 am

    Cho em hỏi là tại sao mình lại chọn vector đầu tiên mà không phải vector thứ 2 hay toàn bộ ạ.
    trích “Các bạn để ý dòng cuối, cái chỗ [:,0,:] chính là lấy vector embedding của token đầu tiên. Để mình vẽ cho các bạn dễ hình dung chỗ này:”, xin cám ơn.

    Reply
  12. Tung Nguyen says:
    July 24, 2024 at 1:54 pm

    Anh ơi nếu muốn lấy entity từ PhoBert thì dùng code như nào vậy a

    Reply
    1. Nguyễn Chiến Thắng says:
      August 18, 2024 at 7:43 am

      Em post lên Group trao đổi, chia sẻ: https://facebook.com/groups/miaigroup cho tiện trao đổi nhé!

      Reply
Show Comments

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Tìm hiểu và cài đặt OpenClaw – trợ lý ảo 24/7 thông minh đa chức năng – Mì Ai
  • Dùng thử Pika – robot học Tiếng Anh cho trẻ cực đỉnh – Mì AI
  • TopView.AI 4.0 – nền tảng tạo AI video cộng tác bá đạo – Mì AI
  • Storm MCP – giải pháp nhanh gọn nhẹ để có MCP Server trong 5 phút – Mì AI
  • VoxCPM thử voice cloning với checkpoint finetune Tiếng Việt – Mì AI

Recent Comments

  1. Chủ tiệm Mì on Thử xây dựng hệ thống Agentic AI với LangGraph – Mì AI
  2. Nguyễn Chiến Thắng on [Nhận diện biển số xe] Chương 3 – Phát hiện biển số bằng OpenCV thuần
  3. Trần Sơn Dương on [Nhận diện biển số xe] Chương 3 – Phát hiện biển số bằng OpenCV thuần
  4. Salomon on [CV] Thử làm model cảnh báo ngủ gật cho tài xế oto bằng Dlib và Resnet
  5. khang on Xây dựng hệ thống nhận diện thủ ngữ – ngôn ngữ ký hiệu tay – để giao tiếp với người khuyết tật

Categories

  • Basic
  • Computer Vision
  • Data Science – Data Analysis
  • Generative AI
  • MÌ ÚP
  • Natural Language Processing
  • RNN-LSTM-GRU
  • Share Data

Là người đi trước, hãy biết đưa tay lại phía sau.

Nguyễn Chiến Thắng
Cảm ơn các bạn đã ủng hộ Mì AI!