Vấn đề này đã đẩy các nhà nghiên cứu và các tổ chức vào việc nghiên cứu và phát triển các công nghệ và phương pháp để phát hiện và loại bỏ tin nhắn rác một cách hiệu quả.Mục tiêu chính c
TÌM HIỂU THUẬT TOÁN K-NEAREST NEIGHBORS (KNN)
Tại sao chúng ta cần thuật toán KNN
Giả sử có hai loại, tức là Loại A và Loại B, và chúng ta có một điểm dữ liệu mới x1, vậy điểm dữ liệu này sẽ nằm trong loại nào trong số các loại này Để giải quyết loại vấn đề này, chúng ta cần thuật toán K-NN Với sự trợ giúp của K-NN, chúng ta có thể dễ dàng xác định danh mục hoặc lớp của một tập dữ liệu cụ thể. Hãy xem xét sơ đồ dưới đây Ảnh 1: Ví dụ về KNN
Định nghĩa và cách hoạt động của thuật toán KNN
K-nearest neighbor là một trong những thuật toán supervised-learning đơn giản nhất (mà hiệu quả trong một vài trường hợp) trong Machine Learning Khi training, thuật toán này không học một điều gì từ dữ liệu training (đây cũng là lý do thuật toán này được xếp vào loại lazy learning), mọi tính toán được thực hiện khi nó cần dự đoán kết quả của dữ liệu mới K-nearest neighbor có thể áp dụng được vào cả hai loại của bài toán Supervised learning là Classification và Regression KNN còn được gọi là một thuật toán Instance-based hay Memory- based learning.
Có một vài khái niệm tương ứng người-máy như sau:
Ngôn ngữ người Ngôn ngữ Máy Học in Machine Learning
Câu hỏi Điểm dữ liệu Data point Đáp án Đầu ra, nhãn Output, Label Ôn thi Huấn luyện Training
Tập tài liệu mang vào phòng thi
Tập dữ liệu tập huấn Training set Đề thi Tập dữ liểu kiểm thử Test set
Bảng 1: Khái niệm người và máy
Với KNN, trong bài toán Classification, label của một điểm dữ liệu mới (hay kết quả của câu hỏi trong bài thi) được suy ra trực tiếp từ K điểm dữ liệu gần nhất trong training set Label của một test data có thể được quyết định bằng major voting (bầu chọn theo số phiếu) giữa các điểm gần nhất, hoặc nó có thể được suy ra bằng cách đánh trọng số khác nhau cho mỗi trong các điểm gần nhất đó rồi suy ra label Chi tiết sẽ được nêu trong phần tiếp theo.
Trong bài toán Regresssion, đầu ra của một điểm dữ liệu sẽ bằng chính đầu ra của điểm dữ liệu đã biết gần nhất (trong trường hợp K=1), hoặc là trung bình có trọng số của đầu ra của những điểm gần nhất, hoặc bằng một mối quan hệ dựa trên khoảng cách tới các điểm gần nhất đó.
Một cách ngắn gọn, KNN là thuật toán đi tìm đầu ra của một điểm dữ liệu mới bằng cách chỉ dựa trên thông tin của K điểm dữ liệu trong training set gần nó nhất (K-lân cận), không quan tâm đến việc có một vài điểm dữ liệu trong những điểm gần nhất này là nhiễu Hình dưới đây là một ví dụ về KNN trong classification với K = 1. Ảnh 2: Bản đồ của 1NN (Nguồn: Wikipedia)
Ví dụ trên đây là bài toán Classification với 3 classes: Đỏ, Lam, Lục Mỗi điểm dữ liệu mới (test data point) sẽ được gán label theo màu của điểm mà nó thuộc về Trong hình này, có một vài vùng nhỏ xem lẫn vào các vùng lớn hơn khác màu Ví dụ có một điểm màu Lục ở gần góc 11 giờ nằm giữa hai vùng lớn với nhiều dữ liệu màu Đỏ và Lam Điểm này rất có thể là nhiễu Dẫn đến nếu dữ liệu test rơi vào vùng này sẽ có nhiều khả năng cho kết quả không chính xác
Khi có một điểm dữ liệu mới cần phân loại hoặc dự đoán, thuật toán KNN thực hiện các bước sau:
Tính khoảng cách giữa điểm dữ liệu mới và tất cả các điểm dữ liệu trong tập huấn luyện Khoảng cách thường được tính bằng cách sử dụng các phương pháp đo lường như khoảng cách Euclidean, khoảng cách Manhattan, hay khoảng cách Cosine.
Chọn K điểm dữ liệu có khoảng cách gần nhất với điểm dữ liệu mới K là một siêu tham số mà người dùng phải xác định trước.
Cuối cùng, chúng ta sử dụng phương pháp voting (nếu là bài toán phân loại) hoặc trung bình (nếu là bài toán dự đoán) trên nhãn của K hàng xóm đã chọn để xác định nhãn hoặc giá trị cho điểm dữ liệu mới.
Các bước triển khai thuật toán KNN
Triển khai thuật toán KNN có thể thực hiện qua các bước cơ bản sau:
2.3.1 Tiền xử lý dữ liệu
Tiền xử lý dữ liệu là một bước quan trọng trong xử lý dữ liệu văn bản trước khi áp dụng các thuật toán Machine Learning như KNN Mục tiêu của tiền xử lý là làm sạch, chuẩn hóa và biểu diễn dữ liệu văn bản thành dạng số hóa để thuật toán có thể xử lý hiệu quả Dưới đây là các bước thường được thực hiện trong tiền xử lý dữ liệu văn bản:
2.3.2 Chuyển đổi văn bản thành chữ thường
Chuyển đổi toàn bộ văn bản thành chữ thường để tránh sự phân biệt giữa các từ viết hoa và không viết hoa.
2.3.3 Loại bỏ dấu câu và ký tự đặc biệt
Loại bỏ các dấu câu, ký tự đặc biệt và số không cần thiết trong văn bản Chỉ giữ lại các từ và ký tự cần thiết để xây dựng đặc trưng cho văn bản.
Tách văn bản thành các từ riêng lẻ (từ token) để chuẩn bị cho các bước tiếp theo trong tiền xử lý và xây dựng đặc trưng.
2.3.5 Loại bỏ từ dừng (Stop words removal)
Loại bỏ các từ dừng như "a", "an", "the", "in", "on" v.v Những từ này không mang ý nghĩa quan trọng trong việc phân loại và dự đoán và thường không cần thiết.
2.3.6 Chuẩn hóa từ (Stemming và Lemmatization)
- Stemming: Chuyển đổi các từ về dạng gốc bằng cách cắt bỏ các hậu tố và tiền tố Ví dụ: "running", "runs", "ran" sẽ được chuyển về "run".
- Lemmatization: Chuyển đổi các từ về dạng gốc bằng cách sử dụng từ điển.
Ví dụ: "better", "best" sẽ được chuyển về "good".
2.3.7 Biểu diễn dữ liệu thành dạng số hóa
Sử dụng kỹ thuật Bag of Words (BoW) hoặc TF-IDF để biểu diễn văn bản thành vector số hóa BoW là một phương pháp đếm số lần xuất hiện của các từ trong văn bản, trong khi TF-IDF là một phương pháp tính trọng số cho từng từ dựa trên tần suất xuất hiện trong văn bản và tần suất xuất hiện trong tập dữ liệu.
Sau khi hoàn thành các bước tiền xử lý, dữ liệu văn bản đã được biểu diễn thành dạng số hóa và sẵn sàng để áp dụng thuật toán KNN hoặc các thuật toán Machine Learning khác Tiền xử lý dữ liệu là một bước quan trọng giúp tăng hiệu quả và độ chính xác của mô hình phát hiện tin nhắn rác.
Tính toán khoảng cách là một bước quan trọng trong thuật toán K-Nearest Neighbors (KNN), giúp xác định sự tương đồng giữa các điểm dữ liệu trong không gian đặc trưng Có nhiều phương pháp tính toán khoảng cách phổ biến, trong đó hai phương pháp phổ biến nhất là khoảng cách Euclidean và khoảng cách Cosine.
Khoảng cách Euclidean là khoảng cách đo giữa hai điểm trong không gian đặc trưng dựa trên độ dài của vector kết nối chúng Đối với hai điểm q(x1, y1) và p(x2, y2) trong không gian hai chiều, khoảng cách Euclidean được tính bằng công thức: Ảnh 3: Đồ thị khoảng cách hai điểm p q distance = sqrt((x2 - x1) 2 + (y2 - y1) 2 ) Đối với không gian đặc trưng có nhiều hơn hai chiều, công thức tính toán tương tự như trên, tổng quát hơn cho mỗi chiều của vector.
2.3.8.2 Khoảng cách Cosine Ảnh 4: Khoảng cách theo Cosine
Khoảng cách Cosine đo sự tương đồng hướng giữa hai vector trong không gian đặc trưng Nó được tính bằng cách tính cosine của góc giữa hai vector. Khoảng cách Cosine giữa hai vector A và B được tính bằng công thức: cosine_distance = 1 - (A.B) / (||A|| * ||B||)
Trong đó, A.B là tích vô hướng của hai vector A và B, ||A|| và ||B|| lần lượt là độ dài của hai vector A và B.
Khoảng cách Euclidean thường được sử dụng cho các dữ liệu có các đặc trưng số và khoảng cách Cosine thường được sử dụng cho các dữ liệu văn bản biểu diễn dưới dạng vector TF-IDF.
Khi đã tính toán khoảng cách giữa điểm dữ liệu mới và tất cả các điểm trong tập huấn luyện, thuật toán KNN sẽ chọn K điểm gần nhất để dự đoán nhãn hoặc giá trị cho điểm dữ liệu mới.
Lựa chọn giá trị của K trong thuật toán K-Nearest Neighbors (KNN) là một phần quan trọng trong quá trình xây dựng mô hình Giá trị K ảnh hưởng đến hiệu suất của mô hình và có thể ảnh hưởng đến khả năng tổng quát hóa và khái quát hóa của mô hình Dưới đây là một số cách để lựa chọn giá trị K:
Một cách thông thường để lựa chọn giá trị K là sử dụng kỹ thuật cross- validation Chia tập dữ liệu huấn luyện thành các tập con và sử dụng một số phần để huấn luyện mô hình và các phần còn lại để đánh giá hiệu suất của mô hình Thử nghiệm với nhiều giá trị K khác nhau (ví dụ: K = 1, 3, 5, 7) và chọn giá trị K tối ưu mà cho kết quả tốt nhất trên tập kiểm tra.
2.3.11 Elbow Method Đối với bài toán phân loại, bạn có thể sử dụng phương pháp Elbow để lựa chọn giá trị K Đây là một phương pháp dựa trên việc vẽ đồ thị giữa giá trị K và sai số của mô hình Khi tăng giá trị K, sai số trên tập huấn luyện sẽ giảm Ảnh 5: K tăng dần làm mịn ranh giới dần Tuy nhiên, khi K quá lớn, mô hình có thể trở nên quá đơn giản và underfitting Điểm "khuỷu tay" trên đồ thị Elbow thường chính là giá trị K tốt nhất. Ảnh 6: Đồ thị của K bến thiên trong K-mean
Hiểu biết về bài toán và dữ liệu cụ thể cũng có thể giúp bạn lựa chọn giá trị K.
Ví dụ, nếu bạn biết rằng các lớp trong dữ liệu có sự tách biệt rõ ràng, thì có thể chọn giá trị K nhỏ hơn Ngược lại, nếu dữ liệu có nhiễu hoặc sự overlap giữa các lớp, bạn có thể cân nhắc chọn K lớn hơn.
2.3.13 Thử nghiệm và đánh giá
Thử nghiệm với một loạt các giá trị K và đánh giá hiệu suất của mô hình trên tập kiểm tra để xác định giá trị K nào tạo ra kết quả tốt nhất.
Phân loại hoặc dự đoán
Trong Machine Learning, "phân loại" và "dự đoán" là hai khái niệm cơ bản liên quan đến việc sử dụng mô hình để đưa ra quyết định hoặc dự đoán về dữ liệu mới Dưới đây là sự khác biệt giữa hai khái niệm này:
Phân loại là quá trình đưa ra quyết định về lớp hoặc nhãn của một điểm dữ liệu dựa trên các thông tin đã học từ dữ liệu huấn luyện Mục tiêu của phân loại là phân chia các điểm dữ liệu vào các lớp khác nhau dựa trên các đặc trưng Ví dụ,trong bài toán phát hiện thư rác, bạn có thể sử dụng phân loại để dự đoán xem một email mới có phải là thư rác (lớp 1) hay không (lớp 0).
Dự đoán là quá trình ước tính giá trị số hoặc dự đoán về một đặc điểm cụ thể của dữ liệu dựa trên thông tin đã học từ dữ liệu huấn luyện Mục tiêu của dự đoán là ước tính giá trị số, thời gian, hoặc một biến liên tục khác dựa trên mô hình học máy Ví dụ, trong bài toán dự đoán giá nhà, bạn có thể sử dụng mô hình để ước tính giá trị số (giá nhà) dựa trên các đặc trưng như diện tích, số phòng ngủ, vị trí, v.v.
Tóm lại, phân loại là quá trình phân chia dữ liệu vào các lớp khác nhau, trong khi dự đoán là quá trình ước tính giá trị số hoặc dự đoán về một biến liên tục cụ thể Cả hai khái niệm đều đóng vai trò quan trọng trong Machine Learning và được sử dụng cho các bài toán khác nhau.
Ưu điểm và hạn chế của thuật toán KNN
2.5.1 Ưu điểm Ưu điểm Đơn giản và dễ triển khai.
Không cần huấn luyện mô hình, do đó việc áp dụng KNN vào dữ liệu mới rất nhanh chóng. Độ chính xác cao khi dữ liệu đồng nhất (gần nhau trong không gian đặc trưng).
Khả năng mở rộng và ứng dụng cho nhiều loại dữ liệu.
Hạn chế Đòi hỏi lưu toàn bộ tập dữ liệu huấn luyện trong bộ nhớ, do đó tốn không gian lưu trữ lớn.
Nhạy cảm với nhiễu và dữ liệu nhiều chiều (curse of dimensionality).
Cần lựa chọn tham số K phù hợp, sai lầm trong lựa chọn
K có thể làm giảm hiệu suất của mô hình.
Hiệu suất của KNN giảm khi dữ liệu có kích thước lớn.
XÂY DỰNG ỨNG DỤNG PHÁT HIỆN TIN NHẮN RÁC
Tải tập dữ liệu
Sử dụng thư viện google.colab để kết nối với Google Drive và mount nó vào thư mục /content/drive
Sử dụng thư viện pandas để đọc dữ liệu từ tệp tin SMSSpamCollection.txt trong Google Drive
Hiển thị 5 dòng đầu tiên của dữ liệu.
Drive.mount(‘/content/drive’): là câu lệnh dùng để kết nối Google Drive với Colab Câu lệnh này sẽ yêu cầu bạn đăng nhập vào tài khoản Google của bạn và cấp quyền truy cập cho Colab.
File_url = ‘/content/drive/My Drive/Colab Notebooks/SMSSpamCollection.txt’: trong Python gán đường dẫn đến dữ liệu Bộ sưu tập thư rác SMS cho biến file_url Biến này sau đó có thể được sử dụng để truy cập tệp để xử lý hoặc phân tích thêm.
Data =: phần này của câu lệnh khai báo cho một biến có tên data và gán kết quả của biểu thức sau cho biến đó.
pd.read_csv(file_url, sep =’\t’, header =None, names = [“label”,
“sms”]): Đây là lệnh gọi hàm đọc tệp dữ liệu Bộ sưu tập thư rác SMS và lưu trữ dữ liệu trong đối tượng DataFrame có tên data.
pd.read_csv(): Đây là chức năng tích hợp từ thư viện Pandas để đọc tệp CSV vào DataFrame.
file_url: Đây là biến chứa đường dẫn đến tập dữ liệu Bộ sưu tập thư rác SMS.
sep = ‘\t’: Tham số này chỉ định rằng dấu phân cách được sử dụng để phân tách các trường trong tệp CSV là ký tự tab (\t).
header = None: Tham số này cho biết hàng đầu tiên của tệp CSV không chứa tên cột.
names = [“label”, “sms”]: Tham số này chỉ định tên cột được gán cho hai cột của DataFrame Cột đầu tiên sẽ được đặt tên label và cột thứ hai sẽ được đặt tên sms.
Câu lệnh data.head() trong Python được sử dụng để hiển thị 5 hàng đầu tiên của một DataFrame data: là tên của DataFrame mà bạn muốn hiển thị 5 hàng đầu tiên .head(): là phương thức của DataFrame được sử dụng để hiển thị 5 hàng đầu tiên.
Xử lý tiền dữ liệu
3.2.1 Tải các thư viện và tập dữ liệu từ nltk để xử lý tiền dữ liệu
Câu lệnh import string sẽ import thư viện string, cung cấp các hàm xử lý chuỗi Thư viện này chứa các hàm như lower(), upper(), len(), split(), join(), v.v.
Câu lệnh import nltk sẽ import thư viện nltk, cung cấp các hàm xử lý ngôn ngữ tự nhiên Thư viện này chứa các hàm như word_tokenize(), tag(), pos_tag(), sent_tokenize(), v.v.
Câu lệnh nltk.download('stopwords') sẽ tải xuống bộ dữ liệu stopwords tiếng Anh Bộ dữ liệu này chứa các từ không mang ý nghĩa trong ngữ cảnh, chẳng hạn như "the", "a", "of", "to", v.v.
Câu lệnh nltk.download('punkt') sẽ tải xuống bộ dữ liệu dấu câu tiếng Anh Bộ dữ liệu này chứa các dấu câu được sử dụng trong tiếng Anh, chẳng hạn như ".", ",", "?", "!", v.v.
Câu lệnh stopwords = nltk.corpus.stopwords.words('english') sẽ lấy bộ stopwords tiếng Anh từ thư viện nltk.
Câu lệnh punctuation = string.punctuation sẽ lấy bộ dấu câu tiếng Anh từ thư viện string.
Câu lệnh print(stopwords[:5]) sẽ in ra 5 stopwords đầu tiên trong bộ dữ liệu stopwords tiếng Anh.
Câu lệnh print(punctuation) sẽ in ra tất cả các dấu câu trong bộ dữ liệu dấu câu tiếng Anh.
3.2.2 Xóa các dấu câu và chuyển đổi thành chữ thường
Câu lệnh def pre_process(sms) định nghĩa hàm pre_process(), có tham số truyền vào là một chuỗi văn bản Hàm này sẽ thực hiện các thao tác xử lý văn bản, bao gồm: chuyển đổi tất cả các ký tự thành chữ thường, xóa tất cả dấu câu, và loại bỏ các từ stopwords.
Câu lệnh sms = sms.lower() sẽ chuyển đổi tất cả các ký tự trong chuỗi sms thành chữ thường Điều này sẽ giúp cho việc xử lý văn bản trở nên đơn giản hơn, vì các từ tiếng Anh thường có ý nghĩa giống nhau khi được viết ở dạng chữ hoa hoặc chữ thường.
Câu lệnh for char in punctuation: sẽ lặp qua tất cả các ký tự trong tập hợp punctuation Tập hợp này chứa các ký tự dấu câu được sử dụng trong tiếng Anh, chẳng hạn như ".", ",", "?", "!", v.v Câu lệnh này sẽ thay thế tất cả các ký tự dấu câu trong chuỗi sms bằng một chuỗi rỗng Điều này là cần thiết vì các ký tự dấu câu thường không mang ý nghĩa trong ngữ cảnh.
Câu lệnh for word in stopwords: sẽ lặp qua tất cả các từ trong tập hợp stopwords Tập hợp này chứa các từ không mang ý nghĩa trong ngữ cảnh, chẳng hạn như "the", "a", "of", "to", v.v Câu lệnh này sẽ thay thế tất cả các lần xuất hiện của các từ stopwords trong chuỗi sms bằng một chuỗi rỗng Điều này giúp loại bỏ các từ không mang ý nghĩa, từ đó cải thiện hiệu quả của các mô hình xử lý ngôn ngữ tự nhiên.
Câu lệnh return sms sẽ trả về chuỗi sms sau khi đã được xử lý.
3.2.3 Tokenize và loại bỏ từ dừng (stopwords) từ văn bản
Câu lệnh def remove_stopwords(sms) định nghĩa hàm remove_stopwords(), có tham số truyền vào là một chuỗi văn bản Hàm này sẽ thực hiện thao tác loại bỏ các từ stopwords khỏi chuỗi văn bản.
Câu lệnh tokens = nltk.word_tokenize(sms) sẽ chuyển đổi chuỗi sms thành danh sách từ bằng hàm word_tokenize() của thư viện nltk Hàm này sẽ chia chuỗi văn bản thành các từ dựa trên các khoảng trắng, dấu câu, và các ký tự đặc biệt khác.
Câu lệnh filtered_tokens = [word for word in tokens if word not in stopwords] sẽ tạo một danh sách mới, filtered_tokens, chứa các từ trong danh sách tokens nhưng không có trong tập hợp stopwords Tập hợp stopwords chứa các từ không mang ý nghĩa trong ngữ cảnh, chẳng hạn như "the", "a", "of", "to", v.v.
Câu lệnh return filtered_tokens sẽ trả về danh sách filtered_tokens.
3.2.4 Thêm một cột mới 'processed' chứa văn bản đã được xử lý
Câu lệnh data['processed'] = data['sms'].apply(lambda x: pre_process(x)) sẽ thêm một cột mới có tên processed vào
Câu lệnh data['processed'] = data['sms'].apply() sẽ áp dụng phương thức apply() cho mỗi giá trị trong cột sms.
Phương thức apply() sẽ lấy hàm pre_process() làm đối số.
Hàm pre_process() sẽ được áp dụng cho mỗi giá trị trong cột sms.
Kết quả của hàm pre_process() sẽ được thêm vào cột processed.
Data[‘processed’]:Tên của cột chứa các tin nhắn đã được xử lý.
head():Phương thức head() của DataFrame sẽ được sử dụng để lấy 5 hàng đầu tiên của cột processed.
Phân loại và đếm từ mã thông báo
3.3.1 Tạo hàm categorize_words() để phân loại và đếm số lần xuất hiện của từ trong văn bản thuộc nhãn 'spam' và 'ham'.
Câu lệnh import nltk sẽ import thư viện nltk, cung cấp các hàm xử lý ngôn ngữ tự nhiên Thư viện này chứa các hàm như word_tokenize(), tag(), pos_tag(), sent_tokenize(), v.v.
Câu lệnh def categorize_words(): định nghĩa hàm categorize_words(), có tham số truyền vào là một DataFrame Hàm này sẽ thực hiện thao tác phân loại các từ trong DataFrame thành hai nhóm: spam và ham.
Câu lệnh spam_words = [] và ham_words = [] sẽ khởi tạo hai danh sách rỗng để chứa các từ spam và ham.
Câu lệnh for sms in data['processed'][data['label'] == 'spam']: sẽ lặp qua tất cả các tin nhắn spam trong DataFrame data.
Câu lệnh for word in sms.split() sẽ lặp qua tất cả các từ trong chuỗi sms.
Câu lệnh spam_words.append(word) sẽ thêm từ word vào danh sách spam_words.
Câu lệnh for sms in data['processed'][data['label'] == 'ham']: sẽ lặp qua tất cả các tin nhắn ham trong DataFrame data.
Câu lệnh for word in sms.split() sẽ lặp qua tất cả các từ trong chuỗi sms.
Câu lệnh ham_words.append(word) sẽ thêm từ word vào danh sách ham_words.
Câu lệnh return spam_words, ham_words sẽ trả về hai danh sách
3.3.2 Hiển thị 5 từ đầu tiên của cả hai danh sách
Câu lệnh print(spam_words[:5]) trong Python được sử dụng để in ra 5 từ spam đầu tiên trong danh sách spam_words.
Cụ thể, câu lệnh này có thể được hiểu thành các phần sau:
spam_words: Danh sách chứa các từ spam.
[:5]: Lấy 5 phần tử đầu tiên của danh sách spam_words.
print(): Hàm in ra các giá trị được truyền vào.
Câu lệnh print(ham_words[:5]) trong Python được sử dụng để in ra 5 từ ham đầu tiên trong danh sách ham_words.
Cụ thể, câu lệnh này có thể được hiểu thành các phần sau:
ham_words: Danh sách chứa các từ ham.
[:5]: Lấy 5 phần tử đầu tiên của danh sách ham_words.
print(): Hàm in ra các giá trị được truyền vào.
Dự đoán hàm
3.4.1 Tạo hàm predict(sms) để dự đoán xem một tin nhắn có phải là 'spam' hay 'ham' dựa trên số lần xuất hiện của từng từ trong tin nhắn
Câu lệnh def predict(sms): định nghĩa hàm predict(), có tham số truyền vào là một chuỗi văn bản Hàm này sẽ thực hiện thao tác dự đoán loại tin nhắn (spam hoặc ham) dựa trên tần suất xuất hiện của các từ trong chuỗi văn bản.
Câu lệnh spam_counter = 0 và ham_counter = 0 sẽ khởi tạo hai biến spam_counter và ham_counter với giá trị 0.
Câu lệnh for word in sms.split() sẽ lặp qua tất cả các từ trong chuỗi văn bản sms.
Câu lệnh if word in spam_words: sẽ kiểm tra xem từ word có phải là một từ spam không.
Nếu từ word là một từ spam, thì câu lệnh spam_counter += 1 sẽ tăng biến spam_counter lên 1.
Ngược lại, nếu từ word không phải là một từ spam, thì câu lệnh ham_counter += 1 sẽ tăng biến ham_counter lên 1.
Câu lệnh if spam_counter > ham_counter: sẽ kiểm tra xem số lượng từ spam nhiều hơn số lượng từ ham hay không.
Nếu số lượng từ spam nhiều hơn số lượng từ ham, thì hàm predict() sẽ trả về giá trị 'spam'.
Ngược lại, hàm predict() sẽ trả về giá trị '
3.4.2 Hiển thị kết quả dự đoán
Câu lệnh if ham_counter > spam_counter: sẽ kiểm tra xem số lượng từ ham nhiều hơn số lượng từ spam hay không Nếu đúng, thì câu lệnh accuracy = round((ham_counter / (ham_counter + spam_counter) * 100)) sẽ tính toán độ chính xác của dự đoán, dựa trên tỷ lệ từ ham trên tổng số từ trong tin nhắn Cuối cùng, câu lệnh print('Tin nhắn không phải là thư rác, với {}% độ chính xác'.format(accuracy)) sẽ in ra kết quả dự đoán, kèm theo độ chính xác.
Câu lệnh elif ham_counter == spam_counter: sẽ kiểm tra xem số lượng từ ham bằng với số lượng từ spam hay không Nếu đúng, thì câu lệnh print('Tin nhắn có thể là thư rác') sẽ in ra kết quả dự đoán.
Câu lệnh else: sẽ được thực thi nếu các câu lệnh if và elif trước đó đều không được thực thi Trong trường hợp này, có nghĩa là số lượng từ spam nhiều hơn số lượng từ ham Do đó, câu lệnh accuracy round((spam_counter / (ham_counter + spam_counter)* 100)) sẽ tính toán độ chính xác của dự đoán, dựa trên tỷ lệ từ spam trên tổng số từ trong tin nhắn Cuối cùng, câu lệnh print('Tin nhắn là thư rác, với {}% độ chính xác'.format(accuracy)) sẽ in ra kết quả dự đoán, kèm theo độ chính xác.
Thu thập thông tin đầu vào và kết quả của người dùng
3.5.1 Yêu cầu người dùng nhập một tin nhắn để kiểm tra
Câu lệnh user_input = input("Vui lòng gõ tin nhắn spam hoặc ham để kiểm tra xem chức năng của chúng tôi có dự đoán chính xác không: \n") sẽ yêu cầu người dùng nhập một tin nhắn spam hoặc ham Tin nhắn này sẽ được sử dụng để kiểm tra độ chính xác của mô hình phân loại thư rác.
3.5.2 Sử dụng Google Translate để chuyển đổi tin nhắn từ tiếng Việt sang tiếng Anh
from googletrans import: Câu lệnh này sẽ nhập thư viện googletrans vào chương trình.
Translator: Đây là tên của lớp Translator trong thư viện googletrans Lớp này cung cấp các hàm để dịch văn bản giữa các ngôn ngữ khác nhau.
Sau khi dòng lệnh này được thực thi, chương trình sẽ có thể sử dụng các hàm trong thư viện googletrans để dịch văn bản.
Câu lệnh def translate_vietnamese_to_english(text): định nghĩa một hàm có tên là translate_vietnamese_to_english(), với tham số đầu vào là một chuỗi văn bản tiếng Việt.
Câu lệnh translator = Translator() tạo ra một đối tượng Translator, được sử dụng để dịch văn bản giữa các ngôn ngữ khác nhau.
Câu lệnh result = translator.translate(text, src='vi', dest='en') dịch chuỗi văn bản tiếng Việt text sang tiếng Anh Tham số src='vi' chỉ định rằng ngôn ngữ nguồn là tiếng Việt, và tham số dest='en' chỉ định rằng ngôn ngữ đích là tiếng Anh.
Câu lệnh return result.text trả về văn bản đã được dịch sang tiếng Anh.
Câu lệnh user_input = translate_vietnamese_to_english(user_input) dịch chuỗi văn bản tiếng Việt user_input sang tiếng Anh, và gán kết quả dịch cho biến user_input.
3.5.3 Tiền xử lý thông tin đầu vào và gọi hàm dự đoán để hiển thị kết quả
Câu lệnh processed_input = pre_process(user_input) sẽ thực hiện việc tiền xử lý đầu vào của người dùng trước khi sử dụng nó để dự đoán loại tin nhắn Cụ thể, hàm pre_process() sẽ thực hiện các tác vụ như:
Loại bỏ các ký tự đặc biệt và dư thừa.
Chuyển đổi tất cả các ký tự thành chữ thường.
Tokenize văn bản thành các từ riêng lẻ.
Loại bỏ các từ dừng (stop words).
Chuẩn hóa các từ (stemming hoặc lemmatization).
Cụ thể, từng bước sẽ diễn ra như sau:
1 Loại bỏ các ký tự đặc biệt và dư thừa: Bước này sẽ loại bỏ các ký tự không liên quan đến nội dung chính của văn bản, chẳng hạn như dấu chấm câu, dấu cách dư thừa, ký tự số, v.v.
2 Chuyển đổi tất cả các ký tự thành chữ thường: Bước này sẽ đảm bảo rằng các từ được xử lý thống nhất, bất kể chúng được viết hoa hay viết thường.
3 Tokenize văn bản thành các từ riêng lẻ: Bước này sẽ chia văn bản thành các từ riêng lẻ để dễ dàng xử lý hơn.
4 Loại bỏ các từ dừng (stop words): Bước này sẽ loại bỏ các từ thường gặp và không mang nhiều ý nghĩa về mặt ngữ nghĩa, chẳng hạn như "the", "a", "an", v.v.
5 Chuẩn hóa các từ (stemming hoặc lemmatization): Bước này sẽ đưa các từ về dạng cơ bản của chúng, giúp giảm thiểu số lượng từ riêng biệt cần xử lý Stemming sẽ cắt bỏ các phụ tố của từ, còn lemmatization sẽ xác định dạng từ gốc của từ.
Sau khi các bước tiền xử lý được thực hiện, văn bản sẽ được lưu trữ trong biến processed_input Biến này sẽ được sử dụng làm đầu vào cho hàm predict(), là hàm sẽ dự đoán loại tin nhắn dựa trên văn bản đã được tiền xử lý.
Hàm predict() sẽ sử dụng mô hình học máy để phân loại tin nhắn thành spam hoặc ham Mô hình học máy này đã được đào tạo trên một bộ dữ liệu lớn các tin nhắn đã được dán nhãn là spam hoặc ham Khi hàm predict() nhận được một tin nhắn mới, nó sẽ sử dụng mô hình học máy để dự đoán loại của tin nhắn đó.