Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
KNN (K Nearest Neighbors) trong Python
Trong bài hướng dẫn này, mình sẽ triển khai thuật toán K Nearest Neighbors (KNN) bằng cách chỉ sử dụng các module có sẵn của Python và thư viện numpy. Đồng thời, bạn cũng sẽ hiểu về khái niệm và toán học đằng sau thuật toán ML phổ biến này.
KNN là gì?
K Nearest Neighbors là một thuật toán học máy đơn giản nhưng mạnh mẽ. Thuật toán này dựa trên nguyên lý "láng giềng gần nhất" để dự đoán nhãn của một điểm dữ liệu dựa vào những dữ liệu lân cận gần nhất trong tập huấn luyện.
KNN thuộc nhóm thuật toán không tham số, tức là không giả định bất kỳ mô hình nào cho tập dữ liệu. Nó rất hữu ích trong cả bài toán phân loại và hồi quy.
Ý tưởng cốt lõi của KNN
- Tính toán khoảng cách giữa điểm cần dự đoán với tất cả các điểm trong tập dữ liệu huấn luyện (thường dùng khoảng cách Euclid).
- Xác định k láng giềng gần nhất (những điểm dữ liệu có khoảng cách ngắn nhất).
- Dựa vào nhãn của các láng giềng gần nhất, chọn ra nhãn phổ biến nhất (trong phân loại) hoặc trung bình (trong hồi quy).
Triển khai thuật toán KNN từ đầu trong Python
Dưới đây là mã Python để triển khai thuật toán KNN:
Bài viết này được đăng tại [free tuts .net]
Code đầy đủ:
import numpy as np from collections import Counter # Thư viện để đếm tần suất các phần tử # Hàm tính khoảng cách Euclid def euclidean_distance(x1, x2): return np.sqrt(np.sum((x1 - x2) ** 2)) # Công thức khoảng cách Euclid # Lớp KNN class KNN: def __init__(self, k=3): # Giá trị k: số láng giềng gần nhất self.k = k def fit(self, X, y): """Lưu lại tập huấn luyện và nhãn tương ứng""" self.X_train = X # Tập dữ liệu huấn luyện self.y_train = y # Nhãn của tập dữ liệu def predict(self, X): """Dự đoán nhãn cho tập dữ liệu mới""" y_pred = [self._predict(x) for x in X] # Duyệt qua từng điểm để dự đoán return np.array(y_pred) # Trả về mảng kết quả def _predict(self, x): """Dự đoán nhãn cho một điểm dữ liệu""" # Tính khoảng cách giữa điểm x và tất cả điểm trong tập huấn luyện distances = [euclidean_distance(x, x_train) for x_train in self.X_train] # Lấy chỉ số của k láng giềng gần nhất k_idx = np.argsort(distances)[:self.k] # argsort sắp xếp chỉ số theo giá trị # Lấy nhãn của k láng giềng gần nhất k_neighbor_labels = [self.y_train[i] for i in k_idx] # Đếm nhãn xuất hiện nhiều nhất và trả về nhãn đó most_common = Counter(k_neighbor_labels).most_common(1) # Trả về nhãn phổ biến nhất return most_common[0][0]
Giải thích mã:
euclidean_distance
: Hàm này tính khoảng cách Euclid giữa hai điểm và bằng công thức:
Lớp KNN
:
__init__(self, k=3)
: Xác định số láng giềng gần nhất .fit(self, X, y)
: Lưu lại tập huấn luyện và nhãn để sử dụng trong dự đoán.predict(self, X)
: Áp dụng hàm_predict
cho từng điểm trong tập dữ liệu mới để trả về dự đoán._predict(self, x)
:- Tính toán khoảng cách từ điểm cần dự đoán đến tất cả các điểm trong tập dữ liệu huấn luyện.
- Chọn điểm gần nhất bằng cách sử dụng
np.argsort
. - Đếm nhãn xuất hiện nhiều nhất trong điểm gần nhất với
Counter.most_common(1)
.
Ưu điểm và hạn chế của KNN trong Python
Ưu điểm:
- Đơn giản để hiểu và triển khai.
- Hiệu quả với dữ liệu nhỏ hoặc dữ liệu có không gian đặc trưng ít.
Hạn chế:
- Hiệu suất chậm khi dữ liệu quá lớn do cần tính khoảng cách cho toàn bộ tập huấn luyện.
- Nhạy cảm với giá trị : Việc chọn sai giá trị có thể dẫn đến dự đoán sai.
Kết bài
KNN là thuật toán học máy mạnh mẽ, dễ triển khai và lý tưởng cho các bài toán phân loại hoặc hồi quy đơn giản. Tuy nhiên, khi làm việc với các tập dữ liệu lớn hơn hoặc nhiều đặc trưng hơn, bạn nên cân nhắc sử dụng các thuật toán khác như SVM hoặc Random Forest để cải thiện hiệu suất.
Chúc bạn học vui!