Học không giám sát (unsupervised learning) làm việc với dữ liệu không có nhãn — mục tiêu là tự tìm ra cấu trúc ẩn: nhóm các mẫu giống nhau (clustering), giảm số chiều để trực quan hoá/nén, phát hiện điểm bất thường và khai phá luật kết hợp. Bài này đi qua K-Means, Hierarchical, DBSCAN, Gaussian Mixture, PCA/t-SNE/UMAP, anomaly detection và Apriori — kèm code sklearn.
Khác với học có giám sát, ở đây không có y — chỉ có X. Mô hình phải tự khám phá quy luật. Vì không có "đáp án đúng", việc đánh giá khó hơn và mang tính diễn giải nhiều hơn. Các nhóm bài toán chính:
| Nhóm bài toán | Mục tiêu | Ví dụ thuật toán |
|---|---|---|
| Clustering (phân cụm) | Gom các mẫu giống nhau thành nhóm | K-Means, Hierarchical, DBSCAN, GMM |
| Dimensionality reduction (giảm chiều) | Nén nhiều chiều xuống ít chiều, giữ thông tin | PCA, t-SNE, UMAP |
| Anomaly detection | Tìm điểm bất thường/hiếm | Isolation Forest, LOF |
| Association rules | Tìm luật "mua A thì mua B" | Apriori, FP-Growth |
Trực giác: chia dữ liệu thành k cụm sao cho mỗi điểm gần tâm (centroid) cụm của nó nhất. Thuật toán lặp (Lloyd):
Chọn k: vì k là tham số ta phải cho trước, dùng: Elbow method (vẽ inertia theo k, tìm "khuỷu tay" nơi giảm chậm lại) và Silhouette score (đo mẫu khớp với cụm của nó so với cụm lân cận; càng gần 1 càng tốt).
Hạn chế: giả định cụm dạng cầu, kích thước tương đương → kém với cụm dài/cong; nhạy với thang đo (phải scale) và với khởi tạo (chạy nhiều lần n_init); nhạy outlier. k-means++ giảm bớt vấn đề init.
from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler Xs = StandardScaler().fit_transform(X) km = KMeans(n_clusters=4, init="k-means++", n_init=10, random_state=42).fit(Xs) labels = km.labels_ # nhãn cụm của mỗi điểm print(km.inertia_) # dùng cho elbow
Agglomerative (từ dưới lên): ban đầu mỗi điểm là một cụm, lặp lại gộp hai cụm gần nhau nhất cho đến khi còn một cụm. Kết quả là một cây dendrogram — cắt ngang cây ở độ cao nào đó để chọn số cụm; không cần định trước k như K-Means.
Linkage — cách đo "khoảng cách giữa hai cụm": single (2 điểm gần nhất — dễ tạo chuỗi), complete (2 điểm xa nhất), average (trung bình), ward (tối thiểu tăng phương sai — thường cho cụm cân đối, phổ biến nhất).
from sklearn.cluster import AgglomerativeClustering agg = AgglomerativeClustering(n_clusters=4, linkage="ward").fit(Xs) # dendrogram: scipy.cluster.hierarchy.dendrogram(linkage(Xs, "ward"))
Trực giác: cụm là vùng mật độ cao tách nhau bởi vùng mật độ thấp. Không cần cho trước số cụm, bắt được cụm hình bất kỳ (dài, cong) và tự động đánh dấu nhiễu (noise) — thứ K-Means không làm được.
Hai tham số: eps (bán kính lân cận) và min_samples (số điểm tối thiểu trong bán kính để thành "core point"). Điểm trong vùng dày = core, điểm rìa = border, còn lại = noise (nhãn -1).
Hạn chế: khó chọn eps khi các cụm có mật độ khác nhau; kém trong không gian nhiều chiều. Chọn eps bằng biểu đồ k-distance.
from sklearn.cluster import DBSCAN db = DBSCAN(eps=0.5, min_samples=5).fit(Xs) labels = db.labels_ # -1 = nhiễu (outlier)
Giả định dữ liệu sinh từ hỗn hợp nhiều phân phối Gaussian. Khác K-Means (gán cứng), GMM cho soft assignment — mỗi điểm thuộc mỗi cụm với một xác suất. Cụm có thể là hình elip (không bắt buộc cầu), linh hoạt hơn K-Means. Huấn luyện bằng thuật toán EM.
from sklearn.mixture import GaussianMixture gmm = GaussianMixture(n_components=4, random_state=42).fit(Xs) proba = gmm.predict_proba(Xs) # xác suất thuộc từng cụm
PCA (Principal Component Analysis): tìm các trục mới (principal components) là eigenvectors của ma trận hiệp phương sai, sắp theo lượng phương sai (variance) chúng giải thích. Chiếu dữ liệu lên vài trục đầu → giảm chiều mà giữ tối đa thông tin. Là phép biến đổi tuyến tính, nhanh, xác định và có thể đảo ngược xấp xỉ.
explained_variance_ratio_ cho biết mỗi component giữ bao nhiêu % phương sai → cộng dồn để chọn số chiều (vd giữ 95%). Khi nào dùng PCA: nén đặc trưng trước khi đưa vào model, khử nhiễu, giảm đa cộng tuyến, tăng tốc huấn luyện, và trực quan hoá thô.
from sklearn.decomposition import PCA pca = PCA(n_components=0.95).fit(Xs) # giữ 95% variance X_reduced = pca.transform(Xs) print(pca.explained_variance_ratio_)
t-SNE & UMAP: kỹ thuật phi tuyến chuyên để trực quan hoá dữ liệu nhiều chiều xuống 2D/3D, giữ tốt cấu trúc cục bộ (điểm gần nhau vẫn gần). UMAP nhanh hơn t-SNE và giữ cả cấu trúc toàn cục tốt hơn.
| PCA | t-SNE / UMAP | |
|---|---|---|
| Bản chất | Tuyến tính | Phi tuyến |
| Mục đích | Nén đặc trưng, tiền xử lý | Trực quan hoá (chủ yếu) |
| Dùng làm feature cho model? | Có | Không — chỉ để nhìn |
| Tính ổn định | Xác định, có thể transform dữ liệu mới | Ngẫu nhiên, khoảng cách/kích thước cụm không tin cậy tuyệt đối |
Isolation Forest: xây các cây chia ngẫu nhiên; điểm bất thường bị "cô lập" bằng ít lần chia hơn (đường dẫn ngắn) → điểm nào dễ tách là outlier. Nhanh, hiệu quả với dữ liệu lớn/nhiều chiều. Tham số contamination = tỉ lệ ước lượng outlier.
LOF (Local Outlier Factor): so mật độ cục bộ quanh một điểm với mật độ của hàng xóm; điểm ở vùng thưa hơn hẳn hàng xóm bị coi là bất thường — bắt tốt outlier cục bộ.
from sklearn.ensemble import IsolationForest iso = IsolationForest(contamination=0.05, random_state=42).fit(X) flags = iso.predict(X) # -1 = bất thường, 1 = bình thường
Market basket analysis: tìm luật kiểu "khách mua bánh mì & bơ thì hay mua sữa". Apriori tìm các tập mặt hàng phổ biến rồi sinh luật, đo bằng ba chỉ số: support (tần suất xuất hiện), confidence (xác suất mua B khi đã mua A) và lift (mức độ A và B đi cùng nhau hơn ngẫu nhiên — lift > 1 là có liên hệ dương). Thường dùng thư viện mlxtend.
from mlxtend.frequent_patterns import apriori, association_rules freq = apriori(basket_onehot, min_support=0.02, use_colnames=True) rules = association_rules(freq, metric="lift", min_threshold=1.0)
StandardScaler) trước khi phân cụm hoặc giảm chiều.