Bag of Words (BoW) là một kỹ thuật trong Xử lý ngôn ngữ tự nhiên (NLP). Kỹ thuật này được sử dụng rộng rãi để chuyển đổi dữ liệu văn bản thành định dạng máy có thể đọc được, cụ thể là các giá trị số, mà không xét đến ngữ pháp và thứ tự từ. Hiểu BoW rất quan trọng với bất kỳ ai làm việc với dữ liệu văn bản. Python cung cấp nhiều công cụ và thư viện để triển khai Bag of Words hiệu quả.
Trong hướng dẫn này, chúng ta sẽ đi sâu vào BoW, giới thiệu các khái niệm, đề cập đến các cách sử dụng, và thực hiện từng bước chi tiết bằng Python. Kết thúc hướng dẫn, bạn sẽ có thể áp dụng mô hình Bag of Words vào các bài toán thực tế. Nếu bạn mới làm quen với NLP, hãy xem lộ trình kỹ năng Natural Language Processing in Python để tìm hiểu thêm.
Bag of Words là gì?
Bag of Words là kỹ thuật trích xuất đặc trưng từ dữ liệu văn bản cho các tác vụ học máy, như phân loại văn bản và phân tích cảm xúc. Điều này quan trọng vì các thuật toán học máy không thể xử lý dữ liệu văn bản thô. Quá trình chuyển văn bản thành số được gọi là trích xuất đặc trưng hoặc mã hóa đặc trưng.
Bag of Words dựa trên số lần xuất hiện của các từ trong một tài liệu. Quá trình bắt đầu bằng việc tìm tập từ vựng trong văn bản và đo lường tần suất xuất hiện của chúng. Nó được gọi là “bag” (túi) vì thứ tự và cấu trúc của từ không được xét đến, chỉ quan tâm đến số lần xuất hiện.
Mô hình Bag of Words khác với Continuous Bag of Words (CBOW), mô hình học các word embedding dạng đặc bằng cách sử dụng các từ xung quanh để dự đoán một từ mục tiêu, từ đó nắm bắt quan hệ ngữ nghĩa giữa các từ. CBOW cần được huấn luyện trên một kho văn bản lớn và tạo ra các vector chiều thấp, hữu ích cho các ứng dụng NLP phức tạp nơi ngữ cảnh từ rất quan trọng.
Khía cạnh
BOW
CBOW
Mục đích
Đếm số lần xuất hiện của từng từ
Dự đoán từ mục tiêu dựa trên ngữ cảnh
Kiểu đầu ra
Vector thưa, chiều cao
Embedding đặc, chiều thấp
Xét ngữ cảnh
Không (bỏ qua thứ tự từ)
Có (dùng các từ xung quanh)
Biểu diễn
Vector tần suất dạng thưa
Vector đặc nắm bắt ngữ nghĩa
Độ phức tạp
Thấp (không cần huấn luyện)
Cao (cần huấn luyện trên kho lớn)
Ứng dụng điển hình
Phân loại văn bản, phân tích cảm xúc
Word embedding, các tác vụ NLP cần ngữ cảnh
Vì sao dùng Bag of Words?
Bag of Words hữu ích trong nhiều tác vụ NLP, một số lý do sử dụng gồm:
Trích xuất đặc trưng: Chuyển đổi dữ liệu văn bản phi cấu trúc thành dữ liệu có cấu trúc, có thể dùng làm đầu vào cho nhiều thuật toán học máy.
Đơn giản và hiệu quả: BoW dễ triển khai về mặt tính toán, và hoạt động tốt với các kho văn bản nhỏ đến vừa.
Tương đồng tài liệu: Có thể sử dụng để tính độ tương đồng giữa các tài liệu văn bản bằng các kỹ thuật như cosine similarity.
Phân loại văn bản: Khi kết hợp với các kỹ thuật như Naive Bayes, BoW hiệu quả cho các tác vụ phân loại văn bản như phân loại spam và phân tích cảm xúc.
Tuy nhiên, cũng có hạn chế như không xét đến ngữ nghĩa, cấu trúc từ, hay trật tự từ.
Các bước triển khai Bag of Words trong Python
Để tạo mô hình bag-of-words, chúng ta lấy tất cả các từ trong một kho ngữ liệu và tạo một cột cho mỗi từ. Các hàng đại diện cho các câu. Nếu một từ nào đó tồn tại trong câu, nó được biểu diễn bằng 1, và nếu không tồn tại thì bằng 0. Mỗi từ trong cột đại diện cho một đặc trưng.
Kết quả cuối cùng là một ma trận thưa. Ma trận thưa là ma trận có rất nhiều số 0.
Tiền xử lý dữ liệu
Để tạo mô hình Bag of Words trong Python, chúng ta cần thực hiện một vài bước tiền xử lý. Các bước này gồm tách từ (tokenization) và loại bỏ stopword.
Tokenization là quá trình chia nhỏ một đoạn văn bản thành các đơn vị nhỏ hơn, thường là từ. Bạn có thể thực hiện tokenization bằng NLTK.
Stop words là các từ phổ biến trong tiếng Anh như "the," "that," và "a," vốn không đóng góp vào sắc thái (polarity) của câu.
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
# Download stopwords and tokenizer if you haven't already
nltk.download("punkt")
nltk.download("stopwords")# Example sentence
sentence ="This is an example showing how to remove stop words from a sentence."# Tokenize the sentence into words
words = word_tokenize(sentence)# Get the list of stop words in English
stop_words =set(stopwords.words("english"))# Remove stop words from the sentence
filtered_sentence =[word for word in words if word.lower()notin stop_words]# Join the words back into a sentence
filtered_sentence =" ".join(filtered_sentence)print(filtered_sentence)Được hỗ trợ bởi
Từ vựng (vocabulary) là tập hợp các từ duy nhất xuất hiện trong một kho văn bản. Xây dựng từ vựng bao gồm thu thập tất cả các từ duy nhất từ kho văn bản và đếm số lần xuất hiện của chúng. Từ vựng này hữu ích cho nhiều tác vụ NLP như mô hình ngôn ngữ, word embedding và phân loại văn bản.
Đoạn mã dưới đây tạo phân bố tần suất đơn giản của các từ trong kho văn bản, hữu ích cho các tác vụ NLP cơ bản như xây dựng từ vựng hoặc hiểu nội dung văn bản:
Biến corpus chứa một vài câu ví dụ. Trong ứng dụng thực tế, nó sẽ chứa dữ liệu văn bản lớn hơn, đa dạng hơn.
vocab = defaultdict(int) giúp đơn giản hóa việc đếm tần suất, tự động khởi tạo mọi từ mới với giá trị 0, cho phép tăng đếm trực tiếp mà không cần kiểm tra.
Mỗi câu được token hóa bằng cách chuyển sang chữ thường và trích xuất từ bằng biểu thức chính quy. Mẫu \b\w+\bxác định các từ chỉ gồm ký tự chữ-số, bỏ qua dấu câu và ký hiệu khác.
Số đếm của mỗi từ được cập nhật trong từ điển vocab.
Từ vựng được sắp xếp theo tần suất giảm dần để dễ thấy các từ phổ biến nhất ở đầu và được hiển thị tham khảo.
import re
# Import the regular expressions module to help with text processingfrom collections import(
defaultdict,)# Import defaultdict to easily handle word frequency counting# Sample corpus of text - a small dataset of sentences to analyze
corpus =["Tokenization is the process of breaking text into words.","Vocabulary is the collection of unique words.","The process of tokenizing is essential in NLP.",]# Initialize a defaultdict with integer values to store word frequencies# defaultdict(int) initializes each new key with a default integer value of 0
vocab = defaultdict(int)# Loop through each sentence in the corpus to tokenize and normalizefor sentence in corpus:# Convert the sentence to lowercase to ensure consistency in counting (e.g., 'Tokenization' and 'tokenization' are treated as the same word)# Use regular expressions to find words composed of alphanumeric characters only
words = re.findall(r"\b\w+\b", sentence.lower())# For each word found, increment its count in the vocab dictionaryfor word in words:
vocab[word]+=1# Convert the defaultdict vocab to a regular dictionary for easier handling and sorting# Sort the dictionary by word frequency in descending order and convert it to a new dictionary
sorted_vocab =dict(sorted(vocab.items(), key=lambda x: x[1], reverse=True))# Display the sorted vocabulary with each word and its frequency countprint("Vocabulary with Frequencies:", sorted_vocab)Được hỗ trợ bởi
Tự xây dựng từ vựng có thể tốn thời gian, đặc biệt với các kho lớn. CountVectorizer của Scikit-learn tự động hóa quá trình này và cho phép xử lý văn bản linh hoạt hơn như chúng ta sẽ thấy sau.
Triển khai Bag of Words bằng Python (từ đầu)
Hãy bắt đầu với một triển khai Bag of Words đơn giản từ đầu bằng Python. Điều này sẽ giúp bạn hiểu các khối xây dựng và cơ chế hoạt động bên dưới.
Triển khai thủ công
Bước 1: Tiền xử lý dữ liệu văn bản
Chúng ta sẽ bắt đầu bằng cách định nghĩa một hàm đơn giản để xử lý văn bản, gồm tokenization, chuyển chữ thường và loại bỏ dấu câu.
from collections import defaultdict
import string
# Sample text data: sentences
corpus =["Python is amazing and fun.","Python is not just fun but also powerful.","Learning Python is fun!",]# Function to preprocess textdefpreprocess(text):# Convert to lowercase
text = text.lower()# Remove punctuation
text = text.translate(str.maketrans("","", string.punctuation))# Tokenize: split the text into words
tokens = text.split()return tokens
# Apply preprocessing to the sample corpus
processed_corpus =[preprocess(sentence)for sentence in corpus]print(processed_corpus)Được hỗ trợ bởi
Kết quả:
[['python','is','amazing','and','fun'],['python','is','not','just','fun','but','also','powerful'],['learning','python','is','fun']]Được hỗ trợ bởi
Bước 2: Xây dựng từ vựng
Giờ chúng ta cần quét qua tất cả tài liệu và xây dựng một danh sách đầy đủ các từ duy nhất, đó là từ vựng của chúng ta.
# Initialize an empty set for the vocabulary
vocabulary =set()# Build the vocabularyfor sentence in processed_corpus:
vocabulary.update(sentence)# Convert to a sorted list
vocabulary =sorted(list(vocabulary))print("Vocabulary:", vocabulary)Được hỗ trợ bởi
Bước 3: Tính tần suất từ và vector hóa
Bây giờ, chúng ta sẽ tính tần suất của mỗi từ trong từ vựng cho từng tài liệu trong kho đã xử lý.
defcreate_bow_vector(sentence, vocab):
vector =[0]*len(vocab)# Initialize a vector of zerosfor word in sentence:if word in vocab:
idx = vocab.index(word)# Find the index of the word in the vocabulary
vector[idx]+=1# Increment the count at that indexreturn vector
Được hỗ trợ bởi
Tại thời điểm này, bạn đã tạo được biểu diễn Bag of Words cho mỗi tài liệu trong kho của mình.
# Create BoW vector for each sentence in the processed corpus
bow_vectors =[create_bow_vector(sentence, vocabulary)for sentence in processed_corpus]print("Bag of Words Vectors:")for vector in bow_vectors:print(vector)Được hỗ trợ bởi
Kết quả:
Bag of Words Vectors:
[0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1]
[1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1]
[0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1]Được hỗ trợ bởi
Sử dụng CountVectorizer của Scikit-learn
Xây dựng mô hình Bag of Words thủ công giúp học tập, nhưng với ứng dụng sản xuất, bạn sẽ muốn dùng các thư viện tối ưu, hiệu quả như Scikit-learn.
Hàm Python dùng để tokenization là CountVectorizer, được import từ sklearn.feature_extraction.text. Một trong các tham số của CountVectorizer là max_features, đại diện cho số lượng từ tối đa bạn muốn có trong mô hình bag of words. Ở đây chúng ta dùng None, nghĩa là sẽ dùng tất cả đặc trưng.
Sau khi tạo một thể hiện của CountVectorizer, dùng phương thức .fit_transform() để tạo mô hình bag of words. Tiếp theo, dùng .toarray() để chuyển mô hình bag of words thành các mảng numpy có thể đưa vào mô hình học máy.
Khi đã fit, CountVectorizer đã xây dựng một từ điển các chỉ số đặc trưng. Giá trị chỉ số của một từ trong từ vựng liên kết với tần suất của nó trong toàn bộ kho huấn luyện.
from sklearn.feature_extraction.text import CountVectorizer
# Original corpus
corpus =["Python is amazing and fun.","Python is not just fun but also powerful.","Learning Python is fun!",]# Create a CountVectorizer Object
vectorizer = CountVectorizer()# Fit and transform the corpus
X = vectorizer.fit_transform(corpus)# Print the generated vocabularyprint("Vocabulary:", vectorizer.get_feature_names_out())# Print the Bag-of-Words matrixprint("BoW Representation:")print(X.toarray())Được hỗ trợ bởi
Kết quả:
markdownVocabulary:['also''amazing''and''but''fun''is''just''learning''not''powerful''python']
BoW Representation:[[01101100001][10011110111][00001101001]]Được hỗ trợ bởi
Ví dụ: Ứng dụng Bag of Words
Bây giờ hãy áp dụng mô hình BoW cho một kho văn bản nhỏ gồm ba bài đánh giá phim để minh họa toàn bộ quy trình.
Chúng ta sẽ dùng CountVectorizer của Scikit-learn để áp dụng mô hình BoW cho kho văn bản nhỏ này.
Các bước chúng ta sẽ thực hiện:
CountVectorizer tự động token hóa văn bản, loại bỏ dấu câu và chuyển chữ thường.
.fit_transform(corpus) chuyển kho văn bản thành ma trận tài liệu–thuật ngữ, trong đó mỗi hàng đại diện cho một tài liệu và mỗi cột đại diện cho một từ trong từ vựng.
X_dense là ma trận đặc biểu diễn tần suất của mỗi từ trong từng tài liệu.
from sklearn.feature_extraction.text import CountVectorizer
# Sample corpus of movie reviews
corpus =["I loved the movie, it was fantastic!","The movie was okay, but not great.","I hated the movie, it was terrible.",]# Initialize the CountVectorizer
vectorizer = CountVectorizer()# Fit and transform the corpus to a document-term matrix
X = vectorizer.fit_transform(corpus)# Convert the document-term matrix into a dense format (optional for visualization)
X_dense = X.toarray()# Get the vocabulary (mapping of words to index positions)
vocab = vectorizer.get_feature_names_out()# Print the vocabulary and document-term matrixprint("Vocabulary:", vocab)print("Document-Term Matrix:\n", X_dense)Được hỗ trợ bởi
Kết quả:
Vocabulary:['but''fantastic''great''hated''it''loved''movie''not''okay''terrible''the''was']
Document-Term Matrix:[[010011100011]# First review: "I loved the movie, it was fantastic!"[101010111011]# Second review: "The movie was okay, but not great."[000110100111]]# Third review: "I hated the movie, it was terrible."Được hỗ trợ bởi
Cách diễn giải kết quả trên như sau:
Mỗi từ duy nhất trong kho được gán một chỉ số, và các từ được sắp theo thứ tự chữ cái. Ví dụ, "but" ở chỉ số 0, "fantastic" ở chỉ số 1, "movie" ở chỉ số 6, v.v.
Mỗi hàng trong ma trận tài liệu đại diện cho một bài đánh giá phim, và mỗi cột tương ứng với một từ trong từ vựng. Các giá trị trong ma trận biểu diễn tần suất của mỗi từ trong tài liệu đó.
Bài đánh giá thứ nhất: [0 1 0 0 1 1 1 0 0 0 1 1] cho thấy rằng:
Từ "fantastic" xuất hiện một lần (1 tại chỉ số 1),
Từ "loved" xuất hiện một lần (1 tại chỉ số 5),
Từ "movie" xuất hiện một lần (1 tại chỉ số 6),
Từ "it" xuất hiện một lần (1 tại chỉ số 4),
Vân vân.
Vector BoW có thể được hiểu như sau:
Mỗi tài liệu là một vector số biểu diễn số lần đếm từ. Số chiều của vector bằng kích thước từ vựng. Trong trường hợp này, từ vựng có 12 từ, nên mỗi bài đánh giá được biến đổi thành vector 12 chiều.
Hầu hết các từ trong mỗi hàng là số 0 vì không phải tài liệu nào cũng chứa mọi từ trong từ vựng. Do đó, các mô hình BoW thường là thưa, tức có nhiều số 0.
Ưu điểm và hạn chế của Bag of Words
Giờ hãy cùng điểm qua một số ưu điểm và hạn chế của mô hình Bag of Words.
Ưu điểm
Dễ triển khai và diễn giải: Bag of Words là một trong những kỹ thuật biểu diễn văn bản đơn giản nhất, phù hợp cho người mới bắt đầu. Sự đơn giản cho phép triển khai nhanh mà không cần tiền xử lý phức tạp hay mô hình chuyên biệt.
Dễ dùng cho các tác vụ phân loại văn bản: Bag of Words phù hợp với các tác vụ cơ bản như phân loại văn bản, phân tích cảm xúc và phát hiện spam. Những tác vụ này thường không cần mô hình ngôn ngữ tinh vi, nên biểu diễn BOW là đủ và hiệu quả.
Hạn chế
Kích thước từ vựng ảnh hưởng đến độ thưa của biểu diễn: Từ vựng càng lớn, biểu diễn càng thưa và chiều càng cao. Độ thưa này có thể khiến mô hình khó học hiệu quả và đòi hỏi tinh chỉnh kích thước từ vựng để tránh chi phí tính toán quá mức.
Sinh ra ma trận thưa tốn kém tính toán: Vì mỗi tài liệu được biểu diễn bằng tần suất của mỗi từ trong một từ vựng có thể rất lớn, các ma trận kết quả thường hầu hết là số 0, kém hiệu quả khi lưu trữ và xử lý trong pipeline học máy. Ma trận thưa tiêu tốn bộ nhớ đáng kể và thường cần công cụ, thư viện chuyên biệt để lưu trữ và tính toán hiệu quả, đặc biệt với bộ dữ liệu lớn.
Mất ý nghĩa và ngữ cảnh: BOW bỏ qua thứ tự từ và cấu trúc câu, dẫn đến mất quan hệ ngữ pháp và ý nghĩa. Hạn chế này khiến nó kém phù hợp cho các tác vụ mà ngữ cảnh, sắc thái và trật tự từ quan trọng, như dịch thuật hoặc phát hiện cảm xúc trong câu phức tạp.
Các chiến lược sau có thể được dùng để giảm kích thước từ vựng trong Bag of Words:
Bỏ qua phân biệt hoa/thường.
Loại bỏ dấu câu.
Loại bỏ stopword, tức các từ phổ biến như the và a.
Đảm bảo tất cả từ được đánh vần đúng.
Dùng kỹ thuật stemming để rút gọn từ về gốc.
Bước tiếp theo: Vượt ra ngoài Bag of Words
Một hạn chế của mô hình Bag of Words là đối xử mọi từ như nhau. Điều này có thể dẫn tới việc một số từ được coi trọng hơn chỉ vì xuất hiện thường xuyên.
TF-IDF (Term Frequency–Inverse Document Frequency) là giải pháp cho vấn đề này, vì nó điều chỉnh trọng số của từ dựa trên tần suất xuất hiện của chúng trên toàn bộ tài liệu.
TF-IDF: Phần mở rộng của Bag of Words
Term Frequency (TF) đại diện cho tần suất một thuật ngữ trong một tài liệu. Inverse Document Frequency (IDF) giảm ảnh hưởng của các từ xuất hiện phổ biến trên nhiều tài liệu. Điểm TF-IDF được tính bằng cách nhân hai đại lượng này.
Xét một tài liệu có 200 từ, trong đó từ love xuất hiện 5 lần. TF cho love là (5 / 200) = 0,025. Giả sử chúng ta có một triệu tài liệu và từ love xuất hiện trong một nghìn tài liệu, thì IDF được tính là log(1000000 / 1000) = 3. Trọng số TF-IDF là tích của hai đại lượng: 0,025 * 3 = 0,075.
Trong Scikit-learn, việc này khá dễ tính bằng lớp TfidfVectorizer.
from sklearn.feature_extraction.text import TfidfVectorizer
# Sample corpus
corpus =["Python is amazing and fun.","Python is not just fun but also powerful.","Learning Python is fun!",]# Create the Tf-idf vectorizer
tfidf_vectorizer = TfidfVectorizer()# Fit and transform the corpus
X_tfidf = tfidf_vectorizer.fit_transform(corpus)# Show the Vocabularyprint("Vocabulary:", tfidf_vectorizer.get_feature_names_out())# Show the TF-IDF Matrixprint("TF-IDF Representation:")print(X_tfidf.toarray())Được hỗ trợ bởi
Kết quả:
Vocabulary:['also''amazing''and''but''fun''is''just''learning''not''powerful''python']
TF-IDF Representation:[[0.0.572928830.572928830.0.3383810.3383810.0.0.0.0.338381][0.406676060.0.0.406676060.240189430.240189430.406676060.0.406676060.406676060.24018943][0.0.0.0.0.412858570.412858570.0.699030330.0.0.41285857]]Được hỗ trợ bởi
Ma trận TF-IDF ở trên cung cấp thước đo có trọng số thay vì tần suất thô.
Dù mô hình Bag of Words có hạn chế, đặc biệt với bộ dữ liệu lớn và phức tạp, nó vẫn là nền tảng quan trọng trong nhiều ứng dụng NLP. Hiểu mô hình này sẽ giúp bạn khi khám phá các mô hình nâng cao hơn như word embedding và Transformers.
Từ đây, bạn có thể thử nghiệm BoW trong dự án của mình, bao gồm phát hiện spam, phân tích cảm xúc, phân cụm tài liệu, và nhiều hơn nữa.
Nếu muốn cải thiện hơn nữa so với Bag of Words, bạn có thể khám phá các phương pháp như Word2Vec, GloVe, hoặc các mô hình học sâu như BERT.
Tổng kết
Bag of Words là một kỹ thuật nền tảng trong Xử lý ngôn ngữ tự nhiên. Nó là cách đơn giản nhưng hiệu quả để chuyển văn bản phi cấu trúc thành các đặc trưng số mà các thuật toán học máy có thể sử dụng. Trong hướng dẫn này, chúng ta đã đề cập:
Bag of Words (BoW) là gì?
Lợi ích của mô hình Bag of Words trong việc xây dựng mô hình học máy.
Cách triển khai mô hình Bag of Words trong Python.
Ưu điểm và hạn chế của Bag of Words.
Lý thuyết và động lực đằng sau mô hình Bag of Words.
Giới thiệu TF-IDF như một cải tiến cho cách tiếp cận Bag of Words truyền thống.
Học cách chuyển đổi văn bản và trích xuất những thông tin hữu ích từ sách, trang web đánh giá và bài viết trực tuyến bằng cách sử dụng Xử lý ngôn ngữ tự nhiên (NLP) trong Python.
Bag of Words (BoW) là một kỹ thuật trong Xử lý ngôn ngữ tự nhiên (NLP). Kỹ thuật này được sử dụng rộng rãi để chuyển đổi dữ liệu văn bản thành định dạng máy có thể đọc được, cụ thể là các giá trị số, mà không xét đến ngữ pháp và thứ tự từ. Hiểu BoW rất quan trọng với bất kỳ ai làm việc với dữ liệu văn bản. Python cung cấp nhiều công cụ và thư viện để triển khai Bag of Words hiệu quả.
Trong hướng dẫn này, chúng ta sẽ đi sâu vào BoW, giới thiệu các khái niệm, đề cập đến các cách sử dụng, và thực hiện từng bước chi tiết bằng Python. Kết thúc hướng dẫn, bạn sẽ có thể áp dụng mô hình Bag of Words vào các bài toán thực tế. Nếu bạn mới làm quen với NLP, hãy xem lộ trình kỹ năng Natural Language Processing in Python để tìm hiểu thêm.
Bag of Words là gì?
Bag of Words là kỹ thuật trích xuất đặc trưng từ dữ liệu văn bản cho các tác vụ học máy, như phân loại văn bản và phân tích cảm xúc. Điều này quan trọng vì các thuật toán học máy không thể xử lý dữ liệu văn bản thô. Quá trình chuyển văn bản thành số được gọi là trích xuất đặc trưng hoặc mã hóa đặc trưng.
Bag of Words dựa trên số lần xuất hiện của các từ trong một tài liệu. Quá trình bắt đầu bằng việc tìm tập từ vựng trong văn bản và đo lường tần suất xuất hiện của chúng. Nó được gọi là “bag” (túi) vì thứ tự và cấu trúc của từ không được xét đến, chỉ quan tâm đến số lần xuất hiện.
Mô hình Bag of Words khác với Continuous Bag of Words (CBOW), mô hình học các word embedding dạng đặc bằng cách sử dụng các từ xung quanh để dự đoán một từ mục tiêu, từ đó nắm bắt quan hệ ngữ nghĩa giữa các từ. CBOW cần được huấn luyện trên một kho văn bản lớn và tạo ra các vector chiều thấp, hữu ích cho các ứng dụng NLP phức tạp nơi ngữ cảnh từ rất quan trọng.
Khía cạnh
BOW
CBOW
Mục đích
Đếm số lần xuất hiện của từng từ
Dự đoán từ mục tiêu dựa trên ngữ cảnh
Kiểu đầu ra
Vector thưa, chiều cao
Embedding đặc, chiều thấp
Xét ngữ cảnh
Không (bỏ qua thứ tự từ)
Có (dùng các từ xung quanh)
Biểu diễn
Vector tần suất dạng thưa
Vector đặc nắm bắt ngữ nghĩa
Độ phức tạp
Thấp (không cần huấn luyện)
Cao (cần huấn luyện trên kho lớn)
Ứng dụng điển hình
Phân loại văn bản, phân tích cảm xúc
Word embedding, các tác vụ NLP cần ngữ cảnh
Vì sao dùng Bag of Words?
Bag of Words hữu ích trong nhiều tác vụ NLP, một số lý do sử dụng gồm:
Tuy nhiên, cũng có hạn chế như không xét đến ngữ nghĩa, cấu trúc từ, hay trật tự từ.
Các bước triển khai Bag of Words trong Python
Để tạo mô hình bag-of-words, chúng ta lấy tất cả các từ trong một kho ngữ liệu và tạo một cột cho mỗi từ. Các hàng đại diện cho các câu. Nếu một từ nào đó tồn tại trong câu, nó được biểu diễn bằng 1, và nếu không tồn tại thì bằng 0. Mỗi từ trong cột đại diện cho một đặc trưng.
Kết quả cuối cùng là một ma trận thưa. Ma trận thưa là ma trận có rất nhiều số 0.
Tiền xử lý dữ liệu
Để tạo mô hình Bag of Words trong Python, chúng ta cần thực hiện một vài bước tiền xử lý. Các bước này gồm tách từ (tokenization) và loại bỏ stopword.
Tokenization là quá trình chia nhỏ một đoạn văn bản thành các đơn vị nhỏ hơn, thường là từ. Bạn có thể thực hiện tokenization bằng NLTK.
Stop words là các từ phổ biến trong tiếng Anh như "the," "that," và "a," vốn không đóng góp vào sắc thái (polarity) của câu.
Kết quả:
Tạo từ vựng
Từ vựng (vocabulary) là tập hợp các từ duy nhất xuất hiện trong một kho văn bản. Xây dựng từ vựng bao gồm thu thập tất cả các từ duy nhất từ kho văn bản và đếm số lần xuất hiện của chúng. Từ vựng này hữu ích cho nhiều tác vụ NLP như mô hình ngôn ngữ, word embedding và phân loại văn bản.
Đoạn mã dưới đây tạo phân bố tần suất đơn giản của các từ trong kho văn bản, hữu ích cho các tác vụ NLP cơ bản như xây dựng từ vựng hoặc hiểu nội dung văn bản:
defaultdict(int)giúp đơn giản hóa việc đếm tần suất, tự động khởi tạo mọi từ mới với giá trị 0, cho phép tăng đếm trực tiếp mà không cần kiểm tra.\b\w+\bxác định các từ chỉ gồm ký tự chữ-số, bỏ qua dấu câu và ký hiệu khác.Kết quả:
Tự xây dựng từ vựng có thể tốn thời gian, đặc biệt với các kho lớn. CountVectorizer của Scikit-learn tự động hóa quá trình này và cho phép xử lý văn bản linh hoạt hơn như chúng ta sẽ thấy sau.
Triển khai Bag of Words bằng Python (từ đầu)
Hãy bắt đầu với một triển khai Bag of Words đơn giản từ đầu bằng Python. Điều này sẽ giúp bạn hiểu các khối xây dựng và cơ chế hoạt động bên dưới.
Triển khai thủ công
Bước 1: Tiền xử lý dữ liệu văn bản
Chúng ta sẽ bắt đầu bằng cách định nghĩa một hàm đơn giản để xử lý văn bản, gồm tokenization, chuyển chữ thường và loại bỏ dấu câu.
Kết quả:
Bước 2: Xây dựng từ vựng
Giờ chúng ta cần quét qua tất cả tài liệu và xây dựng một danh sách đầy đủ các từ duy nhất, đó là từ vựng của chúng ta.
Bước 3: Tính tần suất từ và vector hóa
Bây giờ, chúng ta sẽ tính tần suất của mỗi từ trong từ vựng cho từng tài liệu trong kho đã xử lý.
Tại thời điểm này, bạn đã tạo được biểu diễn Bag of Words cho mỗi tài liệu trong kho của mình.
Kết quả:
Sử dụng CountVectorizer của Scikit-learn
Xây dựng mô hình Bag of Words thủ công giúp học tập, nhưng với ứng dụng sản xuất, bạn sẽ muốn dùng các thư viện tối ưu, hiệu quả như Scikit-learn.
Hàm Python dùng để tokenization là CountVectorizer, được import từ
sklearn.feature_extraction.text. Một trong các tham số củaCountVectorizerlàmax_features, đại diện cho số lượng từ tối đa bạn muốn có trong mô hình bag of words. Ở đây chúng ta dùng None, nghĩa là sẽ dùng tất cả đặc trưng.Sau khi tạo một thể hiện của
CountVectorizer, dùng phương thức.fit_transform() để tạo mô hình bag of words. Tiếp theo, dùng.toarray()để chuyển mô hình bag of words thành các mảng numpy có thể đưa vào mô hình học máy.Khi đã fit, CountVectorizer đã xây dựng một từ điển các chỉ số đặc trưng. Giá trị chỉ số của một từ trong từ vựng liên kết với tần suất của nó trong toàn bộ kho huấn luyện.
Kết quả:
Ví dụ: Ứng dụng Bag of Words
Bây giờ hãy áp dụng mô hình BoW cho một kho văn bản nhỏ gồm ba bài đánh giá phim để minh họa toàn bộ quy trình.
Chúng ta sẽ dùng CountVectorizer của Scikit-learn để áp dụng mô hình BoW cho kho văn bản nhỏ này.
Các bước chúng ta sẽ thực hiện:
CountVectorizertự động token hóa văn bản, loại bỏ dấu câu và chuyển chữ thường..fit_transform(corpus)chuyển kho văn bản thành ma trận tài liệu–thuật ngữ, trong đó mỗi hàng đại diện cho một tài liệu và mỗi cột đại diện cho một từ trong từ vựng.X_denselà ma trận đặc biểu diễn tần suất của mỗi từ trong từng tài liệu.Kết quả:
Cách diễn giải kết quả trên như sau:
Vector BoW có thể được hiểu như sau:
Ưu điểm và hạn chế của Bag of Words
Giờ hãy cùng điểm qua một số ưu điểm và hạn chế của mô hình Bag of Words.
Ưu điểm
Hạn chế
Các chiến lược sau có thể được dùng để giảm kích thước từ vựng trong Bag of Words:
Bước tiếp theo: Vượt ra ngoài Bag of Words
Một hạn chế của mô hình Bag of Words là đối xử mọi từ như nhau. Điều này có thể dẫn tới việc một số từ được coi trọng hơn chỉ vì xuất hiện thường xuyên.
TF-IDF (Term Frequency–Inverse Document Frequency) là giải pháp cho vấn đề này, vì nó điều chỉnh trọng số của từ dựa trên tần suất xuất hiện của chúng trên toàn bộ tài liệu.
TF-IDF: Phần mở rộng của Bag of Words
Term Frequency (TF) đại diện cho tần suất một thuật ngữ trong một tài liệu. Inverse Document Frequency (IDF) giảm ảnh hưởng của các từ xuất hiện phổ biến trên nhiều tài liệu. Điểm TF-IDF được tính bằng cách nhân hai đại lượng này.
Xét một tài liệu có 200 từ, trong đó từ love xuất hiện 5 lần. TF cho love là (5 / 200) = 0,025. Giả sử chúng ta có một triệu tài liệu và từ love xuất hiện trong một nghìn tài liệu, thì IDF được tính là log(1000000 / 1000) = 3. Trọng số TF-IDF là tích của hai đại lượng: 0,025 * 3 = 0,075.
Trong Scikit-learn, việc này khá dễ tính bằng lớp TfidfVectorizer.
Kết quả:
Ma trận TF-IDF ở trên cung cấp thước đo có trọng số thay vì tần suất thô.
Dù mô hình Bag of Words có hạn chế, đặc biệt với bộ dữ liệu lớn và phức tạp, nó vẫn là nền tảng quan trọng trong nhiều ứng dụng NLP. Hiểu mô hình này sẽ giúp bạn khi khám phá các mô hình nâng cao hơn như word embedding và Transformers.
Từ đây, bạn có thể thử nghiệm BoW trong dự án của mình, bao gồm phát hiện spam, phân tích cảm xúc, phân cụm tài liệu, và nhiều hơn nữa.
Nếu muốn cải thiện hơn nữa so với Bag of Words, bạn có thể khám phá các phương pháp như Word2Vec, GloVe, hoặc các mô hình học sâu như BERT.
Tổng kết
Bag of Words là một kỹ thuật nền tảng trong Xử lý ngôn ngữ tự nhiên. Nó là cách đơn giản nhưng hiệu quả để chuyển văn bản phi cấu trúc thành các đặc trưng số mà các thuật toán học máy có thể sử dụng. Trong hướng dẫn này, chúng ta đã đề cập:
Hãy xem lộ trình kỹ năng Natural Language Processing in Python của chúng tôi để đào sâu vào xử lý ngôn ngữ tự nhiên.