Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
LDA (Linear Discriminant Analysis) trong Python
Trong bài hướng dẫn này, mình sẽ triển khai thuật toán LDA (Linear Discriminant Analysis) chỉ bằng cách sử dụng các module Python cơ bản và thư viện numpy
.
LDA là một kỹ thuật giảm chiều dữ liệu phổ biến, thường được sử dụng như một bước tiền xử lý trong các pipeline học máy. Bài viết này sẽ giúp bạn hiểu về các khái niệm, toán học đằng sau thuật toán và cách triển khai chi tiết trong Python.
Tổng quan về LDA trong Python
Linear Discriminant Analysis là phương pháp phân tích tuyến tính, có mục tiêu:
- Tối ưu hóa việc tách biệt các lớp (classes).
- Giảm chiều dữ liệu, giúp cải thiện hiệu quả tính toán mà vẫn giữ được thông tin quan trọng.
LDA tìm kiếm các trục mới (discriminants) để tối đa hóa tỉ lệ giữa độ phân tán giữa các lớp (Between-Class Scatter) và trong mỗi lớp (Within-Class Scatter).
Bài viết này được đăng tại [free tuts .net]
Thuật toán và công thức
Scatter Matrix
Ma trận scatter trong mỗi lớp (SW
):
- $C$: Tổng số lớp.
- $\mu_c$: Trung bình của lớp $c$.
- $x$: Dữ liệu trong lớp $c$.
Ma trận scatter giữa các lớp (SB
):
- $\mu$: Trung bình của toàn bộ dữ liệu.
- $N_c$: Số lượng điểm dữ liệu trong lớp $c$.
Tìm Discriminant
Tìm nghiệm của: Với $A$, ta tìm:
- Giá trị riêng (
eigenvalues
) - Vector riêng (
eigenvectors
)
Các vector riêng tương ứng với các giá trị riêng lớn nhất là các trục chính (linear discriminants), được sử dụng để chiếu dữ liệu về không gian mới.
Lớp LDA
import numpy as np class LDA: def __init__(self, n_components): """ Khởi tạo mô hình LDA. - n_components: Số chiều giảm xuống (số trục discriminant cần giữ). """ self.n_components = n_components self.linear_discriminants = None def fit(self, X, y): """ Huấn luyện mô hình LDA. - X: Dữ liệu đầu vào (n_samples, n_features). - y: Nhãn (0, 1, ... C-1). """ n_features = X.shape[1] class_labels = np.unique(y) # Tính trung bình tổng thể mean_overall = np.mean(X, axis=0) # Khởi tạo ma trận SW và SB SW = np.zeros((n_features, n_features)) SB = np.zeros((n_features, n_features)) # Duyệt qua từng lớp for c in class_labels: X_c = X[y == c] # Lấy các điểm thuộc lớp c mean_c = np.mean(X_c, axis=0) # Trung bình của lớp c # Tính SW: scatter trong mỗi lớp SW += (X_c - mean_c).T.dot((X_c - mean_c)) # Tính SB: scatter giữa các lớp n_c = X_c.shape[0] mean_diff = (mean_c - mean_overall).reshape(n_features, 1) SB += n_c * mean_diff.dot(mean_diff.T) # Tính SW^-1 * SB A = np.linalg.inv(SW).dot(SB) # Tìm giá trị riêng và vector riêng eigenvalues, eigenvectors = np.linalg.eig(A) # Sắp xếp vector riêng theo giá trị riêng giảm dần eigenvectors = eigenvectors.T idxs = np.argsort(abs(eigenvalues))[::-1] eigenvalues = eigenvalues[idxs] eigenvectors = eigenvectors[idxs] # Lưu n_components vector riêng đầu tiên self.linear_discriminants = eigenvectors[0:self.n_components] def transform(self, X): """ Chiếu dữ liệu X lên không gian mới (giảm chiều). """ return np.dot(X, self.linear_discriminants.T)
Giải thích
fit
Method:
- Tính toán ma trận SW và SB.
- Giải bài toán giá trị riêng để tìm trục discriminants.
transform
Method:
- Chiếu dữ liệu về không gian giảm chiều bằng cách nhân với các trục discriminants.
Ví dụ áp dụng
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.linear_model import LogisticRegression # Dữ liệu Iris data = load_iris() X, y = data.data, data.target # Chia dữ liệu thành tập huấn luyện và kiểm tra X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Huấn luyện mô hình LDA để giảm chiều xuống 2 lda = LDA(n_components=2) lda.fit(X_train, y_train) X_train_lda = lda.transform(X_train) X_test_lda = lda.transform(X_test) # Huấn luyện Logistic Regression trên dữ liệu đã giảm chiều clf = LogisticRegression() clf.fit(X_train_lda, y_train) y_pred = clf.predict(X_test_lda) # Đánh giá độ chính xác print("Độ chính xác:", accuracy_score(y_test, y_pred))
Kết quả
-
Giảm Chiều Dữ Liệu: Dữ liệu từ 4 chiều (Iris dataset) đã được giảm xuống 2 chiều nhưng vẫn giữ được thông tin quan trọng.
- Tăng Hiệu Quả Tính Toán: LDA loại bỏ các chiều không cần thiết, giúp các mô hình huấn luyện nhanh hơn.
Kết bài
LDA là một kỹ thuật quan trọng giúp giảm chiều dữ liệu và cải thiện khả năng phân lớp. Việc triển khai từ đầu bằng Python sẽ giúp bạn hiểu rõ hơn về toán học và cơ chế hoạt động của thuật toán, từ đó áp dụng tốt hơn trong các dự án thực tế.