Bài 8

Machine Learning không giám sát

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.

Unsupervised learning là gì
Học từ dữ liệu không nhãn

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ánMục tiêuVí dụ thuật toán
Clustering (phân cụm)Gom các mẫu giống nhau thành nhómK-Means, Hierarchical, DBSCAN, GMM
Dimensionality reduction (giảm chiều)Nén nhiều chiều xuống ít chiều, giữ thông tinPCA, t-SNE, UMAP
Anomaly detectionTìm điểm bất thường/hiếmIsolation Forest, LOF
Association rulesTìm luật "mua A thì mua B"Apriori, FP-Growth
K-Means
Phân cụm theo tâm cụm

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
Hierarchical Clustering
Cây phân cụm & dendrogram

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"))
Khi nào dùng: khi muốn thấy cấu trúc phân cấp (vd phân loại sinh học) hoặc không biết trước số cụm. Nhược: chậm với dữ liệu lớn (~O(n²) trở lên).
DBSCAN
Phân cụm theo mật độ

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)
Gaussian Mixture (GMM)
Soft clustering

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
Giảm chiều: PCA, t-SNE, UMAP
Nén đặc trưng & trực quan hoá

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.

PCAt-SNE / UMAP
Bản chấtTuyến tínhPhi tuyến
Mục đíchNén đặc trưng, tiền xử lýTrực quan hoá (chủ yếu)
Dùng làm feature cho model?Không — chỉ để nhìn
Tính ổn địnhXác định, có thể transform dữ liệu mớiNgẫu nhiên, khoảng cách/kích thước cụm không tin cậy tuyệt đối
Đừng dùng t-SNE/UMAP làm đặc trưng đầu vào cho mô hình dự đoán. Chúng biến dạng khoảng cách để "nhìn đẹp"; kích thước và khoảng cách giữa các cụm trên biểu đồ t-SNE không phản ánh đúng dữ liệu gốc. Chỉ dùng để khám phá/trực quan.
Anomaly Detection
Phát hiện điểm bất thường

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
Association Rules (Apriori)
Phân tích giỏ hà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)
Ứng dụng thực tế
Khi nào dùng unsupervised
Phải scale trước K-Means và PCA: cả hai dựa trên khoảng cách/phương sai nên đặc trưng thang đo lớn sẽ áp đảo kết quả. Luôn chuẩn hoá (StandardScaler) trước khi phân cụm hoặc giảm chiều.
← Quay lại
Bài 7: ML có giám sát