Danh sách bài viết

Bài 36: PCA — giảm chiều dữ liệu để visualize và tăng tốc

PCA (Principal Component Analysis) — giảm chiều tuyến tính bằng eigendecomposition ma trận hiệp phương sai. Trực giác variance lớn nhất, explained variance ratio, chọn n_components, vì sao phải StandardScaler trước, inverse_transform, so sánh PCA vs t-SNE vs UMAP, code Python iris và MNIST.

24/05/2026
14 phút đọc
0 lượt xem
1

PCA là gì

PCAPrincipal Component Analysis (Pearson 1901; Hotelling 1933) — là kỹ thuật giảm chiều tuyến tính. Cho dữ liệu \( d \) chiều, PCA tìm \( K < d \) trục mới (gọi là principal component) sao cho khi project dữ liệu lên các trục đó, phương sai (variance) được giữ lại nhiều nhất có thể.

Đầu ra của PCA:

  • Một biến đổi tuyến tính \( X_{\text{new}} = X_c W \) với \( W \in \mathbb{R}^{d \times K} \) là ma trận trực giao.
  • Mỗi cột của \( W \) là một principal component — vector đơn vị trong không gian gốc.
  • Mỗi component đi kèm một eigenvalue đo lượng phương sai nó giải thích.

PCA là unsupervised — không dùng label \( y \), chỉ dựa vào cấu trúc thống kê của \( X \). Khác với clustering ở Bài 32–35, PCA không gán nhãn cho điểm; nó biến đổi điểm sang không gian khác.

2

Vì sao cần giảm chiều

  • Curse of dimensionality. Trong không gian nhiều chiều, mọi cặp điểm có khoảng cách gần bằng nhau — KNN, K-Means, DBSCAN dựa trên khoảng cách đều giảm hiệu lực. Giảm xuống còn vài chục chiều khôi phục được tín hiệu.
  • Visualization. Người chỉ vẽ được 2D/3D. Project xuống 2 component đầu là cách nhanh nhất để xem cấu trúc cluster, outlier, biến động.
  • Tốc độ. Ít feature thì model train và inference nhanh hơn theo tỉ lệ thẳng (linear models, tree-based) hoặc tỉ lệ bậc hai (kernel SVM).
  • Noise reduction. Component có eigenvalue nhỏ thường là noise — bỏ đi vừa giảm chiều vừa làm sạch dữ liệu.
  • Storage và bandwidth. Lưu \( K \) component thay vì \( d \) feature gốc giảm đáng kể RAM/disk; quan trọng khi serve model với hàng triệu vector embedding.

Đánh đổi: giảm chiều mất một phần thông tin (trừ khi \( K = d \), không giảm gì). PCA chọn cách mất ít variance nhất có thể — nhưng "variance" không luôn trùng với "thông tin có ích cho task" (chi tiết ở mục 12).

3

Trực giác hình học

Hình dung đám mây điểm 2D có dạng ellip nghiêng. Trục dài của ellip là hướng mà điểm trải rộng nhất — phương sai lớn nhất. Trục ngắn là hướng vuông góc, phương sai nhỏ hơn.

PCA làm chính xác việc đó cho \( d \) chiều bất kỳ:

  • Tìm hướng đơn vị \( w_1 \) sao cho \( \mathrm{Var}(X w_1) \) lớn nhất → PC1.
  • Tìm \( w_2 \) vuông góc với \( w_1 \), \( \mathrm{Var}(X w_2) \) lớn nhất → PC2.
  • Tiếp tục đến \( w_d \). Các \( w_i \) tạo thành cơ sở trực chuẩn mới.
  • Project dữ liệu lên \( K \) hướng đầu — giữ phần variance lớn nhất, bỏ phần nhỏ.

Vì các \( w_i \) trực giao, chuyển từ \( d \) chiều sang \( K \) chiều giống xoay hệ trục rồi cắt bỏ các trục cuối — không méo khoảng cách trong các trục đầu, chỉ "đè dẹp" theo các trục bị bỏ.

4

Công thức toán

Cho \( X \in \mathbb{R}^{n \times d} \) (n sample, d feature).

Bước 1 — center. Trừ trung bình cột:

\[ X_c = X - \bar{X}, \quad \bar{X}_j = \frac{1}{n} \sum_{i=1}^{n} X_{ij}. \]

Bước 2 — covariance matrix.

\[ \Sigma = \frac{1}{n - 1} X_c^{\top} X_c \in \mathbb{R}^{d \times d}. \]

\( \Sigma_{jk} \) là hiệp phương sai giữa feature \( j \) và \( k \); đường chéo \( \Sigma_{jj} \) là phương sai của feature \( j \).

Bước 3 — eigendecomposition. Vì \( \Sigma \) đối xứng và nửa xác định dương:

\[ \Sigma = V \Lambda V^{\top}, \quad \Lambda = \mathrm{diag}(\lambda_1, \lambda_2, \ldots, \lambda_d), \quad \lambda_1 \geq \lambda_2 \geq \ldots \geq \lambda_d \geq 0. \]

Cột của \( V \) là các eigenvector (các principal component), \( \lambda_i \) là eigenvalue tương ứng — đúng bằng variance của dữ liệu theo hướng \( v_i \).

Bước 4 — project. Chọn \( K \) cột đầu của \( V \), gọi là \( V_K \in \mathbb{R}^{d \times K} \):

\[ X_{\text{pca}} = X_c V_K \in \mathbb{R}^{n \times K}. \]

Thực tế sklearn dùng SVD trên \( X_c \) thay vì eigendecomp trên \( \Sigma \) (ổn định số học hơn): \( X_c = U S V^{\top} \), với \( V \) giống ở trên và \( \lambda_i = s_i^2 / (n - 1) \).

5

Explained variance — chọn K bao nhiêu

Tổng phương sai của dữ liệu \( = \sum_{i=1}^{d} \lambda_i \). Component \( i \) giải thích tỉ lệ:

\[ r_i = \frac{\lambda_i}{\sum_{j=1}^{d} \lambda_j}. \]

Cumulative explained variance tại \( K \):

\[ R_K = \sum_{i=1}^{K} r_i. \]

Quy tắc thực dụng để chọn \( K \):

  • Ngưỡng cố định: chọn \( K \) nhỏ nhất sao cho \( R_K \geq 0.95 \) (hoặc 0.90, 0.99 — tuỳ task). sklearn cho luôn cú pháp PCA(n_components=0.95).
  • Scree plot: plot \( \lambda_i \) (hoặc \( r_i \)) theo \( i \). Tìm "elbow" — chỗ đường cong gãy. Lấy \( K \) tại elbow.
  • Theo yêu cầu task: visualization → \( K = 2 \) hoặc \( 3 \). Tiền xử lý cho KNN → chọn \( K \) sao cho accuracy không giảm đáng kể qua cross-validation.

Không có \( K \) "đúng" — chọn theo trade-off giữa độ chính xác và chi phí tính toán/lưu trữ.

6

sklearn API

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)        # shape (n, 2)

# Tai tao ve khong gian goc
X_back = pca.inverse_transform(X_pca)

# Tham so quan trong
print(pca.explained_variance_ratio_)  # ti le variance moi component
print(pca.singular_values_)           # singular value tu SVD
print(pca.components_.shape)          # (n_components, d)

Quy ước: PCA tự center dữ liệu (\( X_c = X - \bar{X} \)), nhưng không tự scale — phải StandardScaler trước (mục 9).

7

Tham số quan trọng

  • n_components — ba kiểu giá trị:
    • int: số component cụ thể (vd 2 để visualize).
    • float trong (0, 1): chọn \( K \) nhỏ nhất sao cho cumulative explained variance \( \geq \) ngưỡng này. PCA(n_components=0.95) giữ ít nhất 95% variance.
    • "mle": dùng heuristic của Minka (NeurIPS 2000) tự chọn \( K \).
    • None: giữ tất cả \( \min(n, d) \) component.
  • whiten (mặc định False) — nếu True, scale output sao cho mỗi component có variance = 1. Hữu ích khi đưa vào model giả định feature có cùng scale (KNN, SVM RBF, neural network); làm mất thông tin về độ quan trọng của component.
  • svd_solver"auto" mặc định. Các lựa chọn:
    • "full": SVD đầy đủ qua LAPACK; chính xác, chậm với \( d \) lớn.
    • "randomized" (Halko, Martinsson, Tropp 2009): nhanh hơn nhiều khi \( K \ll d \), gần đúng.
    • "arpack": cho ma trận thưa hoặc cần ít component đầu.
  • random_state — chỉ ảnh hưởng khi svd_solver ngẫu nhiên ("randomized", "arpack"); fix để reproducible.
8

Inspect kết quả

  • pca.explained_variance_ — array \( (\lambda_1, \ldots, \lambda_K) \), variance theo từng component (đơn vị: bình phương đơn vị feature gốc).
  • pca.explained_variance_ratio_ — tỉ lệ \( r_i \) ở mục 5, tổng \( \leq 1 \).
  • pca.components_ — ma trận \( (K, d) \), mỗi hàng là một principal component dưới dạng tổ hợp tuyến tính của feature gốc. Dùng để diễn giải: feature nào đóng góp mạnh vào PC1?
  • pca.singular_values_ — singular value \( s_i \) từ SVD, liên hệ với eigenvalue bởi \( \lambda_i = s_i^2 / (n - 1) \).
  • pca.mean_ — vector trung bình từng feature đã được trừ khi center. Dùng để inverse transform chính xác.
  • pca.noise_variance_ — variance ước lượng của phần "noise" (component bị bỏ), dưới giả định Probabilistic PCA.

Một diagnostic ngắn nên chạy mỗi lần fit:

import numpy as np
print("Variance moi PC:", pca.explained_variance_ratio_.round(4))
print("Cumulative      :", np.cumsum(pca.explained_variance_ratio_).round(4))
9

Standardize TRƯỚC PCA — bắt buộc

PCA tối ưu hoá variance. Variance tỉ lệ với bình phương đơn vị đo. Nếu một feature có scale \( 10^6 \) và một feature có scale \( 10^0 \), feature đầu áp đảo toàn bộ ma trận hiệp phương sai; PC1 gần như trùng với feature đó, các feature còn lại bị bỏ qua hoàn toàn.

Ví dụ: feature tuoi (0–80) và luong_VND (\( 10^7 \)–\( 10^9 \)). PCA không scale → PC1 đi theo lương, PC2, PC3 hầu như không chứa thông tin tuổi. Đổi luong_VND sang luong_trieu sẽ ra kết quả khác — PCA không invariant với đơn vị đo.

Giải pháp: StandardScaler trước PCA (mỗi feature mean = 0, std = 1). Tốt nhất là gói vào Pipeline để fit-transform đồng bộ giữa train và test:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("pca", PCA(n_components=0.95)),
])
X_train_pca = pipe.fit_transform(X_train)
X_test_pca = pipe.transform(X_test)   # KHONG fit lai

Ngoại lệ: dữ liệu hình ảnh pixel grayscale 0–255, tất cả feature cùng đơn vị → có thể không cần StandardScaler (nhưng vẫn nên ít nhất chia cho 255 hoặc trừ mean). Còn lại — luôn standardize.

10

Inverse transform — và mất mát thông tin

Sau khi project xuống \( K \) chiều, có thể chiếu ngược về không gian \( d \) chiều gốc:

\[ \hat{X} = X_{\text{pca}} V_K^{\top} + \bar{X}. \]

X_pca = pca.fit_transform(X)
X_reconstructed = pca.inverse_transform(X_pca)

Nếu \( K = d \), inverse trả về \( X \) gốc (sai số số học rất nhỏ). Nếu \( K < d \), kết quả là phép chiếu vuông góc của \( X \) lên không gian con \( K \) chiềulossy. Phần bị mất chính là variance theo \( d - K \) component bị bỏ.

Tổng bình phương lỗi tái tạo:

\[ \| X - \hat{X} \|_F^2 = (n - 1) \sum_{i = K + 1}^{d} \lambda_i. \]

Đây là cơ sở cho denoising bằng PCA: giả định signal nằm ở component lớn, noise nằm ở component nhỏ → giữ \( K \) đầu rồi inverse, thu được \( \hat{X} \) "sạch" hơn nhưng vẫn ở không gian gốc để dùng tiếp.

11

Use case AI/ML

  • Visualization 2D/3D — project dataset \( d \) chiều xuống 2 (hoặc 3) component đầu rồi vẽ scatter. Cách nhanh nhất để nhìn thấy cluster, outlier, gradient trên dữ liệu nhiều chiều.
  • Tiền xử lý cho KNN / SVM / clustering — giảm chiều trước khi áp dụng các thuật toán dựa trên khoảng cách. Vừa giảm hiệu ứng curse of dimensionality, vừa tăng tốc tính khoảng cách.
  • Noise reduction — bỏ low-variance component để loại nhiễu cảm biến, jitter pixel, tín hiệu ngẫu nhiên.
  • Compression / storage — lưu \( K \) hệ số thay vì \( d \) feature. Áp dụng cho embedding lớn (vd nén từ 1024 chiều xuống 128 trước khi index vector DB).
  • Eigenfaces (Turk & Pentland 1991) — face recognition truyền thống: PCA trên ảnh khuôn mặt, mỗi PC là một "khuôn mặt riêng" (eigenface), gán nhãn theo khoảng cách trong không gian PCA. Đã được CNN vượt qua, nhưng vẫn là ví dụ kinh điển cho diễn giải component.
  • Whitening cho deep learning — ZCA whitening (biến thể của PCA) dùng làm tiền xử lý cho một số model thị giác.
12

Hạn chế của PCA

  • Tuyến tính only. PCA chỉ tìm tổ hợp tuyến tính của feature. Dữ liệu trên xoắn ốc, đường cong S, mặt cong sẽ bị "đè dẹp" sai. Cần t-SNE, UMAP, Autoencoder cho cấu trúc phi tuyến.
  • Mất interpretability. PC1 là tổ hợp tuyến tính của tất cả feature gốc — không phải một feature thực tế. Khi business cần giải thích "vì sao model ra quyết định theo feature X", PCA gây cản trở. Có thể đọc components_ để xem trọng số, nhưng không bằng feature gốc.
  • Variance không luôn = thông tin có ích. Component có variance lớn chưa chắc tương quan với label. Một feature noise scale lớn áp đảo PC1; ngược lại feature signal mạnh nhưng scale nhỏ bị xếp hạng thấp. Đây là lý do StandardScaler trước PCAkhông dùng PCA mù quáng trước classifier — luôn so cross-validation accuracy có/không PCA.
  • Sparse data hỏng. PCA center dữ liệu — phá tính sparse, RAM nổ với ma trận TF-IDF cỡ \( 10^6 \times 10^5 \). Dùng TruncatedSVD (mục 13).
  • Outlier ảnh hưởng mạnh. Variance bị kéo theo outlier xa. Robust PCA (Candès et al. 2011) xử lý, nhưng nặng hơn.
13

Variants — Truncated, Kernel, Incremental

  • TruncatedSVD (sklearn.decomposition.TruncatedSVD) — chạy SVD trực tiếp lên \( X \) (không center) → giữ tính sparse. Mặc định cho ma trận TF-IDF, dùng trong Latent Semantic Analysis. Nếu data dày thì kết quả gần như PCA nhưng không bằng vì không center.
  • Kernel PCA (KernelPCA) — áp dụng kernel trick (RBF, poly, sigmoid) để bắt cấu trúc phi tuyến. Trong không gian feature ngầm định, PCA tuyến tính tương đương phi tuyến trong không gian gốc. Chi phí: \( O(n^2) \) bộ nhớ cho ma trận kernel — không scale với \( n \) lớn.
  • Incremental PCA (IncrementalPCA) — fit theo từng batch, không cần load toàn dataset vào RAM. Phù hợp khi \( n \) hàng triệu hoặc dữ liệu stream. API có thêm partial_fit(batch).
  • Sparse PCA / Dictionary Learning — ép các component thưa (nhiều phần tử = 0) để dễ diễn giải; mỗi PC chỉ chứa vài feature gốc.
  • Probabilistic PCA / Factor Analysis — phiên bản generative, ước lượng bằng EM, cho phép xử lý missing data và đưa ra likelihood.
# TruncatedSVD cho TF-IDF
from sklearn.decomposition import TruncatedSVD
svd = TruncatedSVD(n_components=100, random_state=0)
X_lsa = svd.fit_transform(X_tfidf)    # X_tfidf sparse, khong bi center

# IncrementalPCA cho dataset lon
from sklearn.decomposition import IncrementalPCA
ipca = IncrementalPCA(n_components=50, batch_size=2000)
for batch in batches:
    ipca.partial_fit(batch)
X_reduced = ipca.transform(X_full)
14

PCA vs t-SNE vs UMAP

Tiêu chí PCA t-SNE UMAP
Tuyến tính? Tuyến tính Phi tuyến Phi tuyến
Tốc độ Rất nhanh Chậm (\( O(n^2) \), Barnes-Hut \( O(n \log n) \)) Nhanh hơn t-SNE
Reproducible Có (deterministic) Không (random init, sensitive) Gần như (fix random_state)
Giữ global structure Có (variance toàn cục) Kém — chỉ giữ local neighborhood Khá (tốt hơn t-SNE)
Giữ local structure Kém Tốt Tốt
Transform điểm mới Có (transform()) Không Có (transform())
Dùng cho Tiền xử lý, denoise, viz nhanh Visualization (chỉ vậy) Visualization + tiền xử lý

Quy tắc thực dụng: bắt đầu bằng PCA. Nếu cluster vẫn không tách rõ trên 2D do cấu trúc phi tuyến, dùng UMAP. t-SNE chỉ để vẽ hình đẹp cho paper; không dùng output t-SNE làm feature cho model downstream — khoảng cách t-SNE không có nghĩa global, kết quả cũng đổi mỗi lần chạy.

Một workflow hay gặp: PCA xuống 50 chiều (giữ ~95% variance) rồi UMAP/t-SNE xuống 2D. Bước PCA loại noise và tăng tốc đáng kể cho t-SNE/UMAP.

15

Code Python — iris 4D xuống 2D

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

X, y = load_iris(return_X_y=True)
feature_names = load_iris().feature_names
target_names = load_iris().target_names

X_scaled = StandardScaler().fit_transform(X)

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

print("Explained variance ratio:", pca.explained_variance_ratio_.round(4))
# Vi du: [0.7296 0.2285]  -> 2 PC dau giai thich ~95.8% variance

print("Cumulative              :", np.cumsum(pca.explained_variance_ratio_).round(4))
print("PC1 components_ :", dict(zip(feature_names, pca.components_[0].round(3))))
print("PC2 components_ :", dict(zip(feature_names, pca.components_[1].round(3))))

# Plot
fig, ax = plt.subplots(figsize=(7, 5))
for cls, name in enumerate(target_names):
    mask = y == cls
    ax.scatter(X_pca[mask, 0], X_pca[mask, 1], label=name, s=30, alpha=0.8)
ax.set_xlabel(f"PC1 ({pca.explained_variance_ratio_[0]:.1%})")
ax.set_ylabel(f"PC2 ({pca.explained_variance_ratio_[1]:.1%})")
ax.set_title("Iris 4D -> 2D bang PCA")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

Kết quả: setosa tách hẳn khỏi versicolor/virginica trên PC1; versicolor và virginica chồng lấn nhẹ. PC1 chủ yếu lấy theo petal lengthpetal width (xem hệ số trong components_) — đúng với hiểu biết thực tế rằng kích thước cánh hoa phân biệt loài tốt hơn đài hoa.

Scree plot cho cả 4 component:

pca_full = PCA().fit(X_scaled)
ratios = pca_full.explained_variance_ratio_
plt.bar(range(1, 5), ratios)
plt.plot(range(1, 5), np.cumsum(ratios), "ro-", label="Cumulative")
plt.xlabel("Component")
plt.ylabel("Explained variance ratio")
plt.xticks(range(1, 5))
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
16

Code Python — MNIST digits + KNN trước/sau PCA

Dataset load_digits của sklearn — chữ số viết tay 8×8 = 64 feature. PCA giảm xuống còn ~10–20 chiều giúp KNN nhanh hơn mà giữ accuracy.

import time
import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import Pipeline

X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)

# Baseline: KNN tren 64 chieu
baseline = Pipeline([
    ("scaler", StandardScaler()),
    ("knn", KNeighborsClassifier(n_neighbors=5)),
])
t0 = time.perf_counter()
baseline.fit(X_train, y_train)
acc_full = baseline.score(X_test, y_test)
t_full = time.perf_counter() - t0

# KNN sau PCA giu 95% variance
with_pca = Pipeline([
    ("scaler", StandardScaler()),
    ("pca", PCA(n_components=0.95, random_state=0)),
    ("knn", KNeighborsClassifier(n_neighbors=5)),
])
t0 = time.perf_counter()
with_pca.fit(X_train, y_train)
acc_pca = with_pca.score(X_test, y_test)
t_pca = time.perf_counter() - t0

n_pcs = with_pca.named_steps["pca"].n_components_
print(f"Goc 64D     : acc={acc_full:.4f}, time={t_full:.3f}s")
print(f"PCA 95% ({n_pcs}D): acc={acc_pca:.4f}, time={t_pca:.3f}s")

Trên môi trường thông thường, kết quả gần như: số component giữ 95% variance là 28–30, accuracy chênh trong khoảng \( \pm 0.005 \), thời gian fit+predict giảm rõ. Tăng/giảm ngưỡng để thấy trade-off:

for thr in [0.70, 0.80, 0.90, 0.95, 0.99]:
    pipe = Pipeline([
        ("scaler", StandardScaler()),
        ("pca", PCA(n_components=thr, random_state=0)),
        ("knn", KNeighborsClassifier(n_neighbors=5)),
    ])
    pipe.fit(X_train, y_train)
    k = pipe.named_steps["pca"].n_components_
    acc = pipe.score(X_test, y_test)
    print(f"thr={thr:.2f}  ->  {k:>2} PC,  acc={acc:.4f}")

Xu hướng phổ biến: ngưỡng quá thấp (0.70) bỏ thông tin có ích, accuracy tụt; ngưỡng 0.90–0.95 thường là điểm dừng tốt; ngưỡng 0.99 giữ gần hết chiều, không lợi gì hơn baseline.

17

Tổng kết Module 5

Module 5 — Unsupervised Learning đã hoàn thành 5 bài:

  • Bài 32 — K-Means. Partition theo centroid, cần \( K \), cluster cầu.
  • Bài 33 — Elbow & Silhouette. Chọn \( K \) và đánh giá clustering cầu.
  • Bài 34 — Hierarchical Clustering. Agglomerative + dendrogram, không cần \( K \) tại fit.
  • Bài 35 — DBSCAN. Density-based, không cần \( K \), bắt cluster bất kỳ hình dạng + đánh dấu noise.
  • Bài 36 — PCA. Giảm chiều tuyến tính cho visualization, tăng tốc, denoising.

Liên kết thực tế giữa các bài:

  • Khi data \( d > 50 \), chạy PCA trước rồi mới K-Means / DBSCAN / Hierarchical — vừa nhanh, vừa giảm curse of dimensionality.
  • Khi cần vẽ kết quả clustering, project xuống 2 PC đầu (hoặc UMAP nếu cấu trúc phi tuyến).
  • Khi đánh giá clustering không cầu, Silhouette không đáng tin — đã thảo luận ở Bài 35.

Module 6 (Bài 37+) chuyển sang chủ đề chung cho cả supervised lẫn unsupervised: overfitting/underfitting, regularization, đánh giá model, lựa chọn model cuối series.

18

Bài tập thực hành

Bài 1 — PCA iris xuống 2 chiều. Load iris, standardize, fit PCA(n_components=2), plot scatter có màu theo class. Ghi rõ explained_variance_ratio của 2 PC. Đọc components_ để xác định feature gốc nào đóng góp mạnh nhất vào PC1.

Bài 2 — Đếm component giữ 95% variance. Sinh dữ liệu giả make_classification(n_samples=2000, n_features=1000, n_informative=50, random_state=0). Standardize, fit PCA(n_components=0.95). Báo cáo số component được giữ (pca.n_components_). So sánh với n_informative=50 — có khớp không, vì sao?

Bài 3 — KNN trước/sau PCA. Trên load_digits, so sánh KNN (k=5) tren 64 chiều gốc vs trên 50, 30, 20, 10, 5 PC. Vẽ accuracy theo số PC. Tìm điểm nhỏ nhất sao cho accuracy không giảm quá 1% so với baseline.

Bài 4 — Tác động của StandardScaler. Lấy dataset load_wine. Chạy PCA(n_components=2) không StandardScaler, plot. Chạy lại có StandardScaler, plot. So sánh: PCA không scale chọn PC1 theo feature nào (xem components_)? Vì sao cluster trên hai plot khác nhau?

Bài 5 — Inverse transform và denoising. Trên load_digits, thêm Gaussian noise X_noisy = X + 0.5 * np.random.randn(*X.shape). Fit PCA(n_components=20) trên X_noisy, lấy X_denoised = pca.inverse_transform(pca.transform(X_noisy)). So sánh trực quan 10 chữ số đầu giữa X, X_noisy, X_denoised. Tính MSE giữa XX_denoised, giữa XX_noisy.

19

Bài tiếp theo

Bài 37: Overfitting và Underfitting — mở Module 6 với hai khái niệm xuyên suốt mọi thuật toán ML đã học: model học thuộc lòng training data thay vì học pattern, hoặc model quá đơn giản để bắt được pattern. Bias-variance tradeoff, learning curve, dấu hiệu chẩn đoán, hướng xử lý bằng regularization, cross-validation, thêm/giảm feature.