Giáo trình chuẩn quốc tế · Bản tiếng Việt có phòng thí nghiệm

Nhập môn Học Thống Kê
với Ứng dụng Python (ISLP)

Bản chuyển ngữ công phu cuốn An Introduction to Statistical Learning with Applications in Python của Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani, Jonathan Taylor (Springer, 2023). Bổ sung 18 phòng thí nghiệm tương tác chạy offline trên trình duyệt và 26 hình minh hoạ chuẩn hoá. Mọi khái niệm thống kê cốt lõi đều có thể tự tay khám phá và trực quan hóa.

Nguyên tác: Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani, Jonathan Taylor (2023) Toán học: KaTeX Chạy offline: 100% Client-side Giao diện: Giấy dó & Lò đêm (Sáng / Tối)

Cách học cùng cuốn sách này

Mỗi khi gặp khối PHÒNG THÍ NGHIỆM, hãy dừng lại và thao tác trực tiếp trên các thanh trượt và nút bấm. Mục Việc cần làm ở cuối mỗi phòng thí nghiệm chỉ dẫn chính xác các thao tác giúp bạn "chạm" vào bản chất của hiện tượng — như cách phương sai bùng nổ khi quá khớp, hoặc cách ranh giới quyết định Bayes phân tách không gian dữ liệu.

Lời nói đầu (Preface)

"Thật khó để đưa ra dự đoán, đặc biệt là dự đoán về tương lai."
— Yogi Berra

Học thống kê (Statistical Learning) đề cập đến một tập hợp các công cụ toán học và tính toán để tìm hiểu, khám phá và trích xuất tri thức từ các tập dữ liệu phức tạp. Trong những năm gần đây, chúng ta đã chứng kiến sự gia tăng đáng kinh ngạc cả về quy mô lẫn phạm vi thu thập dữ liệu trên hầu khắp các lĩnh vực khoa học, công nghệ và công nghiệp. Do đó, học thống kê đã nhanh chóng trở thành bộ công cụ thiết yếu cho bất kỳ ai muốn thấu hiểu dữ liệu — và khi ngày càng nhiều công việc hiện đại gắn liền mật thiết với dữ liệu, điều này đồng nghĩa với việc học thống kê đang trở thành hành trang cốt lõi cho tất cả mọi người.

Một trong những cuốn sách kinh điển đầu tiên đặt nền móng toàn diện cho lĩnh vực này — The Elements of Statistical Learning (ESL, bởi Trevor Hastie, Robert Tibshirani, và Jerome Friedman) — được xuất bản lần đầu vào năm 2001, và tái bản lần thứ hai vào năm 2009. ESL đã trở thành tài liệu gối đầu giường nổi tiếng không chỉ trong ngành thống kê mà còn ở khắp các ngành khoa học định lượng liên quan. Một trong những lý do khiến ESL được đón nhận rộng rãi là lối hành văn mạch lạc, chặt chẽ. Tuy nhiên, ESL được thiết kế chủ yếu dành cho các độc giả đã có nền tảng đào tạo chuyên sâu về toán học và xác suất thống kê nâng cao.

Cuốn sách An Introduction to Statistical Learning, with Applications in R (ISLR) — ra mắt lần đầu năm 2013 và tái bản lần thứ hai vào năm 2021 — ra đời xuất phát từ nhu cầu cấp thiết về một tài liệu dễ tiếp cận hơn, ít nặng về biến đổi toán học thuần túy nhưng đào sâu vào bản chất và ứng dụng thực tiễn của các chủ đề trọng tâm trong học thống kê. Bên cạnh việc ôn lại nền tảng hồi quy tuyến tính, ISLR bao quát toàn bộ các phương pháp học thống kê và học máy quan trọng bậc nhất hiện nay:

  • Các phương pháp lấy lại mẫu (Resampling methods): Cross-validation và Bootstrap.
  • Các mô hình điều hòa và thưa (Regularization & Sparsity): Hồi quy Ridge, Lasso trong phân loại và hồi quy.
  • Các mô hình cộng tính tổng quát (Generalized Additive Models - GAMs) và vượt qua tính tuyến tính.
  • Các phương pháp dựa trên cây (Tree-based methods): Cây quyết định (Decision Trees), Bagging, Rừng ngẫu nhiên (Random Forests) và Boosting.
  • Máy vectơ hỗ trợ (Support Vector Machines - SVM).
  • Học sâu (Deep Learning): Mạng nơ-ron truyền thẳng, tích chập (CNN) và hồi quy (RNN).
  • Phân tích sinh tồn (Survival Analysis) và dữ liệu bị cắt cụt (censored data).
  • Học không giám sát (Unsupervised Learning): Phân tích thành phần chính (PCA) và Phân cụm (Clustering).
  • Kiểm định đa giả thuyết (Multiple Testing) và kiểm soát tỷ lệ phát hiện sai (FDR).

Kể từ khi phát hành vào năm 2013, ISLR đã trở thành giáo trình chuẩn mực tại các giảng đường đại học và sau đại học trên toàn thế giới, đồng thời là cuốn cẩm nang tra cứu không thể thiếu của các kỹ sư khoa học dữ liệu (data scientists). Một trong những chìa khóa cốt lõi tạo nên thành công vang dội của cuốn sách là: bắt đầu từ Chương 2, mỗi chương đều đi kèm một phòng thực hành (Lab) minh họa chi tiết cách hiện thực hóa các thuật toán học thống kê bằng mã nguồn thực tế, mang lại cho độc giả trải nghiệm "thực chiến" vô giá.

Tuy nhiên, trong những năm gần đây, Python đã vươn lên trở thành ngôn ngữ phổ biến hàng đầu trong giới khoa học dữ liệu và trí tuệ nhân tạo, kéo theo nhu cầu ngày càng lớn về một phiên bản thay thế ISLR dựa trên nền tảng Python. Do đó, cuốn sách này — An Introduction to Statistical Learning, with Applications in Python (ISLP) — bao quát toàn bộ khối lượng kiến thức chuẩn xác của ISLR nhưng các phòng thí nghiệm và phần thực hành được chuyển dịch hoàn toàn sang Python. Thành quả này được hoàn thiện nhờ sự tham gia của đồng tác giả mới, Jonathan Taylor. Một số bài thực hành khai thác trực tiếp thư viện Python mang tên ISLP, do chính nhóm tác giả phát triển nhằm tạo điều kiện thuận lợi nhất để triển khai các mô hình học thống kê trong môi trường Python hiện đại. Các bài thực hành này được thiết kế để hữu ích cho cả những người mới làm quen với Python lẫn những lập trình viên đã có kinh nghiệm.

Mục tiêu sư phạm của ISLP

Mục đích xuyên suốt của ISLP là tập trung tối đa vào ứng dụng thực tiễn của các phương pháp và giảm bớt các chứng minh toán học nặng tính hàn lâm. Cuốn sách đặc biệt phù hợp cho sinh viên đại học năm cuối, học viên cao học ngành thống kê, khoa học dữ liệu hoặc bất kỳ ai muốn sử dụng các công cụ học thống kê hiện đại để giải quyết các bài toán trên dữ liệu thực tế.

Chúng tôi xin bày tỏ lòng biết ơn sâu sắc tới các độc giả đã đóng góp ý kiến quý báu cho phiên bản đầu tiên và thứ hai của ISLR. Chúng tôi đặc biệt cảm ơn Balasubramanian "Naras" Narasimhan vì sự hỗ trợ không ngừng nghỉ đối với cả hai ấn bản ISLR và ISLP.

Thật vinh dự cho chúng tôi khi được chứng kiến sức ảnh hưởng sâu rộng mà bộ sách đã mang lại cho cách thức mà học thống kê được giảng dạy và ứng dụng trên toàn cầu, cả trong học thuật lẫn trong sản xuất công nghiệp. Chúng tôi hy vọng rằng phiên bản Python mới này sẽ tiếp tục trang bị cho các nhà thống kê ứng dụng và kỹ sư dữ liệu hôm nay và mai sau những công cụ sắc bén nhất để gặt hái thành công trong một thế giới được dẫn dắt bởi dữ liệu.

Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani, Jonathan Taylor

01Chương 1: Giới thiệu (Introduction)

1.1. Tổng quan về Học Thống kê (An Overview of Statistical Learning)

Học thống kê (Statistical Learning) đề cập đến một tập hợp rộng lớn các công cụ toán học và thuật toán phục vụ mục tiêu thấu hiểu dữ liệu. Các công cụ này về cơ bản được phân thành hai nhóm lớn: có giám sát (supervised) hoặc không giám sát (unsupervised).

Nói một cách tổng quát, học thống kê có giám sát liên quan đến việc xây dựng một mô hình thống kê nhằm dự đoán (predicting) hoặc ước lượng (estimating) một giá trị đầu ra (output) dựa trên một hay nhiều biến đầu vào (inputs). Những bài toán thuộc bản chất này xuất hiện dày đặc trong mọi lĩnh vực: từ kinh doanh, tài chính, y học, sinh học phân tử cho đến vật lý thiên văn và chính sách công.

Ngược lại, với học thống kê không giám sát, chúng ta chỉ quan sát được các biến đầu vào mà hoàn toàn không có biến đầu ra giám sát đi kèm; dẫu vậy, chúng ta vẫn có thể học hỏi các mối quan hệ nội tại, cấu trúc phân cụm hoặc quy luật ẩn giấu bên trong khối dữ liệu đó.

Để minh họa sống động cho các ứng dụng đa dạng của học thống kê, chúng ta hãy cùng xem xét 3 bộ dữ liệu thực tế tiêu biểu xuyên suốt cuốn sách này.


Bộ dữ liệu Lương thưởng (Wage Data) — Bài toán Hồi quy

Trong ứng dụng đầu tiên này (chúng ta sẽ gọi là tập dữ liệu Wage), chúng ta kiểm tra một loạt các yếu tố nhân khẩu học và kinh tế liên quan đến mức lương của một nhóm nam giới tại khu vực bờ biển Đại Tây Dương của Hợp chúng quốc Hoa Kỳ. Mục tiêu cốt lõi là thấu hiểu mối liên hệ giữa tuổi tác (Age), trình độ học vấn (Education), cũng như năm khảo sát (Year) đối với mức lương (Wage) của người lao động.

Hãy quan sát ba góc nhìn thực nghiệm từ dữ liệu:

  1. Mối quan hệ giữa Mức lương và Tuổi tác: Tiền lương có xu hướng tăng dần theo độ tuổi khi kinh nghiệm và kỹ năng tích lũy, nhưng sau đó bắt đầu giảm dần sau khoảng 60 tuổi. Tuy nhiên, mức độ biến thiên (variability) xung quanh giá trị trung bình này là rất lớn — chỉ riêng tuổi tác không thể đưa ra một dự đoán thật sự chính xác cho tiền lương của một cá nhân cụ thể.
  2. Mức lương theo Năm khảo sát (2003–2009): Tiền lương trung bình tăng khoảng 10.000 USD theo một xu hướng gần như tuyến tính trong giai đoạn này, phản ánh sự tăng trưởng kinh tế và lạm phát.
  3. Mức lương theo Trình độ học vấn: Có sự phân hóa cực kỳ sâu sắc giữa 5 bậc học vấn (từ mức 1: Chưa tốt nghiệp cấp ba đến mức 5: Bằng sau đại học/Thạc sĩ, Tiến sĩ). Người có học vị cao nhất hưởng mức thu nhập vượt trội so với nhóm có học vấn thấp nhất.

Bản chất bài toán Hồi quy (Regression)

Tập dữ liệu Wage liên quan đến việc dự đoán một biến đầu ra liên tục hoặc có tính định lượng (quantitative/continuous). Trong thống kê, các bài toán dự đoán một giá trị số thực như vậy được gọi là bài toán hồi quy (regression problem).

Tuổi (Age) Lương ($k) Lương theo Tuổi (Phi tuyến) Năm (2003 - 2009) Lương ($k) Lương theo Năm (Tuyến tính) 1 2 3 4 5 Bậc Học Vấn (1: Thấp nhất → 5: Cao nhất) Lương theo Bậc Học vấn
Hình 1.1. Tập dữ liệu Wage khảo sát thu nhập của nam giới. Trái: Mức lương tăng theo độ tuổi rồi giảm sau 60 tuổi (quan hệ phi tuyến). Giữa: Lương tăng nhẹ đều đặn theo năm. Phải: Biểu đồ hộp biểu diễn mức lương theo 5 bậc học vấn — học vấn càng cao thu nhập càng vượt trội.

Rõ ràng, mô hình dự đoán chính xác nhất mức lương của một người lao động sẽ đạt được khi chúng ta kết hợp đồng thời cả ba biến: tuổi tác, học vấn và năm làm việc, đồng thời tính đến cả mối quan hệ phi tuyến (non-linear) giữa lương và độ tuổi.


Bộ dữ liệu Thị trường Chứng khoán (Stock Market Data) — Bài toán Phân loại

Khác với việc dự đoán một con số cụ thể, trong nhiều tình huống thực tế, chúng ta lại muốn dự đoán một biến đầu ra mang tính phân loại, phi số học — tức là một biến định tính (qualitative / categorical output).

Ví dụ tiêu biểu là tập dữ liệu thị trường chứng khoán Smarket, bao gồm các biến động hàng ngày của chỉ số chứng khoán Standard & Poor's 500 (S&P 500) trong khoảng thời gian 5 năm từ 2001 đến 2005. Mục tiêu là: dựa vào tỷ lệ phần trăm thay đổi của chỉ số trong 5 ngày giao dịch gần nhất, hãy dự đoán xem trong ngày hôm nay chỉ số thị trường sẽ Tăng (Up) hay Giảm (Down).

Bản chất bài toán Phân loại (Classification)

Khi biến đầu ra $Y$ thuộc về một tập hợp hữu hạn các lớp rời rạc $Y \in \{\text{Down}, \text{Up}\}$ (hoặc $\{0, 1\}$), bài toán học thống kê được gọi là bài toán phân loại (classification problem).

Nếu phân tích phân phối thay đổi của thị trường ngày hôm trước so với ngày hôm sau, hai biểu đồ phân bố cho hai trạng thái Tăng và Giảm trông gần như trùng khít lên nhau — điều này phản ánh bản chất ngẫu nhiên gần như hiệu quả (efficient market) của thị trường tài chính: không có một quy tắc đơn giản nào chỉ dựa vào ngày hôm qua mà đoán được chính xác hôm nay. Tuy nhiên, thông qua các mô hình học máy hiện đại (như Phân tích biệt số toàn phương - QDA ở Chương 4), chúng ta vẫn có thể bóc tách được các tín hiệu tiềm ẩn yếu ớt nhưng có thật, giúp dự đoán đúng hướng đi của thị trường đạt độ chính xác xấp xỉ 60% — một con số mang lại giá trị thương mại khổng lồ trong đầu tư tài chính định lượng.


Bộ dữ liệu Biểu hiện Gen (NCI60 Data) — Bài toán Học Không Giám Sát

Cả hai bài toán trên đều có cặp đôi đầu vào và đầu ra $(X, Y)$ rõ ràng. Tuy nhiên, một lớp bài toán cực kỳ quan trọng khác lại xuất hiện khi chúng ta chỉ thu thập được các biến đầu vào $X$ mà hoàn toàn không có biến nhãn $Y$.

Ví dụ: trong y sinh học, tập dữ liệu NCI60 đo lường mức độ biểu hiện của 6.830 gen khác nhau trên 64 dòng tế bào ung thư. Ở đây, chúng ta không có một biến đầu ra sẵn có để dự đoán; thay vào đó, câu hỏi khoa học đặt ra là: Liệu có tồn tại các cụm (clusters) hoặc nhóm tế bào tự nhiên nào giữa 64 dòng tế bào này dựa trên mức độ biểu hiện tương đồng của hàng nghìn gen hay không?

Đây là bài toán phân cụm (clustering) — một nhánh then chốt của Học không giám sát (Unsupervised Learning). Thách thức to lớn ở đây là không gian dữ liệu có tới 6.830 chiều, vượt xa khả năng quan sát trực quan bằng mắt thường của con người.

Thành phần chính 1 (Z₁) Thành phần chính 2 (Z₂) 4 Cụm Tự nhiên (Không Giám Sát) Thành phần chính 1 (Z₁) Thành phần chính 2 (Z₂) Đối sánh 14 Loại Ung Thư Thực Tế
Hình 1.4. Biểu diễn 64 dòng tế bào ung thư NCI60 trên không gian 2 chiều (Z₁, Z₂) giảm chiều từ 6.830 gen bằng PCA. Trái: 4 cụm phân tách tự nhiên mà không cần nhãn. Phải: Khi gán nhãn 14 loại ung thư thực tế, các tế bào cùng loại bệnh tập trung sát cạnh nhau, minh chứng cho sức mạnh của học không giám sát.

Bằng cách sử dụng kỹ thuật Phân tích thành phần chính (Principal Components Analysis - PCA), chúng ta có thể nén toàn bộ 6.830 chiều dữ liệu xuống chỉ còn 2 chiều đại diện ($Z_1$ và $Z_2$) mà vẫn bảo toàn phần lớn cấu trúc phân tán của dữ liệu, giúp trực quan hóa rõ nét 4 nhóm tế bào ung thư rõ rệt.


1.2. Lược sử Học Thống kê (A Brief History)

Dù thuật ngữ "Học thống kê" (Statistical Learning) tương đối mới mẻ, nhưng nguồn gốc tư tưởng của nó đã được phát triển từ hàng thế kỷ trước:

  1. Đầu thế kỷ 19: Phương pháp bình phương tối thiểu (Method of Least Squares) được phát minh độc lập bởi Carl Friedrich Gauss (1795/1809) và Adrien-Marie Legendre (1805) để giải các bài toán quỹ đạo thiên văn học. Đây chính là hình thái sớm nhất của Hồi quy tuyến tính (Linear Regression).
  2. Năm 1936: Nhà thống kê lỗi lạc Sir Ronald Fisher đề xuất Phân tích biệt số tuyến tính (Linear Discriminant Analysis - LDA) để phân loại loài hoa Iris dựa trên các đặc trưng hình học — đặt nền móng cho phân loại định tính.
  3. Thập niên 1940: Hồi quy Logistic (Logistic Regression) ra đời như một phương pháp thay thế linh hoạt cho LDA trong phân loại nhị phân.
  4. Đầu thập niên 1970: John Nelder và Robert Wedderburn hợp nhất toàn bộ các phương pháp trên vào khung lý thuyết Mô hình tuyến tính tổng quát (Generalized Linear Models - GLMs).
  5. Thập niên 1980: Khi năng lực tính toán của máy tính tăng vọt, các rào cản tính toán được dỡ bỏ, mở đường cho sự bùng nổ của các phương pháp phi tuyến: Cây phân loại và hồi quy (CART - Breiman et al., 1984), Mô hình cộng tính tổng quát (GAMs - Hastie & Tibshirani, 1986), và Mạng nơ-ron nhân tạo (Neural Networks).
  6. Thập niên 1990: Vladimir Vapnik và các cộng sự tại Bell Labs phát triển Máy vectơ hỗ trợ (Support Vector Machines - SVM) cùng lý thuyết học thống kê (Vapnik-Chervonenkis theory).
  7. Thế kỷ 21: Sự kết hợp giữa Big Data, điện toán đám mây, GPU và mã nguồn mở đã tạo nên cuộc cách mạng Học sâu (Deep Learning) và Học máy hiện đại ngày nay.

1.3. Bốn Tiền đề Cốt lõi của Cuốn sách Này

Cuốn sách ISLP được xây dựng dựa trên 4 nguyên tắc sư phạm nền tảng:

  1. Tính ứng dụng phổ quát: Các phương pháp học thống kê hữu ích cho mọi ngành nghề, không chỉ dành riêng cho chuyên gia toán học. Cuốn sách tập trung vào những thuật toán có tính ứng dụng thực chiến cao nhất.
  2. Không xem thuật toán là "Hộp đen" (No Black Boxes): Không có một thuật toán nào là vạn năng (No Free Lunch Theorem). Nếu không hiểu các bánh răng bên trong cỗ máy hoạt động ra sao, bạn không bao giờ có thể chọn được công cụ tối ưu cho bài toán của mình.
  3. Hiểu cách vận hành, không nhất thiết phải tự chế tạo mọi chi tiết cơ khí: Độc giả cần nắm vững trực giác, giả định, ưu nhược điểm và sự đánh đổi của từng mô hình, mà không cần phải sa lầy vào những chứng minh tối ưu hóa giải tích quá phức tạp.
  4. Thực hành trên dữ liệu thực tế bằng Python: Mỗi chương đều có một phòng thực hành (Python Lab) chi tiết, hướng dẫn từng dòng code với numpy, pandas, statsmodels, scikit-learn và gói thư viện đồng hành ISLP.

1.4. Ký hiệu Toán học & Đại số Ma trận Cơ bản

Để đọc sách một cách thuận lợi và chính xác, chúng ta quy ước các ký hiệu chuẩn thống kê như sau:

  • $n$: Đại diện cho số lượng quan sát (observations) hoặc số điểm dữ liệu trong mẫu khảo sát.
  • $p$: Đại diện cho số lượng biến (variables / features / predictors) dùng để dự đoán.
  • $x_{ij}$: Giá trị của biến thứ $j$ đối với quan sát thứ $i$ ($i = 1, 2, \dots, n$ và $j = 1, 2, \dots, p$).
  • $\mathbf{X}$: Ma trận dữ liệu kích thước $n \times p$:

$$\mathbf{X} = \begin{pmatrix} x_{11} & x_{12} & \dots & x_{1p} \\ x_{21} & x_{22} & \dots & x_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n1} & x_{n2} & \dots & x_{np} \end{pmatrix}$$

  • Vectơ dòng thứ $i$ (đại diện cho mẫu dữ liệu thứ $i$): $$\mathbf{x}_i = \begin{pmatrix} x_{i1} \\ x_{i2} \\ \vdots \\ x_{ip} \end{pmatrix}$$

  • Vectơ cột thứ $j$ (đại diện cho tất cả $n$ quan sát của biến thứ $j$): $$\mathbf{x}_j = \begin{pmatrix} x_{1j} \\ x_{2j} \\ \vdots \\ x_{nj} \end{pmatrix}$$

  • Biến mục tiêu đầu ra được biểu diễn bằng vectơ cột $\mathbf{y}$: $$\mathbf{y} = \begin{pmatrix} y_1 \\ y_2 \\ \vdots \\ y_n \end{pmatrix}$$

Tích vô hướng giữa hai vectơ cột $\mathbf{a}, \mathbf{b} \in \mathbb{R}^k$ được định nghĩa: $$\mathbf{a}^T \mathbf{b} = \langle \mathbf{a}, \mathbf{b} \rangle = \sum_{r=1}^k a_r b_r$$

Ký hiệu Ước lượng

Dấu mũ $\hat{}$ (mũ/hat) luôn được dùng để chỉ giá trị ước lượng từ dữ liệu thực nghiệm thay cho giá trị lý thuyết chưa biết. Ví dụ: $\hat{f}(X)$ là ước lượng của hàm thực sự $f(X)$, và $\hat{y}$ là giá trị dự đoán của $y$.

02Chương 2: Học Thống Kê (Statistical Learning)

2.1. Học Thống Kê là gì? (What Is Statistical Learning?)

Để thấu hiểu bản chất của học thống kê, hãy bắt đầu bằng một bài toán kinh doanh điển hình. Giả sử bạn là một chuyên gia tư vấn thống kê được một doanh nghiệp thuê để nghiên cứu mối quan hệ giữa chi phí quảng cáo và doanh số bán hàng của một sản phẩm.

Bộ dữ liệu Quảng cáo (Advertising) thu thập doanh số của sản phẩm tại 200 thị trường khác nhau, cùng với ngân sách phân bổ cho ba kênh truyền thông đại chúng: Truyền hình (TV), Đài phát thanh (Radio), và Báo in (Newspaper). Doanh nghiệp không thể can thiệp trực tiếp để bắt buộc khách hàng mua nhiều hàng hơn; tuy nhiên, họ hoàn toàn nắm trong tay quyền kiểm soát ngân sách rót vào từng kênh truyền thông. Nếu chúng ta xác định được mối liên hệ định lượng giữa quảng cáo và doanh số, ban giám đốc có thể phân bổ lại dòng tiền một cách tối ưu để tối đa hóa doanh thu.

Trong bài toán này:

  • Ngân sách cho các kênh là các biến đầu vào (input variables), thường được ký hiệu là $X_1$ (TV), $X_2$ (Radio), và $X_3$ (Newspaper). Chúng còn được gọi bằng nhiều tên tương đương: biến dự đoán (predictors), biến độc lập (independent variables), hoặc đặc trưng (features).
  • Doanh số bán hàng là biến đầu ra (output variable), thường được ký hiệu là $Y$, còn gọi là biến phản hồi (response) hoặc biến phụ thuộc (dependent variable).

Một cách tổng quát, giả sử ta quan sát được biến phản hồi định lượng $Y$ và $p$ biến dự đoán khác nhau $X = (X_1, X_2, \dots, X_p)$. Chúng ta giả định rằng giữa $Y$ và $X$ tồn tại một mối quan hệ có thể biểu diễn dưới dạng:

$$Y = f(X) + \epsilon$$

Trong đó:

  • $f$: là một hàm cố định nhưng chưa biết của các biến đầu vào $X_1, \dots, X_p$. Hàm $f$ đại diện cho thông tin có tính hệ thống (systematic information) mà $X$ cung cấp về $Y$.
  • $\epsilon$: là thành phần sai số ngẫu nhiên (random error term), độc lập với $X$ và có giá trị kỳ vọng (trung bình) bằng 0: $\mathbb{E}(\epsilon) = 0$. Sai số này chứa đựng những yếu tố tác động ngoài tầm kiểm soát hoặc các biến số chưa được thu thập (ví dụ: biến động thời tiết, chiến dịch cạnh tranh bất ngờ, v.v.).

2.1.1. Tại sao cần Ước lượng $f$? (Why Estimate $f$?)

Có hai lý do cốt lõi thúc đẩy chúng ta ước lượng hàm $f$: Dự đoán (Prediction) và Suy luận (Inference).

1. Mục tiêu Dự đoán (Prediction)

Trong nhiều trường hợp, một tập hợp các biến đầu vào $X$ đã sẵn sàng, nhưng biến đầu ra $Y$ lại chưa xảy ra hoặc không thể đo đạc trực tiếp một cách dễ dàng. Khi đó, ta muốn dự đoán $Y$ thông qua một ước lượng $\hat{f}$ của hàm $f$:

$$\hat{Y} = \hat{f}(X)$$

Dấu mũ $\hat{}$ biểu thị giá trị ước lượng. Trong thiết lập này, $\hat{f}$ thường được coi như một "hộp đen" — người ta chỉ quan tâm tới độ chính xác của $\hat{Y}$, miễn sao nó sát với thực tế nhất có thể.

Độ chính xác của $\hat{Y}$ phụ thuộc vào hai đại lượng: Sai số triệt tiêu được (Reducible error) và Sai số không thể triệt tiêu (Irreducible error):

$$\begin{aligned} \mathbb{E}(Y - \hat{Y})^2 &= \mathbb{E}[f(X) + \epsilon - \hat{f}(X)]^2 \\ &= \underbrace{[f(X) - \hat{f}(X)]^2}_{\text{Sai số triệt tiêu được (Reducible)}} + \underbrace{\text{Var}(\epsilon)}_{\text{Sai số không thể triệt tiêu (Irreducible)}} \end{aligned}$$

Giới hạn của việc Học máy: Sai số Không thể Triệt tiêu

Cho dù thuật toán của bạn có hoàn hảo đến đâu và ước lượng được $\hat{f} = f$, thì sai số dự đoán vẫn không bao giờ bằng 0. Đại lượng $\text{Var}(\epsilon)$ đại diện cho tính biến thiên tự nhiên vốn có của thế giới thực. Không một mô hình nào có thể dự đoán vượt qua trần giới hạn $\text{Var}(\epsilon)$ này.

2. Mục tiêu Suy luận (Inference)

Khác với dự đoán thuần túy, trong nhiều bài toán mục đích hàng đầu là thấu hiểu cách thức mà $Y$ bị tác động bởi $X$. Khi đó, $\hat{f}$ không thể là hộp đen mà phải có cấu trúc tường minh để trả lời các câu hỏi:

  • Biến dự đoán nào có mối liên hệ thực sự với phản hồi? (Thường chỉ một phần nhỏ các biến đầu vào thực sự có ý nghĩa thống kê).
  • Mối quan hệ giữa biến phản hồi và từng biến dự đoán là gì? (Tăng ngân sách TV thì doanh số tăng hay giảm? Tốc độ tăng nhanh hay chậm?).
  • Mối quan hệ đó có thể xấp xỉ tốt bằng đường thẳng (tuyến tính) hay phải dùng đường cong phức tạp (phi tuyến)?

2.1.2. Làm thế nào để Ước lượng $f$? (How Do We Estimate $f$?)

Để ước lượng hàm $f$ từ tập dữ liệu huấn luyện gồm $n$ điểm $\{(\mathbf{x}_1, y_1), \dots, (\mathbf{x}_n, y_n)\}$, các phương pháp trong học thống kê được chia thành hai trường phái:

Phương pháp Tham số (Parametric Methods)

Tiến trình gồm hai bước:

  1. Đưa ra một giả định về dạng hình học của $f$: Giả sử phổ biến nhất là mô hình tuyến tính: $$f(X) = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_p X_p$$

  2. Khớp (huấn luyện) mô hình: Ước lượng các tham số $\beta_0, \beta_1, \dots, \beta_p$ từ dữ liệu, thông dụng nhất là phương pháp bình phương tối thiểu (Ordinary Least Squares - OLS).

Ưu điểm: Đơn giản, dễ giải thích ý nghĩa từng tham số, không đòi hỏi số lượng điểm dữ liệu quá khổng lồ.
Nhược điểm: Nếu dạng hàm giả định sai lệch lớn so với bản chất thực sự của $f$ trong tự nhiên, mô hình sẽ cho độ chính xác rất kém.

Phương pháp Phi tham số (Non-parametric Methods)

Các phương pháp phi tham số hoàn toàn không áp đặt bất kỳ giả định trước nào về hình dạng toán học của $f$. Thay vào đó, chúng cố gắng tìm một hàm số uốn lượn mượt mà để đi sát nhất có thể qua các điểm dữ liệu mẫu mà không quá gãy khúc (ví dụ: Splines, K láng giềng gần nhất - KNN, Cây quyết định).

Ưu điểm: Có khả năng mô tả chính xác những mối quan hệ phi tuyến vô cùng phức tạp.
Nhược điểm: Đòi hỏi số lượng dữ liệu huấn luyện cực kỳ lớn; nếu không cẩn thận, mô hình sẽ bám theo từng vết nhiễu ngẫu nhiên của dữ liệu huấn luyện dẫn tới hiện tượng quá khớp (overfitting).


2.1.3. Đánh đổi giữa Độ chính xác Dự đoán và Khả năng Diễn giải Mô hình

Tại sao chúng ta không luôn luôn sử dụng những mô hình phi tham số mềm dẻo nhất? Câu trả lời nằm ở sự đánh đổi kinh điển giữa Độ linh hoạt (Flexibility) và Khả năng diễn giải (Interpretability).

  • Các mô hình kém linh hoạt (như Hồi quy tuyến tính, Lasso) có cấu trúc ràng buộc chặt chẽ. Khi nhìn vào hệ số $\beta_j$, ta hiểu ngay biến đó ảnh hưởng thế nào đến kết quả.
  • Các mô hình cộng tính tổng quát (GAMs) cho phép các đường cong phi tuyến nhưng vẫn giữ cấu trúc cộng dồn giữa các biến.
  • Các mô hình cực kỳ linh hoạt (như Boosting, SVM với Kernel phức tạp, Mạng nơ-ron sâu / Deep Learning) có thể đạt sai số huấn luyện cực thấp nhưng lại là những "hộp đen" bí ẩn, gần như không thể giải thích cặn kẽ cơ chế ra quyết định cho từng biến đơn lẻ.
Phòng thí nghiệm 03
Bản đồ Đánh đổi: Độ linh hoạt vs Khả năng diễn giải mô hình
Rê chuột hoặc bấm vào từng thuật toán để khám phá sự đánh đổi cốt lõi trong ISLP
Không gian 2D: Trục Hoành = Khả năng Diễn giải, Trục Tung = Độ Linh hoạt
Thuật toán đang chọnHồi quy Tuyến tính (OLS)
Diễn giải

Hồi quy Tuyến tính (Linear Regression): Khả năng diễn giải tối đa. Mỗi hệ số βⱼ cho biết rõ ràng biến đầu vào tác động thế nào đến đầu ra. Tuy nhiên độ linh hoạt thấp, chỉ mô tả được mối quan hệ đường thẳng.

Quy tắc Lựa chọn trong ISLP

Khi mục tiêu là suy luận (inference) hoặc kiểm định giả thuyết kinh tế/y học, luôn ưu tiên các mô hình ở góc dưới bên phải (Lasso, OLS, GAMs).

Việc cần làm: ① Bấm vào Lasso hoặc Hồi quy Tuyến tính: Độ diễn giải cực cao vì hệ số có nghĩa cụ thể. ② Bấm vào Deep Learning (Học sâu) hoặc Boosting: Độ linh hoạt ở mức tối đa, có thể xấp xỉ các bề mặt siêu phức tạp nhưng là 'hộp đen' bí ẩn. ③ Bấm vào GAMs (Generalized Additive Models): Điểm giao thoa lý tưởng — cho phép các đường cong phi tuyến nhưng vẫn giữ cấu trúc cộng dồn tách biệt từng biến.

Nguyên lý Lưỡi dao Ockham (Ockham's Razor)

Nếu hai mô hình cho độ chính xác kiểm tra tương đương nhau, hãy luôn ưu tiên mô hình đơn giản hơn. Mô hình đơn giản hơn không chỉ giúp con người hiểu sâu hơn về bản chất bài toán mà còn ít có nguy cơ bị sụp đổ khi phân phối dữ liệu tương lai có sự trôi dạt nhẹ.


2.2. Đánh giá Độ chính xác của Mô hình (Assessing Model Accuracy)

Không có một phương pháp học máy nào thống trị vượt trội trên mọi bài toán khả dĩ. Vì vậy, việc đo lường khách quan độ chính xác của từng thuật toán trên dữ liệu là yêu cầu sống còn.

2.2.1. Đo lường Độ Khớp: Lỗi Bình phương Trung bình (MSE)

Trong bài toán hồi quy, thước đo phổ biến nhất để định lượng mức độ sai lệch giữa giá trị dự đoán $\hat{f}(x_i)$ và giá trị thực tế $y_i$ là Lỗi bình phương trung bình (Mean Squared Error - MSE):

$$\text{MSE} = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{f}(x_i))^2$$

Nếu tính toán trên tập dữ liệu đã dùng để huấn luyện mô hình, ta có MSE Huấn luyện (Training MSE). Tuy nhiên, trong thực tế, chúng ta không quan tâm mô hình ghi nhớ dữ liệu cũ tốt đến đâu; điều tối thượng là mô hình hoạt động ra sao trên những dữ liệu mới chưa từng thấy trước đó. Đó chính là MSE Kiểm tra (Test MSE):

$$\text{Ave}_{(x_0, y_0) \in \text{Test}} \left(y_0 - \hat{f}(x_0)\right)^2$$

Khi độ linh hoạt (flexibility) của mô hình tăng lên:

  • Training MSE luôn giảm đơn điệu (mô hình uốn lượn để đi qua từng điểm dữ liệu).
  • Test MSE ban đầu giảm xuống, nhưng sau một ngưỡng tối ưu nó sẽ tăng vọt trở lại, tạo thành đường cong hình chữ U (U-shaped curve) kinh điển. Hiện tượng Test MSE tăng vọt do mô hình quá phức tạp được gọi là Quá khớp (Overfitting).

2.2.2. Sự Đánh đổi giữa Độ chệch và Phương sai (The Bias-Variance Trade-off)

Đường cong hình chữ U của Test MSE là hệ quả tất yếu từ một định lý toán học nền tảng của học máy: Phân rã Độ chệch - Phương sai.

Với một điểm kiểm tra $x_0$ bất kỳ, sai số kỳ vọng của phép dự đoán phân rã thành tổng của 3 thành phần dương:

$$\mathbb{E}\left(y_0 - \hat{f}(x_0)\right)^2 = \underbrace{\text{Var}(\hat{f}(x_0))}_{\text{Phương sai}} + \underbrace{\left[\text{Bias}(\hat{f}(x_0))\right]^2}_{\text{Độ chệch bình phương}} + \underbrace{\text{Var}(\epsilon)}_{\text{Sai số không thể triệt tiêu}}$$

Ý nghĩa bản chất của từng thành phần:

  1. Phương sai (Variance): Đại diện cho mức độ thay đổi của hàm ước lượng $\hat{f}$ nếu ta huấn luyện nó trên một tập dữ liệu huấn luyện độc lập khác. Mô hình có độ linh hoạt càng cao (uốn lượn nhiều) thì phương sai càng lớn, bởi vì chỉ cần dịch chuyển một điểm dữ liệu cũng khiến toàn bộ đường cong thay đổi hình dạng dữ dội.
  2. Độ chệch (Bias): Đại diện cho sai số hệ thống sinh ra do việc đơn giản hóa một hiện tượng tự nhiên phức tạp bằng một mô hình toán học quá thô sơ. Ví dụ, việc ép một mối quan hệ cong queo vào một đường thẳng sẽ tạo ra độ chệch lớn (Underfitting). Mô hình càng linh hoạt thì độ chệch càng giảm.
  3. $\text{Var}(\epsilon)$: Độ nhiễu tự nhiên của dữ liệu, là sàn chặn dưới tuyệt đối mà không thuật toán nào vượt qua được.
Var(ϵ) Sàn sai số không thể triệt tiêu Độ chệch bình phương [Bias(f̂)]² Phương sai Var(f̂) Test MSE (Sai số kiểm tra) Độ linh hoạt tối ưu Độ linh hoạt của mô hình (Flexibility) → Lỗi bình phương trung bình (MSE) →
Hình 2.12. Phân rã Sai số kiểm tra lý thuyết (Test MSE) thành ba thành phần: Độ chệch bình phương (vàng), Phương sai (cam) và Sai số không thể triệt tiêu (đường đứt đoạn xám). Vạch thẳng đứng xanh lá chỉ mức linh hoạt tối ưu — nơi Test MSE chạm đáy thấp nhất.
Phòng thí nghiệm 01
Sự đánh đổi giữa Độ chệch và Phương sai (Bias-Variance Trade-off)
Kéo thanh trượt bậc tự do để quan sát đường cong Test MSE hình chữ U
Hàm thực f(x) (xanh lá nét đứt), mẫu dữ liệu (chấm tròn) và mô hình ước lượng f̂(x) (đỏ)
Đường cong sai số theo độ linh hoạt: Test MSE (đỏ), Train MSE (xanh dương), Bias² (vàng), Var (cam)
3
Bậc 1 = đường thẳng (cứng nhắc). Bậc cao = đa thức uốn éo linh hoạt.
0.35
Đại diện cho sai số không thể triệt tiêu Var(ϵ).
25
Mẫu ít làm phương sai tăng vọt khi mô hình linh hoạt.
Bậc d3
Train MSE0.00
Test MSE0.00
Bias²0.00
Variance0.00
Var(ϵ)0.12
Diễn giải

Quan sát biểu đồ dưới: Train MSE (xanh dương) luôn giảm đơn điệu về gần 0 khi tăng bậc mô hình. Nhưng Test MSE (đỏ) tạo thành hình chữ U! Ban đầu Độ chệch (Bias²) giảm mạnh giúp Test MSE giảm, nhưng khi bậc > 4, Phương sai (Variance) bùng nổ kéo Test MSE vọt lên cao — đó chính là hiện tượng quá khớp (overfitting).

Việc cần làm: ① Ở bậc 1 (đường thẳng): nhìn khoảng cách lớn giữa đường thẳng và hàm cong thật — Bias² rất cao, mô hình đang dưới khớp (underfitting). ② Kéo lên bậc 3–4: đường ước lượng uốn lượn vừa vặn với quy luật thật, Test MSE chạm đáy thấp nhất (điểm tối ưu). ③ Kéo lên bậc 10–12: đường cong ngoằn ngoèo đi qua từng điểm dữ liệu, Train MSE rớt về gần 0 nhưng Test MSE tăng vọt! Hãy bấm 🎲 Lấy mẫu mới liên tục: mỗi lần bấm, đường cong bậc 12 biến dạng hỗn loạn theo hướng hoàn toàn khác — đây chính là minh chứng trực quan nhất cho Phương sai (Variance) cao!

Bản chất của Sự Đánh đổi (Trade-off)

Khi ta tăng độ linh hoạt của mô hình: Độ chệch giảm xuống nhưng Phương sai lại tăng lên. Ban đầu, độ chệch giảm nhanh hơn tốc độ tăng của phương sai, khiến Test MSE giảm. Nhưng đến một điểm tới hạn, độ chệch hầu như không thể giảm thêm trong khi phương sai bùng nổ, kéo theo Test MSE tăng phi mã. Điểm đáy của chữ U chính là điểm cân bằng hoàn hảo giữa Độ chệch và Phương sai.


2.2.3. Thiết lập trong Bài toán Phân loại (The Classification Setting)

Trong bài toán phân loại, biến đầu ra $y_i$ mang tính định tính (ví dụ $y_i \in \{0, 1\}$). Thay vì MSE, chúng ta sử dụng Tỷ lệ lỗi (Error Rate):

$$\text{Tỷ lệ lỗi Huấn luyện} = \frac{1}{n} \sum_{i=1}^n I(y_i \neq \hat{y}_i)$$

Trong đó $I(y_i \neq \hat{y}_i)$ là biến chỉ thị: bằng 1 nếu phân loại sai và bằng 0 nếu phân loại đúng.

Bộ phân loại Bayes (The Bayes Classifier)

Về mặt lý thuyết xác suất, tỷ lệ lỗi kiểm tra sẽ đạt giá trị nhỏ nhất nếu ta phân loại mỗi quan sát vào lớp có xác suất có điều kiện lớn nhất:

$$\max_j \Pr(Y = j \mid X = x_0)$$

Tập hợp những điểm trong không gian mà tại đó $\Pr(Y = 1 \mid X) = \Pr(Y = 2 \mid X) = 0.5$ được gọi là Ranh giới Quyết định Bayes (Bayes Decision Boundary). Sai số mà bộ phân loại Bayes tạo ra được gọi là Tỷ lệ Lỗi Bayes (Bayes Error Rate):

$$\text{Bayes Error Rate} = 1 - \mathbb{E}\left[\max_j \Pr(Y = j \mid X)\right]$$

Đây chính là mức sàn sai số lý thuyết của bài toán phân loại (tương đương với $\text{Var}(\epsilon)$ trong bài toán hồi quy).

Thuật toán $K$ Láng giềng Gần nhất (K-Nearest Neighbors - KNN)

Trong thực tế, ta không hề biết phân phối xác suất thực tế của tự nhiên để áp dụng Bộ phân loại Bayes. Một trong những phương pháp phi tham số trực quan và kinh điển nhất để xấp xỉ nó là KNN:

Cho một điểm kiểm tra $x_0$ và số nguyên dương $K$:

  1. Tìm tập hợp $\mathcal{N}_0$ gồm $K$ điểm trong tập huấn luyện có khoảng cách gần nhất tới $x_0$.
  2. Ước lượng xác suất có điều kiện cho lớp $j$ bằng tỷ lệ các điểm láng giềng thuộc lớp $j$: $$\Pr(Y = j \mid X = x_0) = \frac{1}{K} \sum_{i \in \mathcal{N}_0} I(y_i = j)$$

  3. Phân loại $x_0$ vào lớp có xác suất ước lượng lớn nhất theo nguyên tắc đa số phiếu (majority vote).

Phòng thí nghiệm 02
KNN và Ranh giới Quyết định Bayes (Bayes Boundary vs K-Nearest Neighbors)
Thay đổi K để thấy ranh giới chuyển đổi từ uốn éo quá khớp sang cứng nhắc
Mặt phẳng quyết định: Vùng Cam vs Vùng Lam, ranh giới Bayes lý thuyết (đường tím đứt nét)
7
K = 1: cực kỳ linh hoạt (1/K = 1). K lớn: ranh giới phẳng dần (1/K nhỏ).
K7
Lỗi Train0.0%
Lỗi Test0.0%
Lỗi Bayes lý thuyết12.8%
Diễn giải

Đường tím đứt đoạn là Ranh giới Quyết định Bayes lý thuyết — nơi xác suất giữa hai lớp cân bằng 50/50. KNN không hề biết ranh giới này mà chỉ bầu chọn dựa trên K điểm láng giềng gần nhất. Khi K tối ưu (~7–11), ranh giới của KNN tiệm cận sát ranh giới tối ưu của Bayes.

Việc cần làm: ① Chọn K = 1: Tỷ lệ Lỗi Train là 0.0% tuyệt đối! Nhưng hãy nhìn các 'hòn đảo' ranh giới cô lập quây quanh từng điểm nhiễu lẻ loi — Lỗi Test rất cao (~24%). ② Tăng K lên 7 – 13: Các hòn đảo biến mất, ranh giới mượt mà bám sát đường tím Bayes, Lỗi Test giảm xuống mức thấp kỷ lục (~13.5%), tiệm cận sàn lỗi Bayes. ③ Kéo K lên 45: Ranh giới bị ép thành một đường gần như thẳng đơ, bỏ qua cấu trúc cong của dữ liệu — Lỗi Test tăng trở lại do độ chệch cao.

  • Khi $K = 1$: Mô hình có độ linh hoạt tối đa. Ranh giới quyết định vô cùng gãy khúc, uốn quanh từng điểm dữ liệu đơn lẻ. Lỗi huấn luyện bằng đúng 0%, nhưng phương sai cực kỳ cao $\implies$ Quá khớp (Overfitting).
  • Khi $K$ tăng dần (ví dụ $K = 100$): Mô hình trở nên cứng nhắc hơn, ranh giới tiến gần tới đường thẳng tuyến tính $\implies$ Phương sai thấp nhưng Độ chệch cao (Underfitting).

2.3. Thực Hành Python: Hệ Sinh Thái Khoa Học Dữ Liệu (NumPy, Pandas, Matplotlib)

Trong toàn bộ cuốn sách ISLP, các mô hình học thống kê được xây dựng trên nền tảng ba thư viện cốt lõi của Python: numpy (tính toán ma trận và đại số tuyến tính), pandas (quản lý bảng dữ liệu có cấu trúc DataFrame), và matplotlib (trực quan hóa đồ thị).

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 1. MẢNG ĐA CHIỀU VÀ BROADCASTING TRONG NUMPY
X = np.array([[1.0, 2.0, 3.0],
              [4.0, 5.0, 6.0]])           # Ma trận kích thước (2, 3)
print("Shape:", X.shape, "| Tổng theo cột:", X.sum(axis=0))

# Sinh mẫu ngẫu nhiên chuẩn hóa có hạt giống cố định (Reproducibility)
rng = np.random.default_rng(seed=42)
eps = rng.normal(loc=0.0, scale=1.0, size=100)

# 2. THAO TÁC BẢNG DỮ LIỆU VỚI PANDAS (BỘ DỮ LIỆU AUTO)
# Giả sử đọc từ gói ISLP hoặc file CSV:
# from ISLP import load_data
# Auto = load_data('Auto')
Auto = pd.DataFrame({
    'mpg': [18.0, 15.0, 18.0, 16.0, 30.0, 35.0],
    'horsepower': [130, 165, 150, 150, 70, 65],
    'weight': [3504, 3693, 3436, 3433, 2124, 1800],
    'origin': pd.Categorical(['USA', 'USA', 'USA', 'USA', 'Japan', 'Japan'])
})

# Lọc các dòng thỏa điều kiện (Boolean Indexing) và thống kê mô tả
high_eff = Auto.loc[Auto['mpg'] > 20, ['mpg', 'horsepower', 'weight']]
print(Auto.describe())

# 3. TRỰC QUAN HÓA MỐI QUAN HỆ PHI TUYẾN GIỮA CÔNG SUẤT VÀ MỨC TIÊU HAO NHIÊN LIỆU
fig, ax = plt.subplots(figsize=(7, 4.5))
ax.scatter(Auto['horsepower'], Auto['mpg'], alpha=0.8)
ax.set_xlabel('Công suất động cơ (Horsepower)')
ax.set_ylabel('Quãng đường trên mỗi gallon (MPG)')
ax.set_title('Mối quan hệ nghịch biến phi tuyến giữa Horsepower và MPG')

03Chương 3: Hồi quy Tuyến tính (Linear Regression)

Hồi quy tuyến tính (Linear Regression) là một trong những công cụ thống kê lâu đời nhất, đơn giản nhất nhưng vẫn giữ vị thế nền tảng trong học máy hiện đại. Dù đã có vô số thuật toán tinh vi ra đời sau này, hồi quy tuyến tính vẫn là điểm khởi đầu bắt buộc của mọi nhà khoa học dữ liệu: nó cung cấp một chuẩn đối sánh (baseline) vững chắc, có khả năng diễn giải nhân quả tuyệt đối, và là viên gạch cấu thành nên các phương pháp nâng cao như Ridge, Lasso hay Mạng nơ-ron.


3.1. Hồi quy Tuyến tính Đơn biến (Simple Linear Regression)

Hồi quy tuyến tính đơn biến mô hình hóa mối quan hệ giữa một biến dự đoán duy nhất $X$ và một biến phản hồi định lượng $Y$ thông qua một phương trình đường thẳng:

$$Y \approx \beta_0 + \beta_1 X$$

  • $\beta_0$: hệ số chặn (intercept), giá trị kỳ vọng của $Y$ khi $X = 0$.
  • $\beta_1$: độ dốc (slope), thể hiện mức thay đổi trung bình của $Y$ khi $X$ tăng 1 đơn vị.

Khi đã ước lượng được các hệ số $\hat{\beta}_0$ và $\hat{\beta}_1$ từ dữ liệu mẫu, giá trị dự đoán cho một quan sát mới có $X = x$ được tính bởi:

$$\hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x$$

3.1.1. Ước lượng Hệ số theo Tiêu chuẩn Bình phương Tối thiểu (OLS)

Giả sử ta có $n$ cặp quan sát mẫu $\{(x_1, y_1), (x_2, y_2), \dots, (x_n, y_n)\}$. Với mỗi quan sát thứ $i$, phần chênh lệch giữa giá trị thực tế $y_i$ và giá trị đường thẳng dự đoán $\hat{y}_i$ được gọi là phần dư (residual):

$$e_i = y_i - \hat{y}_i = y_i - (\hat{\beta}_0 + \hat{\beta}_1 x_i)$$

Phương pháp Bình phương Tối thiểu Thông thường (Ordinary Least Squares - OLS) tìm kiếm cặp hệ số $(\hat{\beta}_0, \hat{\beta}_1)$ sao cho Tổng bình phương phần dư (Residual Sum of Squares - RSS) đạt giá trị nhỏ nhất:

$$\text{RSS} = \sum_{i=1}^n e_i^2 = \sum_{i=1}^n \left(y_i - \hat{\beta}_0 - \hat{\beta}_1 x_i\right)^2$$

Bằng cách giải hệ phương trình đạo hàm riêng $\frac{\partial \text{RSS}}{\partial \beta_0} = 0$ và $\frac{\partial \text{RSS}}{\partial \beta_1} = 0$, ta thu được nghiệm giải tích đóng duy nhất:

$$\hat{\beta}_1 = \frac{\sum_{i=1}^n (x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^n (x_i - \bar{x})^2} = \frac{\text{Cov}(X, Y)}{\text{Var}(X)}$$

$$\hat{\beta}_0 = \bar{y} - \hat{\beta}_1 \bar{x}$$

Trong đó $\bar{x} = \frac{1}{n} \sum x_i$ và $\bar{y} = \frac{1}{n} \sum y_i$ là giá trị trung bình mẫu.


3.1.2. Đánh giá Độ chính xác của Ước lượng Hệ số

Các hệ số $\hat{\beta}_0$ và $\hat{\beta}_1$ tính từ một tập mẫu ngẫu nhiên chỉ là các ước lượng không chệch ($\mathbb{E}(\hat{\beta}) = \beta$) của các tham số thực tế ẩn giấu trong quần thể. Mức độ biến động của các ước lượng này qua các mẫu khác nhau được đo lường bởi Sai số Chuẩn (Standard Error - SE):

$$\text{SE}(\hat{\beta}_1)^2 = \frac{\sigma^2}{\sum_{i=1}^n (x_i - \bar{x})^2}, \qquad \text{SE}(\hat{\beta}_0)^2 = \sigma^2 \left[ \frac{1}{n} + \frac{\bar{x}^2}{\sum_{i=1}^n (x_i - \bar{x})^2} \right]$$

Trong đó $\sigma^2 = \text{Var}(\epsilon)$. Do $\sigma$ thường chưa biết, ta ước lượng nó bằng Sai số Chuẩn Phần dư (Residual Standard Error - RSE):

$$\text{RSE} = \sqrt{\frac{\text{RSS}}{n - 2}}$$

Khoảng tin cậy và Kiểm định Giả thuyết
  • Khoảng tin cậy 95% cho $\beta_1$ xấp xỉ: $[\hat{\beta}_1 - 2 \cdot \text{SE}(\hat{\beta}_1), \hat{\beta}_1 + 2 \cdot \text{SE}(\hat{\beta}_1)]$.
  • Kiểm định giả thuyết: Để xác minh liệu $X$ có thực sự tác động lên $Y$ hay không, ta đặt cặp giả thuyết:
    • Giả thuyết không: $H_0: \beta_1 = 0$ (không có mối liên hệ).
    • Giả thuyết đối: $H_a: \beta_1 \neq 0$ (có mối liên hệ thực sự).
  • Thống kê $t$ được định nghĩa: $$t = \frac{\hat{\beta}_1 - 0}{\text{SE}(\hat{\beta}_1)}$$ Nếu $|t|$ đủ lớn (tương ứng với $p$-value $< 0.05$ hoặc $< 0.001$), ta tự tin bác bỏ $H_0$ và kết luận biến $X$ có ý nghĩa thống kê.

3.1.3. Đánh giá Độ khớp của Toàn bộ Mô hình

Có hai chỉ số tiêu chuẩn để đánh giá mô hình khớp dữ liệu tốt đến đâu:

  1. RSE (Residual Standard Error): Đại diện cho độ lệch chuẩn trung bình của sai số dự đoán. RSE có cùng đơn vị đo với $Y$.
  2. Hệ số Xác định $R^2$ (R-squared): Đo lường tỷ lệ phần trăm độ biến thiên của $Y$ được giải thích bởi $X$:

$$R^2 = \frac{\text{TSS} - \text{RSS}}{\text{TSS}} = 1 - \frac{\text{RSS}}{\text{TSS}}$$

Trong đó $\text{TSS} = \sum_{i=1}^n (y_i - \bar{y})^2$ là Tổng biến thiên toàn phần (Total Sum of Squares).
$R^2$ luôn nằm trong đoạn $[0, 1]$: $R^2 \approx 1$ đồng nghĩa mô hình giải thích gần như hoàn hảo sự biến thiên của phản hồi; $R^2 \approx 0$ biểu thị mô hình tuyến tính không nắm bắt được xu hướng dữ liệu.


3.2. Hồi quy Tuyến tính Đa biến (Multiple Linear Regression)

Trong thực tế, một biến phản hồi thường chịu tác động đồng thời của nhiều yếu tố (ví dụ: Doanh số chịu ảnh hưởng của cả TV, Radio và Báo in). Hồi quy tuyến tính đa biến mở rộng mô hình đơn biến cho $p$ đặc trưng:

$$Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_p X_p + \epsilon$$

Ý nghĩa Then chốt của Hệ số Hồi quy Bội

Hệ số $\beta_j$ biểu thị sự thay đổi trung bình của $Y$ khi biến $X_j$ tăng 1 đơn vị, với điều kiện TOÀN BỘ các biến dự đoán khác ($X_k, k \neq j$) ĐƯỢC GIỮ CỐ ĐỊNH. Đây là lý do tại sao hệ số trong hồi quy bội có thể đổi dấu hoặc thay đổi độ lớn đáng kể so với hồi quy đơn biến khi giữa các biến đầu vào có sự tương quan lẫn nhau.

Phòng thí nghiệm 04
Hồi quy Tuyến tính: Hai núm vặn tham số và Thung lũng Lỗi MSE — nay nhìn bằng 3D
Kéo chấm đỏ trên bản đồ đồng mức hoặc bấm lên sàn 3D · kéo chuột trên hình 3D để xoay
Mẫu dữ liệu và đường dự đoán ŷ = β₀ + β₁·x (nét đứt vàng: nghiệm OLS)
Bát MSE(β₁, β₀) tính đúng từ dữ liệu — độ cao là MSE, bóng dưới sàn là đường đồng mức
Bản đồ đồng mức MSE thật (ellipse từ trị riêng của XᵀX/n) — kéo chấm đỏ
2.8
Độ dốc của đường hồi quy.
4.0
Điểm cắt trục tung.
0.05
Thang trượt đổi theo chế độ. Với x thô, GD chỉ ổn định khi η < 1/λmax ≈ 0,071.
MSE hiện tại0.00
MSE tối ưu OLS0.00
R² hiện tại0.00
β₁—
β₀—
Tỉ số trị riêng λ₁/λ₂—
Bước GD0
Diễn giải

Việc cần làm: ① Kéo chấm đỏ lên sườn cao rồi bấm Gradient Descent: với $x$ thô, thung lũng nằm chéo và hẹp (tỉ số trị riêng 76), quỹ đạo nảy qua lại hai vách theo hướng dốc rồi bò dọc hướng thoải — từ điểm xuất phát mặc định cần khoảng 100 bước với η = 0,05. ② Kéo η lên 0,09 (vượt $1/\lambda_{\max} \approx 0{,}071$) rồi Đặt lại và chạy: phân kỳ chỉ sau vài bước. ③ Bật Chuẩn hoá x: cùng dữ liệu, cùng đường thẳng tối ưu, nhưng bát trở nên tròn xoe (hai trị riêng đều bằng 1) và GD với η = 0,5 tới đáy đúng một bước; η = 1 thì nảy qua nảy lại mãi không dừng. Đây là lý do mọi thư viện đều chuẩn hoá đặc trưng trước khi tối ưu. ④ Bấm Nhảy tới nghiệm OLS: MSE = 0,358, R² = 95,2 % — đó là công thức đóng của mục 3.1.1; Gradient Descent chỉ là cách lần mò tới cùng điểm đó.

3.2.1. Kiểm định Giả thuyết Toàn cục: Thống kê $F$

Để trả lời câu hỏi: Liệu có ít nhất một biến dự đoán nào trong $p$ biến thực sự hữu ích cho việc dự đoán $Y$ hay không?, ta sử dụng thống kê $F$:

$$H_0: \beta_1 = \beta_2 = \dots = \beta_p = 0 \quad \text{vs} \quad H_a: \text{tồn tại ít nhất một } \beta_j \neq 0$$

Thống kê $F$ được định nghĩa:

$$F = \frac{(\text{TSS} - \text{RSS}) / p}{\text{RSS} / (n - p - 1)}$$

Nếu $F$ lớn hơn đáng kể so với 1 (kèm $p$-value cực nhỏ), ta có bằng chứng vững chắc để bác bỏ $H_0$.

Lưu ý quan trọng về Kiểm định $F$ so với Kiểm định $t$ đơn lẻ: Khi số lượng biến dự đoán $p$ lớn (ví dụ $p = 100$) và giả thuyết không $H_0$ thực sự đúng (không biến nào có tác dụng), chỉ riêng việc nhìn vào 100 trị số $p$-value của các kiểm định $t$ đơn lẻ ở mức $\alpha = 0.05$ sẽ khiến ta kỳ vọng nhìn thấy khoảng $100 \times 0.05 = 5$ biến "có ý nghĩa thống kê giả tạo" hoàn toàn do ngẫu nhiên! Ngược lại, thống kê $F$ điều chỉnh đúng theo số lượng biến $p$, nên không bị đánh lừa bởi hiện tượng thử nghiệm đa giả thuyết này.


3.2.2. Biến Dự đoán Định tính (Qualitative Predictors / Dummy Variables)

Trong thực tế, nhiều đặc trưng đầu vào không phải là con số liên tục mà là biến phân loại (ví dụ: Giới tính, Vùng miền, Quyền sở hữu nhà).

  1. Biến định tính chỉ có 2 mức (Binary Predictor): Giả sử biến Own (Sở hữu nhà) có hai giá trị Yes và No. Ta tạo một biến giả (dummy variable / indicator variable) nhận giá trị $0$ hoặc $1$: $$x_i = \begin{cases} 1 & \text{nếu người thứ } i \text{ sở hữu nhà} \\ 0 & \text{nếu người thứ } i \text{ không sở hữu nhà} \end{cases}$$ Mô hình hồi quy lúc này trở thành: $$y_i = \beta_0 + \beta_1 x_i + \epsilon_i = \begin{cases} \beta_0 + \beta_1 + \epsilon_i & \text{nếu sở hữu nhà} \\ \beta_0 + \epsilon_i & \text{nếu không sở hữu nhà} \end{cases}$$

    • Ý nghĩa: $\beta_0$ là mức trung bình của nhóm cơ sở (baseline — không sở hữu nhà), còn $\beta_1$ chính là độ chênh lệch trung bình giữa người sở hữu nhà và người không sở hữu nhà.
  2. Biến định tính có nhiều hơn 2 mức ($K$ mức): Một sai lầm phổ biến là gán một cột duy nhất nhận giá trị $\{0, 1, 2\}$ cho 3 vùng Đông, Tây, Nam — làm vậy là vô tình ép khoảng cách giữa các vùng phải bằng nhau và có thứ tự tuyến tính! Quy tắc chuẩn: Với một biến định tính có $K$ mức, ta luôn tạo đúng $K - 1$ biến giả nhị phân. Mức còn lại không có biến giả riêng sẽ đóng vai trò làm mức tham chiếu cơ sở (baseline level).


3.2.3. Mở rộng Mô hình Tuyến tính: Gỡ bỏ Giả định Cộng tính & Tuyến tính

Mô hình hồi quy tuyến tính chuẩn dựa trên hai giả định rất chặt: cộng tính (additivity — tác động của biến $X_1$ lên $Y$ độc lập với giá trị của biến $X_2$) và tuyến tính (linearity — thay đổi 1 đơn vị của $X_j$ luôn tạo ra thay đổi hằng số $\beta_j$ trên $Y$).

1. Số hạng Tương tác (Interaction Terms) và Hiệu ứng Cộng hưởng (Synergy)

Trong bài toán quảng cáo, việc chi tiền cho Radio có thể làm tăng mức độ hiệu quả của quảng cáo trên TV (người tiêu dùng vừa nghe đài vừa thấy hình trên TV sẽ mua hàng nhiều hơn tổng tác động rời rạc). Ta bổ sung số hạng tương tác tích số $X_1 X_2$:

$$Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \beta_3 (X_1 X_2) + \epsilon = \beta_0 + (\beta_1 + \beta_3 X_2) X_1 + \beta_2 X_2 + \epsilon$$

Khi đó, độ dốc hiệu dụng của $X_1$ không còn là hằng số $\beta_1$ nữa mà trở thành $\tilde{\beta}_1 = \beta_1 + \beta_3 X_2$ — thay đổi phụ thuộc trực tiếp vào mức $X_2$!

Mô hình Cộng tính: Y = β₀ + β₁·TV + β₂·Radio Radio thấp Radio vừa Radio cao Độ dốc theo TV không đổi (các đường song song) Mô hình Tương tác: + β₃·(TV × Radio) Radio = 0 Radio = 25 Radio = 50 (Dốc đứng!) Độ dốc theo TV = (β₁ + β₃·Radio) tăng vọt khi Radio lớn
Hình 3.2. Khác biệt hình học giữa Mô hình Cộng tính (trái) và Mô hình có Số hạng Tương tác $X_1 X_2$ (phải). Khi $eta_3 > 0$, chi thêm tiền cho Radio không chỉ nâng hệ số chặn mà còn làm tăng độ dốc hiệu quả của mỗi đồng chi cho TV (hiệu ứng cộng hưởng — synergy).

Nguyên lý Phân cấp (The Hierarchical Principle)

Nếu chúng ta đưa một số hạng tương tác $X_1 X_2$ vào mô hình (vì nó có $p$-value rất nhỏ), chúng ta BẮT BUỘC phải giữ lại cả hai biến thành phần chính $X_1$ và $X_2$ trong mô hình, ngay cả khi $p$-value của các hệ số tác động chính ($\beta_1, \beta_2$) không có ý nghĩa thống kê! Lý do: nếu bỏ $X_1$ hoặc $X_2$, ý nghĩa của tương tác $X_1 X_2$ sẽ bị bóp méo hoàn toàn khi ta dịch chuyển gốc tọa độ của dữ liệu.


3.3. Các Cạm bẫy Thường gặp trong Thực tiễn

Khi triển khai hồi quy tuyến tính trên dữ liệu thực tế, nhà phân tích cần kiểm tra kỹ 5 cạm bẫy kinh điển:

  1. Tính Phi tuyến của Dữ liệu: Nếu mối quan hệ thực sự là đường cong, mô hình tuyến tính sẽ cho kết quả chệch. Hãy vẽ đồ thị phần dư $e_i$ theo giá trị dự đoán $\hat{y}_i$: nếu thấy xuất hiện dạng đường cong hình chữ U, cần bổ sung các số hạng bậc hai ($X^2$) hoặc dùng hồi quy phi tuyến.
  2. Phương sai Sai số Thay đổi (Heteroscedasticity): Đồ thị phần dư loe rộng ra như hình cái loa (funnel shape) khi $\hat{y}$ tăng. Khắc phục bằng cách biến đổi biến mục tiêu $Y$ qua hàm $\log(Y)$ hoặc $\sqrt{Y}$.
  3. Điểm Ngoại lai (Outliers): Những điểm có giá trị $y_i$ khác thường so với dự đoán, làm tăng vọt RSE. Có thể phát hiện bằng phần dư chuẩn hóa (studentized residuals) có giá trị tuyệt đối lớn hơn $3$.
  4. Điểm có Đòn bẩy Cao (High Leverage Points): Những điểm có giá trị $x_i$ nằm rất xa trung tâm đám mây dữ liệu. Dù phần dư nhỏ, điểm đòn bẩy cao có thể "kéo" cả đường hồi quy xoay theo nó. Được định lượng bằng chỉ số đòn bẩy $h_i \in [1/n, 1]$, với trung bình bằng $(p+1)/n$.
  5. Hiện tượng Đa cộng tuyến (Multicollinearity): Hai hoặc nhiều biến dự đoán có tương quan tuyến tính rất chặt chẽ với nhau (ví dụ: Biến Tuổi và Năm kinh nghiệm). Hậu quả: Sai số chuẩn $\text{SE}(\hat{\beta}_j)$ bị thổi phồng, khiến các biến trở nên vô nghĩa thống kê dù toàn bộ mô hình có $R^2$ cao. Được kiểm tra qua Hệ số Lạm phát Phương sai (VIF - Variance Inflation Factor): $$\text{VIF}(\hat{\beta}_j) = \frac{1}{1 - R^2_{X_j \mid X_{-j}}}$$ Trong đó $R^2_{X_j \mid X_{-j}}$ là hệ số $R^2$ khi hồi quy biến $X_j$ theo toàn bộ các biến dự đoán còn lại. Nếu $\text{VIF} > 5$ hoặc $10$, cần loại bỏ hoặc gộp biến cộng tuyến.
1. Mô hình Tuyến tính Đúng giả định Phần dư phân bố ngẫu nhiên, bề rộng đều 2. Bỏ sót Tính Phi tuyến (Hình chữ U) Giải pháp: Thêm bậc cao X², X³ hoặc Splines 3. Phương sai Thay đổi (Hình cái loa) Giải pháp: Biến đổi mục tiêu log(Y) hoặc √Y
Hình 3.1. Ba mẫu hình kinh điển trên đồ thị Phần dư $e_i = y_i - \hat{y}_i$ theo Giá trị dự đoán $\hat{y}_i$: (1) Nhiễu thuần túy có phương sai hằng số $\sigma^2$; (2) Dạng parabol chữ U tố cáo mối quan hệ phi tuyến chưa được mô hình hóa; (3) Đám mây loe rộng hình phễu (Heteroscedasticity) làm sai lệch các khoảng tin cậy và kiểm định $t$.

3.4. So sánh Hồi quy Tuyến tính với $K$-Láng giềng Gần nhất (KNN Regression)

Hồi quy tuyến tính là đại diện tiêu biểu của phương pháp tham số (parametric), trong khi Hồi quy KNN (KNN Regression) ước lượng giá trị tại điểm $x_0$ bằng trung bình cộng của $K$ điểm huấn luyện gần nhất:

$$\hat{f}(x_0) = \frac{1}{K} \sum_{x_i \in \mathcal{N}_0} y_i$$

Khi nào Hồi quy Tuyến tính đánh bại KNN và ngược lại?

  • Khi mối quan hệ thực sự gần tuyến tính: Hồi quy tuyến tính luôn thắng áp đảo; KNN dù chọn $K$ tối ưu vẫn chịu phương sai cao ở vùng biên dữ liệu.
  • Khi số chiều $p$ nhỏ ($p = 1$ hoặc $2$) và mối quan hệ rất phi tuyến: KNN với $K$ nhỏ sẽ thích nghi mượt mà hơn đường thẳng cứng nhắc.
  • Khi số chiều $p$ lớn ($p \ge 4..20$) — Lời nguyền Chiều cao (Curse of Dimensionality): Ngay cả khi hàm thực tế có tính phi tuyến, KNN vẫn suy giảm thảm hại và thua xa Hồi quy Tuyến tính! Lý do: trong không gian 20 chiều, $K$ điểm "gần nhất" thực chất lại nằm rất xa điểm cần dự đoán $x_0$ trên hầu hết các trục tọa độ, khiến trung bình cục bộ của KNN có cả độ chệch lớn lẫn phương sai cao.

3.5. Thực Hành Python (Lab: Hồi Quy Tuyến Tính với statsmodels & ISLP)

import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
from statsmodels.stats.outliers_influence import variance_inflation_factor

# 1. KHỚP HỒI QUY TUYẾN TÍNH BỘI KÈM SỐ HẠNG TƯƠNG TÁC & ĐA THỨC
# Giả lập dữ liệu kiểu Boston / Advertising
rng = np.random.default_rng(42)
n = 200
df = pd.DataFrame({
    'lstat': rng.uniform(2, 35, size=n),
    'age': rng.uniform(15, 100, size=n),
    'chas': rng.integers(0, 2, size=n)
})
df['medv'] = 34.5 - 0.95 * df['lstat'] + 0.012 * (df['lstat'] ** 2) + 3.2 * df['chas'] + rng.normal(0, 3.0, size=n)

# Dùng cú pháp công thức R-style trong statsmodels:
# - lstat:age là số hạng tương tác riêng; lstat * age tự động bao gồm cả lstat + age + lstat:age (Nguyên lý phân cấp)
# - I(lstat**2) thêm số hạng bậc hai
model = smf.ols('medv ~ lstat + I(lstat**2) + age + C(chas)', data=df).fit()
print(model.summary())

# 2. KIỂM ĐỊNH ANOVA (F-TEST) SO SÁNH MÔ HÌNH TUYẾN TÍNH VÀ MÔ HÌNH BẬC HAI
model_linear = smf.ols('medv ~ lstat', data=df).fit()
model_quad = smf.ols('medv ~ lstat + I(lstat**2)', data=df).fit()
anova_res = sm.stats.anova_lm(model_linear, model_quad)
print("\nBảng kiểm định ANOVA F-test giữa Bậc 1 và Bậc 2:\n", anova_res)

# 3. TÍNH HỆ SỐ LẠM PHÁT PHƯƠNG SAI (VIF) ĐỂ PHÁT HIỆN ĐA CỘNG TUYẾN
X_design = sm.add_constant(df[['lstat', 'age', 'chas']])
vif_table = pd.DataFrame({
    'Biến': X_design.columns,
    'VIF': [variance_inflation_factor(X_design.values, i) for i in range(X_design.shape[1])]
})
print("\nBảng kiểm tra Đa cộng tuyến (VIF):\n", vif_table)

# 4. CHẨN ĐOÁN ĐIỂM ĐÒN BẨY CAO (LEVERAGE) VÀ PHẦN DƯ CHUẨN HÓA
infl = model.get_influence()
leverage = infl.hat_matrix_diag
student_resid = infl.resid_studentized_internal
print("Chỉ số đòn bẩy lớn nhất:", leverage.max().round(4))

04Chương 4: Phân Loại (Classification)

Trong nhiều bài toán thực tiễn, biến phản hồi $Y$ không phải là một con số định lượng liên tục mà là một biến định tính (qualitative / categorical variable). Ví dụ: một giao dịch thẻ tín dụng là Hợp lệ hay Gian lận; một người bệnh Dương tính hay Âm tính; một email là Hộp thư đến hay Thư rác (Spam). Những tác vụ dự đoán biến định tính như vậy được gọi là bài toán phân loại (classification).


4.1. Tại sao Không Dùng Hồi quy Tuyến tính để Phân loại?

Giả sử ta muốn phân loại tình trạng bệnh nhân vào phòng cấp cứu thành 3 nhóm: Đột quỵ (Stroke), Dùng thuốc quá liều (Drug overdose), và Động kinh (Epileptic seizure). Ta có thể nghĩ đến việc gán nhãn số học: $Y = 1$ (Đột quỵ), $Y = 2$ (Quá liều), $Y = 3$ (Động kinh) rồi chạy hồi quy tuyến tính. Tuy nhiên, cách tiếp cận này mắc phải hai sai lầm tai hại:

  1. Áp đặt thứ tự và khoảng cách giả tạo: Việc gán nhãn vô tình ép buộc giả định rằng "khoảng cách giữa Đột quỵ và Quá liều bằng khoảng cách giữa Quá liều và Động kinh", và "Đột quỵ nằm ở giữa hai bệnh còn lại". Nếu đảo thứ tự gán nhãn, kết quả hồi quy sẽ biến dạng hoàn toàn.
  2. Dự đoán vượt ngưỡng xác suất: Trong bài toán phân loại nhị phân ($Y \in \{0, 1\}$), hàm hồi quy tuyến tính $\hat{Y} = X\hat{\beta}$ hoàn toàn có thể cho ra kết quả dự đoán $\hat{y} < 0$ hoặc $\hat{y} > 1$ đối với các điểm ở xa trung tâm — vi phạm nguyên lý toán học của xác suất ($\Pr \in [0, 1]$).

Do đó, chúng ta cần các mô hình chuyên biệt được thiết kế để luôn đảm bảo đầu ra nằm chuẩn xác trong khoảng xác suất $[0, 1]$.


4.2. Hồi quy Logistic (Logistic Regression)

Hồi quy Logistic mô hình hóa trực tiếp xác suất có điều kiện $p(X) = \Pr(Y = 1 \mid X)$ thay vì dự đoán trực tiếp nhãn $Y$.

4.2.1. Hàm Sigmoid và Tỷ số Tỷ lệ Cược (Odds)

Để ép xác suất luôn rơi vào khoảng $(0, 1)$ với mọi giá trị đầu vào $X$, hồi quy Logistic sử dụng hàm Logistic (hay hàm Sigmoid):

$$p(X) = \frac{e^{\beta_0 + \beta_1 X}}{1 + e^{\beta_0 + \beta_1 X}} = \frac{1}{1 + e^{-(\beta_0 + \beta_1 X)}}$$

Sau một vài biến đổi đại số cơ bản, ta thu được:

$$\frac{p(X)}{1 - p(X)} = e^{\beta_0 + \beta_1 X}$$

Vế trái $\frac{p(X)}{1 - p(X)}$ được gọi là Tỷ số Tỷ lệ Cược (Odds), nhận giá trị trong khoảng $[0, \infty)$. Lấy logarit tự nhiên hai vế, ta có hàm Logit (hay Log-odds):

$$\log\left(\frac{p(X)}{1 - p(X)}\right) = \beta_0 + \beta_1 X$$

Bản chất của Hồi quy Logistic

Hồi quy Logistic có mối liên hệ tuyến tính theo tham số đối với hàm log-odds. Nghĩa là: tăng $X$ thêm 1 đơn vị sẽ làm thay đổi log-odds một lượng cố định bằng $\beta_1$, hay nhân tỷ lệ cược (odds) lên một hệ số $e^{\beta_1}$.

4.2.2. Ước lượng Hệ số theo Phương pháp Hợp lý Cực đại (MLE)

Không thể dùng OLS cho hồi quy logistic vì phương trình là phi tuyến. Thay vào đó, ta sử dụng Ước lượng Hợp lý Cực đại (Maximum Likelihood Estimation - MLE). Hàm hợp lý (Likelihood function) đo lường xác suất đồng thời quan sát được tập nhãn thực tế $\{y_1, \dots, y_n\}$:

$$\ell(\beta_0, \beta_1) = \prod_{i: y_i = 1} p(x_i) \prod_{i': y_{i'} = 0} (1 - p(x_{i'}))$$

Ta tìm cặp $(\hat{\beta}_0, \hat{\beta}_1)$ để tối đa hóa $\ell(\beta_0, \beta_1)$ (thường thông qua thuật toán lặp Gradient Ascent hoặc Newton-Raphson / IRLS).

4.2.3. Hồi quy Logistic Đa biến và Cạm bẫy Biến Nhiễu (Confounding)

Mở rộng sang $p$ biến dự đoán $X = (X_1, \dots, X_p)$, phương trình log-odds có dạng:

$$\log\left(\frac{p(X)}{1 - p(X)}\right) = \beta_0 + \beta_1 X_1 + \dots + \beta_p X_p \implies p(X) = \frac{e^{\beta_0 + \beta_1 X_1 + \dots + \beta_p X_p}}{1 + e^{\beta_0 + \beta_1 X_1 + \dots + \beta_p X_p}}$$

Một bài học kinh điển nhất của Chương 4 trong sách ISLP là hiện tượng biến nhiễu (confounding — Nghịch lý Simpson) trên bộ dữ liệu tín dụng Default:

  • Khi chạy hồi quy đơn biến chỉ dùng biến giả student (Sinh viên = 1, Không phải SV = 0): hệ số ước lượng là $\hat{\beta}_{\text{student}} = +0.4049$ ($p\text{-value} = 0.0004$). Có vẻ như sinh viên có xác suất vỡ nợ cao hơn người đi làm!
  • Nhưng khi chạy hồi quy đa biến gồm cả balance (dư nợ thẻ), income và student: hệ số của student lập tức đảo dấu thành $\hat{\beta}_{\text{student}} = -0.6468$ ($p\text{-value} = 0.006$)!
  • Giải thích bản chất: Biến student và biến balance có tương quan dương mạnh (sinh viên thường tích lũy dư nợ thẻ tín dụng trung bình cao hơn người không phải sinh viên). Ở mọi mức dư nợ balance cố định, sinh viên thực chất có tỷ lệ vỡ nợ thấp hơn người không phải sinh viên. Khi bỏ biến balance ra khỏi mô hình đơn biến, biến student đã vô tình "gánh" luôn hiệu ứng rủi ro của dư nợ cao!
1. Xác suất Vỡ nợ theo Dư nợ thẻ (Balance) Không phải SV (Cao hơn ở cùng Balance!) Sinh viên (Thấp hơn ở cùng Balance) Trục ngang: Dư nợ thẻ tín dụng (Balance $) → 2. Giải mã Biến nhiễu: Sinh viên mang Dư nợ cao hơn! Nhóm Không phải SV Nhóm Sinh viên Sinh viên hay nợ thẻ nhiều hơn → đẩy tỷ lệ gộp tăng giả tạo Trục ngang: Phân phối Dư nợ thẻ (Balance $) →
Hình 4.1 (Nghịch lý Simpson trên bộ dữ liệu Default). Khi chạy hồi quy đơn biến chỉ có biến student, hệ số mang dấu dương ($\hat{eta} = +0.40$, sinh viên có vẻ dễ vỡ nợ hơn). Nhưng khi đưa biến balance vào hồi quy đa biến, hệ số của student đảo chiều thành âm ($\hat{eta} = -0.65$): ở bất kỳ mức dư nợ cố định nào, sinh viên thực chất ít vỡ nợ hơn người đi làm!

4.2.4. Hồi quy Logistic Đa lớp (Multinomial Logistic Regression & Softmax)

Khi biến mục tiêu $Y$ có $K > 2$ lớp (ví dụ: Đột quỵ, Quá liều thuốc, Động kinh), hồi quy logistic tổng quát hóa thông qua mã hóa Softmax (còn là tầng đầu ra tiêu chuẩn của mạng nơ-ron học sâu):

$$\Pr(Y = k \mid X = x) = \frac{e^{\beta_{k0} + \beta_{k1} x_1 + \dots + \beta_{kp} x_p}}{\sum_{l=1}^K e^{\beta_{l0} + \beta_{l1} x_1 + \dots + \beta_{lp} x_p}}$$

Khi đó, tỷ số log-odds giữa hai lớp $k$ và $k'$ bất kỳ vẫn là một hàm tuyến tính theo $x$.


4.3. Phân tích Biệt số Tuyến tính (Linear Discriminant Analysis - LDA)

Tại sao chúng ta lại cần LDA khi đã có Hồi quy Logistic?

  1. Khi các lớp được phân tách rất rõ ràng (well-separated), các ước lượng tham số của hồi quy logistic trở nên bất ổn định (các hệ số bị thổi phồng tiến tới vô cực). LDA không gặp vấn đề này.
  2. Nếu số lượng mẫu $n$ nhỏ và phân phối của $X$ xấp xỉ chuẩn trong từng lớp, mô hình LDA cho độ chính xác và độ ổn định cao hơn hẳn logistic.
  3. LDA mở rộng cực kỳ tự nhiên cho bài toán phân loại nhiều hơn hai lớp ($K > 2$).

4.3.1. Tiếp cận theo Định lý Bayes

Thay vì mô hình hóa trực tiếp $\Pr(Y = k \mid X = x)$ như Logistic, LDA đảo ngược bài toán bằng cách sử dụng Định lý Bayes:

$$\Pr(Y = k \mid X = x) = \frac{\pi_k f_k(x)}{\sum_{l=1}^K \pi_l f_l(x)}$$

Trong đó:

  • $\pi_k$: xác suất tiên nghiệm (prior probability), tức tỷ lệ ngẫu nhiên một quan sát thuộc về lớp $k$.
  • $f_k(x) = \Pr(X = x \mid Y = k)$: hàm mật độ xác suất của các biến đầu vào đối với những mẫu thuộc lớp $k$.

4.3.2. Giả định Cốt lõi của LDA

LDA giả định rằng trong mỗi lớp $k$, các biến đầu vào tuân theo phân phối chuẩn đa biến với vectơ kỳ vọng riêng $\boldsymbol{\mu}_k$, nhưng dùng chung một ma trận hiệp phương sai $\boldsymbol{\Sigma}$ trên toàn bộ các lớp: $f_k(x) \sim \mathcal{N}(\boldsymbol{\mu}_k, \boldsymbol{\Sigma})$.

Hàm phân biệt (discriminant function) của LDA đối với lớp $k$ có dạng:

$$\delta_k(x) = x^T \boldsymbol{\Sigma}^{-1} \boldsymbol{\mu}_k - \frac{1}{2} \boldsymbol{\mu}_k^T \boldsymbol{\Sigma}^{-1} \boldsymbol{\mu}_k + \log(\pi_k)$$

Vì $\delta_k(x)$ là hàm bậc nhất tuyến tính theo $x$, ranh giới quyết định giữa hai lớp bất kỳ ($\delta_k(x) = \delta_l(x)$) luôn luôn là một siêu phẳng hoặc đường thẳng tuyến tính.

4.3.3. Độ Nhạy (Sensitivity), Độ Đặc Hiệu (Specificity), Dịch Ngưỡng và Đường Cong ROC

Một bộ phân loại Bayes hay LDA mặc định gán nhãn Dương tính ($Y = 1$) khi xác suất hậu nghiệm vượt ngưỡng $\tau = 0.5$. Tuy nhiên, trên dữ liệu mất cân bằng (như tập Default chỉ có $3.33\%$ khách hàng vỡ nợ), ngưỡng $\tau = 0.5$ đạt tổng tỷ lệ lỗi rất thấp ($2.75\%$) nhưng lại bỏ lỡ tới $252 / 333 = 75.7\%$ số người vỡ nợ thật (Độ nhạy / Recall chỉ đạt $24.3\%$).

  • Độ nhạy (Sensitivity / True Positive Rate - TPR): Tỷ lệ người vỡ nợ thật được phát hiện đúng $\text{TP} / (\text{TP} + \text{FN})$.
  • Độ đặc hiệu (Specificity / True Negative Rate - TNR): Tỷ lệ người trả nợ tốt được phân loại đúng $\text{TN} / (\text{TN} + \text{FP})$.
  • Dịch chuyển ngưỡng theo chi phí nghiệp vụ: Đối với ngân hàng, chi phí bỏ lỡ một khách vỡ nợ (FN) đắt hơn nhiều so với việc kiểm tra nhầm một khách tốt (FP). Khi hạ ngưỡng quyết định từ $\tau = 0.5$ xuống $\tau = 0.2$, tỷ lệ bắt trúng khách vỡ nợ (Sensitivity) tăng vọt từ $24.3\%$ lên $58.6\%$, đổi lấy việc tỷ lệ lỗi tổng thể tăng nhẹ lên $3.75\%$.
  • Đường cong ROC & Diện tích AUC: Quét toàn bộ ngưỡng $\tau \in (0, 1)$ và vẽ đồ thị $\text{TPR}$ theo $\text{FPR} = 1 - \text{Specificity}$ tạo ra đường cong ROC. Diện tích dưới đường cong (AUC) càng gần $1.0$ chứng tỏ bộ phân loại càng tách lớp xuất sắc trên mọi ngưỡng.

4.4. Phân tích Biệt số Toàn phương (QDA) và Naive Bayes

4.4.1. QDA (Quadratic Discriminant Analysis)

Nếu ta dỡ bỏ giả định dùng chung ma trận hiệp phương sai và cho phép mỗi lớp $k$ sở hữu một ma trận hiệp phương sai riêng biệt $\boldsymbol{\Sigma}_k$, hàm phân biệt trở thành một hàm bậc hai theo $x$:

$$\delta_k(x) = -\frac{1}{2} x^T \boldsymbol{\Sigma}_k^{-1} x + x^T \boldsymbol{\Sigma}_k^{-1} \boldsymbol{\mu}_k - \frac{1}{2} \boldsymbol{\mu}_k^T \boldsymbol{\Sigma}_k^{-1} \boldsymbol{\mu}_k - \frac{1}{2} \log|\boldsymbol{\Sigma}_k| + \log(\pi_k)$$

Ranh giới quyết định của QDA là đường cong toàn phương (parabol, elip hoặc hyperbol).
Đánh đổi Bias-Variance: Với $p$ đặc trưng, LDA chỉ cần ước lượng $p(p+1)/2$ tham số hiệp phương sai chung, trong khi QDA phải ước lượng $K \cdot p(p+1)/2$ tham số. Do đó LDA ít phương sai hơn khi $n$ nhỏ, còn QDA tỏa sáng khi $n$ lớn hoặc khi các lớp thực sự có độ phân tán/tương quan khác hẳn nhau.

Phòng thí nghiệm 05
So sánh Ranh giới Phân loại: Logistic vs LDA vs QDA
Đổi qua lại giữa các mô hình để thấy sự khác biệt giữa ranh giới thẳng và ranh giới cong
Mặt phẳng phân loại 2 chiều: Các điểm dữ liệu và Ranh giới Quyết định
Mô hìnhHồi quy Logistic
Độ chính xác Train89.5%
Độ chính xác Test87.0%
Dạng ranh giớiSiêu phẳng Tuyến tính
Diễn giải

Hồi quy Logistic và LDA đều tạo ra ranh giới phân loại tuyến tính (đường thẳng), nhưng ước lượng theo hai nguyên lý khác nhau (MLE trực tiếp vs Định lý Bayes phân phối chuẩn). Khi chuyển sang QDA, ranh giới trở thành đường cong bậc hai uốn lượn linh hoạt.

Việc cần làm: ① Ở dữ liệu mặc định: cả Logistic và LDA đều tách rất tốt bằng đường thẳng. ② Bấm Đổi phân phối dữ liệu (Phi tuyến): dữ liệu lớp 1 bị bao bọc bởi lớp 0. Lúc này cả Logistic và LDA đều hoàn toàn bất lực (độ chính xác rớt thảm hại vì đường thẳng không thể bao bọc). Chuyển sang QDA: ranh giới hình elip khép kín ôm trọn lấy lớp bên trong, độ chính xác tăng vọt!

4.4.2. Phân loại Naive Bayes

Khi số lượng đặc trưng $p$ rất lớn, việc ước lượng toàn bộ ma trận hiệp phương sai trở nên bất khả thi. Naive Bayes đưa ra giả định đơn giản hóa triệt để: trong mỗi lớp $k$, toàn bộ $p$ biến dự đoán độc lập có điều kiện với nhau:

$$f_k(x) = f_{k1}(x_1) \times f_{k2}(x_2) \times \dots \times f_{kp}(x_p)$$

Hàm phân biệt log-hậu nghiệm lúc này biến thành tổng của các hàm đơn biến $\sum_{j=1}^p \log f_{kj}(x_j)$ — tương đương về mặt cấu trúc với một Mô hình Cộng tính Tổng quát (GAM). Dù giả định độc lập gần như không bao giờ đúng hoàn toàn trong tự nhiên, Naive Bayes lại hoạt động cực tốt trong các bài toán chiều cao ($p \gg n$) nhờ triệt tiêu phương sai ước lượng hiệp phương sai chéo.


4.5. Đặt Lên Bàn Cân: So Sánh 5 Phương Pháp Phân Loại

Phương pháp Hình dạng Ranh giới Giả định Phân phối Điểm mạnh Nổi bật Khi nào Thất bại?
Logistic Regression Tuyến tính (Siêu phẳng) Không giả định phân phối của $X$ Linh hoạt với biến đầu vào không chuẩn; diễn giải tỷ lệ cược (Odds) trực tiếp Các lớp tách biệt hoàn toàn (hệ số nổ); ranh giới cong phức tạp
LDA Tuyến tính (Siêu phẳng) Chuẩn đa biến, chung $\boldsymbol{\Sigma}$ Ổn định hơn Logistic khi $n$ nhỏ hoặc các lớp tách rời xa; tự nhiên cho $K > 2$ Các lớp có phương sai khác nhau hoặc ranh giới phi tuyến
QDA Bậc hai (Parabol / Elip) Chuẩn đa biến, riêng $\boldsymbol{\Sigma}_k$ Bắt được ranh giới cong bậc hai và tương tác $X_j X_l$ Số chiều $p$ lớn so với $n$ (quá khớp do nổ số tham số $Kp^2/2$)
Naive Bayes Phi tuyến cộng tính Độc lập có điều kiện trong từng lớp Cực mạnh khi $p$ lớn, $n$ nhỏ (văn bản, spam); không cần ma trận $\boldsymbol{\Sigma}$ Các đặc trưng có tương quan chéo quyết định nhãn
KNN Phi tham số tùy ý Không giả định bất kỳ phân phối nào Thích nghi mọi ranh giới ngoằn ngoèo khi $p$ nhỏ và $n$ lớn Lời nguyền chiều cao ($p$ lớn); không cho biết biến nào quan trọng

4.6. Mô hình Tuyến tính Tổng quát (GLM) & Hồi quy Poisson cho Dữ liệu Đếm

Trong nhiều bài toán thực tế, biến mục tiêu $Y$ không phải là số thực liên tục âm dương tùy ý, cũng không phải là nhãn nhị phân $\{0, 1\}$, mà là dữ liệu đếm không âm (Count Data: $Y \in \{0, 1, 2, \dots\}$) — ví dụ: số lượt thuê xe đạp công cộng mỗi giờ trong bộ dữ liệu Bikeshare, số lượng lỗi phần mềm trong một module, hoặc số ca cấp cứu mỗi ngày.

Nếu cố tình dùng Hồi quy Tuyến tính (OLS) cho dữ liệu đếm, ta gặp hai bất cập lớn:

  1. Mô hình tuyến tính có thể dự đoán số lượt thuê xe âm ($\hat{y} < 0$) vào những giờ thời tiết xấu.
  2. Dữ liệu đếm luôn có phương sai tăng theo kỳ vọng (giờ cao điểm trung bình 500 xe thì dao động $\pm 80$ xe; lúc 3 giờ sáng trung bình 2 xe thì chỉ dao động $\pm 1..2$ xe), vi phạm nghiêm trọng giả định phương sai hằng số $\sigma^2$ của OLS!

4.6.1. Hồi quy Poisson (Poisson Regression)

Biến ngẫu nhiên $Y$ tuân theo phân phối Poisson với kỳ vọng $\lambda = \mathbb{E}(Y) = \text{Var}(Y) > 0$ có hàm khối xác suất:

$$\Pr(Y = k) = \frac{e^{-\lambda} \lambda^k}{k!}, \qquad k = 0, 1, 2, \dots$$

Để đảm bảo kỳ vọng $\lambda(X)$ luôn luôn dương với mọi giá trị của $X$, Hồi quy Poisson mô hình hóa logarit tự nhiên của $\lambda(X)$ bằng một tổ hợp tuyến tính:

$$\log(\lambda(X)) = \beta_0 + \beta_1 X_1 + \dots + \beta_p X_p \iff \lambda(X) = e^{\beta_0 + \beta_1 X_1 + \dots + \beta_p X_p}$$

  • Ý nghĩa nhân tính của hệ số: Tăng biến $X_j$ thêm 1 đơn vị sẽ nhân kỳ vọng số đếm $\lambda(X)$ lên một hệ số bằng $e^{\beta_j}$!
  • Ước lượng tham số: Cực đại hóa hàm hợp lý (Log-Likelihood): $$\ell(\beta) = \sum_{i=1}^n \left( y_i (\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip}) - e^{\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip}} - \log(y_i!) \right)$$

4.6.2. Khung Lý thuyết Thống nhất: Generalized Linear Models (GLM)

Hồi quy Tuyến tính, Hồi quy Logistic và Hồi quy Poisson thực chất là ba trường hợp riêng của cùng một kiến trúc toán học duy nhất gọi là Mô hình Tuyến tính Tổng quát (GLM):

  1. Thành phần ngẫu nhiên: $Y \mid X$ thuộc họ phân phối mũ (Gaussian, Bernoulli, Poisson, Gamma…).
  2. Thành phần hệ thống: Tổ hợp tuyến tính $\eta = \beta_0 + \sum_{j=1}^p \beta_j X_j$.
  3. Hàm liên kết (Link Function $\eta(\mu)$): Kết nối kỳ vọng có điều kiện $\mu(X) = \mathbb{E}(Y \mid X)$ với tổ hợp tuyến tính qua $\eta(\mu(X)) = \beta_0 + \sum_{j=1}^p \beta_j X_j$:
    • Hồi quy Tuyến tính: Hàm liên kết đồng nhất $\eta(\mu) = \mu$.
    • Hồi quy Logistic: Hàm liên kết Logit $\eta(\mu) = \log\left(\frac{\mu}{1-\mu}\right)$.
    • Hồi quy Poisson: Hàm liên kết Log $\eta(\mu) = \log(\mu)$.
1. Hồi quy Tuyến tính (Gaussian) • Miền giá trị Y: Số thực (−∞, +∞) • Phân phối: Chuẩn N(μ, σ²) • Hàm liên kết η(μ): Đồng nhất η(μ) = μ • Kỳ vọng: μ(X) = β₀ + β₁X₁ + … Phương sai không đổi Var(Y|X) = σ² 2. Hồi quy Logistic (Bernoulli) • Miền giá trị Y: Nhị phân {0, 1} • Phân phối: Bernoulli(μ), μ ∈ (0, 1) • Hàm liên kết: Logit ln(μ / (1−μ)) • Kỳ vọng: μ(X) = 1 / (1 + e⁻ᶻ) Phương sai ở biên bằng 0: Var = μ(1−μ) 3. Hồi quy Poisson (Dữ liệu đếm) • Miền giá trị Y: Số nguyên {0, 1, 2, …} • Phân phối: Poisson(λ), λ > 0 • Hàm liên kết: Logarit η(λ) = ln(λ) • Kỳ vọng: λ(X) = exp(β₀ + β₁X₁ + …) Phương sai tăng theo kỳ vọng: Var(Y|X) = λ
Hình 4.2. Ba thành viên cốt lõi của họ Mô hình Tuyến tính Tổng quát (Generalized Linear Models — GLM). Cả ba đều tính tổ hợp tuyến tính $z = eta_0 + \sum eta_j X_j$, rồi ánh xạ qua hàm liên kết $\eta(\mu) = z$ phù hợp với bản chất vật lý của biến phản hồi $Y$ và ước lượng tham số bằng Hợp lý Cực đại (MLE).

4.7. Thực Hành Python (Lab: Phân Loại & Hồi Quy Poisson với statsmodels & scikit-learn)

import numpy as np
import pandas as pd
import statsmodels.api as sm
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix, roc_auc_score

# 1. SO SÁNH 5 BỘ PHÂN LOẠI TRÊN DỮ LIỆU CHỨNG KHOÁN / TÍN DỤNG
rng = np.random.default_rng(42)
X_train = rng.normal(0, 1, size=(400, 2))
# Tạo quy luật phi tuyến bậc hai thực sự cho nhãn Y
y_train = ((X_train[:, 0] ** 2 + 0.8 * X_train[:, 1] - 0.6 + rng.normal(0, 0.4, 400)) > 0).astype(int)

X_test = rng.normal(0, 1, size=(200, 2))
y_test = ((X_test[:, 0] ** 2 + 0.8 * X_test[:, 1] - 0.6 + rng.normal(0, 0.4, 200)) > 0).astype(int)

classifiers = {
    'LDA (Tuyến tính)': LinearDiscriminantAnalysis(),
    'QDA (Toàn phương)': QuadraticDiscriminantAnalysis(),
    'Naive Bayes': GaussianNB(),
    'KNN (K=7)': KNeighborsClassifier(n_neighbors=7)
}

for name, clf in classifiers.items():
    clf.fit(X_train, y_train)
    probs = clf.predict_proba(X_test)[:, 1]
    preds_05 = (probs >= 0.5).astype(int)
    auc = roc_auc_score(y_test, probs)
    acc = (preds_05 == y_test).mean()
    print(f"{name:<20} | Test Accuracy (ngưỡng 0.5): {acc:.3f} | ROC-AUC: {auc:.3f}")

# 2. HỒI QUY POISSON (GLM VỚI HÀM LIÊN KẾT LOG) CHO DỮ LIỆU ĐẾM (BIKESHARE)
temp = rng.uniform(0.1, 0.9, size=300)          # Nhiệt độ chuẩn hóa
workingday = rng.integers(0, 2, size=300)       # Ngày làm việc (0/1)
# Số lượng xe thuê thực tế tuân theo phân phối Poisson với kỳ vọng exp(3.2 + 1.8*temp + 0.25*workingday)
lam_true = np.exp(3.2 + 1.8 * temp + 0.25 * workingday)
bikers = rng.poisson(lam=lam_true)

X_pois = sm.add_constant(pd.DataFrame({'temp': temp, 'workingday': workingday}))
poisson_glm = sm.GLM(bikers, X_pois, family=sm.families.Poisson()).fit()
print("\nKết quả khớp Hồi quy Poisson (GLM):\n", poisson_glm.summary())

05Chương 5: Các Phương Pháp Lấy Lại Mẫu (Resampling Methods)

Các phương pháp lấy lại mẫu (resampling methods) là một trong những công cụ nền tảng và quyền lực nhất của khoa học thống kê hiện đại. Ý tưởng cốt lõi vô cùng mộc mạc nhưng hiệu quả phi thường: thay vì chỉ khớp mô hình một lần duy nhất trên toàn bộ dữ liệu hiện có, ta tiến hành trích xuất lặp đi lặp lại các tập mẫu con từ tập huấn luyện, khớp mô hình trên từng mẫu con đó, rồi tổng hợp kết quả để thu hoạch những tri thức sâu sắc về độ ổn định, tính bất định và chất lượng dự đoán của mô hình.

Phương pháp lấy lại mẫu thường phục vụ hai nhiệm vụ sống còn trong học máy:

  1. Đánh giá mô hình (Model Assessment): Ước lượng mức sai số kiểm tra (test error) của một mô hình thống kê nhất định để đánh giá năng lực tổng quát hóa thực tế của nó trên các dữ liệu chưa từng thấy.
  2. Lựa chọn mô hình (Model Selection): Tìm kiếm mức độ linh hoạt (flexibility) hoặc độ phức tạp tối ưu cho mô hình (chẳng hạn như chọn bậc đa thức $d$, chọn số láng giềng $K$ trong KNN, hoặc chọn hệ số điều hòa $\lambda$ trong hồi quy Ridge/Lasso).

Trong chương này, chúng ta sẽ đi sâu vào hai phương pháp lấy lại mẫu phổ biến và quan trọng nhất: Kiểm định chéo (Cross-Validation) và Bootstrap.


5.1. Kiểm định Chéo (Cross-Validation)

Như đã phân tích ở Chương 2, sự khác biệt giữa sai số huấn luyện (training error) và sai số kiểm tra (test error) là nguồn cơn của hầu hết mọi bi kịch trong học máy. Sai số huấn luyện được tính trực tiếp trên tập dữ liệu đã dùng để tối ưu hóa tham số mô hình; vì vậy, nó luôn có xu hướng đánh giá quá lạc quan năng lực của thuật toán. Khi mô hình trở nên phức tạp hơn, sai số huấn luyện sẽ giảm đều đặn về 0, trong khi sai số kiểm tra thực tế có thể bùng nổ do hiện tượng quá khớp (overfitting).

Lý tưởng nhất, nếu chúng ta sở hữu một tập dữ liệu kiểm tra độc lập khổng lồ được niêm phong từ trước, ta chỉ việc đưa mô hình vào chạy và đo lường MSE hoặc tỷ lệ lỗi thực tế. Tuy nhiên, trong đại đa số các bài toán thực tiễn, dữ liệu thu thập được là hữu hạn và vô cùng quý giá. Làm thế nào để ước lượng khách quan sai số kiểm tra mà không cần phải hi sinh thêm dữ liệu mới? Kiểm định chéo chính là câu trả lời.


5.1.1. Phương pháp Tập Kiểm định (The Validation Set Approach)

Chiến lược trực diện nhất là phương pháp tập kiểm định (validation set approach). Ta ngẫu nhiên chia $n$ quan sát ban đầu thành hai nửa tách biệt:

  • Tập huấn luyện (Training set): Thường chiếm $50\%$ hoặc $70-80\%$ dữ liệu, dùng để huấn luyện mô hình.
  • Tập kiểm định (Validation set / Hold-out set): Phần dữ liệu còn lại, được giữ kín hoàn toàn trong suốt quá trình huấn luyện.

Sau khi mô hình được khớp trên tập huấn luyện, ta dùng nó để dự đoán các quan sát trong tập kiểm định. Sai số bình phương trung bình trên tập kiểm định ($\text{MSE}_{\text{val}}$) sẽ đóng vai trò là một ước lượng cho sai số kiểm tra thực tế:

$$\text{MSE}_{\text{val}} = \frac{1}{n_{\text{val}}} \sum_{i \in \text{Validation}} (y_i - \hat{y}_i)^2$$

1. Phương pháp Tập Kiểm định (Validation Set) Chia ngẫu nhiên thành 2 phần: Huấn luyện (50-70%) và Kiểm định (30-50%) Tập Huấn luyện (Train ~50%) Kiểm định (Val) • Đơn giản, tính toán 1 lần duy nhất. • Nhược điểm: Phương sai cao, đánh giá quá bi quan. 2. LOOCV (Leave-One-Out, K = n) Mỗi lượt rút đúng 1 quan sát làm kiểm định, lặp n lần 1 Lượt 1 2 Lượt 2 ⋮ ⋮ ⋮ n Lượt n • Độ chệch cực thấp, không ngẫu nhiên. • Chi phí cao, phương sai cao do tương quan mẫu. 3. K-Fold CV (K = 5 hoặc 10) Cân bằng tối ưu Độ chệch & Phương sai Val Train (4/5 dữ liệu) Val Val Val Val ✓ Chuẩn mực vàng trong thống kê thực nghiệm. • Huấn luyện 5 hoặc 10 lần, phương sai thấp. Tập Huấn luyện (Training Set) Tập Kiểm định (Validation Fold) Ước lượng sai số kiểm tra = Trung bình sai số trên các tập kiểm định
Hình 5.1. So sánh ba cơ chế phân vùng mẫu trong đánh giá mô hình. Trái: Tập kiểm định truyền thống (phương sai cao do chia đôi ngẫu nhiên). Giữa: LOOCV (huấn luyện n lần, mỗi lần giữ 1 mẫu). Phải: K-Fold Cross-Validation (K=5 hoặc 10), giải pháp vàng cân bằng hoàn hảo giữa độ chệch và phương sai.
Thực nghiệm trên bộ dữ liệu Auto

Xét bài toán hồi quy dự đoán mức tiêu thụ nhiên liệu (mpg) dựa trên công suất động cơ (horsepower) trong tập dữ liệu Auto gồm 392 chiếc xe hơi. Ta muốn so sánh các mô hình đa thức từ bậc 1 (tuyến tính) đến bậc 10.

  • Chia ngẫu nhiên 392 xe thành hai phần bằng nhau: 196 xe cho tập huấn luyện và 196 xe cho tập kiểm định.
  • Kết quả tính toán cho thấy: mô hình bậc 1 cho $\text{MSE}_{\text{val}} \approx 24.0$, mô hình bậc 2 giảm ngoạn mục xuống $\approx 19.3$. Tuy nhiên, khi tăng tiếp lên bậc 3 hay bậc 4, $\text{MSE}_{\text{val}}$ dao động nhẹ quanh mức $19.3 - 19.4$ mà không giảm thêm. Điều này khẳng định quy luật thực sự có dạng bậc hai (quadratic) và việc thêm các bậc cao hơn là không cần thiết.
Hai nhược điểm chí mạng của Tập Kiểm định:
  1. Phương sai ước lượng rất cao (High variability): Ước lượng sai số phụ thuộc nặng nề vào việc những điểm dữ liệu nào may mắn rơi vào tập huấn luyện và điểm nào rơi vào tập kiểm định. Nếu ta lặp lại phép chia ngẫu nhiên 10 lần khác nhau, ta sẽ thu được 10 đường cong sai số kiểm tra phân kỳ mạnh mẽ, đôi khi đưa ra những gợi ý mâu thuẫn về bậc tối ưu của mô hình.
  2. Đánh giá quá bi quan về sai số thực (Overestimation of test error): Các phương pháp học thống kê thường hoạt động kém đi khi được huấn luyện trên ít dữ liệu hơn. Vì ta chỉ sử dụng một phần nhỏ dữ liệu (ví dụ 50%) để huấn luyện, mô hình được khớp sẽ kém chính xác hơn so với khi được huấn luyện trên toàn bộ $n$ quan sát. Do đó, $\text{MSE}_{\text{val}}$ thường có xu hướng thổi phồng sai số kiểm tra thực tế của mô hình cuối cùng.

5.1.2. Kiểm định Chéo Rút một (Leave-One-Out Cross-Validation - LOOCV)

Nhằm khắc phục triệt để hai điểm yếu trên của phương pháp tập kiểm định, LOOCV ra đời. Thay vì chia đôi tập dữ liệu, LOOCV thực hiện một quy trình chia tách cực hạn:

  • Giữ lại đúng 1 quan sát duy nhất $(x_1, y_1)$ làm tập kiểm định.
  • Dùng toàn bộ $n - 1$ quan sát còn lại $\{(x_2, y_2), \dots, (x_n, y_n)\}$ làm tập huấn luyện để khớp mô hình.
  • Dự đoán giá trị cho quan sát bị giữ lại: $\hat{y}_1$. Sai số của quan sát này là $\text{MSE}_1 = (y_1 - \hat{y}_1)^2$.
  • Lặp lại quy trình này $n$ lần cho từng quan sát $i = 1, 2, \dots, n$. Mỗi lần, quan sát thứ $i$ được giữ làm kiểm định và $n-1$ quan sát kia dùng để huấn luyện.

Ước lượng sai số kiểm tra của LOOCV là trung bình cộng của $n$ sai số kiểm định đơn lẻ:

$$\text{CV}_{(n)} = \frac{1}{n} \sum_{i=1}^n \text{MSE}_i = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2$$

Những ưu điểm vượt trội của LOOCV:
  • Độ chệch (Bias) cực thấp: Ở mỗi lượt lặp, mô hình được huấn luyện trên $n - 1$ quan sát, gần như tương đương với toàn bộ tập dữ liệu gốc. Vì vậy, LOOCV hầu như không đánh giá quá cao sai số kiểm tra thực tế.
  • Tính tất định tuyệt đối: Không có bất kỳ yếu tố ngẫu nhiên nào trong việc phân chia dữ liệu. Dù bạn chạy thuật toán bao nhiêu lần, kết quả LOOCV luôn hoàn toàn giống nhau.

Công thức Kỳ diệu: Tính LOOCV cho Hồi quy OLS trong Nháy mắt

Nhược điểm lớn nhất của LOOCV là chi phí tính toán: nếu mô hình mất 1 giây để khớp và $n = 100{,}000$, bạn sẽ phải chờ hơn 27 tiếng đồng hồ để hoàn thành $n$ lần lặp! Tuy nhiên, đối với mô hình hồi quy tuyến tính bình phương tối thiểu (OLS), có một định lý toán học tuyệt đẹp cho phép ta tính chính xác giá trị LOOCV chỉ sau đúng 1 lần khớp duy nhất trên toàn bộ dữ liệu:

$$\text{CV}_{(n)} = \frac{1}{n} \sum_{i=1}^n \left( \frac{y_i - \hat{y}_i}{1 - h_i} \right)^2$$

Trong đó $\hat{y}_i$ là giá trị dự đoán từ mô hình OLS khớp trên toàn bộ $n$ quan sát, và $h_i$ là độ đòn bẩy (leverage) của quan sát thứ $i$, chính là phần tử thứ $i$ trên đường chéo chính của ma trận mũ (hat matrix) $\mathbf{H} = \mathbf{X}(\mathbf{X}^T \mathbf{X})^{-1}\mathbf{X}^T$:

$$h_i = \frac{1}{n} + \frac{(x_i - \bar{x})^2}{\sum_{j=1}^n (x_j - \bar{x})^2}$$

Vì $h_i$ nằm trong khoảng $[1/n, 1]$, mẫu số $1 - h_i$ sẽ co giãn phần dư $e_i = y_i - \hat{y}_i$. Điểm dữ liệu nào có đòn bẩy càng cao ($h_i$ lớn, tức nằm xa trung tâm), thì khi rút nó ra khỏi mô hình, dự đoán cho chính nó sẽ lệch đi càng mạnh, phản ánh chính xác tác động của việc bỏ mẫu mà không cần chạy lại hồi quy!


5.1.3. Kiểm định Chéo $K$-Phần ($K$-Fold Cross-Validation)

Mặc dù công thức rút gọn trên giải quyết được bài toán OLS, phần lớn các mô hình học máy hiện đại (Logistic regression, Cây quyết định, SVM, Mạng nơ-ron) không có công thức giải tích đóng như vậy. Khi đó, LOOCV trở nên cực kỳ đắt đỏ về mặt tính toán.

$K$-fold Cross-Validation là giải pháp cân bằng toàn diện:

  1. Chia ngẫu nhiên tập dữ liệu thành $K$ phần (folds) có kích thước xấp xỉ bằng nhau: $C_1, C_2, \dots, C_K$.
  2. Ở mỗi lượt $k \in \{1, \dots, K\}$:

    • Giữ lại phần thứ $k$ ($C_k$) làm tập kiểm định.
    • Dùng toàn bộ $K - 1$ phần còn lại làm tập huấn luyện để khớp mô hình.
    • Tính sai số bình phương trung bình trên phần bị giữ lại: $$\text{MSE}_k = \frac{1}{n_k} \sum_{i \in C_k} (y_i - \hat{y}_i)^2$$
  3. Ước lượng sai số kiểm định chéo $K$-fold là trung bình của $K$ sai số kiểm định:

$$\text{CV}_{(K)} = \frac{1}{K} \sum_{k=1}^K \text{MSE}_k$$

Trong thực tế, người ta thường chọn $K = 5$ hoặc $K = 10$. Hãy chú ý rằng LOOCV thực chất là một trường hợp đặc biệt của $K$-fold khi ta đặt $K = n$.

Phòng thí nghiệm C
K-Fold Cross-Validation vs Bootstrap (Mô phỏng Phân vùng & Lấy lại Mẫu)
Chuyển chế độ K-Fold / Bootstrap để quan sát phân vùng mẫu và sai số ước lượng
Sơ đồ phân vùng mẫu: Xanh dương = Huấn luyện (Train), Vàng/Đỏ = Kiểm định (Validation / OOB)
Kết quả: Phân phối sai số các Fold (K-Fold) hoặc Phân phối Bootstrap α̂* (Bootstrap)
5
K = 5 hoặc 10 là chuẩn mực cân bằng giữa độ chệch và phương sai.
40
Số lượng điểm dữ liệu quan sát ban đầu.
0.35
Độ biến thiên ngẫu nhiên của môi trường thực nghiệm.
Chế độK-Fold (K=5)
CV MSE / ᾱ*0.00
Phương sai / SE0.00
Tỷ lệ OOB / Val20.0%
Diễn giải

Trong chế độ K-Fold CV: Toàn bộ n quan sát được chia thành K phần đều nhau. Mỗi lượt chạy, 1 phần đóng vai trò làm tập kiểm định (vàng) và K-1 phần còn lại dùng để huấn luyện (xanh). Khi chuyển sang Bootstrap, ta lấy mẫu có hoàn lại: trung bình khoảng 36.8% mẫu sẽ bị bỏ rơi ngoài túi (Out-of-Bag - OOB)!

Việc cần làm: ① Ở chế độ K-Fold CV: Kéo thanh trượt K từ 2 lên 5 rồi 10 để thấy kích thước tập kiểm định thu nhỏ dần và mô hình học được nhiều dữ liệu hơn ở mỗi fold. ② Bấm chuyển sang tab Bootstrap: Hãy nhìn các ô màu xanh lặp lại và các ô màu đỏ ngoài túi (OOB). Tỷ lệ OOB thực nghiệm luôn dao động sát mốc ~36.8% lý thuyết ($1/e$). ③ Bấm ⚡ Chạy mô phỏng: Biểu đồ dưới sẽ mô phỏng hàng trăm lượt lấy mẫu bootstrap để vẽ nên phân phối hình chuông tuyệt đẹp của ước lượng thống kê mà không cần bất kỳ giả định toán học cổ điển nào!


5.1.4. Sự Đánh đổi Độ chệch - Phương sai trong Kiểm định Chéo

Nhiều người thường lầm tưởng rằng vì LOOCV sử dụng $n-1$ mẫu để huấn luyện ở mỗi lượt (độ chệch thấp nhất), nên nó đương nhiên vượt trội hơn $K$-fold CV ($K=5$ hoặc $10$). Tuy nhiên, đây là một ngộ nhận sâu sắc liên quan đến sự đánh đổi giữa Độ chệch (Bias) và Phương sai (Variance) của chính ước lượng sai số.

Tiêu chí LOOCV ($K = n$) $K$-fold CV ($K = 5$ hoặc $10$)
Độ chệch (Bias) Cực thấp (mỗi mô hình học trên $n-1$ điểm) Hơi chệch nhẹ (học trên $\approx 80-90\%$ điểm)
Phương sai (Variance) Rất cao Thấp hơn đáng kể
Chi phí tính toán $O(n)$ lần khớp (rất nặng nếu không có shortcut) $O(K)$ lần khớp (rất nhanh, thường chỉ 5–10 lần)

Cạm bẫy Thống kê: Tại sao LOOCV lại có Phương sai Cao hơn $K$-Fold?

Hãy xem xét bản chất của phép tính trung bình. Phương sai của tổng hai biến ngẫu nhiên là:

$$\text{Var}(A + B) = \text{Var}(A) + \text{Var}(B) + 2\text{Cov}(A, B)$$

Trong LOOCV, ta lấy trung bình của $n$ ước lượng $\text{MSE}_i$. Nhưng mỗi mô hình trong số $n$ mô hình đó được huấn luyện trên những tập dữ liệu gần như trùng khớp hoàn toàn (chúng chia sẻ chung $n - 2$ quan sát!). Do đó, các giá trị $\text{MSE}_i$ có hệ số tương quan dương cực kỳ cao với nhau. Khi lấy trung bình của nhiều đại lượng tương quan thuận mạnh mẽ, phương sai của trung bình mẫu không thể triệt tiêu hiệu quả.

Ngược lại, trong 10-fold CV, mỗi mô hình chỉ chia sẻ một lượng vừa phải dữ liệu huấn luyện, khiến các ước lượng $\text{MSE}_k$ ít tương quan với nhau hơn nhiều. Kết quả là ước lượng tổng hợp $\text{CV}_{(10)}$ có phương sai thấp hơn, ổn định hơn và đáng tin cậy hơn trên thực tế. Vì vậy, $K=5$ hoặc $K=10$ là chuẩn mực vàng trong mọi bài toán thực nghiệm.


5.1.5. Kiểm định Chéo trong Bài toán Phân loại

Khi biến phản hồi $Y$ mang tính định tính (phân loại), nguyên lý của Cross-Validation hoàn toàn không thay đổi, chỉ có công thức đo lường sai số được chuyển từ MSE sang tỷ lệ lỗi phân loại (error rate).

Ở fold thứ $k$, tỷ lệ lỗi trên tập kiểm định $C_k$ được tính bằng:

$$\text{Err}_k = \frac{1}{n_k} \sum_{i \in C_k} I(y_i \neq \hat{y}_i)$$

Trong đó $I(\cdot)$ là biến chỉ thị (nhận giá trị 1 nếu phân loại sai, và 0 nếu phân loại đúng). Ước lượng $K$-fold CV tổng thể là:

$$\text{CV}_{(K)} = \frac{1}{K} \sum_{k=1}^K \text{Err}_k$$

Nếu bài toán quan tâm tới xác suất dự đoán (ví dụ dùng Logistic Regression), ta cũng có thể thay tỷ lệ lỗi bằng hàm mất mát Cross-Entropy (hoặc Negative Log-Likelihood).


5.2. Kỹ thuật Bootstrap

Được phát minh bởi nhà thống kê lừng danh Bradley Efron vào năm 1979, Bootstrap là một cuộc cách mạng trong thống kê máy tính. Phương pháp này cho phép ta định lượng mức độ bất định (tính sai số chuẩn $\text{SE}$ và xây dựng khoảng tin cậy) của bất kỳ ước lượng thống kê nào mà không cần dựa vào các giả định phân phối toán học phức tạp.

Dữ liệu Gốc (n = 6) 1 2 3 4 5 6 Mỗi quan sát độc nhất 1 lần Lấy mẫu có hoàn lại (with replacement) Mẫu Bootstrap 1: 2 2* 4 5 5* 6 Mẫu ngoài túi (OOB): {1, 3} (33.3%) → α̂*¹ = 0.58 Mẫu Bootstrap 2: 1 3 3* 4 6 6* Mẫu ngoài túi (OOB): {2, 5} (33.3%) → α̂*² = 0.61 ⋮ Lặp B = 1000 lần ⋮ Mẫu Bootstrap B: [Lấy n mẫu ngẫu nhiên...] → α̂*ᴮ = 0.59 Ước lượng SE_B(α̂) SE_B = Độ lệch chuẩn của {α̂*¹, α̂*², ..., α̂*ᴮ}
Hình 5.2. Cơ chế lấy mẫu lặp lại có hoàn lại của Bootstrap. Từ n điểm ban đầu, ta rút n phần tử để tạo thành mỗi mẫu bootstrap. Trung bình 63.2% quan sát xuất hiện (các số có dấu * là lặp lại) và 36.8% quan sát bị bỏ rơi làm tập ngoài túi (OOB). Phân phối của các ước lượng bootstrap cho phép tính sai số chuẩn và khoảng tin cậy phi tham số.

5.2.1. Động lực: Bài toán Tối ưu hóa Danh mục Đầu tư

Giả sử ta muốn phân bổ vốn vào hai tài sản tài chính có lợi suất ngẫu nhiên là $X$ và $Y$, với phương sai lần lượt là $\sigma_X^2$, $\sigma_Y^2$ và hiệp phương sai $\sigma_{XY} = \text{Cov}(X, Y)$. Ta đầu tư tỷ trọng $\alpha$ vào $X$ và $(1 - \alpha)$ vào $Y$. Tổng rủi ro (phương sai danh mục) là:

$$\text{Var}(\alpha X + (1 - \alpha) Y) = \alpha^2 \sigma_X^2 + (1 - \alpha)^2 \sigma_Y^2 + 2\alpha(1 - \alpha)\sigma_{XY}$$

Bằng phép đạo hàm tìm cực tiểu, tỷ trọng tối ưu $\alpha$ giúp giảm thiểu rủi ro tuyệt đối là:

$$\alpha = \frac{\sigma_Y^2 - \sigma_{XY}}{\sigma_X^2 + \sigma_Y^2 - 2\sigma_{XY}}$$

Trong thực tế, các tham số dân số $\sigma_X^2, \sigma_Y^2, \sigma_{XY}$ không hề được biết trước. Ta chỉ có một mẫu dữ liệu lịch sử gồm $n$ cặp quan sát và phải ước lượng $\hat{\alpha}$ thông qua các phương sai mẫu $\hat{\sigma}_X^2, \hat{\sigma}_Y^2, \hat{\sigma}_{XY}$. Câu hỏi đặt ra là: Sai số chuẩn $\text{SE}(\hat{\alpha})$ của ước lượng này bằng bao nhiêu? Do công thức của $\alpha$ là một hàm phi tuyến phức tạp của ba đại lượng mẫu, việc tìm công thức giải tích cho sai số chuẩn theo lý thuyết thống kê cổ điển là vô cùng hóc búa.


5.2.2. Cơ chế Hoạt động của Bootstrap

Nếu ta có thể tiếp tục thu thập thêm hàng nghìn tập dữ liệu độc lập khác từ thế giới thực, việc tính $\text{SE}(\hat{\alpha})$ sẽ rất đơn giản: chỉ cần tính $\hat{\alpha}$ trên từng tập và tính độ lệch chuẩn của chúng. Nhưng thực tế ta chỉ có duy nhất một tập dữ liệu ban đầu gồm $n$ quan sát $\mathbf{Z} = \{z_1, z_2, \dots, z_n\}$.

Bootstrap giải quyết nghịch lý này bằng cách coi chính tập dữ liệu gốc $\mathbf{Z}$ như một "tiểu vũ trụ dân số":

  1. Lấy mẫu có hoàn lại (Sampling with replacement): Từ tập $\mathbf{Z}$ kích thước $n$, ta rút ngẫu nhiên $n$ quan sát để tạo thành một tập dữ liệu bootstrap $\mathbf{Z}^{*1}$. Vì có hoàn lại, một số quan sát ban đầu có thể xuất hiện nhiều lần, trong khi một số quan sát khác hoàn toàn vắng mặt.
  2. Tính toán ước lượng thống kê trên tập bootstrap này: $\hat{\alpha}^{*1}$.
  3. Lặp lại bước 1 và 2 một số lượng lớn $B$ lần (thường chọn $B = 1{,}000$ đến $2{,}000$), thu được một chuỗi các ước lượng bootstrap: $\hat{\alpha}^{*1}, \hat{\alpha}^{*2}, \dots, \hat{\alpha}^{*B}$.
  4. Ước lượng sai số chuẩn Bootstrap chính là độ lệch chuẩn mẫu của $B$ ước lượng này:

$$\text{SE}_B(\hat{\alpha}) = \sqrt{\frac{1}{B - 1} \sum_{r=1}^B \left( \hat{\alpha}^{*r} - \bar{\alpha}^* \right)^2}, \quad \text{với } \bar{\alpha}^* = \frac{1}{B} \sum_{r=1}^B \hat{\alpha}^{*r}$$


5.2.3. Định lý Mẫu Ngoài Túi (Out-of-Bag - OOB) và Con số Kỳ diệu 63.2%

Mỗi tập mẫu bootstrap có kích thước đúng bằng $n$. Vậy xác suất để một quan sát thứ $j$ cụ thể từ tập dữ liệu gốc không được chọn vào mẫu bootstrap là bao nhiêu?

  • Ở mỗi lần rút ngẫu nhiên 1 điểm từ $n$ điểm, xác suất chọn phải điểm thứ $j$ là $1/n$.
  • Do đó, xác suất không chọn phải điểm thứ $j$ trong một lần rút là $1 - 1/n$.
  • Vì các lần rút là độc lập có hoàn lại, xác suất để điểm thứ $j$ vắng mặt trong toàn bộ cả $n$ lần rút là:

$$P(\text{Quan sát } j \text{ không nằm trong mẫu}) = \left( 1 - \frac{1}{n} \right)^n$$

Khi kích thước mẫu $n$ tăng lên, theo định nghĩa giới hạn kinh điển của hằng số toán học $e$:

$$\lim_{n \to \infty} \left( 1 - \frac{1}{n} \right)^n = e^{-1} = \frac{1}{e} \approx 0.367879 \dots \approx 36.8\%$$

Quy luật 63.2% và Mẫu Out-of-Bag (OOB)

Trung bình, trong bất kỳ mẫu bootstrap nào:

  • Khoảng 63.2% các quan sát độc nhất của tập dữ liệu gốc sẽ xuất hiện (một số điểm lặp lại 2, 3 lần).
  • Khoảng 36.8% các quan sát hoàn toàn không được chọn. Những điểm bị bỏ rơi này được gọi là quan sát ngoài túi (Out-of-Bag observations - OOB).

Tính chất toán học tuyệt đẹp này đóng vai trò sống còn trong thuật toán Random Forests và Bagging (sẽ học ở Chương 8), nơi các mẫu OOB đóng vai trò như một tập kiểm định tự nhiên miễn phí mà không cần phải thực hiện kiểm định chéo riêng biệt!


5.3. Thực Hành Python: Cross-Validation và Bootstrap

Dưới đây là mã nguồn Python chuẩn mực minh họa kiểm định chéo (LOOCV, $K$-Fold) và kỹ thuật Bootstrap trên các bộ dữ liệu kinh điển.

import numpy as np
import pandas as pd
from sklearn.model_selection import KFold, LeaveOneOut, cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline

# 1. TẢI DỮ LIỆU AUTO VÀ CHUẨN BỊ
url = "https://raw.githubusercontent.com/intro-stat-learning/ISLP_labs/v2/Auto.csv"
auto = pd.read_csv(url).dropna()
X = auto[['horsepower']].values
y = auto['mpg'].values
n = len(y)

# 2. SO SÁNH CÁC BẬC ĐA THỨC BẰNG 10-FOLD CROSS-VALIDATION
print("=== K-FOLD CV (K = 10) ĐÁNH GIÁ ĐA THỨC BẬC 1 ĐẾN 4 ===")
kf = KFold(n_splits=10, shuffle=True, random_state=42)

for degree in range(1, 5):
    poly_model = make_pipeline(PolynomialFeatures(degree), LinearRegression())
    # cross_val_score mặc định trả về negative MSE
    scores = cross_val_score(poly_model, X, y, cv=kf, scoring='neg_mean_squared_error')
    mse_cv = -scores.mean()
    print(f"Đa thức bậc {degree}: CV MSE = {mse_cv:.3f}")

# 3. LEAVE-ONE-OUT CROSS-VALIDATION (LOOCV)
print("\n=== LEAVE-ONE-OUT CROSS-VALIDATION (LOOCV) ===")
loo = LeaveOneOut()
for degree in [1, 2]:
    poly_model = make_pipeline(PolynomialFeatures(degree), LinearRegression())
    scores = cross_val_score(poly_model, X, y, cv=loo, scoring='neg_mean_squared_error')
    print(f"Đa thức bậc {degree}: LOOCV MSE = {-scores.mean():.3f}")

# 4. KỸ THUẬT BOOTSTRAP: TÍNH SAI SỐ CHUẨN CHO BÀI TOÁN DANH MỤC ĐẦU TƯ
print("\n=== ƯỚC LƯỢNG BOOTSTRAP TỶ TRỌNG ĐẦU TƯ ALPHA ===")
np.random.seed(42)

def compute_alpha(data_indices):
    """Tính alpha tối ưu từ các chỉ số mẫu được chọn"""
    sample = auto.iloc[data_indices]
    X_var = np.var(sample['horsepower'], ddof=1)
    Y_var = np.var(sample['mpg'], ddof=1)
    cov_XY = np.cov(sample['horsepower'], sample['mpg'])[0, 1]
    return (Y_var - cov_XY) / (X_var + Y_var - 2 * cov_XY)

B = 1000
boot_alphas = np.zeros(B)
for b in range(B):
    indices = np.random.choice(n, size=n, replace=True)
    boot_alphas[b] = compute_alpha(indices)

se_boot = np.std(boot_alphas, ddof=1)
alpha_hat = compute_alpha(np.arange(n))
ci_lower, ci_upper = np.percentile(boot_alphas, [2.5, 97.5])

print(f"Alpha ước lượng ban đầu: {alpha_hat:.4f}")
print(f"Sai số chuẩn Bootstrap SE_B(alpha): {se_boot:.4f}")
print(f"Khoảng tin cậy 95% Bootstrap: [{ci_lower:.4f}, {ci_upper:.4f}]")

5.4. Tóm Tắt Trực Quan Các Phương Pháp Lấy Lại Mẫu

Phương pháp Lấy Lại Mẫu (Resampling)
 ├── 1. Kiểm định Chéo (Cross-Validation)
 │     ├── Validation Set: Đơn giản, nhưng Phương sai cao & Đánh giá quá bi quan
 │     ├── LOOCV (K = n): Độ chệch tối thiểu, nhưng Phương sai cao do tương quan mẫu
 │     └── K-Fold (K = 5 hoặc 10): Cân bằng hoàn hảo Độ chệch - Phương sai (Chuẩn mực thực tế)
 └── 2. Bootstrap (Lấy mẫu có hoàn lại)
       ├── Ước lượng Sai số chuẩn (SE) & Khoảng tin cậy phi tham số
       └── Định lý Mẫu Ngoài Túi (Out-of-Bag): 63.2% trong túi / 36.8% OOB

06Chương 6: Lựa Chọn Mô Hình và Điều Hòa (Model Selection and Regularization)

Mô hình tuyến tính cổ điển:

$$Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_p X_p + \epsilon$$

được coi là "ngựa thồ" của ngành thống kê trong suốt nhiều thế kỷ nhờ tính minh bạch, dễ ước lượng bằng phương pháp bình phương tối thiểu (OLS) và khả năng diễn giải nhân quả rõ ràng. Tuy nhiên, trong kỷ nguyên dữ liệu lớn và học máy hiện đại, OLS bộc lộ hai điểm nghẽn nghiêm trọng:

  1. Độ chính xác dự đoán (Prediction Accuracy):

    • Khi số lượng quan sát $n$ vượt trội hơn rất nhiều so với số lượng biến $p$ ($n \gg p$), ước lượng OLS có độ chệch thấp và phương sai nhỏ, mang lại chất lượng dự đoán xuất sắc.
    • Nhưng khi $n$ chỉ nhỉnh hơn $p$ một chút, ước lượng OLS sẽ có phương sai bùng nổ, dẫn đến hiện tượng quá khớp (overfitting) trầm trọng.
    • Đặc biệt, khi số biến vượt quá số mẫu ($p > n$), ma trận hiệp phương sai mẫu không khả đảo, OLS hoàn toàn sụp đổ: tồn tại vô số nghiệm làm cho $\text{RSS} = 0$ trên tập huấn luyện nhưng sai số kiểm tra thực tế lại tiến tới vô cùng!
  2. Khả năng diễn giải mô hình (Model Interpretability):

    • Thường chỉ có một nhóm nhỏ các biến thực sự có liên hệ hữu cơ với biến phản hồi $Y$.
    • OLS hầu như không bao giờ ước lượng bất kỳ hệ số nào bằng đúng 0 tuyệt đối. Giữ lại hàng chục biến gây nhiễu vô giá trị khiến mô hình trở nên rối rắm, biến việc diễn giải cơ chế vận hành thành nhiệm vụ bất khả thi.

Để khắc phục những hạn chế này, Chương 6 giới thiệu ba nhóm phương pháp mở rộng hiện đại cho mô hình tuyến tính:

  • Lựa chọn tập con (Subset Selection): Tìm kiếm tập con tối ưu các biến độc lập và khớp OLS trên tập con đó.
  • Phương pháp co rút / Điều hòa (Shrinkage / Regularization): Khớp mô hình trên toàn bộ $p$ biến nhưng ép các hệ số $\beta_j$ co lại về phía 0 (Ridge và Lasso), giúp giảm mạnh phương sai và tự động lọc biến.
  • Phương pháp giảm chiều (Dimension Reduction): Chiếu $p$ biến ban đầu lên một không gian con $M$ chiều ($M < p$) thông qua các tổ hợp tuyến tính (PCR và PLS).

6.1. Lựa Chọn Tập Con (Subset Selection)

Ý tưởng trực giác nhất để đơn giản hóa mô hình là loại bỏ các biến không cần thiết.

6.1.1. Lựa chọn Tập con Tốt nhất (Best Subset Selection)

Thuật toán lựa chọn tập con tốt nhất tiến hành quét vét cạn toàn bộ các không gian mô hình khả dĩ:

Thuật toán: Best Subset Selection

  1. Gọi $\mathcal{M}_0$ là mô hình rỗng (null model), chỉ chứa hệ số chặn $\beta_0$, dự đoán mọi quan sát bằng giá trị trung bình mẫu $\bar{y}$.
  2. Với mỗi kích thước $k = 1, 2, \dots, p$:
    • Khớp tất cả $\binom{p}{k} = \frac{p!}{k!(p-k)!}$ mô hình chứa đúng $k$ biến dự đoán.
    • Chọn ra mô hình tốt nhất trong số đó, ký hiệu là $\mathcal{M}_k$, định nghĩa là mô hình có RSS nhỏ nhất (hoặc $R^2$ lớn nhất) trên tập huấn luyện.
  3. Ta thu được một chuỗi $p + 1$ mô hình ứng viên: $\mathcal{M}_0, \mathcal{M}_1, \dots, \mathcal{M}_p$. Chọn ra duy nhất một mô hình tối ưu từ danh sách này bằng cách sử dụng sai số kiểm định chéo (Cross-Validation) hoặc các chỉ số hiệu chỉnh như $C_p$, AIC, BIC, hay Adjusted $R^2$.
Best Subset Selection: Duyệt Toàn bộ 2ᵖ k = 0: 1 mô hình (M₀) k = 1: p mô hình k = 2: p(p-1)/2 mô hình ⋮ ⋮ ⋮ (Bùng nổ tổ hợp) k = p/2: Số mô hình cực đại! (hàng tỷ mô hình) p = 40 → hơn 1,000,000,000,000 mô hình (bất khả thi!) Forward Stepwise: 1 + p(p+1)/2 Mô hình M₀ +biến tốt nhất M₁ +biến tiếp theo M₂ Mₚ Ưu điểm vượt trội: • Với p = 40: Chỉ cần khớp đúng 821 mô hình (chạy trong 1 giây). Chạy được cả khi p > n (dừng ở bước n - 1)
Hình 6.1. So sánh không gian tìm kiếm giữa Best Subset Selection (quét toàn bộ 2ᵖ mô hình, bùng nổ tổ hợp khi p lớn) và Forward Stepwise Selection (tiếp cận tham lam, chỉ khớp 1 + p(p+1)/2 mô hình, khả thi trong dữ liệu thực tế lớn).
Cạm bẫy Bùng nổ Tổ hợp (Combinatorial Explosion):

Tổng số mô hình cần phải khớp trong Best Subset Selection là:

$$\sum_{k=0}^p \binom{p}{k} = 2^p$$

  • Với $p = 10$: $2^{10} = 1{,}024$ mô hình (máy tính tính trong 0.1 giây).
  • Với $p = 20$: $2^{20} = 1{,}048{,}576$ mô hình (mất vài phút).
  • Với $p = 40$: $2^{40} \approx 1.1 \times 10^{12}$ mô hình (hơn một nghìn tỷ mô hình, bất khả thi đối với cả siêu máy tính!).

Bên cạnh gánh nặng tính toán, việc tìm kiếm trên một không gian $2^p$ mô hình khổng lồ còn dễ dẫn tới quá khớp mô hình cấp cao (meta-overfitting): thuật toán sẽ vô tình nhặt phải những biến hoàn toàn vô nghĩa nhưng do ngẫu nhiên lại khớp quá đẹp trên tập mẫu cụ thể.


6.1.2. Lựa chọn Từng bước (Stepwise Selection)

Để vượt qua rào cản tính toán của Best Subset, các thuật toán tham lam (greedy heuristics) được áp dụng.

1. Chọn tiến từng bước (Forward Stepwise Selection)
  • Bắt đầu từ mô hình rỗng $\mathcal{M}_0$.
  • Ở mỗi bước $k$, thuật toán xem xét $p - k$ biến chưa có mặt trong mô hình, thử thêm từng biến một vào và chọn biến nào giúp giảm RSS nhiều nhất để tạo thành $\mathcal{M}_{k+1}$.
  • Tổng số mô hình cần khớp chỉ là: $$1 + \sum_{k=0}^{p-1} (p - k) = 1 + \frac{p(p+1)}{2}$$ Với $p = 40$, số mô hình giảm từ $10^{12}$ xuống chỉ còn 821 mô hình!

  • Ưu điểm lớn: Có thể chạy được ngay cả khi $p > n$ (thuật toán sẽ dừng ở bước thứ $n-1$).

2. Chọn lùi từng bước (Backward Stepwise Selection)
  • Bắt đầu từ mô hình đầy đủ $\mathcal{M}_p$ chứa tất cả $p$ biến.
  • Ở mỗi bước, loại bỏ biến "vô dụng nhất" (biến có $p$-value lớn nhất hoặc khi bỏ đi làm tăng RSS ít nhất).
  • Hạn chế chí mạng: Bắt buộc $n > p$. Nếu $p \ge n$, mô hình ban đầu không thể khớp được bằng OLS nên Backward Stepwise hoàn toàn bất lực.
3. Phương pháp Lai (Hybrid Stepwise Selection)

Kết hợp cả hai chiều: sau mỗi lần thêm một biến mới như Forward, thuật toán kiểm tra lại xem có biến nào đã thêm từ trước trở nên dư thừa do tương quan hay không để loại bỏ (tương tự như kiểm tra Backward).


6.1.3. Lựa chọn Mô hình Tối ưu: Phạt Gián tiếp vs Kiểm định Trực tiếp

Tại sao ta không thể dùng trực tiếp $\text{RSS}$ hay $R^2$ huấn luyện để chọn kích thước $k$ giữa các mô hình $\mathcal{M}_0, \mathcal{M}_1, \dots, \mathcal{M}_p$? Bởi vì trên tập huấn luyện, $\text{RSS}$ luôn giảm đơn điệu và $R^2$ luôn tăng khi thêm biến, điều này sẽ luôn luôn thiên vị mô hình cồng kềnh nhất $\mathcal{M}_p$.

Để ước lượng sai số kiểm tra thực tế, ta có hai trường phái:

Trường phái 1: Điều chỉnh Sai số Huấn luyện bằng Hệ số Phạt

Các nhà thống kê điều chỉnh $\text{RSS}_{\text{train}}$ bằng cách cộng thêm một lượng phạt tương ứng với số tham số $d$:

  1. Tiêu chuẩn $C_p$ của Mallows: $$C_p = \frac{1}{n} \left( \text{RSS} + 2d\hat{\sigma}^2 \right)$$ Trong đó $d$ là số biến trong mô hình, và $\hat{\sigma}^2$ là ước lượng phương sai của sai số $\epsilon$ từ mô hình đầy đủ. Giá trị $C_p$ càng nhỏ, mô hình càng tốt. Hệ số phạt $2d\hat{\sigma}^2$ bù trừ chính xác cho sự lạc quan của RSS huấn luyện.

  2. Tiêu chuẩn Thông tin Akaike (AIC): Dành cho các mô hình ước lượng bằng hợp lý cực đại (Maximum Likelihood): $$\text{AIC} = -2\log L + 2d$$ Đối với hồi quy tuyến tính OLS với sai số chuẩn, AIC tỷ lệ thuận với $C_p$: $\text{AIC} = \frac{1}{n\hat{\sigma}^2} (\text{RSS} + 2d\hat{\sigma}^2)$.

  3. Tiêu chuẩn Thông tin Bayes (BIC): Xuất phát từ góc nhìn xác suất hậu nghiệm Bayes: $$\text{BIC} = \frac{1}{n} \left( \text{RSS} + \log(n)d\hat{\sigma}^2 \right)$$ Vì với mọi $n \ge 8$ thì $\log(n) > 2$, hệ số phạt của BIC nặng hơn rất nhiều so với hệ số phạt $2d$ của $C_p$/AIC. Do đó, BIC luôn có xu hướng chọn mô hình ít biến hơn, đơn giản hơn.

  4. Hệ số Xác định Hiệu chỉnh (Adjusted $R^2$): $$\text{Adjusted } R^2 = 1 - \frac{\text{RSS} / (n - d - 1)}{\text{TSS} / (n - 1)}$$ Khác với các tiêu chí trên, ta tìm mô hình có Adjusted $R^2$ lớn nhất.

Trường phái 2: Đánh giá Trực tiếp bằng Cross-Validation và Quy tắc 1-SE

Sử dụng $K$-fold CV để tính trực tiếp $\text{CV}_{(K)}$ cho từng mô hình $\mathcal{M}_k$.

  • Ưu điểm: Hoàn toàn không cần giả định phân phối, không cần ước lượng $\hat{\sigma}^2$, áp dụng được cả khi $p > n$.
  • Quy tắc Một Độ lệch Chuẩn (One-Standard-Error Rule): Tìm mô hình có sai số CV thấp nhất. Sau đó, tính khoảng sai số chuẩn của ước lượng đó: $\text{SE}(\text{CV}_{\min})$. Ta chọn mô hình đơn giản nhất (ít biến nhất) có giá trị CV nằm trong phạm vi 1 độ lệch chuẩn tính từ đáy sai số: $$\text{CV}_k \le \text{CV}_{\min} + \text{SE}(\text{CV}_{\min})$$ Triết lý này bảo vệ ta khỏi việc chọn thêm các biến phụ chỉ để giảm sai số một lượng không đáng kể.

6.2. Các Phương Pháp Co Rút (Shrinkage Methods)

Thay vì loại bỏ dứt khoát biến số theo kiểu "được ăn cả, ngã về không" như Subset Selection (vốn là một quá trình gián đoạn và có phương sai cao), các phương pháp co rút (shrinkage / regularization) giữ lại tất cả các biến nhưng đưa vào một ràng buộc toán học để ép các hệ số hồi quy co dần về 0.

Hai phương pháp điều hòa trụ cột là Hồi quy Ridge ($L_2$) và Hồi quy Lasso ($L_1$).


6.2.1. Hồi quy Ridge ($L_2$ Regularization)

Hồi quy Ridge ước lượng các hệ số $\beta$ bằng cách giải bài toán cực tiểu hóa hàm mất mát gồm tổng bình phương phần dư cộng với một đại lượng phạt co rút bình phương:

$$\min_{\beta} \left\{ \sum_{i=1}^n \left( y_i - \beta_0 - \sum_{j=1}^p \beta_j x_{ij} \right)^2 + \lambda \sum_{j=1}^p \beta_j^2 \right\} = \min_{\beta} \left\{ \text{RSS} + \lambda \|\beta\|_2^2 \right\}$$

Trong đó $\lambda \ge 0$ là siêu tham số điều hòa (tuning parameter):

  • Khi $\lambda = 0$: Thành phần phạt biến mất, Ridge trở về nghiệm OLS thông thường.
  • Khi $\lambda \to \infty$: Tác động của hình phạt chế ngự hoàn toàn, buộc tất cả các hệ số ước lượng $\hat{\beta}_1^R, \dots, \hat{\beta}_p^R \to 0$.

Lưu ý Sống còn: Chuẩn hóa Biến số (Standardization) trong Hồi quy Ridge

Trong OLS cổ điển, việc thay đổi đơn vị đo lường của biến $X_j$ (ví dụ: đổi từ mét sang milimét) sẽ chỉ đơn thuần làm hệ số $\hat{\beta}_j$ tự động co giãn theo tỷ lệ nghịch, trong khi giá trị dự đoán $\hat{Y}$ hoàn toàn không đổi. Hồi quy OLS bất biến với phép nhân vô hướng.

Tuy nhiên, hồi quy Ridge thì KHÔNG bất biến! Số hạng phạt $\lambda \sum \beta_j^2$ đối xử bình đẳng với mọi hệ số. Nếu biến $X_1$ đo bằng đô la và biến $X_2$ đo bằng nghìn đô la, hệ số của $X_1$ sẽ rất nhỏ và hầu như không bị phạt, trong khi hệ số của $X_2$ rất lớn và bị phạt tàn bạo. Vì vậy, bắt buộc phải chuẩn hóa dữ liệu về trung bình 0 và phương sai 1 trước khi chạy Ridge:

$$\tilde{x}_{ij} = \frac{x_{ij} - \bar{x}_j}{\sqrt{\frac{1}{n} \sum_{i=1}^n (x_{ij} - \bar{x}_j)^2}}$$

Ngoài ra, chú ý rằng hệ số chặn $\beta_0$ không bao giờ bị đưa vào hình phạt, bởi vì $\beta_0$ đại diện cho giá trị kỳ vọng nền tảng của phản hồi khi mọi biến bằng 0.

Tại sao Ridge cải thiện chất lượng dự đoán?

Điểm tinh hoa của Ridge nằm ở định lý toán học: ma trận $\mathbf{X}^T \mathbf{X} + \lambda \mathbf{I}$ luôn luôn khả đảo với mọi $\lambda > 0$, ngay cả khi $p > n$ hoặc khi các biến có hiện tượng đa cộng tuyến hoàn hảo! Nghiệm giải tích tường minh của Ridge là:

$$\hat{\beta}^R = (\mathbf{X}^T \mathbf{X} + \lambda \mathbf{I})^{-1} \mathbf{X}^T \mathbf{y}$$

Khi tăng $\lambda$, độ linh hoạt của mô hình giảm xuống: độ chệch (bias) tăng nhẹ không đáng kể, nhưng phương sai (variance) của các hệ số giảm cực kỳ nhanh chóng. Nhờ đó, tổng sai số MSE kiểm tra đạt đáy ở một giá trị $\lambda > 0$ tối ưu.


6.2.2. Hồi quy Lasso ($L_1$ Regularization)

Mặc dù Ridge giảm phương sai xuất sắc, nó có một nhược điểm lớn: không thể thực hiện chọn lọc biến. Với bất kỳ giá trị hữu hạn nào của $\lambda$, các hệ số $\hat{\beta}_j^R$ chỉ tiến sát về 0 chứ không bao giờ bằng đúng 0.

Năm 1996, Robert Tibshirani phát minh ra Lasso (Least Absolute Shrinkage and Selection Operator). Lasso thay thế hình phạt bình phương $L_2$ bằng hình phạt giá trị tuyệt đối $L_1$:

$$\min_{\beta} \left\{ \sum_{i=1}^n \left( y_i - \beta_0 - \sum_{j=1}^p \beta_j x_{ij} \right)^2 + \lambda \sum_{j=1}^p |\beta_j| \right\} = \min_{\beta} \left\{ \text{RSS} + \lambda \|\beta\|_1 \right\}$$

Nhờ dạng hình học đặc biệt của chuẩn $L_1$, khi $\lambda$ đủ lớn, Lasso sẽ ép một số hệ số về đúng bằng 0 tuyệt đối. Vì vậy, Lasso vừa đóng vai trò của một thuật toán co rút vừa là một cơ chế lựa chọn biến tự động, tạo ra các mô hình thưa (sparse models) vô cùng thanh lịch và dễ diễn giải.

Hồi quy Lasso (Chuẩn L₁: |β₁| + |β₂| ≤ s) β₁ β₂ |β₁|+|β₂| ≤ s β̂ (OLS) Nghiệm Lasso: β̂₁ = 0! Đỉnh nhọn trên trục tọa độ ép hệ số về 0 (tính thưa) Hồi quy Ridge (Chuẩn L₂: β₁² + β₂² ≤ s) β₁ β₂ β₁²+β₂² ≤ s β̂ (OLS) Nghiệm Ridge: β̂₁ ≠ 0, β̂₂ ≠ 0 Đường tròn trơn nhẵn: co rút hệ số nhưng không triệt tiêu
Hình 6.2. Bản chất hình học giải thích tại sao Lasso ép hệ số về 0 còn Ridge thì không. Các đường elip đỏ là đường đồng mức của hàm mất mát RSS bao quanh nghiệm OLS tự do. Điểm nghiệm điều hòa là điểm đầu tiên đường elip RSS tiếp xúc với vùng ràng buộc. Vùng hình thoi của Lasso có các đỉnh nhọn nằm ngay trên các trục tọa độ, khiến elip rất dễ tiếp xúc tại đỉnh (tức một hệ số bằng 0). Ngược lại, vùng hình tròn của Ridge trơn nhẵn nên điểm tiếp xúc hầu như không bao giờ nằm trên trục.
Phòng thí nghiệm D
Quỹ đạo Nghiệm Hồi quy: Ridge (L₂) vs Lasso (L₁)
Kéo ngân sách ràng buộc s hoặc tâm OLS để khám phá vì sao Lasso ép hệ số về 0
Không gian 2D (β₁, β₂): Elip RSS tiếp xúc Vùng Ràng buộc (Hình tròn L₂ vs Hình thoi L₁)
Quỹ đạo Hệ số theo Ngân sách s: β₁ (đỏ) và β₂ (xanh dương)
1.6
s nhỏ = phạt mạnh (λ lớn). s lớn = tiến sát nghiệm OLS tự do.
0.45
Độ nghiêng và độ dẹt của các đường elip đồng mức RSS.
β̂₁ (Lasso)0.00
β̂₂ (Lasso)1.60
β̂₁ (Ridge)0.52
β̂₂ (Ridge)1.45
OLS Tâm(1.2, 2.0)
Diễn giải

Quan sát điểm tiếp xúc trên hình: Với Lasso, vùng ràng buộc là một hình thoi có các đỉnh nhọn nằm ngay trên các trục tọa độ. Khi elip RSS mở rộng từ tâm OLS, nó có xác suất rất cao sẽ chạm vào đúng một trong các đỉnh nhọn — tại đó hệ số β₁ bị ép bằng đúng 0 tuyệt đối! Ngược lại, vùng của Ridge là hình tròn trơn nên điểm tiếp xúc nằm trên cung tròn, cả hai hệ số đều co lại nhưng không triệt tiêu.

Việc cần làm: ① Chọn chế độ Lasso: Kéo thanh trượt Ngân sách s từ 4.0 giảm dần về 0.1. Nhìn trên đồ thị quỹ đạo dưới: đường màu đỏ chạm trục hoành tại một giá trị s hữu hạn và **nằm bẹp trên mức 0** — đây chính là cơ chế chọn lọc biến tự động của Lasso! ② Chuyển sang chế độ Ridge: Khi s giảm, cả hai hệ số co dần đều về 0 nhưng không bao giờ chạm đúng 0 cho đến khi s = 0. ③ Dùng chuột kéo trực tiếp điểm OLS (chấm đen) trên khung vẽ 2D để thử nghiệm các cấu hình biến khác nhau!


6.2.3. Minh Họa Hình Học: Tại sao Lasso Ép Hệ Số về 0 còn Ridge thì Không?

Để thấu hiểu nguồn gốc sâu xa của tính thưa trong Lasso, ta có thể viết lại bài toán Ridge và Lasso dưới dạng tối ưu hóa có ràng buộc tương đương:

  • Ridge: Cực tiểu hóa $\text{RSS}$ với ràng buộc: $\beta_1^2 + \beta_2^2 \le s$
  • Lasso: Cực tiểu hóa $\text{RSS}$ với ràng buộc: $|\beta_1| + |\beta_2| \le s$

Trong không gian hai chiều $(\beta_1, \beta_2)$:

  1. Các đường đồng mức của hàm mất mát $\text{RSS}$ là các đường elip đồng tâm bao quanh điểm ước lượng OLS không ràng buộc $\hat{\beta}$. Càng xa tâm OLS, giá trị RSS càng lớn.
  2. Vùng ràng buộc của Ridge là một hình tròn trơn nhẵn $\beta_1^2 + \beta_2^2 \le s$.
  3. Vùng ràng buộc của Lasso là một hình thoi (diamond) với các đỉnh nhọn sắc bén nằm ngay trên các trục tọa độ $\beta_1 = 0$ và $\beta_2 = 0$.

Khi ta mở rộng các đường elip RSS từ tâm OLS cho tới khi nó chạm vào vùng ràng buộc lần đầu tiên:

  • Đối với Ridge: Do hình tròn trơn tru và không có góc cạnh, điểm tiếp xúc hầu như luôn luôn xảy ra tại một điểm trên đường cong, nơi cả hai tọa độ $\beta_1$ và $\beta_2$ đều khác 0.
  • Đối với Lasso: Hình thoi có các đỉnh nhọn chĩa thẳng ra các trục toạ độ. Do tính chất lồi và góc cạnh này, đường elip đồng mức có xác suất cực kỳ cao sẽ chạm vào một trong các đỉnh nhọn trước tiên! Tại bất kỳ đỉnh nhọn nào trên trục tọa độ, một trong các hệ số lập tức bằng 0 tuyệt đối.

Trong không gian nhiều chiều ($p > 2$), vùng ràng buộc của Lasso trở thành một đa diện siêu chiều (polytope) với vô số góc nhọn và cạnh phẳng nằm trên các siêu phẳng tọa độ, giải thích tại sao Lasso có thể loại bỏ đồng loạt hàng trăm biến dư thừa cùng lúc.


6.2.4. Góc Nhìn Thống Kê Bayes về Ridge và Lasso

Dưới lăng kính của xác suất Bayes, việc điều hòa tương đương với việc đặt một phân phối tiên nghiệm (prior distribution) lên các hệ số $\beta_j$:

$$p(\beta \mid Y) \propto f(Y \mid \beta) \, p(\beta)$$

  • Hồi quy Ridge: Tương ứng với phân phối tiên nghiệm Chuẩn (Gaussian) độc lập cho từng hệ số với kỳ vọng bằng 0: $\beta_j \sim \mathcal{N}(0, \tau^2)$. Đồ thị phân phối chuẩn hình chuông mượt mà ở đỉnh, do đó nghiệm hậu nghiệm lớn nhất (MAP) chỉ kéo hệ số về sát 0.
  • Hồi quy Lasso: Tương ứng với phân phối tiên nghiệm Laplace (Double-exponential): $$p(\beta_j) = \frac{1}{2b} \exp(-|\beta_j| / b)$$ Đồ thị phân phối Laplace có đỉnh nhọn hoắt (chóp nhọn) tại điểm 0. Mật độ xác suất tập trung cực hạn ngay tại gốc tọa độ, giải thích vì sao theo quan điểm Bayes, Lasso có xu hướng gán xác suất cao cho việc hệ số bằng đúng 0.

6.3. Các Phương Pháp Giảm Chiều (Dimension Reduction)

Nhóm phương pháp thứ ba không chọn lọc biến gốc cũng không co rút trực tiếp trên không gian ban đầu, mà tiến hành biến đổi toán học:

  1. Chiếu $p$ biến gốc $X_1, \dots, X_p$ sang một tập hợp $M$ biến mới $Z_1, \dots, Z_M$ ($M < p$) là các tổ hợp tuyến tính: $$Z_m = \sum_{j=1}^p \phi_{jm} X_j$$

  2. Khớp mô hình hồi quy tuyến tính OLS trên $M$ biến dự đoán mới này: $$y_i = \theta_0 + \sum_{m=1}^M \theta_m z_{im} + \epsilon_i$$

Số lượng tham số cần ước lượng giảm từ $p + 1$ xuống chỉ còn $M + 1$, giúp triệt tiêu hoàn toàn hiện tượng đa cộng tuyến và giảm mạnh phương sai.

6.3.1. Hồi quy Thành phần Chính (Principal Components Regression - PCR)

  • Sử dụng Phân tích Thành phần Chính (PCA) để tạo ra các biến $Z_m$.
  • Thành phần chính thứ nhất $Z_1$ là hướng trong không gian $p$ chiều mà dữ liệu biến thiên mạnh nhất.
  • Hạn chế chí mạng của PCR: PCA là một kỹ thuật học không giám sát (unsupervised). Nó chỉ quan tâm đến cấu trúc phương sai nội tại giữa các biến $X$ mà hoàn toàn "mù" trước biến mục tiêu $Y$. Không có gì đảm bảo rằng hướng biến thiên lớn nhất của $X$ lại chính là hướng có khả năng dự đoán $Y$ tốt nhất!

6.3.2. Bình phương Tối thiểu Từng phần (Partial Least Squares - PLS)

  • PLS là phiên bản có giám sát (supervised) của việc giảm chiều.
  • Khi xây dựng thành phần thứ nhất $Z_1 = \sum \phi_{j1} X_j$, PLS gán trọng số $\phi_{j1}$ tỷ lệ thuận với hệ số hồi quy đơn biến giữa $Y$ và $X_j$.
  • Nhờ đó, PLS ưu tiên những hướng trong không gian vừa có phương sai lớn vừa có mối tương quan mạnh nhất với biến mục tiêu $Y$.

6.4. Thách Thức trong Dữ Liệu Chiều Cao ($p \gg n$)

Trong những thập niên gần đây, các lĩnh vực công nghệ cao chứng kiến sự bùng nổ của các tập dữ liệu có số chiều cực lớn ($p$ lên tới hàng chục nghìn hoặc hàng triệu) trong khi số quan sát $n$ lại rất khiêm tốn (vài chục đến vài trăm):

  • Y sinh học & Di truyền: Đo đạc mức biểu hiện của $p = 20{,}000$ gen trên $n = 100$ bệnh nhân ung thư.
  • Xử lý ngôn ngữ tự nhiên: Số lượng từ vựng trong từ điển $p = 50{,}000$ trên $n = 500$ văn bản.

Hiểm họa Khi $p \gg n$

  • Ảo tưởng về sự hoàn hảo: Khi $p \ge n$, OLS luôn tìm được một siêu phẳng đi qua chính xác 100% các điểm dữ liệu. Bạn sẽ thấy $\text{RSS} = 0$ và $R^2 = 1.0$ hoàn hảo trên tập huấn luyện! Nhưng mô hình đó chỉ đang khớp vào các vết nhiễu ngẫu nhiên và hoàn toàn vô dụng trên tập kiểm tra.
  • Đa cộng tuyến nghiêm trọng: Bất kỳ biến nào cũng có thể biểu diễn thành tổ hợp tuyến tính của các biến khác. Các kiểm định thống kê cổ điển ($t$-test, $F$-test, $p$-value) hoàn toàn mất hiệu lực.
  • Tương quan giả (Spurious correlations): Với hàng chục nghìn biến ngẫu nhiên độc lập hoàn toàn với $Y$, xác suất để có ít nhất một vài biến tình cờ tương quan cực mạnh với $Y$ là gần như 100%.

Trong không gian chiều cao, Lasso và Ridge là những cứu cánh duy nhất. Đặc biệt, quy tắc lựa chọn biến cần cực kỳ khắt khe, và kết quả tìm thấy chỉ được xem là các giả thuyết gợi mở chứ không thể khẳng định mối quan hệ nhân quả nếu chưa được kiểm chứng độc lập trong phòng thí nghiệm.


6.5. Thực Hành Python: Ridge, Lasso và ElasticNet

import numpy as np
import pandas as pd
from sklearn.linear_model import Ridge, Lasso, RidgeCV, LassoCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 1. TẢI VÀ TIỀN XỬ LÝ DỮ LIỆU HITTERS (LƯƠNG CẦU THỦ BÓNG CHÀY)
url = "https://raw.githubusercontent.com/intro-stat-learning/ISLP_labs/v2/Hitters.csv"
hitters = pd.read_csv(url).dropna()

# Mã hóa one-hot cho các biến định tính
hitters = pd.get_dummies(hitters, drop_first=True)
X = hitters.drop(columns=['Salary']).values
y = hitters['Salary'].values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

# Chuẩn hóa đặc trưng
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 2. HỒI QUY RIDGE VỚI TỐI ƯU HÓA CV
alphas = np.logspace(-2, 4, 100)
ridge_cv = RidgeCV(alphas=alphas, cv=10, scoring='neg_mean_squared_error')
ridge_cv.fit(X_train_scaled, y_train)

y_pred_ridge = ridge_cv.predict(X_test_scaled)
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
print(f"=== HỒI QUY RIDGE ===")
print(f"Lambda tối ưu (alpha): {ridge_cv.alpha_:.4f}")
print(f"Test MSE của Ridge: {mse_ridge:.2f}")

# 3. HỒI QUY LASSO VỚI TỐI ƯU HÓA CV VÀ LỌC BIẾN TỰ ĐỘNG
lasso_cv = LassoCV(alphas=alphas, cv=10, max_iter=10000, random_state=42)
lasso_cv.fit(X_train_scaled, y_train)

y_pred_lasso = lasso_cv.predict(X_test_scaled)
mse_lasso = mean_squared_error(y_test, y_pred_lasso)
non_zero_count = np.sum(lasso_cv.coef_ != 0)

print(f"\n=== HỒI QUY LASSO ===")
print(f"Lambda tối ưu (alpha): {lasso_cv.alpha_:.4f}")
print(f"Test MSE của Lasso: {mse_lasso:.2f}")
print(f"Số biến được Lasso giữ lại: {non_zero_count} / {X.shape[1]}")
print(f"Số biến bị ép về 0: {np.sum(lasso_cv.coef_ == 0)}")

6.6. Bảng So Sánh Tổng Hợp Các Phương Pháp

Đặc tính Best Subset Hồi quy Ridge ($L_2$) Hồi quy Lasso ($L_1$) PCR / PLS
Chọn lọc biến Có (rời rạc) Không (giữ đủ $p$ biến) Có (liên tục, thưa) Không (giữ dạng tổ hợp)
Không gian $p > n$ Không thể chạy $p \ge n$ Chạy tốt Chạy rất tốt Chạy tốt với $M < n$
Xử lý đa cộng tuyến Kém Xuất sắc Khá (chọn 1 biến bất kỳ) Rất tốt
Tính toán Cực kỳ đắt đỏ ($2^p$) Nhanh (nghiệm giải tích) Nhanh (tối ưu lồi) Rất nhanh

07Chương 7: Vượt Qua Tính Tuyến Tính (Moving Beyond Linearity)

Trong các chương trước, chúng ta đã khai thác sâu sắc mô hình tuyến tính: từ hồi quy bình phương tối thiểu (OLS) đến các kỹ thuật co rút tinh vi như Ridge và Lasso. Mặc dù các mô hình này sở hữu ưu thế vượt trội về mặt diễn giải và tính toán, giả định về mối quan hệ tuyến tính giữa các biến dự đoán và biến phản hồi hầu như luôn chỉ là một phép xấp xỉ thô sơ, và trong nhiều trường hợp thực tiễn, nó là một phép xấp xỉ rất tồi.

Thế giới tự nhiên không vận hành theo những đường thẳng cứng nhắc: mức lương tăng vọt ở độ tuổi trung niên rồi chững lại khi về già; hiệu quả của thuốc đạt ngưỡng bão hòa sau một liều lượng nhất định; doanh số bán hàng bùng nổ theo hình chữ S khi thương hiệu thâm nhập thị trường.

Làm thế nào để mô hình hóa những đường cong phi tuyến phức tạp đó mà vẫn bảo toàn được tính minh bạch, khả năng diễn giải và tránh được cạm bẫy quá khớp (overfitting)? Đó chính là trọng tâm của Chương 7. Chúng ta sẽ lần lượt khảo sát từ các mở rộng đơn giản như hồi quy đa thức và hàm bậc thang, tiến tới các công cụ tinh vi hơn như hàm ghép hồi quy (Regression Splines), hàm ghép làm trơn (Smoothing Splines), hồi quy cục bộ (Local Regression), và đỉnh cao là Mô hình Cộng tính Tổng quát (Generalized Additive Models - GAMs).


7.1. Hồi Quy Đa Thức (Polynomial Regression)

Phương pháp cổ điển và quen thuộc nhất để bẻ cong đường thẳng tuyến tính là bổ sung thêm các lũy thừa bậc cao của biến đầu vào:

$$y_i = \beta_0 + \beta_1 x_i + \beta_2 x_i^2 + \beta_3 x_i^3 + \dots + \beta_d x_i^d + \epsilon_i$$

Mặc dù hàm số phi tuyến theo biến $x$, nó vẫn hoàn toàn là một mô hình tuyến tính theo các hệ số $\beta$! Do đó, ta có thể ước lượng toàn bộ các tham số $\beta_0, \dots, \beta_d$ bằng phương pháp bình phương tối thiểu thông thường mà không cần bất kỳ thuật toán tối ưu phi tuyến phức tạp nào.

Mô hình Đa thức Bậc d:
X ──► [X, X², X³, ..., Xᵈ] ──► Hồi quy Tuyến tính OLS ──► Đường cong f̂(X)
Đa thức trong Bài toán Phân loại (Polynomial Logistic Regression)

Với biến đầu ra nhị phân $Y \in \{0, 1\}$, ta có thể kết hợp đa thức với mô hình Logit:

$$\log\left(\frac{p(X)}{1 - p(X)}\right) = \beta_0 + \beta_1 X + \beta_2 X^2 + \dots + \beta_d X^d$$

Từ đó, xác suất dự đoán là:

$$p(X) = \Pr(Y = 1 \mid X) = \frac{\exp(\beta_0 + \beta_1 X + \dots + \beta_d X^d)}{1 + \exp(\beta_0 + \beta_1 X + \dots + \beta_d X^d)}$$

Hiểm họa Bậc cao và Hiện tượng Rung ở Biên (Runge's Phenomenon)

Trong thực tế, hiếm khi người ta sử dụng bậc $d$ lớn hơn 3 hoặc 4. Khi $d \ge 5$, hàm đa thức trở nên quá mềm dẻo và phát sinh hiện tượng dao động biên dữ dội (Runge's phenomenon). Ở gần các mép biên ngoài cùng của biến $X$ (nơi có ít điểm dữ liệu), đường cong đa thức thường vểnh ngược lên trời hoặc cắm dốc xuống vực một cách phi lý, khiến sai số dự đoán cho các điểm kiểm tra ở vùng biên tăng phi mã.


7.2. Hàm Bậc Thang (Step Functions)

Thay vì dùng một hàm toàn cục liên tục trên toàn bộ miền giá trị, hàm bậc thang chia miền của $X$ thành các khoảng rời rạc bằng các điểm cắt $c_1, c_2, \dots, c_K$:

$$C_0 = (-\infty, c_1), \quad C_1 = [c_1, c_2), \quad \dots, \quad C_K = [c_K, \infty)$$

Ta tạo ra $K$ biến chỉ thị (dummy variables) $I(X \in C_k)$, và khớp mô hình hồi quy:

$$y_i = \beta_0 + \beta_1 I(x_i \in C_1) + \beta_2 I(x_i \in C_2) + \dots + \beta_K I(x_i \in C_K) + \epsilon_i$$

Ưu điểm: Rất phổ biến trong dịch tễ học và đánh giá tín dụng (chia độ tuổi thành các nhóm: dưới 25, 25–45, trên 45).
Nhược điểm: Hàm bị đứt gãy gián đoạn tại các điểm ranh giới $c_k$. Trong tự nhiên, con người bước từ 24 tuổi sang 25 tuổi không lập tức thay đổi đột ngột toàn bộ mức lương hay xác suất mắc bệnh!


7.3. Hàm Ghép Cơ Sở và Hồi Quy Splines (Regression Splines)

Hồi quy đa thức và hàm bậc thang thực chất là hai trường hợp riêng biệt của một khung làm việc tổng quát gọi là phương pháp hàm cơ sở (basis functions):

$$y_i = \beta_0 + \beta_1 b_1(x_i) + \beta_2 b_2(x_i) + \dots + \beta_K b_K(x_i) + \epsilon_i$$

Trong đó các hàm cơ sở $b_1(X), \dots, b_K(X)$ được cố định từ trước. Hàm ghép hồi quy (Regression Splines) là sự kết hợp hoàn hảo nhất giữa tính linh hoạt của đa thức và tính cục bộ của hàm bậc thang.

1. Đa thức Từng khúc Gián đoạn Mấu nút ξ Đứt gãy tại mấu nút! Không có bất kỳ ràng buộc nào 2. Hàm ghép Bậc ba (Cubic Spline) Mấu nút ξ ✓ Liên tục hàm f(ξ⁻) = f(ξ⁺) ✓ Đạo hàm cấp 1 trơn f'(ξ) ✓ Đạo hàm cấp 2 trơn f''(ξ) Mắt người không nhận ra mấu nối 3. Hàm ghép Tự nhiên (Natural Spline) ξ₁ ξ₂ Thẳng Uốn lượn bậc 3 Thẳng Ép f''(x) = 0 ở ngoài 2 nút biên → Triệt tiêu phương sai bùng nổ ở biên!
Hình 7.1. Quá trình hình thành của Splines. Trái: Đa thức từng khúc bị gián đoạn đứt gãy. Giữa: Cubic Spline áp đặt 3 ràng buộc liên tục (hàm, đạo hàm cấp 1, đạo hàm cấp 2) tạo nên đường cong trơn tru hoàn hảo. Phải: Natural Spline bổ sung thêm ràng buộc tuyến tính (thẳng) ở hai bên ngoài mấu nút biên cùng, giúp dải dự đoán ổn định vững chắc ở hai mép dữ liệu.

7.3.1. Đa Thức Từng Khúc và Ràng Buộc Trơn

Giả sử ta chọn một mấu nút (knot) $c$. Thay vì khớp một đa thức bậc 3 trên toàn bộ dữ liệu, ta khớp hai đa thức bậc 3 riêng biệt ở hai bên mấu nút:

  • Nếu không áp đặt ràng buộc: Hai đường cong sẽ bị đứt gãy tại $c$ (Piecewise Cubic).
  • Ràng buộc 1 (Liên tục): Bắt buộc hai đường cong phải gặp nhau tại điểm $c$: $f(c^-) = f(c^+)$.
  • Ràng buộc 2 (Đạo hàm cấp 1 liên tục): $f'(c^-) = f'(c^+)$ (đồ thị không có góc nhọn bẻ gập).
  • Ràng buộc 3 (Đạo hàm cấp 2 liên tục): $f''(c^-) = f''(c^+)$ (độ cong trơn tru hoàn hảo tại mấu nối, mắt người hoàn toàn không thể nhận ra điểm ghép nối).

Một hàm đa thức từng khúc bậc $d$ có các đạo hàm liên tục đến cấp $d-1$ tại mỗi mấu nút được gọi là Hàm ghép bậc $d$ (Spline of degree $d$). Trong thực tế, Hàm ghép bậc ba (Cubic Spline) là chuẩn mực phổ biến nhất vì nó vừa đủ trơn tru cho thị giác con người mà không tốn quá nhiều bậc tự do.


7.3.2. Cơ Sở Lũy Thừa Cắt Cụt (Truncated Power Basis)

Làm thế nào để biểu diễn một Cubic Spline với $K$ mấu nút $\xi_1, \xi_2, \dots, \xi_K$ thành một bài toán OLS tuyến tính đơn giản? Lời giải nằm ở hàm cơ sở lũy thừa cắt cụt (truncated power function):

$$h(x, \xi) = (x - \xi)_+^3 = \begin{cases} (x - \xi)^3 & \text{nếu } x > \xi \\ 0 & \text{nếu } x \le \xi \end{cases}$$

Khi đó, bất kỳ hàm ghép bậc ba nào với $K$ mấu nút đều có thể biểu diễn tường minh dưới dạng:

$$y = \beta_0 + \beta_1 x + \beta_2 x^2 + \beta_3 x^3 + \sum_{k=1}^K \theta_k (x - \xi_k)_+^3$$

  • Đa thức ban đầu $\beta_0 + \beta_1 x + \beta_2 x^2 + \beta_3 x^3$ chịu trách nhiệm uốn lượn ở khoảng đầu tiên.
  • Mỗi khi giá trị $x$ vượt qua một mấu nút $\xi_k$, số hạng $\theta_k (x - \xi_k)_+^3$ bắt đầu "kích hoạt", nhẹ nhàng bổ sung thêm một lượng biến thiên bậc 3 mà vẫn bảo toàn nguyên vẹn tính liên tục của hàm, đạo hàm cấp 1 và cấp 2!
  • Bậc tự do (Degrees of Freedom - df): Với $K$ mấu nút, mô hình có đúng $K + 4$ bậc tự do (bao gồm hệ số chặn).

7.3.3. Hàm Ghép Tự Nhiên (Natural Cubic Splines)

Tương tự như hồi quy đa thức thông thường, Cubic Spline vẫn có xu hướng dao động rất mạnh ở hai đầu biên dữ liệu (phía bên trái nút đầu tiên $\xi_1$ và phía bên phải nút cuối cùng $\xi_K$).

Hàm ghép tự nhiên (Natural Spline) giải quyết triệt để vấn đề này bằng cách áp đặt thêm một ràng buộc biên:

Ràng buộc Tự nhiên: Hàm bắt buộc phải là đường thẳng tuyến tính (đạo hàm cấp hai $f''(x) = 0$) ở bên ngoài hai mấu nút biên cùng: khi $x < \xi_1$ và khi $x > \xi_K$.

Nhờ việc ép tuyến tính ở hai biên, Natural Cubic Spline:

  1. Triệt tiêu hoàn toàn hiện tượng uốn éo hoang dại ở biên, giúp dải khoảng tin cậy hẹp lại và ổn định hơn rất nhiều.
  2. Tiết kiệm được 4 bậc tự do phụ, cho phép ta đặt thêm nhiều mấu nút hơn ở vùng trung tâm nơi tập trung mật độ dữ liệu dày đặc.
Phòng thí nghiệm E
Hàm ghép Splines & Độ trơn (Knots & Smoothing Splines)
Kéo các mấu nút ξ trên trục hoành để khám phá tính trơn và hành vi biên của Splines
Đồ thị Hồi quy Spline: Dữ liệu (chấm), Mấu nút ξ (vạch vàng có thể kéo thả), Đường cong khớp
Các hàm cơ sở Spline (Basis functions) tương ứng với từng mấu nút
3
Số điểm phân chia miền dữ liệu (vị trí ban đầu chia đều).
0.0
Chỉ dùng cho Smoothing Spline: λ lớn = đường thẳng, λ nhỏ = uốn lượn.
0.35
Nhiễu ngẫu nhiên của các điểm dữ liệu.
Loại SplineNatural Cubic
Số nút K3
Bậc tự do df4
Train MSE0.00
Lỗi ở Biên0.00
Diễn giải

Natural Cubic Spline áp đặt ràng buộc tuyến tính (đường thẳng) ở bên ngoài hai nút biên cùng. Nhờ đó, nó triệt tiêu hoàn toàn hiện tượng rung lắc hoang dại ở hai mép dữ liệu. Bạn có thể dùng chuột bấm và kéo các vạch màu vàng trên đồ thị để thay đổi vị trí các mấu nút!

Việc cần làm: ① Chuyển đổi giữa Cubic Spline và Natural Spline: Hãy nhìn kỹ hai mép ngoài cùng của đồ thị. Ở Cubic Spline thông thường, đường cong thường vểnh ngược hoặc chúi dốc rất mạnh ở hai đầu biên (phương sai cao). Khi bật Natural Spline, hai đầu lập tức duỗi thẳng tắp một cách vững vàng! ② Thử chọn Đa thức Gián đoạn (Piecewise): Quan sát đường cong bị đứt gãy gập ghềnh tại mỗi mấu nút màu vàng. Khi quay lại Cubic Spline, các điều kiện liên tục đạo hàm cấp 1 và cấp 2 ép các đoạn nối lại trơn tru hoàn hảo. ③ Chọn Smoothing Spline và kéo thanh log₁₀(λ): λ = -4 uốn lượn qua từng điểm dữ liệu; kéo lên λ = 4 hàm biến thành một đường thẳng OLS duy nhất.


7.4. Hàm Ghép Làm Trơn (Smoothing Splines)

Trong Regression Splines ở trên, ta phải đau đầu lựa chọn: đặt bao nhiêu mấu nút và đặt chúng ở tọa độ nào? Hàm ghép làm trơn (Smoothing Splines) tiếp cận bài toán theo một triết lý toán học hoàn toàn khác: biến phân hóa (variational optimization).

Ta muốn tìm một hàm $g(x)$ bất kỳ sao cho vừa khớp tốt dữ liệu (RSS nhỏ) vừa có đồ thị thật êm ái trơn mượt:

$$\min_g \left\{ \sum_{i=1}^n (y_i - g(x_i))^2 + \lambda \int g''(t)^2 \, dt \right\}$$

Trong đó:

  • $\sum (y_i - g(x_i))^2$: Thước đo mức độ mất mát dữ liệu (Loss term).
  • $\int g''(t)^2 dt$: Thành phần phạt độ nhám (Roughness penalty). Đạo hàm cấp hai $g''(t)$ đại diện cho gia tốc và độ cong của hàm tại điểm $t$. Nếu $g(t)$ là một đường thẳng, $g''(t) = 0$ và tích phân bằng 0. Nếu $g(t)$ uốn lượn ngoằn ngoèo, đạo hàm cấp 2 sẽ rất lớn khiến tích phân bùng nổ.
  • $\lambda \ge 0$: Siêu tham số điều hòa độ trơn:
    • Khi $\lambda = 0$: Không có hình phạt, $g$ có thể là bất kỳ hàm nào đi qua chính xác $100\%$ các điểm mẫu (nội suy hoàn hảo, Train MSE = 0, quá khớp tối đa).
    • Khi $\lambda \to \infty$: Hình phạt chế ngự hoàn toàn, ép $g''(t) = 0$ ở mọi nơi $\implies$ hàm $g$ bắt buộc phải là một đường thẳng hồi quy OLS!

Định lý Đẹp về Nghiệm của Smoothing Spline

Thoạt nhìn, việc tối ưu hóa trên không gian vô hạn chiều của mọi hàm khả vi $g$ có vẻ là bất khả thi. Tuy nhiên, các nhà toán học đã chứng minh một định lý phi thường: Hàm $g(x)$ cực tiểu hóa biểu thức trên chính là một Natural Cubic Spline duy nhất có mấu nút tại CHÍNH TẤT CẢ các điểm dữ liệu $x_1, x_2, \dots, x_n$!

Mặc dù có $n$ mấu nút, mô hình không hề bị quá khớp vì thành phần phạt $\lambda$ đã co rút độ uốn lượn của các hệ số một cách liên tục.

Bậc tự do hiệu dụng (Effective Degrees of Freedom - $df_\lambda$)

Thay vì đếm số tham số rời rạc, đối với Smoothing Splines ta sử dụng ma trận làm trơn $\mathbf{S}_\lambda$:

$$\hat{\mathbf{g}}_\lambda = \mathbf{S}_\lambda \mathbf{y} \implies df_\lambda = \text{tr}(\mathbf{S}_\lambda) = \sum_{i=1}^n \{\mathbf{S}_\lambda\}_{ii}$$

Giá trị $df_\lambda$ giảm đơn điệu từ $n$ (khi $\lambda = 0$) xuống còn 2 (khi $\lambda \to \infty$). Ta có thể tối ưu hóa $\lambda$ bằng LOOCV thông qua công thức shortcut kỳ diệu:

$$\text{CV}_{(\lambda)} = \frac{1}{n} \sum_{i=1}^n \left( \frac{y_i - \hat{g}_\lambda(x_i)}{1 - \{\mathbf{S}_\lambda\}_{ii}} \right)^2$$


7.5. Hồi Quy Cục Bộ (Local Regression / LOESS)

Hồi quy cục bộ hoạt động theo nguyên lý "chia để trị" tương tự như thuật toán $K$ láng giềng gần nhất (KNN), nhưng thay vì lấy trung bình thô sơ, nó khớp một đường hồi quy tuyến tính có trọng số tại vùng lân cận của từng điểm cần dự đoán $x_0$:

  1. Tập hợp một tỷ lệ $s$ (gọi là băng thông / span) các điểm dữ liệu gần $x_0$ nhất.
  2. Gán cho mỗi điểm láng giềng $x_i$ một trọng số hạt nhân (kernel weight) $K_{i0} = W\left(\frac{|x_i - x_0|}{h}\right)$: điểm càng gần $x_0$ thì trọng số càng lớn, điểm nằm ngoài bán kính $h$ nhận trọng số 0.
  3. Khớp một mô hình hồi quy tuyến tính có trọng số (Weighted Least Squares): $$\min_{\beta_0, \beta_1} \sum_{i=1}^n K_{i0} (y_i - \beta_0 - \beta_1 x_i)^2$$

  4. Giá trị dự đoán tại $x_0$ chính là $\hat{f}(x_0) = \hat{\beta}_0 + \hat{\beta}_1 x_0$.

Ý nghĩa của tham số span $s$: Khi $s$ nhỏ, vùng lân cận hẹp, mô hình rất linh hoạt (variance cao, bias thấp). Khi $s$ lớn, vùng lân cận rộng, mô hình phẳng dần và trơn tru hơn (variance thấp, bias cao).


7.6. Mô Hình Cộng Tính Tổng Quát (Generalized Additive Models - GAMs)

Tất cả các kỹ thuật trên (Đa thức, Splines, Hồi quy cục bộ) đều hoạt động rất tốt trên một biến dự đoán đơn lẻ $X$. Nhưng trong thực tế, ta thường phải đối mặt với bài toán có nhiều biến $X_1, X_2, \dots, X_p$.

Nếu cố gắng mở rộng Splines sang không gian đa chiều trực tiếp (ví dụ: Splines hai chiều $X_1 \times X_2$, hoặc ba chiều), ta sẽ lập tức đâm sầm vào bức tường Lời nguyền số chiều (Curse of dimensionality): số lượng mấu nút tăng theo hàm số mũ và dữ liệu trở nên cực kỳ thưa thớt.

Mô hình Cộng tính Tổng quát (GAMs) giải quyết bài toán này một cách tài tình bằng cách duy trì giả định về tính chất cộng tính (additivity) giữa các biến:

$$y_i = \beta_0 + f_1(x_{i1}) + f_2(x_{i2}) + \dots + f_p(x_{ip}) + \epsilon_i$$

Trong đó mỗi $f_j(X_j)$ là một hàm phi tuyến trơn mượt riêng biệt của biến thứ $j$ (có thể là Natural Spline, Smoothing Spline, hoặc hàm bậc thang).

Kiến trúc GAMs:
Y = β₀ + f₁(Tuổi) + f₂(Năm) + f₃(Học vấn) + ε
         │          │         │
         ▼          ▼         ▼
     [Spline]   [Tuyến]    [Bậc thang]
Ưu và Nhược điểm Cốt lõi của GAMs:
  • Ưu điểm lớn nhất:

    1. Cho phép mô hình hóa các mối quan hệ phi tuyến tự nhiên cho từng biến mà không bị ảnh hưởng bởi lời nguyền số chiều.
    2. Khả năng diễn giải tuyệt vời: Ta có thể vẽ đồ thị riêng rẽ từng hàm thành phần $\hat{f}_j(X_j)$ trên trục tọa độ 2D. Nhìn vào đồ thị, ta thấy chính xác biến đó tác động phi tuyến thế nào lên đầu ra khi đã cố định tất cả các biến khác!
  • Hạn chế: Cấu trúc cộng dồn thuần túy bỏ qua các tương tác tiềm ẩn giữa các cặp biến (ví dụ: tác động của $X_1$ có thể phụ thuộc vào giá trị của $X_2$). Tuy nhiên, ta có thể khắc phục thủ công bằng cách bổ sung thêm các số hạng tương tác hai chiều: $f_{jk}(X_j, X_k)$.

GAMs cho Bài toán Phân loại (Logistic GAMs)

Áp dụng hàm liên kết Logit:

$$\log\left(\frac{p(X)}{1 - p(X)}\right) = \beta_0 + f_1(X_1) + f_2(X_2) + \dots + f_p(X_p)$$

Mô hình được huấn luyện hiệu quả bằng thuật toán Backfitting (lần lượt làm trơn từng biến một trong khi cố định các biến còn lại).


7.7. Thực Hành Python: Splines và GAMs

Dưới đây là mã nguồn Python sử dụng scikit-learn và patsy để khớp Splines và GAMs trên dữ liệu thực tế:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import SplineTransformer
from sklearn.pipeline import make_pipeline
from patsy import dmatrix

# 1. TẢI DỮ LIỆU WAGE (LƯƠNG THEO TUỔI)
url = "https://raw.githubusercontent.com/intro-stat-learning/ISLP_labs/v2/Wage.csv"
wage = pd.read_csv(url).dropna()
X = wage[['age']].values
y = wage['wage'].values

# Lưới giá trị tuổi để dự đoán trơn tru
age_grid = np.linspace(X.min(), X.max(), 300).reshape(-1, 1)

# 2. HỒI QUY NATURAL SPLINE BẰNG PATSY (BẬC TỰ DO DF = 4)
# patsy hỗ trợ tạo ma trận cơ sở Natural Spline 'cr' (natural cubic spline)
transformed_x = dmatrix("cr(train, df=4) - 1", {"train": X.flatten()}, return_type='dataframe')
transformed_grid = dmatrix("cr(grid, df=4) - 1", {"grid": age_grid.flatten()}, return_type='dataframe')

model_ns = LinearRegression().fit(transformed_x, y)
pred_ns = model_ns.predict(transformed_grid)

print("=== HỒI QUY NATURAL CUBIC SPLINE ===")
print(f"Hệ số chặn: {model_ns.intercept_:.2f}")
print(f"Hệ số cơ sở: {model_ns.coef_}")

# 3. HỒI QUY B-SPLINE BẰNG SCIKIT-LEARN
# n_knots=4, degree=3 tạo ra Cubic B-Spline
spline_pipe = make_pipeline(
    SplineTransformer(n_knots=5, degree=3, include_bias=False),
    LinearRegression()
)
spline_pipe.fit(X, y)
pred_bs = spline_pipe.predict(age_grid)

print("\n=== CUBIC B-SPLINE (SCIKIT-LEARN) ===")
print(f"R² huấn luyện của Cubic Spline: {spline_pipe.score(X, y):.4f}")

# 4. MÔ PHỎNG MÔ HÌNH CỘNG TÍNH TỔNG QUÁT (GAMs)
# wage ~ s(age) + s(year) + education
gam_formula = "cr(age, df=4) + cr(year, df=3) + C(education)"
X_gam = dmatrix(gam_formula, wage, return_type='dataframe')
model_gam = LinearRegression().fit(X_gam, y)
print(f"\n=== MÔ HÌNH CỘNG TÍNH GAMs ===")
print(f"R² của GAMs đa biến: {model_gam.score(X_gam, y):.4f}")

7.8. Tổng Kết Bậc Thang Tiến Hóa của Mô Hình Thống Kê

Độ linh hoạt tăng dần  ──►
[Tuyến tính OLS]  ──►  [Ridge / Lasso]  ──►  [Đa thức / Splines]  ──►  [GAMs]  ──►  [Deep Learning]
(Cứng nhắc,            (Giảm phương sai,     (Uốn lượn 1D trơn     (Phi tuyến đa     (Hộp đen tối
 dễ giải thích)         thưa hóa biến)        truyệt vời)           biến cộng tính)   hảo, linh hoạt)

08Chương 8: Các Phương Pháp Dựa Trên Cây (Tree-Based Methods)

Trong chương này, chúng ta nghiên cứu các phương pháp dựa trên cây phục vụ cho cả hai bài toán hồi quy và phân loại. Bản chất của các phương pháp này là phân chia hoặc phân đoạn không gian các biến dự đoán thành một tập hợp các vùng đơn giản. Để đưa ra dự đoán cho một quan sát mới, ta lấy giá trị trung bình (trong bài toán hồi quy) hoặc nhãn chiếm đa số (trong bài toán phân loại) của các quan sát huấn luyện rơi vào cùng vùng đó.

Do tập hợp các quy tắc phân chia không gian có thể tóm tắt trực quan dưới dạng một sơ đồ cây phân nhánh, những phương pháp này được gọi chung là phương pháp cây quyết định (decision tree methods).

Cây quyết định đơn lẻ mang ưu điểm vượt trội về tính trực quan và khả năng diễn giải sâu sắc. Tuy nhiên, nếu xét riêng về độ chính xác dự đoán thuần túy, một cây đơn lẻ thường khó cạnh tranh với các phương pháp học có giám sát tốt nhất (như hồi quy phi tuyến, GAMs hay SVM). Để khắc phục nhược điểm cốt tử đó, chương này sẽ giới thiệu bốn kỹ thuật kết hợp mô hình (ensemble methods) hàng đầu: Bagging (Đóng bao mẫu), Random Forests (Rừng ngẫu nhiên), Boosting (Tăng cường), và BART (Cây hồi quy cộng tính Bayes). Mỗi phương pháp này kết hợp hàng trăm hoặc hàng nghìn cây quyết định đơn lẻ lại với nhau để tạo ra một dự đoán đồng thuận duy nhất, mang lại bước nhảy vọt ngoạn mục về độ chính xác dự đoán.


8.1. Cây Quyết Định Căn Bản (The Basics of Decision Trees)

Cây quyết định có thể áp dụng linh hoạt cho cả bài toán hồi quy lẫn phân loại. Chúng ta sẽ bắt đầu tìm hiểu với cây hồi quy trước khi mở rộng sang cây phân loại.

8.1.1. Cây Hồi Quy (Regression Trees)

Để hình dung trực quan cơ chế hoạt động của cây hồi quy, hãy xem xét bài toán thực tế dự đoán thu nhập của các cầu thủ bóng chày chuyên nghiệp trong tập dữ liệu Hitters. Chúng ta muốn dự đoán $\log(\text{Salary})$ (logarit lương năm 1987) dựa trên hai biến dự đoán:

  • Years: Số năm thi đấu tại giải bóng chày nhà nghề Major League.
  • Hits: Số lần đánh trúng bóng của cầu thủ đó trong mùa giải trước (năm 1986).
Sơ đồ Cây Hồi quy (Hitters Data) Years < 4.5 ? Đúng Sai Vùng R₁ ŷ = 5.11 ($166k) Hits < 117.5 ? Đúng Sai Vùng R₂ ŷ = 6.00 ($403k) Vùng R₃ ŷ = 6.74 ($845k) Phân hoạch Không gian Đặc trưng (Years × Hits) R₁ ŷ = 5.11 R₂ ŷ = 6.00 R₃ ŷ = 6.74 Years = 4.5 Hits = 117.5 Số năm thi đấu (Years) Số cú đánh (Hits)
Hình 8.1. Cây hồi quy trên tập dữ liệu Hitters. Trái: Sơ đồ phân nhánh nhị phân dẫn tới 3 nút lá tận cùng. Phải: Không gian 2 chiều của Years và Hits được phân hoạch thành 3 vùng chữ nhật trực giao $R_1, R_2, R_3$.

Cây quyết định trong hình minh họa trên hoạt động theo quy tắc nhị phân từ trên xuống dưới:

  1. Nút trên cùng gọi là nút gốc (root node). Tại đây, toàn bộ tập dữ liệu được kiểm tra điều kiện: Years < 4.5 hay không?
  2. Nếu Years < 4.5 (nhánh trái), quá trình phân chia dừng lại tại một nút lá (leaf / terminal node). Giá trị dự đoán cho tất cả các cầu thủ có dưới 4.5 năm kinh nghiệm là $5.11$ (tương đương mức lương trung bình $e^{5.11} \times 1000 \approx 165,660\ \$$). 3. Nếu `Years >= 4.5` (nhánh phải), câu hỏi tiếp theo được đặt ra tại **nút trong (internal node)**: cầu thủ đó có số lần đánh trúng bóng `Hits < 117.5` hay không? * Nếu có (`Hits < 117.5`), giá trị dự đoán là $6.00$ ($\approx 402,830\ \$$).

    • Nếu không (Hits >= 117.5), giá trị dự đoán là $6.74$ ($\approx 845,350\ \$$).

      Bài học kinh tế rút ra từ cây quyết định

      Cây hồi quy đơn giản trên lập tức hé lộ hai quy luật kinh tế rõ rệt:
      1. Kinh nghiệm thi đấu là yếu tố then chốt nhất: Cầu thủ có ít kinh nghiệm (dưới 4.5 năm) nhận lương thấp hơn hẳn bất kể số lần đánh trúng bóng của họ là bao nhiêu.
      2. Đối với những cầu thủ đã dạn dày kinh nghiệm: Số lần đánh trúng bóng trở thành thước đo giá trị phân hóa sâu sắc — người đánh trúng từ 118 lần trở lên có thu nhập gấp hơn 2 lần người dưới 118 lần.

      #### Phân Hoạch Không Gian Dự Đoán (Predictor Space Partitioning) Về mặt toán học, quá trình xây dựng cây hồi quy gồm hai bước nền tảng: 1. Chúng ta phân chia không gian $p$ chiều của các biến dự đoán $(X_1, X_2, \dots, X_p)$ thành $J$ vùng riêng biệt, không chồng lấn lên nhau: $R_1, R_2, \dots, R_J$. 2. Với mọi quan sát mới rơi vào vùng $R_j$, ta đưa ra cùng một giá trị dự đoán duy nhất: chính là **giá trị trung bình mẫu** của biến phản hồi $y_i$ thuộc các quan sát huấn luyện nằm trong $R_j$: $$\hat{y}{R_j} = \frac{1}{|R_j|} \sum} y_i$$ Mục tiêu tối thượng là tìm các vùng $R_1, \dots, R_J$ sao cho **Tổng bình phương phần dư (Residual Sum of Squares - RSS)** trên toàn bộ tập dữ liệu đạt giá trị nhỏ nhất: $$\text{RSS} = \sum_{j=1}^J \sum_{i \in R_j} (y_i - \hat{y{R_j})^2$$ Tuy nhiên, việc xem xét mọi cách phân hoạch không gian khả dĩ để tìm nghiệm tối ưu toàn cục là bất khả thi về mặt tính toán (bài toán NP-đầy đủ). Do đó, chúng ta áp dụng một giải thuật xấp xỉ xoi mói theo phương pháp tham lam từ trên xuống: **Phân chia nhị phân đệ quy (Recursive Binary Splitting)**. #### Thuật Toán Phân Chia Nhị Phân Đệ Quy (Recursive Binary Splitting) Phương pháp này mang tính chất **tham lam (greedy)** vì tại mỗi bước đơn lẻ, nó chỉ tìm nhát cắt tốt nhất cho bước đó mà không cần quan tâm liệu việc này có mang lại nhát cắt tối ưu cho các bước tiếp theo hay không. Cụ thể, tại bất kỳ nút nào cần phân chia: * Ta quét qua mọi biến dự đoán khả dĩ $X_j$ ($j = 1, \dots, p$) và mọi ngưỡng cắt $s$. * Phép cắt $(j, s)$ chia vùng hiện tại thành hai nửa không gian: $$R_1(j, s) = {X \mid X_j < s} \quad \text{và} \quad R_2(j, s) = {X \mid X_j \ge s}$$ * Chúng ta tìm cặp $(j, s)$ sao cho tổng RSS thu được trên hai nửa không gian là nhỏ nhất: $$\min} \left[ \sum_{i: x_i \in R_1(j, s)} (y_i - \hat{y{R_1})^2 + \sum} (y_i - \hat{y{R_2})^2 \right]$$ Quá trình này được lặp lại đệ quy trên từng vùng con cho đến khi thỏa mãn một điều kiện dừng (ví dụ: số quan sát trong mỗi nút con nhỏ hơn một ngưỡng định trước, chẳng hạn không quá 5 quan sát). #### Tỉa Cây theo Độ Phức Tạp Chi Phí (Cost-Complexity Pruning) Cây quyết định được nuôi lớn tự do (cho đến khi mỗi nút chỉ chứa vài quan sát) sẽ khớp rất khít dữ liệu huấn luyện, đạt RSS huấn luyện gần như bằng 0. Nhưng cái giá phải trả là mô hình sẽ có **phương sai khổng lồ** và bị **quá khớp (overfitting)** nghiêm trọng. Ngược lại, một cây quá nông (ít nút) lại có **độ chệch cao** và không nắm bắt được quy luật thực tế. Do đó, chiến lược chuẩn mực trong học thống kê là: 1. Phát triển một cây thật lớn $T_0$ cho đến khi các nút lá đạt kích thước tối thiểu. 2. Tiến hành **tỉa bớt các cành phụ (pruning)** để thu được một cây con tối ưu $T \subset T_0$. Để cân bằng giữa kích thước cây và độ khớp dữ liệu, ta áp dụng kỹ thuật **Tỉa cây theo độ phức tạp chi phí (Cost-Complexity Pruning)**, còn gọi là *tỉa liên kết yếu nhất (weakest link pruning)*. Với mỗi giá trị của tham số điều hòa không âm $\alpha \ge 0$, ta tìm cây con $T \subset T_0$ tối thiểu hóa hàm chi phí phạt: $$\sum}^{|T|} \sum_{i: x_i \in R_m} (y_i - \hat{y{R_m})^2 + \alpha |T| = \text{RSS}(T) + \alpha |T|$$ Trong đó: * $|T|$ là số lượng nút lá của cây con $T$. * $\text{RSS}(T)$ là tổng bình phương sai số của cây con $T$. * $\alpha \ge 0$ là **hệ số phạt độ phức tạp (complexity parameter)**.

      Ý nghĩa của tham số $\alpha$ trong hàm chi phí phạt

      Vai trò của $\alpha$ ở đây hoàn toàn tương đồng với tham số $\lambda$ trong hồi quy Lasso:
      • Khi $\alpha = 0$: Số hạng phạt biến mất, cây con tối ưu chính là cây lớn ban đầu $T = T_0$.
      • Khi $\alpha \to \infty$: Mức phạt trên số nút lá trở nên vô cùng lớn, ép cây con phải co lại thành một nút gốc duy nhất có 1 lá ($|T| = 1$).
      • Với mỗi giá trị $\alpha$, luôn tồn tại một cây con $T_\alpha$ duy nhất đạt chi phí nhỏ nhất. Ta dùng Kiểm định chéo K-lần (K-fold Cross-Validation) để quét tìm giá trị $\alpha$ cho sai số kiểm tra nhỏ nhất.

      Phòng thí nghiệm F
      Cây Quyết Định và Tỉa Cành theo Độ Phức Tạp Chi Phí (Cost-Complexity Pruning)
      Kéo thanh trượt tham số phạt α để quan sát các cành sâu tự động bị tỉa bớt và tìm cấu trúc cây tối ưu
      Sơ đồ Cấu trúc Cây: các nút lá và điều kiện cắt (nhánh mờ nét đứt là cành đã bị tỉa)
      Trái: Phân hoạch không gian 2D (các hộp Rⱼ) · Phải: Đường cong Train RSS vs Test CV MSE theo α
      0.02
      α = 0: Cây lớn đầy đủ. α lớn: Phạt nặng số lá |T|, ép tỉa cành.
      4
      Cây càng sâu càng nhiều lá nhưng phương sai càng cao.
      Số nút lá |T|7
      Tham số α0.020
      Train RSS/Error0.14
      Test CV MSE0.38
      Đánh giá câyKhớp vừa vặn
      Diễn giải

      Quan sát sơ đồ cây ở trên: Khi α = 0.00, cây giữ nguyên mọi cành sâu (7 lá), Train RSS rất thấp nhưng Test CV MSE lớn do quá khớp. Khi bạn tăng α, các nhánh con có mức giảm sai số nhỏ nhất sẽ bị tỉa đầu tiên (chuyển sang màu xám mờ). Ở điểm cực tiểu của đường cong Test CV MSE (đỏ), cây đạt kích thước cân bằng hoàn hảo!

      Việc cần làm: ① Để α = 0.00: xem các vùng chữ nhật trên không gian 2D bị chia nhỏ vụn vặt. ② Kéo từ từ α lên khoảng 0.025 – 0.040: các hộp nhỏ sáp nhập lại thành các vùng lớn trơn tru, và Test CV MSE chạm đáy chữ U. ③ Kéo α > 0.08: cây bị tỉa trụi chỉ còn 1 hoặc 2 lá duy nhất — mô hình rơi vào trạng thái dưới khớp (underfitting)!

      --- ### 8.1.2. Cây Phân Loại (Classification Trees) Cây phân loại giải quyết bài toán mà biến phản hồi $Y$ mang tính định tính (chẳng hạn dự đoán một khách hàng sẽ mua hàng: `Yes` hay `No`). Đối với cây phân loại: * Dự đoán cho quan sát rơi vào vùng lá $R_m$ là **lớp chiếm đa số (majority class)** của các quan sát huấn luyện trong vùng đó. * Tỷ lệ các quan sát trong vùng $R_m$ thuộc về lớp thứ $k$ ($k = 1, \dots, K$) được ký hiệu là: $$\hat{p}
      } = \frac{1}{N_m} \sum_{i \in R_m} I(y_i = k)$$ Khi xây dựng cây phân loại, ta không thể dùng RSS. Thay vào đó, ba thước đo phổ biến nhất là: #### 1. Tỷ Lệ Lỗi Phân Loại (Classification Error Rate) Tỷ lệ các quan sát trong vùng không thuộc về lớp chiếm đa số: $$E_m = 1 - \max_k (\hat{p{mk})$$ Mặc dù rất trực quan, tỷ lệ lỗi phân loại lại **không đủ độ nhạy (insufficiently sensitive)** để phát triển cây. Một nhát cắt có thể làm tăng độ thuần khiết của các nút con nhưng giá trị $E_m$ trung bình trước và sau khi cắt vẫn không đổi! #### 2. Chỉ Số Gini (Gini Index) Chỉ số Gini đo lường tổng phương sai giữa các lớp trong nút $m$: $$G_m = \sum}^K \hat{p{mk} (1 - \hat{p}}) = 1 - \sum_{k=1}^K \hat{p{mk}^2$$ Chỉ số Gini là thước đo **độ thuần khiết của nút (node purity)**: * Nếu một nút chỉ chứa toàn quan sát của một lớp duy nhất, $\hat{p}_{mk} = 1$ và các $\hat{p}_{mk'} = 0$, khi đó $G_m = 0$ (thuần khiết tuyệt đối). * Nếu các lớp phân bố đều nhau, $G_m$ đạt giá trị cực đại. * Do đó, chỉ số Gini càng nhỏ, nút phân chia càng thuần khiết và phân loại càng tin cậy. #### 3. Entropy Chéo (Cross-Entropy / Deviance) Xuất phát từ lý thuyết thông tin của Claude Shannon, Entropy đo mức độ hỗn loạn của nút: $$D_m = - \sum}^K \hat{p{mk} \log \hat{p}}$$ Tương tự như chỉ số Gini, nếu nút $m$ thuần khiết (chỉ gồm một lớp), thì $D_m \approx 0$ (quy ước $0 \log 0 = 0$). Ngược lại, nếu các lớp phân tán đều, Entropy đạt giá trị cao nhất.

      Quy tắc vàng khi chọn tiêu chuẩn phân chia và tỉa cành

      • Khi phát triển cây (growing tree): Luôn ưu tiên dùng Chỉ số Gini hoặc Entropy vì chúng đánh giá độ thuần khiết của nút tinh nhạy hơn hẳn so với tỷ lệ lỗi.
      • Khi tỉa cây (pruning tree): Có thể dùng Tỷ lệ lỗi phân loại nếu mục đích cuối cùng của mô hình là tối đa hóa độ chính xác dự đoán tổng thể.

      --- ### 8.1.3. So Sánh Cây Quyết Định và Các Mô Hình Tuyến Tính Mô hình nào vượt trội hơn: Cây quyết định hay Mô hình tuyến tính cổ điển? Câu trả lời hoàn toàn phụ thuộc vào **cấu trúc hình học thực tế của dữ liệu**. Giả sử ta xét bài toán 2 biến dự đoán $X_1, X_2$: * **Mô hình tuyến tính** giả định dạng hàm: $$f(X) = \beta_0 + \beta_1 X_1 + \beta_2 X_2$$ Ranh giới phân tách của mô hình tuyến tính là một đường thẳng chéo cắt ngang không gian. * **Cây quyết định** phân chia không gian bằng các nhát cắt trực giao song song với các trục tọa độ: $$f(X) = \sum_{m=1}^M c_m I(X \in R_m)$$ Ranh giới phân tách của cây quyết định là tập hợp các đường gấp khúc tạo thành các hộp hình chữ nhật.
      Ranh giới Thực tế Tuyến tính (Chéo) Hồi quy tuyến tính (xanh) vượt trội; Cây (vàng nét đứt) phải xấp xỉ bậc thang. Ranh giới Thực tế Dạng Hộp Trực giao Cây quyết định (vàng) cắt hộp hoàn hảo; Mô hình tuyến tính (xanh nét đứt) bất lực.
      Hình 8.2. So sánh bản chất hình học giữa Mô hình tuyến tính và Cây quyết định. Trái: Khi ranh giới thật là đường chéo phẳng, mô hình tuyến tính tối ưu tuyệt đối. Phải: Khi ranh giới thực tế là các lát cắt song song với trục, cây quyết định thể hiện ưu thế vượt trội.
      * Nếu ranh giới thực tế là một đường chéo phẳng, mô hình tuyến tính sẽ khớp hoàn hảo, trong khi cây quyết định phải dùng vô số nhát cắt bậc thang zíc-zắc để xấp xỉ đường chéo đó (kém hiệu quả). * Nếu ranh giới thực tế có dạng hộp hoặc chứa các tương tác phức tạp (ví dụ: $Y$ chỉ cao khi cả $X_1 > 5$ VÀ $X_2 < 3$), cây quyết định sẽ áp đảo hoàn toàn mô hình tuyến tính cổ điển.
      Phòng thí nghiệm 15 · 3D
      Mặt dự đoán ŷ(x⁽¹⁾, x⁽²⁾): năm mô hình, năm hình dạng
      Kéo để xoay · kéo vạch tím trên bản đồ để dời lát cắt
      Bề mặt dự đoán (màu theo ŷ) · chấm: dữ liệu huấn luyện · đường tím: lát cắt x⁽²⁾ = s
      Nhìn từ trên — kéo vạch tím
      Lát cắt: ŷ theo x⁽¹⁾ khi cố định x⁽²⁾ = s
      120 điểm huấn luyện + 200 điểm kiểm tra, nhiễu σ = 0,3 (MSE không thể thấp hơn 0,09).
      5
      2
      6
      0.00
      MSE train—
      MSE test—
      Tham số—
      Diễn giải

      —

      Việc cần làm: ① Mô hình Cây trên dữ liệu hai cái hộp: kéo độ sâu từ 1 lên 4 và nhìn bậc thang mọc thêm bậc trên bản đồ lẫn trên mặt 3D. Cây sâu 4 (12 lá) đạt MSE test ≈ 0,17, trong khi Tuyến tính chịu chết ở 0,41 — đúng tình huống “$Y$ chỉ cao khi $X_1 > a$ VÀ $X_2 < b$” mà mục 8.1.3 mô tả. ② Đổi sang dữ liệu mặt phẳng nghiêng: cây sâu 6 với 25 lá vẫn thua ba tham số của một mặt phẳng (0,14 so với 0,08) — bậc thang xấp xỉ một đường chéo rất tốn kém, đúng như Hình 8.2. ③ k-NN với k = 1: mặt gồ ghề chạm đúng từng điểm (MSE train = 0) nhưng MSE test 0,18; k quanh 5–10 mới tốt (≈ 0,11). ④ Kéo vạch tím để dời lát cắt: lát cắt của cây là hàm bậc thang, của mặt phẳng là đường thẳng, của k-NN là đường gấp khúc — ba “dạng hàm” khác nhau cho cùng một câu hỏi $f(X) = ?$.

      --- ### 8.1.4. Đánh Giá Toàn Diện Ưu và Nhược Điểm của Cây Đơn Lẻ | Ưu điểm nổi bật | Nhược điểm cốt tử | | :--- | :--- | | **Dễ giải thích và trực quan hóa**: Cây quyết định có thể vẽ ra giấy và giải thích dễ dàng cho cả những người không chuyên về toán. | **Độ chính xác dự đoán thấp hơn**: Một cây đơn lẻ hiếm khi đạt độ chính xác tương đương SVM hay Boosting. | | **Phản chiếu tư duy con người**: Mô phỏng sát sao quy trình ra quyết định theo từng điều kiện rẽ nhánh "nếu... thì...". | **Độ nhạy và phương sai rất cao**: Chỉ cần thay đổi nhẹ một vài điểm trong tập dữ liệu huấn luyện, cấu trúc phân nhánh của cây có thể biến dạng hoàn toàn. | | **Tự nhiên xử lý biến định tính**: Có thể phân chia trực tiếp trên các biến hạng mục mà không cần tạo biến giả (dummy variables). | **Khó xấp xỉ mối quan hệ tuyến tính mượt mà**: Phải dùng rất nhiều nhánh bậc thang để xấp xỉ một đường thẳng nghiêng. | Để giữ trọn những ưu điểm tính toán mạnh mẽ của cây nhưng triệt tiêu hoàn toàn nhược điểm về độ chính xác và phương sai cao, chúng ta bước vào thế giới của **Các Phương Pháp Kết Hợp Cây (Ensemble Methods)**. --- ## 8.2. Các Phương Pháp Kết Hợp Cây (Ensemble Methods) ### 8.2.1. Đóng Bao Mẫu Bootstrap (Bagging - Bootstrap Aggregation) Cây quyết định đơn lẻ có nhược điểm chí mạng là **phương sai cao**. Đóng bao mẫu (Bagging) là một quy trình thống kê tổng quát giúp giảm thiểu phương sai của bất kỳ phương pháp học máy nào, đặc biệt hữu hiệu với cây quyết định. Xuất phát từ nguyên lý xác suất cơ bản: Nếu ta có $B$ biến ngẫu nhiên độc lập cùng phân phối $Z_1, \dots, Z_B$ với phương sai $\sigma^2$, thì phương sai của giá trị trung bình $\bar{Z} = \frac{1}{B}\sum_{b=1}^B Z_b$ sẽ là $\frac{\sigma^2}{B}$. Việc lấy trung bình nhiều ước lượng độc lập giúp giảm phương sai theo cấp số nhân! Tuy nhiên, trong thực tế ta chỉ có một tập dữ liệu huấn luyện duy nhất. Làm sao để có được $B$ tập dữ liệu khác nhau? Câu trả lời chính là **Kỹ thuật Tự lấy mẫu (Bootstrap)**: 1. Rút $B$ mẫu có hoàn lại (bootstrap samples) từ tập dữ liệu gốc, mỗi mẫu có kích thước đúng bằng $n$. 2. Trên mỗi mẫu bootstrap thứ $b$, huấn luyện một cây quyết định sâu $\hat{f}^{*b}(x)$ mà **không cần tỉa cành** (cây sâu có độ chệch rất thấp dù phương sai cao). 3. Kết hợp kết quả của $B$ cây: * **Hồi quy**: Lấy trung bình cộng dự đoán của $B$ cây: $$\hat{f{\text{bag}}(x) = \frac{1}{B} \sum g(X; T_j, M_j)$$ Sau đó, cây $T_k$ được biến đổi ngẫu nhiên thông qua một trong các phép biến đổi nhỏ:}^B \hat{f}^{*b}(x)$$ * **Phân loại**: Áp dụng nguyên tắc bỏ phiếu đa số (majority vote) trong số $B$ cây. #### Ước Lượng Sai Số Ngoài Mẫu (Out-of-Bag - OOB Error) Một lợi thế xuất sắc của Bagging là khả năng đánh giá sai số kiểm tra một cách hoàn toàn khách quan mà **không cần thực hiện kiểm định chéo (Cross-Validation)**. Với một tập dữ liệu có $n$ quan sát, khi rút ngẫu nhiên $n$ lần có hoàn lại, xác suất một quan sát bất kỳ KHÔNG được chọn trong một lần rút là $1 - 1/n$. Do đó, xác suất quan sát đó không bao giờ xuất hiện trong mẫu bootstrap cỡ $n$ là: $$\lim_{n \to \infty} \left(1 - \frac{1}{n}\right)^n = \frac{1}{e} \approx 0.368 \approx 36.8\%$$ Như vậy, trung bình mỗi cây chỉ được huấn luyện trên khoảng $63.2\%$ số quan sát; còn lại **$1/3$ số quan sát không hề tham gia huấn luyện cây đó**, được gọi là các quan sát **ngoài mẫu (Out-of-Bag - OOB)**. Để dự đoán cho quan sát thứ $i$, ta chỉ lấy trung bình (hoặc bỏ phiếu) trên các cây mà quan sát $i$ là OOB (khoảng $B/3$ cây). Sai số tính trên toàn bộ các dự đoán OOB này là ước lượng không thiên vị của sai số kiểm tra! #### Thước Đo Tầm Quan Trọng của Biến (Variable Importance Measures) Bagging kết hợp hàng trăm cây, làm mất đi tính minh bạch của một sơ đồ cây đơn lẻ. Để khôi phục khả năng diễn giải, ta sử dụng hai thước đo tầm quan trọng của biến: 1. **Đối với hồi quy**: Tính tổng lượng giảm RSS tạo ra bởi các nhát cắt dựa trên biến $X_j$, tính trung bình qua tất cả $B$ cây. Biến nào làm giảm RSS càng nhiều thì càng quan trọng. 2. **Đối với phân loại**: Tính tổng lượng giảm chỉ số Gini (hoặc Entropy) tạo ra bởi các nhát cắt dựa trên biến $X_j$, lấy trung bình qua $B$ cây. --- ### 8.2.2. Rừng Ngẫu Nhiên (Random Forests) Mặc dù Bagging vượt trội hơn cây đơn lẻ, nó vẫn tồn tại một điểm nghẽn tiềm ẩn: **Sự tương quan giữa các cây (Tree correlation)**. Hãy tưởng tượng trong dữ liệu có một biến dự đoán cực mạnh cùng vài biến dự đoán vừa phải. Trong Bagging, hầu như tất cả $B$ cây bootstrap đều chọn biến mạnh đó làm nhát cắt ở ngay nút gốc! Do đó, tất cả các cây đều có cấu trúc tương tự nhau. Theo lý thuyết xác suất, nếu ta lấy trung bình của $B$ biến ngẫu nhiên có phương sai $\sigma^2$ và hệ số tương quan dương $\rho$, thì phương sai của trung bình là: $$\text{Var}(\bar{X}) = \rho \sigma^2 + \frac{1 - \rho}{B} \sigma^2$$ Khi $B \to \infty$, số hạng thứ hai tiến về 0, nhưng số hạng thứ nhất vẫn còn lại $\rho \sigma^2 > 0$! Nếu các cây tương quan cao với nhau ($\rho$ lớn), việc lấy trung bình hàng nghìn cây cũng không thể kéo giảm phương sai xuống mức tối ưu.
      Cơ Chế Khử Tương Quan (Decorrelation) trong Random Forests Bagging Thuần Túy (m = p) Mọi cây đều xét trọn bộ p biến X₁ X₁ X₁ Biến mạnh X₁ thống trị nút gốc! Các cây tương quan cao: Var(X̄) → ρσ² > 0 Không thể giảm phương sai triệt để Random Forests (m ≈ √p) Mỗi nút chỉ chọn ngẫu nhiên m biến X₃ X₇ X₂ Buộc cây khám phá các biến tiềm năng khác Hệ số tương quan ρ giảm mạnh gần về 0! Phương sai tổng thể sụt giảm ngoạn mục
      Hình 8.3. So sánh cơ chế chọn biến giữa Bagging và Random Forests. Việc cưỡng bức chỉ chọn $m pprox \sqrt{p}$ biến tại mỗi lần phân chia giúp phá vỡ sự độc quyền của các biến mạnh, khử tương quan giữa các cây.
      **Rừng ngẫu nhiên (Random Forests)** giải quyết triệt để vấn đề này bằng một cơ chế tinh tế: **Khử tương quan giữa các cây (Decorrelating the trees)**.

      Nguyên lý cốt lõi của Random Forests

      Khi xây dựng mỗi cây trong rừng: tại mỗi lần phân chia nút, thuật toán không cho phép xem xét toàn bộ $p$ biến, mà chỉ được phép chọn ngẫu nhiên một tập con gồm $m$ biến dự đoán.
      • Với bài toán phân loại: chọn thông thường là $m \approx \sqrt{p}$.
      • Với bài toán hồi quy: chọn thông thường là $m \approx p/3$.
      Nhát cắt chỉ được phép thực hiện trên 1 trong $m$ biến này. Nhờ đó, các biến mạnh không thể độc chiếm mọi nút gốc, buộc các cây phải khám phá tiềm năng của các biến dự đoán khác, làm cho các cây trở nên độc lập hơn (giảm mạnh $\rho$), kéo phương sai tổng thể giảm sâu!

      *Lưu ý*: Nếu ta chọn $m = p$, Random Forests chính là Bagging. Khi chọn $m < p$ (đặc biệt khi dữ liệu có nhiều biến tương quan), Random Forests luôn vượt trội hơn Bagging một cách rõ rệt. --- ### 8.2.3. Tăng Cường (Boosting - Gradient Boosting) Trong khi Bagging và Random Forests xây dựng các cây độc lập song song từ các mẫu dữ liệu khác nhau, **Tăng cường (Boosting)** tiếp cận bài toán theo triết lý hoàn toàn đối lập: **Xây dựng các cây tuần tự (sequential learning)**, trong đó mỗi cây mới được sinh ra để sửa chữa những sai lầm mà các cây trước đó mắc phải. Triết lý của Boosting là: *"Học chậm để hiểu sâu"* (Learn slowly). Thay vì trồng những cây sâu phức tạp khớp dữ liệu trong một bước, Boosting xây dựng hàng loạt cây rất nông (shallow trees) và cập nhật mô hình từng chút một dựa trên **phần dư (residuals)**. #### Thuật Toán Boosting cho Cây Hồi Quy 1. Khởi tạo giá trị dự đoán ban đầu bằng 0: $\hat{f}(x) = 0$, và phần dư ban đầu bằng chính biến phản hồi: $r_i = y_i$ cho mọi $i = 1, \dots, n$. 2. Với mỗi vòng lặp $b = 1, 2, \dots, B$: * Khớp một cây quyết định $\hat{f}^b(x)$ với $d$ nhát cắt (tức có $d+1$ lá) trên tập dữ liệu $(X, r)$, tức dùng phần dư hiện tại làm biến đích. * Cập nhật hàm dự đoán tổng thể bằng cách cộng thêm phiên bản thu nhỏ của cây mới: $$\hat{f}(x) \leftarrow \hat{f}(x) + \lambda \hat{f}^b(x)$$ * Cập nhật lại các phần dư cho vòng lặp tiếp theo: $$r_i \leftarrow r_i - \lambda \hat{f}^b(x_i)$$ 3. Mô hình tăng cường cuối cùng là tổng có trọng số của tất cả $B$ cây: $$\hat{f}(x) = \sum_{b=1}^B \lambda \hat{f}^b(x)$$ #### Ba Siêu Tham Số Then Chốt của Boosting 1. **Số lượng cây $B$**: Khác với Bagging và Random Forests (nơi $B$ lớn không bao giờ gây quá khớp), trong Boosting, nếu $B$ quá lớn, mô hình sẽ dần dần học cả vào các vết nhiễu của dữ liệu dẫn đến **quá khớp (overfitting)**. Ta chọn $B$ tối ưu thông qua kiểm định chéo. 2. **Tham số co ngót / Tốc độ học $\lambda$ (Shrinkage parameter / Learning rate)**: Thường là một số dương nhỏ như $0.01$ hoặc $0.001$. $\lambda$ kiểm soát tốc độ học của thuật toán. Giá trị $\lambda$ càng nhỏ đòi hỏi số cây $B$ càng lớn, nhưng thường mang lại độ chính xác kiểm tra cao hơn đáng kể. 3. **Số nhát cắt của mỗi cây $d$ (Interaction depth)**: Kiểm soát độ phức tạp của từng cây thành phần. Khi $d=1$, mỗi cây chỉ có đúng 1 nhát cắt và 2 nút lá (gọi là **gốc cây - stump**). Mô hình khi đó là một mô hình cộng tính đơn giản $f(X) = \sum f_j(X_j)$. Nếu $d=2$, cây có thể mô hình hóa tương tác giữa 2 biến. Thông thường $d$ chỉ cần từ $1$ đến $6$ là đủ cho hầu hết các bài toán thực tế. --- ### 8.2.4. Cây Hồi Quy Cộng Tính Bayes (BART - Bayesian Additive Regression Trees) **BART** là một phương pháp ensemble hiện đại kết hợp sức mạnh của cây quyết định với khung lý thuyết xác suất Bayes. Mô hình BART biểu diễn biến phản hồi dưới dạng tổng của $K$ cây quyết định (thường cố định $K = 200$): $$Y = \sum_{k=1}^K g(X; T_k, M_k) + \epsilon, \quad \epsilon \sim \mathcal{N}(0, \sigma^2)$$ Trong đó $T_k$ là cấu trúc phân nhánh của cây thứ $k$, và $M_k$ là tập hợp các giá trị dự đoán tại các nút lá của nó. #### Cơ Chế Hoạt Động của BART BART không trồng các cây mới từ đầu như Boosting, mà áp dụng giải thuật **MCMC (Markov Chain Monte Carlo)** để liên tục hiệu chỉnh và biến đổi nhẹ (perturb) $K$ cây hiện có qua từng vòng lặp: 1. **Khởi tạo**: Tất cả $K$ cây ban đầu được đặt là các nút gốc đơn giản nhất. 2. **Ở mỗi vòng lặp MCMC $b = 1, \dots, B$**: Ta duyệt qua từng cây $k = 1, \dots, K$. Để cập nhật cây $k$, ta tính **phần dư từng phần (partial residual)**: $$R_k = Y - \sum_{j \neq k
    • Mọc nhánh (Grow): Chọn ngẫu nhiên một nút lá và chia đôi nó thành hai lá mới.
    • Tỉa cành (Prune): Chọn ngẫu nhiên một cặp lá và gộp chúng lại thành một lá duy nhất.
    • Đổi điều kiện cắt (Change): Giữ nguyên cấu trúc cây nhưng thay đổi biến cắt hoặc ngưỡng cắt tại một nút trong.
  3. Phân phối tiên nghiệm chuẩn hóa (Regularizing Priors): Khung tiếp cận Bayes gán một phân phối tiên nghiệm để phạt nặng các cây quá sâu và ép các giá trị tại nút lá phải co ngót về 0. Nhờ đó, mỗi cây chỉ đóng góp một phần siêu nhỏ vào tổng thể, ngăn chặn hoàn toàn hiện tượng quá khớp mà không cần tinh chỉnh quá nhiều siêu tham số phức tạp!

Dự đoán cuối cùng của BART thu được bằng cách lấy trung bình mẫu các dự đoán sau khi đã loại bỏ một số vòng lặp đầu tiên (giai đoạn khởi động - burn-in).


8.3. Thực Hành Python (Lab: Tree-Based Methods)

Dưới đây là mã nguồn Python chuẩn mực minh họa việc ứng dụng các thuật toán dựa trên cây trên các tập dữ liệu kinh điển bằng scikit-learn và thư viện ISLP.

Khởi tạo và Phân loại Cây Quyết Định trên Carseats

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, KFold, cross_val_score
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor, plot_tree
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import accuracy_score, mean_squared_error

# 1. CÂY PHÂN LOẠI (CLASSIFICATION TREE)
# Tập dữ liệu Carseats: biến Sales được nhị phân thành High (1 nếu Sales > 8)
from ISLP import load_data
carseats = load_data('Carseats')
carseats['High'] = (carseats['Sales'] > 8).astype(int)

# Chuyển đổi các biến phân loại thành dummy variables
X = pd.get_dummies(carseats.drop(columns=['Sales', 'High']), drop_first=True)
y = carseats['High']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

# Khớp cây phân loại với tiêu chuẩn Entropy
clf = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
clf.fit(X_train, y_train)

# Đánh giá độ chính xác trên tập kiểm tra
y_pred = clf.predict(X_test)
print(f'Độ chính xác cây phân loại (max_depth=3): {accuracy_score(y_test, y_pred):.3f}')

# Trực quan hóa cây quyết định
plt.figure(figsize=(12, 6))
plot_tree(clf, feature_names=X.columns, class_names=['No', 'Yes'], filled=True)
plt.title('Cây phân loại Carseats (max_depth=3)')
plt.show()

Tỉa Cây theo Độ Phức Tạp Chi Phí với K-Fold CV

# Tỉa cây: Tìm đường đi tỉa cành (Cost-Complexity Pruning Path)
clf_full = DecisionTreeClassifier(criterion='entropy', random_state=0)
path = clf_full.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas = path.ccp_alphas[:-1] # Loại bỏ alpha cực đại cuối cùng

# Tìm alpha tối ưu qua 10-fold CV
cv_scores = []
for alpha in ccp_alphas:
    tree = DecisionTreeClassifier(criterion='entropy', ccp_alpha=alpha, random_state=0)
    scores = cross_val_score(tree, X_train, y_train, cv=10, scoring='accuracy')
    cv_scores.append(scores.mean())

best_alpha = ccp_alphas[np.argmax(cv_scores)]
print(f'Tham số alpha tối ưu từ CV: {best_alpha:.5f}')

# Đánh giá cây sau khi tỉa
pruned_tree = DecisionTreeClassifier(criterion='entropy', ccp_alpha=best_alpha, random_state=0)
pruned_tree.fit(X_train, y_train)
print(f'Độ chính xác sau khi tỉa: {pruned_tree.score(X_test, y_test):.3f}')

Bagging, Random Forests và Gradient Boosting trên Tập Boston

# 2. CÂY HỒI QUY: BAGGING VÀ RANDOM FORESTS TRÊN TẬP DỮ LIỆU BOSTON
boston = load_data('Boston')
X_b = boston.drop(columns=['medv'])
y_b = boston['medv']
X_tr, X_te, y_tr, y_te = train_test_split(X_b, y_b, test_size=0.3, random_state=1)

# Bagging: Sử dụng toàn bộ m = p đặc trưng tại mỗi nhát cắt (max_features=1.0)
bag = RandomForestRegressor(max_features=1.0, oob_score=True, random_state=1)
bag.fit(X_tr, y_tr)
print(f'Bagging Test MSE: {mean_squared_error(y_te, bag.predict(X_te)):.2f}')
print(f'Bagging OOB Score (R^2): {bag.oob_score_:.3f}')

# Random Forest: Chỉ sử dụng m = p/3 đặc trưng (hoặc sqrt(p))
rf = RandomForestRegressor(max_features='sqrt', random_state=1)
rf.fit(X_tr, y_tr)
print(f'Random Forest Test MSE: {mean_squared_error(y_te, rf.predict(X_te)):.2f}')

# Tầm quan trọng của các biến trong Random Forest
importance = pd.Series(rf.feature_importances_, index=X_b.columns).sort_values(ascending=False)
print('\nTop 5 biến quan trọng nhất (Random Forest):')
print(importance.head(5))

# Gradient Boosting: Học tuần tự trên phần dư
gbr = GradientBoostingRegressor(n_estimators=500, learning_rate=0.01, max_depth=3, random_state=1)
gbr.fit(X_tr, y_tr)
print(f'\nGradient Boosting Test MSE: {mean_squared_error(y_te, gbr.predict(X_te)):.2f}')

09Chương 9: Máy Vectơ Hỗ Trợ (Support Vector Machines - SVM)

Trong chương này, chúng ta nghiên cứu Máy Vectơ Hỗ Trợ (Support Vector Machines - SVM), một trong những phương pháp tiếp cận kinh điển, thanh lịch và mạnh mẽ nhất của học máy để giải quyết bài toán phân loại nhị phân và phi tuyến.

Để thấu hiểu sâu sắc bản chất toán học của SVM, hành trình của chúng ta sẽ được xây dựng tuần tự qua ba nấc thang tiến hóa:

  1. Bộ phân loại Siêu phẳng Cực đại (Maximal Margin Classifier): Thiết lập lý tưởng khi hai lớp dữ liệu có thể phân tách hoàn hảo bằng một ranh giới thẳng.
  2. Bộ phân loại Vectơ Hỗ trợ (Support Vector Classifier / Soft Margin Classifier): Nới lỏng ràng buộc bằng khái niệm "lề mềm" để chịu đựng nhiễu và xử lý dữ liệu không thể phân tách tuyến tính hoàn hảo.
  3. Máy Vectơ Hỗ trợ (Support Vector Machine - SVM): Đột phá toán học thông qua "Thủ thuật Kernel" (Kernel Trick), cho phép tạo ra các ranh giới quyết định phi tuyến uốn lượn phức tạp trong không gian nhiều chiều với chi phí tính toán tối thiểu.

Cuối chương, chúng ta sẽ mở rộng SVM cho bài toán phân loại đa lớp (multi-class), khám phá mối liên hệ sâu sắc giữa SVM và Hồi quy Logistic thông qua hàm mất mát bản lề (Hinge Loss), và thực hành toàn diện bằng Python trên thư viện scikit-learn.


9.1. Bộ Phân Loại Siêu Phẳng Cực Đại (Maximal Margin Classifier)

9.1.1. Siêu Phẳng là gì? (What Is a Hyperplane?)

Trong không gian $p$ chiều, một siêu phẳng (hyperplane) là một không gian con affine phẳng có số chiều bằng $p - 1$:

  • Trong không gian 2 chiều ($p = 2$), siêu phẳng đơn giản là một đường thẳng phẳng tuân theo phương trình: $$\beta_0 + \beta_1 X_1 + \beta_2 X_2 = 0$$

  • Trong không gian 3 chiều ($p = 3$), siêu phẳng là một mặt phẳng 2 chiều: $$\beta_0 + \beta_1 X_1 + \beta_2 X_2 + \beta_3 X_3 = 0$$

  • Tổng quát, trong không gian $p$ chiều, phương trình siêu phẳng có dạng: $$\beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_p X_p = 0$$

Nếu một điểm $X = (X_1, \dots, X_p)^T$ thỏa mãn phương trình trên, điểm đó nằm chính xác trên siêu phẳng. Nếu phương trình cho kết quả $> 0$, điểm nằm về một phía của siêu phẳng; nếu $< 0$, điểm nằm về phía đối diện. Như vậy, siêu phẳng chia không gian $p$ chiều thành hai nửa không gian riêng biệt.


9.1.2. Phân Loại bằng Siêu Phẳng Phân Tách (Separating Hyperplane)

Giả sử ta có tập dữ liệu huấn luyện gồm $n$ quan sát trong không gian $p$ chiều: $$x_1, x_2, \dots, x_n \in \mathbb{R}^p$$ và các nhãn lớp tương ứng thuộc về hai lớp nhị phân, quy ước ký hiệu là $y_i \in \{-1, +1\}$.

Nếu tồn tại một siêu phẳng có khả năng phân tách hoàn hảo hai lớp dữ liệu mà không mắc bất kỳ sai sót nào, ta gọi đó là siêu phẳng phân tách (separating hyperplane). Khi đó:

  • $\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip} > 0$ đối với mọi quan sát có $y_i = +1$.
  • $\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip} < 0$ đối với mọi quan sát có $y_i = -1$.

Hai điều kiện trên có thể viết cô đọng thành một bất đẳng thức duy nhất cho toàn bộ $n$ quan sát:

$$y_i \left(\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip}\right) > 0, \quad \forall i = 1, \dots, n$$

Khi đã tìm được siêu phẳng phân tách, việc phân loại một quan sát kiểm tra mới $x^*$ trở nên vô cùng đơn giản: ta chỉ cần tính giá trị hàm $f(x^*) = \beta_0 + \beta_1 x_1^* + \dots + \beta_p x_p^*$:

  • Nếu $f(x^*) > 0$, ta dự đoán $\hat{y}^* = +1$.
  • Nếu $f(x^*) < 0$, ta dự đoán $\hat{y}^* = -1$.

Hơn nữa, độ lớn tuyệt đối $|f(x^*)|$ phản ánh độ tin cậy của phép dự đoán: nếu $|f(x^*)|$ rất lớn, điểm kiểm tra nằm rất xa siêu phẳng về phía đúng của nó, cho thấy ta rất tự tin vào kết quả phân loại; nếu $|f(x^*)| \approx 0$, điểm nằm sát rạt ranh giới phân định, quyết định phân loại trở nên kém chắc chắn hơn.


9.1.3. Bộ Phân Loại Siêu Phẳng Cực Đại (The Maximal Margin Classifier)

Nếu dữ liệu có thể phân tách tuyến tính hoàn hảo, trên thực tế sẽ tồn tại vô số siêu phẳng phân tách khác nhau. Vậy ta nên chọn siêu phẳng nào trong số đó?

Lựa chọn tự nhiên và tối ưu nhất là chọn siêu phẳng nằm cách xa các điểm dữ liệu của cả hai lớp nhất có thể. Khoảng cách ngắn nhất từ các điểm dữ liệu huấn luyện tới siêu phẳng được gọi là lề (margin). Siêu phẳng phân tách có độ rộng lề lớn nhất được gọi là Siêu phẳng Cực đại (Maximal Margin Hyperplane), và thuật toán phân loại tương ứng là Bộ phân loại Siêu phẳng Cực đại (Maximal Margin Classifier).

Siêu Phẳng Lề Cực Đại (Maximal Margin) và Các Vectơ Hỗ Trợ f(x) = -1 f(x) = β₀ + β₁X₁ + β₂X₂ = 0 f(x) = +1 Lề M Vectơ hỗ trợ (+) Vectơ hỗ trợ (-)
Hình 9.1. Cấu trúc Siêu phẳng Lề Cực đại. Đường đỏ đậm ở giữa là siêu phẳng phân tách $f(x) = 0$. Hai đường nét đứt biểu thị biên của lề với độ rộng $M$. Các điểm nằm chính xác trên đường biên lề (khoanh tròn đôi) là các Vectơ Hỗ Trợ duy nhất quyết định vị trí của siêu phẳng.

Về mặt toán học, bài toán tìm siêu phẳng lề cực đại được phát biểu dưới dạng bài toán tối ưu hóa có ràng buộc:

$$\max_{\beta_0, \beta_1, \dots, \beta_p, M} M$$

thỏa mãn các điều kiện:

  1. Chuẩn hóa độ dài vectơ pháp tuyến: $$\sum_{j=1}^p \beta_j^2 = 1$$

  2. Mọi điểm dữ liệu phải nằm đúng phía và cách siêu phẳng ít nhất một khoảng $M$: $$y_i \left(\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip}\right) \ge M, \quad \forall i = 1, \dots, n$$

Trong đó $M > 0$ chính là độ rộng của lề.


Phòng thí nghiệm 16 · 3D
Siêu phẳng là một mặt phẳng thật — SVM trong ba chiều
Kéo để xoay · các nút dịch chuyển một điểm rồi giải lại toàn bộ
Hai lớp điểm trong không gian 3 chiều · mặt phẳng phân tách w·x − b = 0 (vàng) và hai mặt lề w·x − b = ±1 (nét đứt)
Thước lề — mỗi điểm đặt tại f(x) = w·x − b của nó; vectơ hỗ trợ (vòng vàng) nằm đúng trên ±1
1.50
Kéo nhỏ lại cho hai cụm chồng lấn — lúc đó không mặt phẳng nào tách hoàn hảo được nữa.
1000
Mức phạt cho mỗi đơn vị vi phạm lề. C = 1000 gần như lề cứng; C = 0,1 chấp nhận nhiều vi phạm để đổi lấy lề rộng.
Lề 2/‖w‖—
Vectơ hỗ trợ—
Vi phạm lề—
Độ chính xác—
Diễn giải

—

Việc cần làm: ① Đây là siêu phẳng $\beta_0 + \beta_1 X_1 + \beta_2 X_2 + \beta_3 X_3 = 0$ của mục 9.1.1 với $p = 3$ — lần đầu nó là một mặt phẳng nhìn thấy được (ở đây $\mathbf{w} = (\beta_1, \beta_2, \beta_3)$ và $b = -\beta_0$). Lề $2/\|\mathbf{w}\| = 0{,}71$, chỉ 4 vectơ hỗ trợ chạm hai mặt lề; trên thước bên dưới chúng nằm đúng tại $\pm 1$. ② Bấm Dịch một điểm ở xa: giải lại từ đầu mà $\mathbf{w}$ xoay đúng 0,00° — đúng như mục 9.1.4: quan sát nằm xa lề không ảnh hưởng tới bộ phân loại. ③ Bấm Đẩy một vectơ hỗ trợ vào lề: mặt phẳng xoay khoảng 19°, lề co từ 0,71 xuống 0,49 — một quan sát đổi chỗ, toàn bộ siêu phẳng đổi theo. ④ Kéo khoảng cách hai cụm xuống 0,8 để hai lớp chồng lấn (mục 9.2): còn 1 điểm vi phạm dù $C = 1000$. Hạ $C$ xuống 0,1: lề nở từ 0,13 lên 1,41 nhưng 38 điểm nằm trong lề — đúng cơ chế của tham số điều hoà $C$ ở mục 9.2.2. Với dữ liệu tách được, $C = 0{,}1$ vẫn cho 22 điểm vi phạm lề mà độ chính xác 100 %: vi phạm lề và phân loại sai là hai chuyện khác nhau.

9.1.4. Vectơ Hỗ Trợ là gì? (What Are Support Vectors?)

Khi giải bài toán tối ưu trên, ta phát hiện một tính chất hình học kỳ diệu: Siêu phẳng lề cực đại được định hình và giữ cố định chỉ bởi một số lượng rất ít các điểm dữ liệu!

Những điểm dữ liệu huấn luyện nằm chính xác trên đường biên của lề — tức thỏa mãn: $$y_i \left(\beta_0 + \sum_{j=1}^p \beta_j x_{ij}\right) = M$$ được gọi là các Vectơ Hỗ Trợ (Support Vectors).

Tính chất đặc biệt của các Vectơ Hỗ Trợ

• Các vectơ hỗ trợ đóng vai trò như những cây cột chống đỡ toàn bộ cấu trúc siêu phẳng. Nếu ta di chuyển nhẹ bất kỳ một vectơ hỗ trợ nào, siêu phẳng lề cực đại sẽ lập tức bị xoay chuyển hoặc tịnh tiến theo!
• Ngược lại, đối với mọi điểm dữ liệu khác nằm ngoài lề: dù bạn có dịch chuyển chúng, xáo trộn chúng, hay thậm chí xóa bỏ chúng hoàn toàn khỏi tập dữ liệu (miễn là không xâm phạm vào trong lề), thì siêu phẳng phân tách và độ rộng lề hoàn toàn không hề suy suyển!

Nhược Điểm của Siêu Phẳng Lề Cực Đại

Mặc dù rất tao nhã, Bộ phân loại Siêu phẳng Cực đại có hai điểm nghẽn nghiêm trọng trong thực tế:

  1. Quá nhạy cảm với dữ liệu cá biệt (High Variance): Chỉ cần thêm một điểm dữ liệu ngoại lai (outlier) nằm gần ranh giới, siêu phẳng có thể bị bẻ gập một góc rất lớn, làm giảm mạnh độ rộng lề của các điểm còn lại và suy giảm khả năng khái quát hóa.
  2. Không tồn tại nghiệm khi dữ liệu không tách biệt (Non-separable case): Trong thế giới thực, dữ liệu gần như luôn có sự chồng lấn nhẹ giữa các lớp do nhiễu đo đạc. Khi đó, không tồn tại bất kỳ siêu phẳng nào phân tách hoàn hảo, và bài toán tối ưu trên hoàn toàn vô nghiệm!

Để khắc phục triệt để hai vấn đề này, chúng ta cần nới lỏng khái niệm lề tuyệt đối thành lề mềm (soft margin).


9.2. Bộ Phân Loại Vectơ Hỗ Trợ (Support Vector Classifiers)

Thay vì bắt buộc mọi quan sát phải nằm hoàn toàn bên ngoài lề, chúng ta chủ động cho phép một số điểm được phép rơi vào trong vùng lề, hoặc thậm chí rơi sang nhầm phía của siêu phẳng. Ý tưởng này dẫn tới Bộ Phân Loại Vectơ Hỗ Trợ (Support Vector Classifier), hay còn gọi là Bộ phân loại Lề mềm (Soft Margin Classifier).

9.2.1. Thiết Lập Bài Toán Tối Ưu Lề Mềm

Chúng ta đưa vào các biến trượt (slack variables) $\epsilon_1, \epsilon_2, \dots, \epsilon_n \ge 0$ để đo lường mức độ vi phạm lề của từng quan sát:

$$\max_{\beta_0, \beta_1, \dots, \beta_p, \epsilon_1, \dots, \epsilon_n, M} M$$

thỏa mãn: $$\sum_{j=1}^p \beta_j^2 = 1$$ $$y_i \left(\beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip}\right) \ge M (1 - \epsilon_i), \quad \forall i = 1, \dots, n$$ $$\epsilon_i \ge 0, \quad \sum_{i=1}^n \epsilon_i \le C$$

Trong đó:

  • $\epsilon_i$ là biến bù vi phạm của quan sát thứ $i$:
    • Nếu $\epsilon_i = 0$: Quan sát $i$ nằm đúng phía và nằm an toàn bên ngoài lề (không vi phạm).
    • Nếu $0 < \epsilon_i \le 1$: Quan sát $i$ đã xâm phạm vào trong khoảng lề, nhưng vẫn nằm đúng phía của siêu phẳng phân tách.
    • Nếu $\epsilon_i > 1$: Quan sát $i$ đã vượt qua siêu phẳng và rơi sang sai phía (bị phân loại sai).
  • $C \ge 0$ là tham số ngân sách vi phạm (budget parameter), kiểm soát tổng mức độ vi phạm lề tối đa cho phép: $\sum_{i=1}^n \epsilon_i \le C$.

9.2.2. Vai Trò Cốt Lõi của Tham Số Điều Hòa $C$

Tham số $C$ đóng vai trò quyết định sự đánh đổi giữa Độ chệch (Bias) và Phương sai (Variance) của mô hình:

  • Khi $C$ lớn: Ngân sách vi phạm rất rộng lượng. Thuật toán cho phép nhiều điểm xâm phạm lề, lề mở rất rộng và thu nạp nhiều vectơ hỗ trợ hơn. Nhờ lề rộng bao dung, mô hình trở nên lì lợm, ít bị xao động bởi các điểm dị biệt $\implies$ Phương sai thấp nhưng Độ chệch cao hơn.
  • Khi $C$ nhỏ: Ngân sách khắt khe. Mô hình phạt nặng mọi vi phạm, ép lề phải co hẹp lại để ít điểm vi phạm nhất. Siêu phẳng phải uốn mình né tránh từng điểm dữ liệu $\implies$ Độ chệch thấp nhưng Phương sai cao (dễ quá khớp).
  • Khi $C = 0$: Bài toán quay trở về Bộ phân loại Siêu phẳng Cực đại tuyệt đối (không dung thứ bất kỳ vi phạm nào).

Đặc trưng quyết định của Bộ phân loại Vectơ Hỗ trợ

Chỉ những điểm dữ liệu nằm trên lề hoặc xâm phạm lề ($\epsilon_i > 0$) mới là các Vectơ Hỗ Trợ tham gia xác định siêu phẳng. Mọi quan sát khác nằm đúng phía ngoài lề đều hoàn toàn vô can!
Điều này giải thích tại sao Support Vector Classifier có sức đề kháng cực kỳ mạnh mẽ trước những điểm dị biệt nằm xa ranh giới phân loại, vượt trội hơn nhiều so với Hồi quy Tuyến tính hay Phân tích Biệt thức Tuyến tính (LDA).


9.3. Máy Vectơ Hỗ Trợ (Support Vector Machines - SVM)

9.3.1. Phân Loại với Ranh Giới Phi Tuyến

Bộ phân loại Vectơ Hỗ trợ (SVC) tạo ra một ranh giới phẳng tuyến tính. Tuy nhiên, nếu hai lớp dữ liệu có cấu trúc phi tuyến phức tạp — ví dụ một cụm điểm lớp này bị bao bọc hoàn toàn bên trong lớp kia theo hình tròn hay hình elip — thì không một siêu phẳng thẳng nào có thể phân loại tốt.

Một ý tưởng cổ điển là mở rộng không gian đặc trưng (enlarging the feature space): thay vì chỉ dùng $X_1, X_2$, ta đưa thêm các số hạng bậc hai $X_1^2, X_2^2, X_1 X_2$, hay bậc ba vào mô hình. Khi đó, một ranh giới tuyến tính trong không gian mở rộng nhiều chiều sẽ tương ứng với một đường cong phi tuyến uốn lượn trong không gian 2 chiều ban đầu!

Tuy nhiên, nếu số chiều đặc trưng $p$ ban đầu lớn, việc mở rộng không gian bằng đa thức sẽ khiến số chiều bùng nổ theo cấp số nhân (curse of dimensionality), làm tê liệt mọi hệ thống máy tính.

Làm thế nào để tận hưởng sức mạnh của không gian vô số chiều mà không phải trả giá bằng chi phí tính toán khổng lồ? Câu trả lời chính là Thủ Thuật Kernel (The Kernel Trick).


9.3.2. Thủ Thuật Kernel (The Kernel Trick)

Khi giải bài toán tối ưu hóa của Bộ phân loại Vectơ Hỗ trợ bằng lý thuyết đối ngẫu Lagrange (Lagrange Duality), người ta chứng minh được rằng hàm quyết định tuyến tính có thể viết hoàn toàn dưới dạng tích vô hướng (inner products) giữa điểm cần dự đoán $x$ và các điểm huấn luyện $x_i$:

$$f(x) = \beta_0 + \sum_{i \in \mathcal{S}} \alpha_i \langle x, x_i \rangle$$

Trong đó:

  • $\langle x, x_i \rangle = \sum_{j=1}^p x_j x_{ij}$ là tích vô hướng chuẩn trong không gian $p$ chiều.
  • $\mathcal{S}$ là tập hợp các chỉ số của các Vectơ Hỗ trợ (với mọi điểm khác ngoài lề, hệ số Lagrange $\alpha_i = 0$).

Bây giờ, nếu ta muốn ánh xạ dữ liệu sang một không gian đặc trưng mới nhiều chiều $\Phi(x)$, tích vô hướng sẽ trở thành $\langle \Phi(x), \Phi(x_i) \rangle$.

Thủ thuật Kernel phát biểu rằng: nếu tồn tại một hàm hạt nhân $K(x, x')$ sao cho: $$K(x, x') = \langle \Phi(x), \Phi(x') \rangle$$ thì chúng ta không bao giờ cần phải tính toán hay lưu trữ tường minh phép ánh xạ $\Phi(x)$! Ta chỉ việc thay thế trực tiếp tích vô hướng bằng hàm $K(x, x_i)$ vào phương trình phân loại:

$$f(x) = \beta_0 + \sum_{i \in \mathcal{S}} \alpha_i K(x, x_i)$$

1. Không Gian 2D Ban Đầu (Phi tuyến) Không thể phân tách bằng bất kỳ đường thẳng nào! Kernel Trick Φ(X) 2. Không Gian 3D (Tách biệt phẳng) Siêu phẳng tách Trong không gian mới, một mặt phẳng thẳng cắt ngang phân tách tuyệt đối!
Hình 9.2. Trực quan hóa Thủ thuật Kernel. Dữ liệu đồng tâm 2 chiều không thể tách bằng đường thẳng được ánh xạ ngầm sang không gian 3 chiều có dạng paraboloid $Z = X_1^2 + X_2^2$, nơi một mặt phẳng ngang phân tách hai lớp hoàn hảo.

Khi áp dụng hàm Kernel phi tuyến, Bộ phân loại Vectơ Hỗ trợ chính thức trở thành Máy Vectơ Hỗ Trợ (Support Vector Machine - SVM).


9.3.3. Các Hàm Kernel Thông Dụng Nhất

1. Kernel Tuyến Tính (Linear Kernel)

Tương đương với tích vô hướng thông thường: $$K(x, x') = \sum_{j=1}^p x_j x'_j$$ Đây chính là Bộ phân loại Vectơ Hỗ trợ (SVC) ban đầu.

2. Kernel Đa Thức Bậc $d$ (Polynomial Kernel)

$$K(x, x') = \left(1 + \sum_{j=1}^p x_j x'_j\right)^d$$ Với $d > 1$, hàm này ngầm tính toán mọi tương tác tích chéo và lũy thừa lên đến bậc $d$. Ranh giới quyết định tạo thành các đường cong đa thức mượt mà.

3. Kernel Bán Kính Cơ Sở (Radial Basis Function - RBF Kernel)

Hàm Kernel phổ biến và quyền năng bậc nhất trong thực tế:

$$K(x, x') = \exp\left(-\gamma \sum_{j=1}^p (x_j - x'_j)^2\right) = \exp\left(-\gamma \|x - x'\|^2\right)$$

Trong đó $\gamma > 0$ là một tham số dương.

Bản chất của RBF Kernel: Không gian vô hạn chiều

Về mặt toán học, thông qua khai triển chuỗi Taylor của hàm số mũ $e^z$, RBF Kernel tương đương với việc ánh xạ dữ liệu vào một không gian Hilbert có vô hạn chiều!
Về mặt hình học trực quan: RBF Kernel hoạt động như một thước đo khoảng cách cục bộ (local similarity). Nếu một điểm kiểm tra $x$ nằm xa một vectơ hỗ trợ $x_i$, khoảng cách $\|x - x_i\|^2$ lớn, hàm $K(x, x_i) \approx 0$ và vectơ đó không có tiếng nói trong việc phân loại $x$.
• Khi $\gamma$ lớn: Quả chuông bán kính rất hẹp, chỉ những điểm cực gần mới ảnh hưởng đến nhau $\implies$ Ranh giới quyết định co cụm uốn lượn quanh từng điểm dữ liệu đơn lẻ (nguy cơ quá khớp cao).
• Khi $\gamma$ nhỏ: Quả chuông trải rộng phẳng phiu $\implies$ Ranh giới quyết định mượt mà, bao quát diện rộng.

Phòng thí nghiệm G
SVM Phi Tuyến & Thủ Thuật Kernel (The Kernel Trick)
Khám phá sức mạnh của RBF Kernel và Polynomial Kernel trong việc bẻ cong không gian và kiểm soát lề mềm
Mặt phẳng Quyết định 2D: Ranh giới f(x)=0 (nét đậm), Biên lề f(x)=±1 (nét đứt) và các Vectơ Hỗ Trợ (khoanh tròn đôi)
Phổ khoảng cách hàm quyết định f(xᵢ): Các điểm nằm trong vùng lề (-1 < f < 1) là Vectơ Hỗ Trợ vi phạm lề
5.0
C lớn: Phạt nặng vi phạm, lề hẹp, ít vectơ hỗ trợ. C nhỏ: Lề rộng, chấp nhận nhiều điểm vi phạm.
1.5
γ lớn: Quả chuông nhọn, ranh giới co cụm quanh từng điểm. γ nhỏ: Ranh giới mượt mà.
Số Vectơ Hỗ Trợ18 / 60
Độ rộng lề M0.34
Train Accuracy98.3%
Test Accuracy95.0%
Trạng tháiPhân tách xuất sắc
Diễn giải

Hãy nhìn vào dữ liệu hai vòng tròn đồng tâm: Với Linear Kernel, SVM hoàn toàn bất lực (độ chính xác chỉ quanh 50%). Nhưng ngay khi chuyển sang RBF Kernel, ranh giới quyết định lập tức uốn thành một đường tròn hoàn hảo bao bọc lớp trung tâm! Chỉ những điểm nằm trên biên lề hoặc xâm phạm vào trong lề (khoanh tròn đôi) mới là các Vectơ Hỗ Trợ duy nhất giữ cấu trúc của mô hình.

Việc cần làm: ① Chọn dữ liệu Đồng tâm và bấm chọn Linear Kernel: thấy rõ đường thẳng không thể tách biệt. ② Chuyển sang RBF Kernel: ranh giới uốn cong tuyệt đẹp. Thử tăng γ lên mức 6.0 – 8.0: quan sát ranh giới co quắp thành các ốc đảo cô lập xung quanh từng điểm dữ liệu (quá khớp!). ③ Giảm C về 0.2: lề mở rộng ra đáng kể và số lượng Vectơ Hỗ Trợ tăng vọt!


9.4. SVM Cho Bài Toán Nhiều Hơn Hai Lớp (Multi-Class SVM)

Về bản chất toán học nguyên thủy, SVM được thiết kế cho phân loại nhị phân ($y \in \{-1, +1\}$). Khi bài toán có $K > 2$ lớp, hai chiến lược mở rộng chuẩn mực được áp dụng:

9.4.1. Phân Loại Một-chọi-Một (One-versus-One - OvO)

  • Huấn luyện một bộ phân loại nhị phân riêng biệt cho từng cặp lớp khả dĩ.
  • Tổng số bộ phân loại SVM cần huấn luyện là: $$\binom{K}{2} = \frac{K(K - 1)}{2}$$

  • Khi cần dự đoán nhãn cho một quan sát kiểm tra $x^*$, ta đưa $x^*$ lần lượt qua cả $\frac{K(K-1)}{2}$ mô hình. Mỗi mô hình sẽ bầu 1 phiếu cho lớp thắng cuộc. Nhãn cuối cùng là lớp nhận được nhiều phiếu bầu nhất (majority vote).

9.4.2. Phân Loại Một-chọi-Tất cả (One-versus-All / One-versus-Rest - OvA)

  • Huấn luyện đúng $K$ bộ phân loại SVM riêng biệt.
  • Bộ phân loại thứ $k$ ($k = 1, \dots, K$) được huấn luyện để phân biệt lớp $k$ (gán nhãn $+1$) với toàn bộ $K - 1$ lớp còn lại (gán nhãn $-1$).
  • Gọi $f_k(x) = \beta_{0k} + \beta_{1k} x_1 + \dots + \beta_{pk} x_p$ là hàm số điểm của bộ phân loại thứ $k$. Quan sát mới $x^*$ sẽ được gán cho lớp có điểm số biên cao nhất: $$\arg\max_{k \in \{1, \dots, K\}} f_k(x^*)$$

Trong thực hành với scikit-learn, phương pháp OvO thường được sử dụng mặc định cho SVM vì mỗi mô hình con chỉ huấn luyện trên một tập con nhỏ của dữ liệu, giúp thời gian khớp mô hình tổng thể nhanh hơn.


9.5. Mối Liên Hệ Mật Thiết Giữa SVM và Hồi Quy Logistic

Nhiều người nghĩ SVM và Hồi quy Logistic là hai trường phái hoàn toàn biệt lập: một bên dựa trên tối ưu hình học khoảng cách lề, một bên dựa trên mô hình xác suất thống kê. Tuy nhiên, khi nhìn qua lăng kính của Bài toán Tối thiểu hóa Mất mát có Điều hòa (Loss + Penalty Formulation), hai phương pháp thực chất là anh em ruột thịt!

Bất kỳ mô hình phân loại có giám sát nào cũng có thể biểu diễn dưới dạng:

$$\min_{\beta} \sum_{i=1}^n L(y_i, f(x_i)) + \lambda \sum_{j=1}^p \beta_j^2$$

Trong đó $L(y, f(x))$ là hàm mất mát (loss function) phạt những dự đoán sai lệch, và $\lambda \sum \beta_j^2$ là thành phần điều hòa Ridge ($L_2$ penalty).

So Sánh Hàm Mất Mát Bản Lề (Hinge Loss) và Logistic Loss y · f(x) Mất mát L 1 (Biên lề) 0 1.0 Hinge Loss: [1 - yf(x)]₊ Bằng 0 tuyệt đối khi y·f(x) ≥ 1 Logistic Loss (Log-Loss) → 0 nhưng không bao giờ bằng 0 Lỗi phân loại 0-1 (Rời rạc)
Hình 9.3. So sánh Hàm mất mát Bản lề (Hinge Loss của SVM, đường đỏ) và Logistic Loss (đường xanh nét đứt). Hinge Loss bằng đúng 0 tuyệt đối đối với mọi điểm có $y \cdot f(x) \ge 1$ (nằm đúng phía ngoài lề), tạo nên tính chất thưa độc nhất của các Vectơ Hỗ Trợ.
  • Đối với Hồi quy Logistic: Hàm mất mát là Log-Loss (Negative Log-Likelihood): $$L(y, f(x)) = \log\left(1 + e^{-y f(x)}\right)$$

  • Đối với SVM: Hàm mất mát là Hàm Mất Mát Bản Lề (Hinge Loss): $$L(y, f(x)) = \max\left(0, 1 - y f(x)\right) = \left[1 - y f(x)\right]_+$$

Sự khác biệt cốt tử giữa Hinge Loss và Logistic Loss

Hãy chú ý kỹ hành vi của Hinge Loss khi $y f(x) \ge 1$:
• Khi một điểm dữ liệu nằm đúng phía và nằm an toàn bên ngoài lề ($y f(x) \ge 1$), Hinge Loss bằng đúng 0 tuyệt đối! Đạo hàm của hàm mất mát tại điểm này bằng 0, nghĩa là điểm này hoàn toàn không tạo ra bất kỳ lực kéo nào lên các trọng số $\beta$. Đây chính là nguồn gốc toán học tạo nên tính chất thưa (sparsity) và sự xuất hiện của các Vectơ Hỗ trợ.
• Ngược lại, hàm Log-Loss của Hồi quy Logistic tiến rất gần tới 0 nhưng không bao giờ bằng 0 tuyệt đối. Mọi điểm dữ liệu trong tập huấn luyện, dù nằm xa ranh giới đến đâu, vẫn tác động một lực nhỏ kéo dịch chuyển nghiệm ước lượng.
Kết luận: Khi các lớp phân tách tốt, SVM với Hinge Loss tạo ra ranh giới rất ổn định. Khi các lớp chồng lấn phức tạp và bạn cần ước lượng xác suất chính xác $\Pr(Y=1|X)$, Hồi quy Logistic là sự lựa chọn vượt trội.


9.6. Thực Hành Python (Lab: Support Vector Machines)

Dưới đây là quy trình thực hành chuẩn mực trên Python sử dụng module sklearn.svm và trực quan hóa ranh giới phân loại.

Huấn luyện Support Vector Classifier Tuyến tính và Trích xuất Vectơ Hỗ Trợ

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import accuracy_score, roc_curve, auc, RocCurveDisplay

# 1. TẠO DỮ LIỆU MẪU HAI LỚP
np.random.seed(1)
X = np.random.randn(50, 2)
y = np.where(X[:, 0] + X[:, 1] > 0.3, 1, -1)
# Tạo một chút nhiễu chồng lấn
y[np.random.choice(50, 5, replace=False)] *= -1

# Khớp Support Vector Classifier với chi phí C lớn (lề hẹp) và C nhỏ (lề rộng)
svc_tight = SVC(kernel='linear', C=10.0).fit(X, y)
svc_soft = SVC(kernel='linear', C=0.1).fit(X, y)

print(f"Số lượng vectơ hỗ trợ (C=10.0): {len(svc_tight.support_)}")
print(f"Số lượng vectơ hỗ trợ (C=0.1): {len(svc_soft.support_)}")
print(f"Vị trí các chỉ số vectơ hỗ trợ (C=10.0):\n{svc_tight.support_}")

SVM Phi Tuyến với RBF Kernel và Tối Ưu Siêu Tham Số bằng GridSearchCV

# 2. KHỞI TẠO DỮ LIỆU PHI TUYẾN DẠNG ĐỒNG TÂM
np.random.seed(42)
X_circ = np.random.randn(200, 2)
y_circ = np.where(X_circ[:, 0]**2 + X_circ[:, 1]**2 > 1.4, 1, -1)

X_train, X_test, y_train, y_test = train_test_split(X_circ, y_circ, test_size=0.3, random_state=42)

# Thiết lập lưới tìm kiếm siêu tham số cho RBF Kernel: C và gamma
param_grid = {
    'C': [0.1, 1, 10, 100],
    'gamma': [0.1, 0.5, 1.0, 5.0]
}

grid_search = GridSearchCV(SVC(kernel='rbf'), param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)

print(f"Tham số tối ưu từ Cross-Validation: {grid_search.best_params_}")
best_svm = grid_search.best_estimator_

y_pred = best_svm.predict(X_test)
print(f"Độ chính xác trên tập kiểm tra: {accuracy_score(y_test, y_pred):.3f}")

# Vẽ đường cong ROC trên tập kiểm tra
fig, ax = plt.subplots(figsize=(7, 5))
RocCurveDisplay.from_estimator(best_svm, X_test, y_test, ax=ax, name='SVM RBF Kernel')
plt.plot([0, 1], [0, 1], 'k--', label='Đoán ngẫu nhiên (AUC = 0.5)')
plt.title("Đường cong ROC của mô hình SVM Phi tuyến")
plt.legend()
plt.show()

SVM Đa Lớp (Multi-class) trên Dữ liệu Biểu Hiện Gen Ung Thư Khan

# 3. SVM ĐA LỚP TRÊN TẬP DỮ LIỆU KHAN (BIỂU HIỆN GEN UNG THƯ KHỐI U MÔ MỀM TRẺ EM)
from ISLP import load_data
khan = load_data('Khan')

# Dữ liệu gen có số chiều p = 2308 biến cực lớn, trong khi n_train chỉ có 63 mẫu!
X_k_train = khan['xtrain']
y_k_train = khan['ytrain']
X_k_test = khan['xtest']
y_k_test = khan['ytest']

print(f"Kích thước ma trận gen huấn luyện: {X_k_train.shape}")
print(f"Các lớp phân loại khối u (4 nhóm): {np.unique(y_k_train)}")

# Trong không gian p >> n, một siêu phẳng tuyến tính là thừa sức phân tách hoàn hảo
svm_khan = SVC(kernel='linear', C=10.0)
svm_khan.fit(X_k_train, y_k_train)

# Đánh giá trên tập huấn luyện và kiểm tra
train_acc = accuracy_score(y_k_train, svm_khan.predict(X_k_train))
test_acc = accuracy_score(y_k_test, svm_khan.predict(X_k_test))
print(f"Độ chính xác tập huấn luyện (p >> n): {train_acc * 100:.1f}%")
print(f"Độ chính xác tập kiểm tra: {test_acc * 100:.1f}%")

10Chương 10: Học Sâu (Deep Learning)

Trong thập kỷ qua, Học Sâu (Deep Learning) đã tạo nên một cuộc cách mạng toàn cầu trong trí tuệ nhân tạo, thúc đẩy những bước nhảy vọt phi thường từ nhận diện khuôn mặt, lái xe tự động, dịch thuật ngôn ngữ đến các mô hình ngôn ngữ lớn (LLMs).

Về mặt lịch sử và toán học, học sâu không phải là một phép màu bí ẩn, mà chính là sự kế thừa và tiến hóa mạnh mẽ của mô hình mạng nơ-ron nhân tạo (artificial neural networks) ra đời từ thập niên 1980. Điểm khác biệt mấu chốt là ngày nay, nhờ sự bùng nổ của khối lượng dữ liệu khổng lồ, năng lực tính toán siêu việt của chip đồ họa (GPU), cùng các đột phá về thuật toán tối ưu hóa (như hàm kích hoạt ReLU, Dropout, Adam), chúng ta có thể huấn luyện những mạng nơ-ron có hàng chục, hàng trăm tầng ẩn với hàng tỷ tham số.

Chương này sẽ dẫn dắt bạn đi từ những khối gạch nền móng đơn giản nhất:

  • Khởi đầu từ Mạng Nơ-ron Đơn tầng và Mạng Nơ-ron Truyền thẳng Đa tầng (MLP).
  • Khám phá cơ chế lan truyền ngược (Backpropagation) và các hàm kích hoạt phi tuyến.
  • Đi sâu vào hai cấu trúc chuyên biệt vĩ đại: Mạng Nơ-ron Tích chập (CNN) cho thị giác máy tính và Mạng Nơ-ron Hồi quy (RNN) cho dữ liệu chuỗi và văn bản.
  • Luận giải triết lý thống kê: Khi nào nên dùng Học Sâu? Khám phá hiện tượng kỳ thú Hạ dốc kép (Double Descent) và thực hành xây dựng mô hình bằng framework chuẩn công nghiệp PyTorch.

10.1. Mạng Nơ-ron Đơn Tầng (Single Layer Neural Networks)

Một mạng nơ-ron truyền thẳng (feedforward neural network) tiếp nhận một vectơ đặc trưng đầu vào $X = (X_1, X_2, \dots, X_p)^T$ và xây dựng hàm dự đoán thông qua một tầng trung gian chứa $K$ nút ẩn (hidden units hay nơ-ron).

Kiến Trúc Mạng Nơ-ron Truyền Thẳng Đa Tầng (MLP) Tầng Vào (X) X₁ X₂ X₃ X₄ Tầng Ẩn 1: A⁽¹⁾ = g(W⁽¹⁾X) A₁ A₂ A₃ A₄ Tầng Ẩn 2: A⁽²⁾ B₁ B₂ B₃ Tầng Ra (Output) f₁(X) f₂(X)
Hình 10.1. Sơ đồ kiến trúc Mạng Nơ-ron Truyền Thẳng Đa Tầng (MLP) với 4 biến đầu vào, 2 tầng ẩn và 2 đầu ra phân loại Softmax. Mỗi liên kết mang một trọng số được tối ưu thông qua giải thuật lan truyền ngược.

Mô hình bao gồm hai bước chuyển hóa toán học liên tiếp:

1. Tầng Ẩn (The Hidden Layer)

Mỗi nút ẩn thứ $k$ ($k = 1, \dots, K$) trước tiên tính toán một tổ hợp tuyến tính của các biến đầu vào, sau đó áp dụng một hàm kích hoạt phi tuyến (nonlinear activation function) $g(\cdot)$:

$$A_k = g\left(w_{k0} + \sum_{j=1}^p w_{kj} X_j\right) = g(w_k^T X)$$

Trong đó:

  • $w_{k0}$ là hệ số điều chỉnh tự do (chệch / bias).
  • $w_{k1}, \dots, w_{kp}$ là các trọng số (weights) kết nối từ $p$ biến đầu vào tới nút ẩn thứ $k$.
  • $A_k$ là giá trị kích hoạt (activation) xuất ra từ nút ẩn $k$.

2. Tầng Đầu Ra (The Output Layer)

Các giá trị kích hoạt $A_1, \dots, A_K$ tiếp tục được gom lại thành tổ hợp tuyến tính ở tầng đầu ra để tạo thành hàm dự đoán cuối cùng $f(X)$:

$$f(X) = \beta_0 + \sum_{k=1}^K \beta_k A_k = \beta_0 + \sum_{k=1}^K \beta_k g\left(w_{k0} + \sum_{j=1}^p w_{kj} X_j\right)$$

Tại sao hàm kích hoạt $g(z)$ bắt buộc phải phi tuyến?

Nếu $g(z)$ là một hàm tuyến tính đơn giản (ví dụ $g(z) = c \cdot z$), thì tầng đầu ra $f(X)$ chỉ là tổ hợp tuyến tính của các tổ hợp tuyến tính — tức quay về đúng một mô hình hồi quy tuyến tính cổ điển!
Chính hàm kích hoạt phi tuyến $g(\cdot)$ mới là chiếc chìa khóa vạn năng cho phép mạng nơ-ron bẻ cong không gian và mô hình hóa những mối quan hệ phi tuyến vô cùng phức tạp trong tự nhiên.

Các Hàm Kích Hoạt Phi Tuyến Thông Dụng

  1. Hàm Sigmoid: $$g(z) = \frac{1}{1 + e^{-z}} = \frac{e^z}{1 + e^z}$$ Nén mọi giá trị thực $(-\infty, +\infty)$ về khoảng êm ái $(0, 1)$. Sigmoid từng thống trị trong các mạng nơ-ron đời đầu, nhưng có nhược điểm chí mạng là hiện tượng bão hòa đạo hàm (vanishing gradient) khi $|z|$ lớn.

  2. Đơn Vị Hiệu Chỉnh Tuyến Tính (Rectified Linear Unit - ReLU): $$g(z) = \max(0, z)$$ ReLU là hàm kích hoạt mặc định số 1 trong học sâu hiện đại.

    • Ưu điểm vượt trội: Cực kỳ đơn giản về mặt tính toán, đạo hàm bằng 1 khi $z > 0$, triệt tiêu hoàn toàn hiện tượng bão hòa đạo hàm, giúp mạng hội tụ nhanh gấp nhiều lần so với Sigmoid.

Dạng Thức Đầu Ra Theo Từng Bài Toán

  • Bài toán Hồi quy: Tầng ra là hàm tuyến tính trực tiếp: $f(X) = \beta_0 + \sum \beta_k A_k$.
  • Bài toán Phân loại Nhị phân: Tầng ra bọc thêm hàm Sigmoid để ước lượng xác suất: $$\Pr(Y = 1 \mid X) = \frac{1}{1 + e^{-f(X)}}$$

  • Bài toán Phân loại Đa lớp ($M$ lớp): Sử dụng hàm Softmax biến đổi $M$ giá trị tuyến tính $Z_1, \dots, Z_M$ thành một phân phối xác suất hợp lệ có tổng bằng 1: $$\Pr(Y = m \mid X) = \frac{e^{Z_m}}{\sum_{k=1}^M e^{Z_k}}, \quad m = 1, \dots, M$$

Phòng thí nghiệm 17 · 3D
Mặt dự đoán ŷ(x⁽¹⁾, x⁽²⁾): năm mô hình, năm hình dạng
Kéo để xoay · kéo vạch tím trên bản đồ để dời lát cắt
Bề mặt dự đoán (màu theo ŷ) · chấm: dữ liệu huấn luyện · đường tím: lát cắt x⁽²⁾ = s
Nhìn từ trên — kéo vạch tím
Lát cắt: ŷ theo x⁽¹⁾ khi cố định x⁽²⁾ = s
120 điểm huấn luyện + 200 điểm kiểm tra, nhiễu σ = 0,3 (MSE không thể thấp hơn 0,09).
5
2
6
0.00
MSE train—
MSE test—
Tham số—
Diễn giải

—

Việc cần làm: ① MLP 6 nơ-ron tanh trên mặt cong trơn, bấm Huấn luyện: mặt cong uốn dần theo dữ liệu, MSE test về ≈ 0,09, sát mức nhiễu 0,09. ② Chọn “Chỉ hiện nơ-ron 1”, 2, 3…: mỗi $A_k = g(w_{k0} + w_{k1}X_1 + w_{k2}X_2)$ là một con dốc thẳng chỉ đổi giá trị theo hướng $w_k$; còn $f(X) = \beta_0 + \sum_k \beta_k A_k$ chỉ là tổng các con dốc — đúng công thức của mục 10.1, nay nhìn thấy được. ③ Hạ về 1 nơ-ron rồi huấn luyện lại: một con dốc không tạo nổi đồi (MSE test ≈ 0,19). ④ Đổi sang ReLU: dốc gấp khúc thay cho dốc trơn, 6 nơ-ron ReLU đạt ≈ 0,13 — vẫn là tổng các dốc, chỉ khác hình dáng từng dốc. ⑤ Logistic: ranh giới quyết định là lát cắt $p = 0{,}5$ của tấm sigmoid, nên luôn là đường thẳng; MLP là cách bẻ cong tấm đó.


10.2. Mạng Nơ-ron Truyền Thẳng Đa Tầng (Multilayer Neural Networks)

Khi xếp chồng nhiều tầng ẩn nối tiếp nhau, ta thu được Mạng Nơ-ron Truyền thẳng Đa tầng (Multilayer Perceptron - MLP):

$$A^{(1)} = g\left(W^{(1)} X + b^{(1)}\right)$$ $$A^{(2)} = g\left(W^{(2)} A^{(1)} + b^{(2)}\right)$$ $$\dots$$ $$A^{(L)} = g\left(W^{(L)} A^{(L-1)} + b^{(L)}\right)$$ $$f(X) = W_{\text{out}} A^{(L)} + b_{\text{out}}$$

Cơ Chế Học Biểu Diễn Phân Tầng (Hierarchical Representation Learning)

Tại sao mạng sâu (nhiều tầng) lại mạnh mẽ hơn mạng nông (1 tầng)?

Theo Định lý Xấp xỉ Phổ quát (Universal Approximation Theorem), một mạng nơ-ron chỉ với 1 tầng ẩn nhưng có số lượng nút $K$ vô cùng lớn về lý thuyết có thể xấp xỉ bất kỳ hàm liên tục nào. Tuy nhiên, một mạng nông như vậy đòi hỏi số lượng nơ-ron khổng lồ đến mức không tưởng và rất khó tối ưu.

Ngược lại, kiến trúc nhiều tầng sâu tạo điều kiện cho mạng học theo cơ chế biểu diễn phân tầng:

  • Các tầng đầu tiên: Nhận diện các đặc trưng cấp thấp mang tính cục bộ (như các cạnh sáng tối, góc nhọn, đường biên thẳng).
  • Các tầng trung gian: Lắp ghép các cạnh thành các bộ phận cụ thể (hình tròn của bánh xe, đường cong của cánh cửa, sống mũi, con mắt).
  • Các tầng sâu nhất: Kết hợp các bộ phận thành khái niệm ngữ nghĩa hoàn chỉnh ở cấp độ vĩ mô (toàn bộ chiếc xe hơi, khuôn mặt con người, con mèo).

10.3. Mạng Nơ-ron Tích Chập (Convolutional Neural Networks - CNN)

10.3.1. Thách Thức Khi Xử Lý Dữ Liệu Hình Ảnh Bằng MLP

Hãy tưởng tượng bạn có một bức ảnh màu kích thước trung bình $200 \times 200$ pixel với 3 kênh màu RGB. Nếu dùng MLP, vectơ đầu vào $X$ sẽ có độ dài: $$200 \times 200 \times 3 = 120,000\ \text{chiều!}$$ Nếu tầng ẩn đầu tiên chỉ cần $1,000$ nơ-ron, ma trận trọng số kết nối đầy đủ (fully connected) sẽ ngốn tới $120,000,000$ tham số! Mạng sẽ lập tức bị bùng nổ bộ nhớ và quá khớp dữ dội. Hơn nữa, việc kéo phẳng bức ảnh thành một chuỗi 1 chiều làm phá hủy hoàn toàn cấu trúc không gian 2 chiều tự nhiên (quan hệ giữa các pixel lân cận trên - dưới - trái - phải).

Mạng Nơ-ron Tích chập (CNN) ra đời để giải quyết triệt để thách thức này nhờ hai cơ chế toán học then chốt: Phép toán Tích chập (Convolution) và Lớp Gộp (Pooling).

Dòng Chảy Thông Tin trong Mạng Nơ-ron Tích Chập (CNN) 8 Ảnh gốc (28×28) Conv 3×3 Feature Maps Pool 2×2 Gộp (14×14) Flatten Vectơ 1D Dense Fully Conn Dự đoán Softmax Số 3: 0.02 Số 8: 0.94 Số 9: 0.03
Hình 10.2. Tiến trình xử lý từ đầu đến cuối của một mạng CNN: từ ảnh số nguyên bản qua các tầng Tích chập (trích xuất đặc trưng hình thái), Gộp cực đại (nén chiều không gian), kéo phẳng và đưa vào mạng nơ-ron kết nối đầy đủ để xuất ra xác suất phân loại.

10.3.2. Phép Toán Tích Chập 2D (The 2D Convolution Operation)

Trọng tâm của tầng tích chập là một ma trận số nhỏ gọi là Bộ lọc (Filter hay Kernel), thường có kích thước $3 \times 3$ hoặc $5 \times 5$.

Quá trình tích chập diễn ra như sau:

  1. Đặt bộ lọc lên một vùng cục bộ cùng kích thước của bức ảnh đầu vào.
  2. Thực hiện phép nhân từng phần tử tương ứng (element-wise multiplication) giữa ma trận bộ lọc và ma trận điểm ảnh, sau đó cộng dồn tất cả lại kèm một hệ số chệch $b$ để thu được một con số duy nhất: $$S(i, j) = \sum_{u} \sum_{v} I(i + u, j + v) \cdot K(u, v) + b$$

  3. Trượt bộ lọc sang vị trí tiếp theo theo chiều ngang hoặc dọc với một bước nhảy xác định (Bước trượt / Stride) và lặp lại phép tính.

Kết quả của toàn bộ quá trình quét này tạo ra một ma trận 2D mới gọi là Bản đồ đặc trưng (Feature Map).

Phòng thí nghiệm H
Cơ Chế Trượt Tích Chập 2D trong CNN (Convolution Sliding Window)
Trực quan hóa từng bước phép nhân ma trận, cộng dồn phần tử và kích hoạt ReLU khi bộ lọc 3×3 trượt trên ảnh
Trái: Ảnh đầu vào 6×6 & Khung trượt 3×3 (đỏ) · Giữa: Bộ lọc Kernel 3×3 · Phải: Bản đồ Đặc trưng 4×4
Bảng tính chi tiết: Phép nhân từng phần tử tương ứng ∑ I(u,v)·K(u,v) + Bias và kích hoạt ReLU
Vị trí cửa sổ (r, c)(0, 0)
Tổng tích chập ∑145.0
Đầu ra sau ReLU145.0
Kích thước không gian6×6 → 4×4
Đặc trưng nhận diệnCạnh đứng mạnh
Diễn giải

Khung màu đỏ $3 \times 3$ đang nằm tại tọa độ $(r, c)$ trên ảnh gốc. Tại mỗi vị trí, 9 điểm ảnh trong khung được nhân tương ứng với 9 trọng số của bộ lọc (Kernel), sau đó cộng dồn lại thành một con số duy nhất điền vào ô tương ứng trên Bản đồ Đặc trưng (Feature Map 4×4). Khi đi qua ReLU, mọi giá trị âm sẽ bị gạt về 0 để tạo tính phi tuyến.

Việc cần làm: ① Bấm Bước tiếp ▶ hoặc ⏯ Tự động trượt để xem cửa sổ quét từ trái sang phải, từ trên xuống dưới. ② Chú ý bảng tính toán bên dưới: quan sát cách các điểm ảnh trùng khớp với họa tiết của bộ lọc tạo ra giá trị kích hoạt cực lớn. ③ Bấm ⚡ Xem Max Pooling 2×2 để chứng kiến bản đồ đặc trưng $4 \times 4$ được nén tiếp thành ma trận $2 \times 2$ nhưng vẫn lưu giữ trọn vẹn những điểm đặc trưng nổi trội nhất!

Hai đặc tính siêu việt của Tầng Tích Chập

1. Chia sẻ trọng số (Weight Sharing / Parameter Sharing): Toàn bộ bức ảnh được quét bởi cùng một bộ lọc $3 \times 3$ (chỉ gồm đúng $9$ tham số trọng số). Số lượng tham số giảm đi hàng trăm nghìn lần so với kết nối đầy đủ!
2. Bất biến với phép tịnh tiến (Translation Invariance): Nếu một bộ lọc được học để phát hiện cạnh dọc hay một họa tiết cụ thể, nó có thể phát hiện họa tiết đó ở bất kỳ vị trí nào trên ảnh — dù nằm ở góc trên bên trái, chính giữa hay góc dưới bên phải.

  • Đệm viền (Padding): Khi trượt bộ lọc, các pixel ở mép ảnh sẽ ít được quét hơn và kích thước Feature Map bị co nhỏ lại. Kỹ thuật đệm số 0 bao quanh viền ngoài ảnh (Zero Padding) giúp giữ nguyên kích thước không gian (padding='same') hoặc cắt bỏ viền (padding='valid').

10.3.3. Lớp Gộp (Pooling Layer)

Sau khi đi qua hàm kích hoạt ReLU, bản đồ đặc trưng thường được đưa qua một Tầng Gộp (Pooling Layer), phổ biến nhất là Gộp cực đại (Max Pooling) với kích thước cửa sổ $2 \times 2$ và bước trượt bằng 2:

  • Cửa sổ $2 \times 2$ quét qua Feature Map và chỉ giữ lại giá trị lớn nhất trong mỗi ô 4 pixel.
  • Phép toán này lập tức nén giảm $75\%$ kích thước không gian (chiều rộng và chiều cao đều giảm một nửa), giúp cắt giảm đáng kể gánh nặng tính toán cho các tầng kế tiếp.
  • Đồng thời, Max Pooling giữ lại các tín hiệu kích hoạt mạnh nhất, giúp mô hình miễn nhiễm với các biến dạng hoặc dịch chuyển nhỏ của đặc trưng.

10.3.4. Kiến Trúc Hoàn Chỉnh của Một Mạng CNN

Một mạng CNN tiêu chuẩn là chuỗi xếp chồng tuần tự: $$\text{Ảnh đầu vào} \to [\text{Conv} \to \text{ReLU} \to \text{MaxPool}] \times L \to \text{Flatten} \to \text{Dense (Fully Connected)} \to \text{Softmax}$$


10.4. Mạng Nơ-ron Hồi Quy (Recurrent Neural Networks - RNN)

Dữ liệu hình ảnh có cấu trúc không gian 2D cố định, nhưng nhiều bài toán thực tế lại làm việc với dữ liệu chuỗi tuần tự theo thời gian (Sequential Data) — ví dụ: giá cổ phiếu từng ngày, tín hiệu âm thanh, hoặc văn bản tự nhiên (chuỗi các từ ngữ nối tiếp nhau). Trong dữ liệu chuỗi, thứ tự trước - sau của các phần tử mang ý nghĩa sống còn.

Cơ Chế Trải Mạng Hồi Quy (RNN Unrolling Through Time) Dạng Thu Gọn Xₜ W hₜ U Yₜ = Trải Dài Theo Trục Thời Gian Xₜ₋₁ hₜ₋₁ Yₜ₋₁ U Xₜ hₜ Yₜ U Xₜ₊₁ hₜ₊₁ Yₜ₊₁ ...
Hình 10.3. Cơ chế hoạt động của Mạng Nơ-ron Hồi quy (RNN). Trái: Mô hình mạng thu gọn với vòng lặp hồi tiếp qua ma trận $U$. Phải: Mạng được trải dài theo chuỗi thời gian, thông tin từ quá khứ truyền sang tương lai thông qua trạng thái ẩn $h_t$.

Mạng Nơ-ron Hồi quy (RNN) xử lý chuỗi đầu vào $X = (x_1, x_2, \dots, x_T)$ bằng cách duy trì một trạng thái ẩn (hidden state) $h_t$ đóng vai trò như "bộ nhớ" lưu trữ thông tin của quá khứ:

$$h_t = g\left(W x_t + U h_{t-1} + b\right)$$

Tại mỗi bước thời gian $t$:

  • Nơ-ron nhận đầu vào hiện tại $x_t$ và kết hợp với trạng thái ẩn của bước trước đó $h_{t-1}$ thông qua hai ma trận trọng số $W$ và $U$.
  • Trọng số $W, U, b$ được chia sẻ cố định qua mọi bước thời gian.

Thách Thức Bão Hòa Đạo Hàm và Sự Tiến Hóa Sang LSTM / Transformer

Khi chuỗi thời gian quá dài ($T > 50$), thuật toán Lan truyền ngược qua thời gian (Backpropagation Through Time - BPTT) phải liên tục nhân ma trận trọng số $U$ qua hàng chục bước, dẫn tới hiện tượng triệt tiêu đạo hàm (vanishing gradient) hoặc bùng nổ đạo hàm (exploding gradient). Mạng RNN cổ điển hầu như bị "mất trí nhớ", không thể ghi nhớ các mối liên hệ ngữ cảnh cách xa nhau.

Để khắc phục:

  • LSTM (Long Short-Term Memory) và GRU (Gated Recurrent Unit) đưa vào các cơ chế "cổng" (input gate, forget gate, output gate) để chủ động quyết định thông tin nào cần nhớ và thông tin nào cần quên.
  • Mô hình Transformer (Attention Mechanism): Ra đời năm 2017 với bài báo kinh điển "Attention Is All You Need", loại bỏ hoàn toàn cơ chế tuần tự của RNN để xử lý toàn bộ chuỗi song song thông qua cơ chế tự chú ý (Self-Attention), đặt nền móng cho cuộc cách mạng của BERT, GPT và các mô hình nền tảng ngày nay.

10.5. Khi Nào Nên Dùng Học Sâu? (When to Use Deep Learning?)

Học sâu vô cùng mạnh mẽ, nhưng liệu nó có phải là câu trả lời tối ưu cho mọi bài toán học máy?

Sự thật về Học Sâu trên Dữ liệu Bảng (Tabular Data)

Thực nghiệm phong phú trên hàng trăm bộ dữ liệu chuẩn mực chỉ ra rằng:
• Dữ liệu phi cấu trúc (Unstructured Data: Hình ảnh, Âm thanh, Video, Văn bản tự nhiên): Học Sâu thống trị tuyệt đối. Các phương pháp cổ điển hoàn toàn bất lực trước những miền dữ liệu này.
• Dữ liệu bảng có cấu trúc (Tabular Data: Doanh số, bảng điểm tín dụng, tài chính ngân hàng, bảng khảo sát khách hàng): Các phương pháp dựa trên cây kết hợp — đặc biệt là Random Forests, Gradient Boosting (XGBoost, LightGBM, CatBoost) — thường xuyên đánh bại hoặc cho kết quả ngang ngửa Mạng Nơ-ron Sâu!
Cây kết hợp trên dữ liệu bảng đòi hỏi ít dữ liệu hơn, huấn luyện nhanh hơn hàng chục lần, ít siêu tham số phải tinh chỉnh hơn, và dễ dàng diễn giải hơn theo nguyên lý Lưỡi dao Ockham.


10.6. Kỹ Thuật Điều Hòa Trong Học Sâu (Regularization)

Do mạng nơ-ron sâu có hàng triệu tham số, nguy cơ quá khớp dữ liệu là cực lớn. Ba kỹ thuật điều hòa chuẩn mực luôn được áp dụng:

  1. Giảm Dần Trọng Số (Weight Decay / $L_2$ Regularization): Cộng thêm số hạng phạt $\frac{1}{2} \lambda \sum w^2$ vào hàm mất mát, ép các trọng số co nhỏ về gần 0, giữ cho hàm dự đoán trơn tru mượt mà.

  2. Loại Bỏ Ngẫu Nhiên (Dropout): Tại mỗi bước huấn luyện mini-batch, ta ngẫu nhiên "tắt" (gán giá trị bằng 0) một tỷ lệ $p$ các nơ-ron trong tầng ẩn (thường chọn $p = 0.5$).

    • Kỹ thuật này ép các nơ-ron không được phụ thuộc hay "dựa dẫm" vào nhau (ngăn chặn co-adaptation).
    • Về mặt toán học, Dropout tương đương với việc huấn luyện đồng thời một tổ hợp ensemble gồm $2^K$ mạng nơ-ron con khác nhau, mang lại khả năng khái quát hóa phi thường.
  3. Dừng Sớm (Early Stopping): Liên tục theo dõi sai số trên tập kiểm định (validation loss) qua từng vòng lặp huấn luyện (epoch). Khi thấy validation loss bắt đầu có dấu hiệu tăng ngược trở lại (mạng bắt đầu học vào nhiễu), ta lập tức dừng huấn luyện và lưu lại bộ trọng số tốt nhất.


10.7. Phép Nội Suy và Hiện Tượng Hạ Dốc Kép (Double Descent)

Trong lý thuyết thống kê cổ điển, mối quan hệ giữa độ phức tạp mô hình và sai số kiểm tra tuân theo đường cong hình chữ U: khi số tham số $p$ vượt qua số lượng mẫu quan sát $n$, mô hình sẽ bị quá khớp nghiêm trọng và sai số kiểm tra bùng nổ.

Tuy nhiên, trong học sâu hiện đại, các nhà nghiên cứu phát hiện một hiện tượng kỳ lạ phá vỡ trực giác cổ điển: Hiện tượng Hạ Dốc Kép (Double Descent)!

Hiện Tượng Hạ Dốc Kép (The Double Descent Phenomenon) Số lượng Tham số p Sai số (MSE) p = n (Ngưỡng Nội Suy) 1. Vùng Dưới Tham Số Hóa (p < n) 2. Vùng Siêu Tham Số Hóa (p >> n) Train MSE = 0 Đáy chữ U cổ điển Đỉnh quá khớp tại p ≈ n Hạ dốc lần 2 (Hiện đại)
Hình 10.4. Hiện tượng Hạ dốc kép (Double Descent). Bên trái ngưỡng nội suy $p = n$ là thế giới thống kê cổ điển với đường cong chữ U. Khi vượt qua $p = n$ sang vùng siêu tham số hóa ($p \gg n$), sai số kiểm tra quay đầu giảm mạnh mẽ trở lại nhờ cơ chế điều hòa ngầm của các thuật toán tối ưu hiện đại.
  1. Vùng dưới tham số hóa ($p < n$): Sai số tuân theo đường cong chữ U cổ điển. Sai số kiểm tra tăng vọt khi số tham số tiến sát số lượng mẫu ($p \approx n$, gọi là ngưỡng nội suy - interpolation boundary). Tại đây, mạng vừa đủ linh hoạt để khớp khít 100% dữ liệu huấn luyện (Training Error = 0) nhưng phương sai đạt đỉnh cực đại.
  2. Vùng siêu tham số hóa ($p \gg n$): Khi ta tiếp tục tăng số tham số vượt xa số mẫu, sai số kiểm tra không hề tăng lên vô hạn, mà bất ngờ quay đầu giảm dần một lần nữa!
    • Lý do: Trong không gian vô số chiều của vùng siêu tham số hóa, tồn tại vô số nghiệm có sai số huấn luyện bằng 0. Thuật toán tối ưu (như SGD với bước học nhỏ và khởi tạo ngẫu nhiên) sẽ ngầm chọn ra nghiệm có chuẩn nhỏ nhất (minimum-norm solution) — chính là nghiệm trơn tru nhất, mang lại khả năng khái quát hóa vượt trội!

10.8. Thực Hành PyTorch (PyTorch Lab)

Dưới đây là mã nguồn Python chuẩn mực triển khai huấn luyện một mạng CNN phân loại ảnh bằng framework hàng đầu thế giới PyTorch.

Định Nghĩa Mạng Nơ-ron Tích Chập (CNN) Bằng PyTorch

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

# 1. THIẾT LẬP THIẾT BỊ TÍNH TOÁN (GPU NẾU CÓ, HOẶC CPU)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Đang sử dụng thiết bị: {device}")

# 2. ĐỊNH NGHĨA KIẾN TRÚC MẠNG CNN
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        # Khối tích chập 1: 1 kênh ảnh xám -> 32 bản đồ đặc trưng, kernel 3x3
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
        self.relu1 = nn.ReLU()
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) # 28x28 -> 14x14

        # Khối tích chập 2: 32 kênh -> 64 kênh, kernel 3x3
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
        self.relu2 = nn.ReLU()
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) # 14x14 -> 7x7

        # Tầng kết nối đầy đủ (Dense / Fully Connected) với Dropout
        self.dropout = nn.Dropout(p=0.5)
        self.fc1 = nn.Linear(64 * 7 * 7, 128)
        self.relu3 = nn.ReLU()
        self.fc2 = nn.Linear(128, 10) # 10 lớp đầu ra (chữ số 0 đến 9)

    def forward(self, x):
        x = self.pool1(self.relu1(self.conv1(x)))
        x = self.pool2(self.relu2(self.conv2(x)))
        x = x.view(x.size(0), -1) # Kéo phẳng (Flatten) thành 1D
        x = self.dropout(self.relu3(self.fc1(x)))
        x = self.fc2(x)
        return x

model = SimpleCNN().to(device)
print(model)

Chu Trình Huấn Luyện Chuẩn Mực (Training Loop) với PyTorch

# 3. CHUẨN BỊ DỮ LIỆU HUẤN LUYỆN VÀ KIỂM TRA (TẬP MNIST)
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,)) # Chuẩn hóa mean, std chuẩn MNIST
])

train_data = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_data = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

train_loader = DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = DataLoader(test_data, batch_size=1000, shuffle=False)

# 4. HÀM MẤT MÁT VÀ BỘ TỐI ƯU HÓA ADAM
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4) # Weight decay L2

# 5. CHU TRÌNH HUẤN LUYỆN QUA TỪNG EPOCH
def train_epoch(model, loader, optimizer, criterion):
    model.train() # Chuyển sang chế độ huấn luyện (bật Dropout)
    running_loss = 0.0
    correct = 0
    total = 0
    for images, labels in loader:
        images, labels = images.to(device), labels.to(device)

        optimizer.zero_grad()               # Bước 1: Xóa gradient cũ
        outputs = model(images)             # Bước 2: Lan truyền xuôi (Forward pass)
        loss = criterion(outputs, labels)   # Bước 3: Tính toán hàm mất mát
        loss.backward()                     # Bước 4: Lan truyền ngược (Backpropagation)
        optimizer.step()                    # Bước 5: Cập nhật trọng số

        running_loss += loss.item() * images.size(0)
        _, preds = torch.max(outputs, 1)
        correct += (preds == labels).sum().item()
        total += labels.size(0)

    return running_loss / total, correct / total

# 6. ĐÁNH GIÁ MÔ HÌNH TRÊN TẬP KIỂM TRA
def evaluate(model, loader):
    model.eval() # Chuyển sang chế độ đánh giá (tắt Dropout)
    correct = 0
    total = 0
    with torch.no_grad(): # Không tính gradient để tiết kiệm bộ nhớ
        for images, labels in loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, preds = torch.max(outputs, 1)
            correct += (preds == labels).sum().item()
            total += labels.size(0)
    return correct / total

print("Bắt đầu huấn luyện mô hình CNN...")
for epoch in range(1, 4): # Huấn luyện 3 epoch minh họa
    train_loss, train_acc = train_epoch(model, train_loader, optimizer, criterion)
    test_acc = evaluate(model, test_loader)
    print(f"Epoch {epoch:02d} | Train Loss: {train_loss:.4f} | Train Acc: {train_acc*100:.2f}% | Test Acc: {test_acc*100:.2f}%")

11Chương 11: Phân Tích Sinh Tồn và Dữ Liệu Cắt Cụt (Survival Analysis)

Trong hầu hết các bài toán học có giám sát đã khảo sát ở các chương trước, biến phản hồi $Y$ hoặc là một đại lượng định lượng liên tục (trong bài toán hồi quy), hoặc là một nhãn phân loại rời rạc (trong bài toán phân loại). Tuy nhiên, có một lớp bài toán thực tiễn vô cùng đặc biệt xuất hiện liên tục trong y học, kỹ thuật độ tin cậy và kinh doanh số: biến phản hồi là khoảng thời gian dẫn tới khi một sự kiện quan tâm xảy ra.

Ví dụ điển hình:

  • Y học lâm sàng: Thời gian sống sót của bệnh nhân từ thời điểm chẩn đoán ung thư não cho đến khi tử vong.
  • Kỹ thuật công nghiệp: Thời gian hoạt động liên tục của động cơ máy bay cho đến khi một linh kiện then chốt bị hỏng hóc.
  • Kinh doanh số & SaaS: Thời gian một khách hàng duy trì thuê bao trả lời câu hỏi khi nào họ sẽ rời bỏ dịch vụ (churn).
  • Nghiên cứu khoa học: Thời gian từ khi một đề tài nghiên cứu bắt đầu cho đến khi bài báo khoa học được xuất bản thành công.

Lớp phương pháp thống kê chuyên biệt để phân tích loại dữ liệu này được gọi là Phân tích Sinh tồn (Survival Analysis).


11.1. Thời Gian Sinh Tồn và Bản Chất Dữ Liệu Bị Cắt Cụt (Censoring)

Tại sao chúng ta không thể đơn giản dùng Hồi quy Tuyến tính OLS tiêu chuẩn để dự đoán thời gian sống $Y$? Trở ngại cốt lõi và mang tính quyết định nằm ở hiện tượng Dữ liệu bị cắt cụt (Censoring).

Trong một thử nghiệm lâm sàng kéo dài 5 năm khảo sát một loại thuốc mới điều trị ung thư não:

  1. Một số bệnh nhân không may tử vong trong suốt quá trình nghiên cứu: ta ghi nhận chính xác thời gian sống $T_i$ của họ.
  2. Một số bệnh nhân vẫn sống khỏe mạnh cho tới thời điểm nghiên cứu kết thúc sau 5 năm. Chúng ta chỉ biết chắc chắn rằng họ sống ít nhất 5 năm, nhưng thời gian sống thực sự $T_i$ của họ là bao lâu thì chưa biết.
  3. Một số bệnh nhân chuyển nơi cư trú, mất liên lạc sau 2 năm theo dõi. Chúng ta chỉ biết họ sống sót ít nhất 2 năm.

Cả trường hợp (2) và (3) đều được gọi là bị cắt cụt bên phải (right-censoring).

Cạm bẫy Chết người: Loại bỏ hoặc Gán ép Điểm Cắt cụt

Nếu bạn loại bỏ tất cả bệnh nhân bị cắt cụt khỏi tập dữ liệu, bạn đã phạm phải sai lệch chọn mẫu (selection bias) trầm trọng: những người sống thọ nhất (vẫn còn sống khi nghiên cứu kết thúc) bị gạt bỏ, khiến thời gian sống trung bình bị ước lượng thấp hơn thực tế rất nhiều. Ngược lại, nếu bạn coi thời điểm theo dõi cuối cùng là thời điểm tử vong, bạn đang ngộ nhận rằng toàn bộ những người còn sống đều chết đúng vào ngày nghiên cứu đóng cửa! Cả hai cách xử lý ngây thơ này đều phá hủy hoàn toàn tính xác thực của nghiên cứu.

11.1.1. Định dạng Toán học của Dữ liệu Sinh tồn

Gọi:

  • $T_i \ge 0$: là thời gian sinh tồn tiềm ẩn (true survival time) của cá thể thứ $i$ (khoảng thời gian từ khi bắt đầu theo dõi đến khi sự kiện xảy ra).
  • $C_i \ge 0$: là thời gian cắt cụt (censoring time) của cá thể thứ $i$ (thời điểm cá thể rút khỏi nghiên cứu hoặc nghiên cứu kết thúc).

Trong thực tế, ta không quan sát được đồng thời cả $T_i$ và $C_i$. Thay vào đó, với mỗi cá thể $i = 1, \dots, n$, ta chỉ quan sát được cặp đại lượng $(Y_i, \delta_i)$:

$$Y_i = \min(T_i, C_i)$$

$$\delta_i = I(T_i \le C_i) = \begin{cases} 1 & \text{nếu sự kiện xảy ra (quan sát đầy đủ)} \\ 0 & \text{nếu bị cắt cụt (censored)} \end{cases}$$

Trong đó $I(\cdot)$ là hàm chỉ báo (indicator function).

  • Nếu $\delta_i = 1$, ta biết $Y_i = T_i$, tức sự kiện thực sự đã xảy ra tại thời điểm $Y_i$.
  • Nếu $\delta_i = 0$, ta chỉ biết $T_i > Y_i$, tức cá thể đã sống sót vượt qua mốc thời gian $Y_i$.

11.1.2. Giả định Cắt cụt Không Mang Thông tin (Non-informative Censoring)

Phần lớn các phương pháp phân tích sinh tồn cổ điển dựa trên một giả định tiên quyết sống còn: thời gian sinh tồn $T_i$ độc lập với thời gian cắt cụt $C_i$:

$$T_i \perp C_i$$

Nói cách khác, việc một bệnh nhân rút khỏi nghiên cứu tại thời điểm $C_i$ hoàn toàn không liên quan đến việc tình trạng bệnh của họ đang tốt lên hay xấu đi. Nếu một bệnh nhân vì quá yếu sắp hấp hối mà xin về nhà (dẫn tới bị mất dấu theo dõi $C_i$), giả định này sẽ bị vi phạm (gọi là informative censoring) và đòi hỏi các mô hình mở rộng phức tạp hơn nhiều.


11.2. Hàm Sinh Tồn và Hàm Nguy Cơ (Survival & Hazard Functions)

Để mô tả phân phối xác suất của biến ngẫu nhiên thời gian sinh tồn $T$, chúng ta có hai công cụ giải tích song hành: Hàm Sinh tồn và Hàm Nguy cơ.

11.2.1. Hàm Sinh Tồn $S(t)$

Hàm Sinh tồn (Survival Function) $S(t)$ là xác suất để một cá thể sống sót vượt qua mốc thời gian $t$:

$$S(t) = \Pr(T > t) = 1 - F(t) = \int_t^\infty f(u) \, du$$

Trong đó $F(t) = \Pr(T \le t)$ là hàm phân phối tích lũy (CDF) và $f(t)$ là hàm mật độ xác suất (PDF) của $T$.

Các tính chất toán học của $S(t)$:

  1. $S(0) = 1$: Tại thời điểm bắt đầu ($t = 0$), $100\%$ cá thể còn sống.
  2. $S(t)$ là một hàm giảm đơn điệu theo $t$: Khi thời gian trôi qua, xác suất tiếp tục sống sót không thể tăng lên.
  3. $\lim_{t \to \infty} S(t) = 0$: Về lâu dài, mọi cá thể cuối cùng đều sẽ trải qua sự kiện.

11.2.2. Hàm Nguy Cơ $h(t)$

Nếu Hàm Sinh tồn nhìn từ góc độ toàn cục "xác suất sống từ đầu đến $t$", thì Hàm Nguy cơ (Hazard Function / Hazard Rate) $h(t)$ nhìn từ góc độ vi mô tức thời: Nếu một cá thể đã sống sót đến thời điểm $t$, thì xác suất tử vong ngay trong khoảnh khắc tiếp theo là bao nhiêu?

$$h(t) = \lim_{\Delta t \to 0} \frac{\Pr(t \le T < t + \Delta t \mid T \ge t)}{\Delta t}$$

Sử dụng công thức xác suất có điều kiện $\Pr(A \mid B) = \frac{\Pr(A \cap B)}{\Pr(B)}$, ta có:

$$h(t) = \lim_{\Delta t \to 0} \frac{F(t + \Delta t) - F(t)}{\Delta t \cdot S(t)} = \frac{f(t)}{S(t)} = \frac{-S'(t)}{S(t)}$$

Mối Liên Hệ Giải Tích Tuyệt Đẹp Giữa $S(t)$ và $h(t)$

Nhận thấy rằng $\frac{d}{dt} \log S(t) = \frac{S'(t)}{S(t)} = -h(t)$. Lấy tích phân hai vế từ $0$ đến $t$ với điều kiện $S(0) = 1$, ta thu được công thức chuyển đổi nền tảng:

$$S(t) = \exp\left( - \int_0^t h(u) \, du \right) = \exp(-H(t))$$

Trong đó $H(t) = \int_0^t h(u) \, du$ được gọi là Hàm Nguy cơ Tích lũy (Cumulative Hazard Function). Biết được hàm nguy cơ $h(t)$, ta suy ra ngay hàm sinh tồn $S(t)$ và ngược lại.

Thời gian t → Giá trị 1. Nguy cơ Không đổi h(t) = λ h(t) (Hằng số) S(t) = e^{-λt} Thời gian t → Giá trị 2. Lão hoá: h(t) Tăng Dần h(t) tăng S(t) Thời gian t → Giá trị 3. Hậu phẫu: h(t) Giảm Dần h(t) giảm S(t)
Hình 11.1. Ba hình thái cơ bản của hàm sinh tồn $S(t)$ (đường nét liền xanh dương) và hàm nguy cơ tức thời $h(t)$ (đường đứt nét đỏ). Trái: Nguy cơ không đổi $h(t) = \lambda$ sinh ra hàm sinh tồn phân phối mũ. Giữa: Nguy cơ tăng theo tuổi tác (mô hình lão hóa/hao mòn). Phải: Nguy cơ tử vong cao nhất ngay sau phẫu thuật rồi giảm dần khi bệnh nhân hồi phục.

Hình thái của hàm nguy cơ $h(t)$ mang thông điệp sinh học/kỹ thuật rất rõ nét:

  • $h(t) = \text{const}$: Nguy cơ không đổi theo thời gian (phân phối hàm mũ — vật thể không bị lão hóa).
  • $h(t)$ tăng theo $t$: Sự hao mòn/lão hóa tự nhiên theo tuổi tác.
  • $h(t)$ giảm theo $t$: Thường thấy sau phẫu thuật phức tạp — nguy cơ biến chứng tử vong cao nhất trong vài ngày đầu, nếu vượt qua được thì nguy cơ giảm dần.

11.3. Ước Lượng Kaplan–Meier (Kaplan–Meier Estimator)

Khi dữ liệu không bị cắt cụt, ta có thể ước lượng trực tiếp $S(t)$ bằng tỷ lệ mẫu $\frac{1}{n}\sum I(T_i > t)$. Nhưng khi có dữ liệu bị cắt cụt, ta phải dùng đến Ước lượng Kaplan–Meier (1958) — một kiệt tác phi tham số được trích dẫn nhiều bậc nhất trong toàn bộ nền khoa học hiện đại.

11.3.1. Thuật Toán Xây Dựng Đường Cong Kaplan–Meier

Giả sử trong $n$ quan sát, có $K$ mốc thời gian xảy ra biến cố tử vong riêng biệt được sắp xếp theo thứ tự tăng dần:

$$d_1 < d_2 < \dots < d_K$$

Tại mỗi mốc thời gian tử vong thứ $j$ ($j = 1, \dots, K$):

  • Gọi $r_j$ là số lượng cá thể trong tập nguy cơ (risk set) tại thời điểm ngay trước $d_j$: là những người vẫn còn sống và chưa bị cắt cụt trước $d_j$.
  • Gọi $q_j$ là số ca tử vong thực sự xảy ra tại mốc $d_j$.

Xác suất có điều kiện một cá thể sống sót vượt qua mốc $d_j$, biết rằng người đó còn sống ngay trước $d_j$, được ước lượng tự nhiên bằng:

$$1 - \frac{q_j}{r_j}$$

Áp dụng quy tắc nhân xác suất liên tiếp cho các biến cố sống sót có điều kiện, ước lượng Kaplan–Meier cho hàm sinh tồn tại mốc thời gian $t$ là:

$$\hat{S}(t) = \prod_{j: d_j \le t} \left( 1 - \frac{q_j}{r_j} \right)$$

Đường cong $\hat{S}(t)$ có dạng đồ thị hình bậc thang (step function):

  • Giá trị $\hat{S}(t)$ chỉ tụt xuống tại các mốc có ca tử vong $d_j$.
  • Tại các mốc có dữ liệu bị cắt cụt, đường cong không tụt xuống, nhưng số lượng trong tập nguy cơ $r_j$ của các bước kế tiếp sẽ bị giảm đi, làm cho các bước nhảy sau đó có độ sâu lớn hơn.
  • Trên đồ thị, các thời điểm bị cắt cụt thường được đánh dấu bằng một dấu gạch nhỏ (tick mark).
Phòng thí nghiệm 06
Đường Cong Sinh Tồn Kaplan–Meier & Sự Tác Động của Dữ Liệu Cắt Cụt (Censoring)
Kéo tỷ lệ cắt cụt hoặc so sánh 2 nhóm điều trị để quan sát bước nhảy Kaplan-Meier và kiểm định Log-rank
Đường cong sinh tồn bậc thang Ŝ(t) với vạch tick cắt cụt và dải tin cậy 95%
Thời gian theo dõi từng bệnh nhân (Đỏ: Tử vong, Vàng: Bị cắt cụt)
30%
Tỷ lệ phần trăm bệnh nhân rút lui hoặc sống sót qua theo dõi.
Tổng số cá thể (N)40
Số ca tử vong (Events)28
Bị cắt cụt (Censored)12
Thời gian sống trung vị24.5 tháng
Log-Rank p-value—
Diễn giải

Quan sát biểu đồ trên: Đường cong Kaplan-Meier chỉ tụt xuống tại các mốc có biến cố tử vong (chấm đỏ). Tại các mốc có dữ liệu bị cắt cụt (vạch tick vàng), đường cong không tụt mà giữ nguyên, nhưng số người trong tập nguy cơ giảm đi khiến các bước nhảy tiếp theo sâu hơn!

Việc cần làm: ① Tăng dần Tỷ lệ Cắt Cụt từ 0% lên 70%: Quan sát dải tin cậy ở phần đuôi đường cong nở rộng ra nhanh chóng do số cá thể trong tập nguy cơ rⱼ giảm mạnh. ② Bấm chuyển sang So sánh 2 Nhóm để đối sánh Nhóm Thuốc Mới vs Đối Chứng và quan sát chỉ số p-value của kiểm định Log-Rank. ③ Bấm Lấy Mẫu Mới để thấy tính ngẫu nhiên của các mẫu lâm sàng.


11.4. So Sánh Các Nhóm Bệnh Nhân: Kiểm Định Log-Rank (The Log-Rank Test)

Trong nghiên cứu thử nghiệm y sinh, câu hỏi trọng tâm thường là: Liệu phương pháp điều trị mới có kéo dài thời gian sống sót của bệnh nhân một cách có ý nghĩa thống kê so với phương pháp đối chứng cũ hay không?

Giả sử ta muốn so sánh $S_1(t)$ (nhóm 1) và $S_2(t)$ (nhóm 2). Chúng ta đặt cặp giả thuyết:

  • $H_0: S_1(t) = S_2(t)$ với mọi $t \ge 0$ (hai phác đồ điều trị có hiệu quả sinh tồn như nhau).
  • $H_a: S_1(t) \neq S_2(t)$ tại ít nhất một mốc thời gian.

Không thể so sánh thời gian sống trung bình bằng kiểm định $t$-Student hay ANOVA thông thường vì có dữ liệu bị cắt cụt. Thay vào đó, tiêu chuẩn vàng là Kiểm định Log-Rank.

11.4.1. Cơ Chế Bảng Tiếp Liên $2 \times 2$ của Kiểm Định Log-Rank

Tại mỗi mốc thời gian tử vong $d_j$ ($j = 1, \dots, K$) trên toàn bộ tập mẫu gộp chung, ta lập một bảng tiếp liên $2 \times 2$:

Nhóm Tử vong tại $d_j$ Còn sống sau $d_j$ Tổng số trong tập nguy cơ
Nhóm 1 $q_{1j}$ $r_{1j} - q_{1j}$ $r_{1j}$
Nhóm 2 $q_{2j}$ $r_{2j} - q_{2j}$ $r_{2j}$
Tổng cộng $q_j$ $r_j - q_j$ $r_j$

Dưới giả thuyết không $H_0$ (nguy cơ tử vong ở hai nhóm là như nhau), xác suất tử vong chung tại mốc $d_j$ là $\frac{q_j}{r_j}$. Do đó, số ca tử vong kỳ vọng ở Nhóm 1 là:

$$E_{1j} = r_{1j} \cdot \frac{q_j}{r_j}$$

Phương sai của $q_{1j}$ (theo phân phối siêu bội hypergeometric) là:

$$\text{Var}(q_{1j}) = \frac{r_{1j} r_{2j} q_j (r_j - q_j)}{r_j^2 (r_j - 1)}$$

11.4.2. Thống Kê Kiểm Định Log-Rank

Ta cộng dồn sai lệch giữa số ca tử vong thực tế quan sát được ($O_1 = \sum_{j=1}^K q_{1j}$) và số ca tử vong kỳ vọng ($E_1 = \sum_{j=1}^K E_{1j}$):

$$W = \frac{\sum_{j=1}^K (q_{1j} - E_{1j})}{\sqrt{\sum_{j=1}^K \text{Var}(q_{1j})}}$$

Dưới giả thuyết $H_0$, thống kê $W$ xấp xỉ phân phối chuẩn tắc $N(0, 1)$, hoặc tương đương $W^2 \sim \chi^2_1$ (phân phối Chi-bình phương với 1 bậc tự do). Nếu trị số $p$-value $< 0.05$, ta bác bỏ $H_0$ và kết luận hai đường cong sinh tồn có sự khác biệt thực sự.


11.5. Mô Hình Hồi Quy Sinh Tồn: Mô Hình Rủi Ro Tỷ Lệ Cox (Cox Proportional Hazards Model)

Kiểm định Log-rank chỉ so sánh được giữa các phân nhóm rời rạc và không thể kiểm soát đồng thời nhiều biến số gây nhiễu (như tuổi tác, giai đoạn khối u, tiền sử bệnh án). Để đưa các biến dự đoán $X = (X_1, \dots, X_p)$ vào dự báo sinh tồn, Sir David Cox (1972) đã đề xuất Mô hình Rủi ro Tỷ lệ Cox (Cox Proportional Hazards Model).

11.5.1. Cấu Trúc Mô Hình Cox

Mô hình Cox mô hình hóa hàm nguy cơ của một cá thể có bộ đặc trưng $x = (x_1, \dots, x_p)$ dưới dạng:

$$h(t \mid x) = h_0(t) \exp\left( \sum_{j=1}^p \beta_j x_j \right) = h_0(t) \exp(x^T \beta)$$

Trong đó:

  • $h_0(t) \ge 0$: là nguy cơ nền (baseline hazard) — hàm nguy cơ của một cá thể có tất cả các biến dự đoán bằng 0 ($x = 0$). Hàm $h_0(t)$ biến thiên tự do theo thời gian mà không cần tuân theo bất kỳ phân phối tham số nào (như Weibull hay Gamma).
  • $\exp(x^T \beta)$: là hệ số nhân tương đối, độc lập với thời gian $t$.

Ý Nghĩa của Giả Định "Rủi Ro Tỷ Lệ" (Proportional Hazards)

Xét tỷ số nguy cơ (Hazard Ratio - HR) giữa hai cá thể có bộ đặc trưng $x$ và $x^*$: $$\frac{h(t \mid x)}{h(t \mid x^*)} = \frac{h_0(t) \exp(x^T \beta)}{h_0(t) \exp({x^*}^T \beta)} = \exp((x - x^*)^T \beta)$$ Thành phần nguy cơ nền $h_0(t)$ bị triệt tiêu hoàn toàn! Tỷ số nguy cơ giữa hai người là một hằng số cố định không đổi theo thời gian. Nếu một bệnh nhân có nguy cơ tử vong cao gấp 2 lần người khác hôm nay, thì sau 1 năm hay 3 năm, tỷ số nguy cơ đó vẫn bằng 2.

11.5.2. Ước Lượng Tham Số qua Hàm Hợp Lý Riêng Phần (Partial Likelihood)

Điểm đột phá vĩ đại nhất của Cox là: ta có thể ước lượng các hệ số hồi quy $\beta$ mà hoàn toàn không cần biết dạng của hàm nguy cơ nền $h_0(t)$.

Tại mốc thời gian tử vong $y_i$ của cá thể thứ $i$, tập các cá thể có nguy cơ tử vong ngay trước thời điểm đó là $R(y_i) = \{k: y_k \ge y_i\}$. Xác suất để chính cá thể $i$ tử vong (biết rằng có đúng một ca tử vong trong tập nguy cơ $R(y_i)$) là:

$$\Pr(\text{cá thể } i \text{ tử vong} \mid 1 \text{ ca tử vong tại } y_i) = \frac{h(y_i \mid x_i)}{\sum_{k \in R(y_i)} h(y_i \mid x_k)} = \frac{h_0(y_i) \exp(x_i^T \beta)}{\sum_{k \in R(y_i)} h_0(y_i) \exp(x_k^T \beta)} = \frac{\exp(x_i^T \beta)}{\sum_{k \in R(y_i)} \exp(x_k^T \beta)}$$

Tích của các xác suất này trên toàn bộ các quan sát không bị cắt cụt ($\delta_i = 1$) tạo nên Hàm Hợp lý Riêng phần (Partial Likelihood):

$$PL(\beta) = \prod_{i: \delta_i = 1} \frac{\exp(x_i^T \beta)}{\sum_{k \in R(y_i)} \exp(x_k^T \beta)}$$

Lấy logarit tự nhiên:

$$\log PL(\beta) = \sum_{i: \delta_i = 1} \left[ x_i^T \beta - \log\left( \sum_{k \in R(y_i)} \exp(x_k^T \beta) \right) \right]$$

Ta tối đa hóa $\log PL(\beta)$ bằng thuật toán Newton–Raphson để tìm các ước lượng $\hat{\beta}_j$.

  • Hệ số $\beta_j > 0$ ($\exp(\beta_j) > 1$): Biến $X_j$ tăng làm tăng nguy cơ tử vong $\to$ thời gian sống ngắn đi.
  • Hệ số $\beta_j < 0$ ($\exp(\beta_j) < 1$): Biến $X_j$ có tác dụng bảo vệ, giảm nguy cơ tử vong $\to$ thời gian sống kéo dài.

11.6. Thu Hẹp Tham Số Cho Mô Hình Cox (Shrinkage & Regularization)

Khi số lượng biến dự đoán $p$ lớn (ví dụ trong nghiên cứu biểu hiện gen với $p > 1.000$ mà $n \approx 100$), mô hình Cox tiêu chuẩn sẽ bị quá khớp hoặc không thể ước lượng được. Tương tự như hồi quy tuyến tính, ta bổ sung số hạng phạt điều hòa vào hàm log hợp lý riêng phần:

$$\max_\beta \left\{ \log PL(\beta) - P_\lambda(\beta) \right\}$$

  • Ridge Cox: $P_\lambda(\beta) = \lambda \sum_{j=1}^p \beta_j^2$. Thu nhỏ các hệ số về gần 0, xử lý hiện tượng đa cộng tuyến.
  • Lasso Cox: $P_\lambda(\beta) = \lambda \sum_{j=1}^p |\beta_j|$. Triệt tiêu hẳn các biến không quan trọng về đúng bằng 0, tự động thực hiện chọn lọc đặc trưng sinh tồn.

11.7. Các Chủ Đề Mở Rộng trong Phân Tích Sinh Tồn

  1. Đo Lường Lực Phân Biệt: Chỉ số $C$ của Harrell (Harrell's Concordance Index / C-index): Mở rộng khái niệm diện tích dưới đường cong ROC (AUC) cho dữ liệu bị cắt cụt. Xét tất cả các cặp cá thể $(i, j)$ có thể so sánh được (một người tử vong trước người kia): $$C = \frac{\text{Số cặp có nguy cơ dự đoán } \hat{\eta}_i > \hat{\eta}_j \text{ đồng thời } T_i < T_j}{\text{Tổng số cặp hợp lệ}}$$ $C = 0.5$ tương đương đoán mò ngẫu nhiên; $C = 1.0$ là dự báo thứ tự tử vong hoàn hảo.

  2. Kiểm Tra Giả Định Rủi Ro Tỷ Lệ (Schoenfeld Residuals): Nếu mối quan hệ của một biến dự đoán thay đổi theo thời gian (ví dụ hiệu quả thuốc giảm dần sau 6 tháng), giả định tỷ lệ bị vi phạm. Ta kiểm tra bằng cách phân tích phần dư Schoenfeld: nếu phần dư có tương quan với hàm thời gian $g(t)$, cần đưa thêm số hạng tương tác phụ thuộc thời gian $x_j \times t$.

  3. Cây Sinh Tồn (Survival Trees): Áp dụng kiến trúc Cây quyết định (Chương 8) cho dữ liệu sinh tồn bằng cách dùng thống kê kiểm định Log-rank làm tiêu chí phân tách nút (split criterion) để nhóm các bệnh nhân có đường cong sinh tồn khác biệt tối đa.


11.8. Thực Hành Python: Thư Viện lifelines

Trong hệ sinh thái Python, thư viện chuẩn mực và toàn diện nhất cho phân tích sinh tồn là lifelines.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from lifelines import KaplanMeierFitter, CoxPHFitter
from lifelines.statistics import logrank_test
from ISLP import load_data

# 1. Tải bộ dữ liệu Ung thư Não (BrainCancer)
# Các cột: time (tháng), status (1 = tử vong, 0 = cắt cụt), sex, diagnosis, loc, ki, gtv, stereo
brain = load_data('BrainCancer')
print(brain.head())

# 2. Khớp và vẽ Đường cong Kaplan-Meier toàn thể
kmf = KaplanMeierFitter()
kmf.fit(durations=brain['time'], event_observed=brain['status'], label='Toàn bộ bệnh nhân')

plt.figure(figsize=(8, 5))
kmf.plot_survival_function(ci_show=True) # Hiện khoảng tin cậy 95%
plt.title("Đường cong Sinh tồn Kaplan-Meier: Dữ liệu Ung thư Não")
plt.xlabel("Thời gian (Tháng)")
plt.ylabel("Xác suất sống sót S(t)")
plt.grid(True, alpha=0.3)
plt.show()

# 3. So sánh Sinh tồn giữa Nam và Nữ bằng Kiểm định Log-Rank
male_mask = (brain['sex'] == 'Male')
female_mask = ~male_mask

res = logrank_test(
    durations_A=brain.loc[male_mask, 'time'],
    durations_B=brain.loc[female_mask, 'time'],
    event_observed_A=brain.loc[male_mask, 'status'],
    event_observed_B=brain.loc[female_mask, 'status']
)
print(f"Log-rank test statistic: {res.test_statistic:.3f}, p-value: {res.p_value:.4f}")

# 4. Khớp Mô hình Rủi ro Tỷ lệ Cox (Cox Proportional Hazards)
cph = CoxPHFitter()
# Loại bỏ các dòng có dữ liệu khuyết
brain_clean = brain.dropna()
cph.fit(brain_clean, duration_col='time', event_col='status')
cph.print_summary()

# Xem Tỷ số Nguy cơ (Hazard Ratio = exp(coef))
print(cph.hazard_ratios_)

Mô hình Cox cho thấy: chỉ số thể trạng Karnofsky (ki) cao làm giảm mạnh nguy cơ tử vong ($\text{HR} < 1$), trong khi thể tích khối u (gtv) lớn làm tăng đáng kể nguy cơ tử vong ($\text{HR} > 1$).

12Chương 12: Học Không Giám Sát (Unsupervised Learning)

Phần lớn cuốn sách này tập trung vào các phương pháp Học có Giám sát (Supervised Learning), nơi mỗi quan sát dữ liệu đầu vào $\mathbf{x}_i = (x_{i1}, \dots, x_{ip})$ luôn đi kèm một biến phản hồi mục tiêu $y_i$. Mục tiêu tối thượng của học có giám sát là tìm hàm $f$ để dự đoán chính xác $y_i$ hoặc thấu hiểu mối liên hệ nhân quả giữa $X$ và $Y$.

Tuy nhiên, trong vô số bài toán của kỷ nguyên dữ liệu lớn, chúng ta chỉ sở hữu tập các đặc trưng $\mathbf{x}_1, \dots, \mathbf{x}_n$ mà hoàn toàn không có bất kỳ biến phản hồi $y$ nào đi kèm. Lớp phương pháp phân tích nhằm khai mở các cấu trúc, khuôn mẫu và mối quan hệ nội tại ẩn giấu trong dữ liệu như vậy được gọi là Học Không Giám Sát (Unsupervised Learning).


12.1. Thách Thức của Học Không Giám Sát (The Challenge of Unsupervised Learning)

Học không giám sát khó khăn và thách thức hơn học có giám sát rất nhiều ở cả phương diện lý thuyết lẫn thực hành:

  1. Không có "chân lý mặt đất" (Ground Truth): Trong học có giám sát, ta luôn có nhãn thực tế $y$ để kiểm tra mô hình qua tập kiểm tra (test set) và tính toán sai số khách quan (như MSE hoặc tỷ lệ lỗi phân loại). Trong học không giám sát, không có nhãn $y$, do đó không có thước đo sai số kiểm tra khách quan duy nhất để khẳng định mô hình nào "đúng" hay "tốt hơn".
  2. Tính chủ quan trong đánh giá kết quả: Kết quả phân nhóm khách hàng hay giảm chiều dữ liệu có thực sự hữu ích hay không phụ thuộc rất lớn vào kiến thức chuyên ngành (domain knowledge) và khả năng diễn giải trực quan của con người.
  3. Mục tiêu khám phá cấu trúc tiềm ẩn:
    • Giảm chiều dữ liệu (Dimensionality Reduction): Tìm kiếm một số ít trục tọa độ mới giữ lại phần lớn thông tin biến thiên của hàng trăm, hàng nghìn đặc trưng ban đầu.
    • Phân cụm (Clustering): Phát hiện các nhóm quan sát tự nhiên có tính đồng nhất cao bên trong nhóm nhưng tách biệt rõ rệt giữa các nhóm.
    • Hoàn thiện ma trận (Matrix Completion): Khôi phục các giá trị bị khuyết thiếu dựa trên mối tương quan ẩn giữa các hàng và các cột.

12.2. Phân Tích Thành Phần Chính (Principal Components Analysis - PCA)

Khi tập dữ liệu có số lượng biến $p$ rất lớn (hàng chục, hàng trăm hoặc hàng nghìn chiều), việc vẽ đồ thị để quan sát trực tiếp dữ liệu là điều bất khả thi. Phân tích Thành phần Chính (PCA) là phương pháp giảm chiều dữ liệu kinh điển và mạnh mẽ nhất, biến đổi không gian $p$ chiều ban đầu thành một không gian mới có số chiều $M \ll p$ nhỏ hơn rất nhiều nhưng vẫn bảo tồn tối đa lượng thông tin (đo bằng phương sai) của dữ liệu.

12.2.1. Thành Phần Chính Thứ Nhất: Trục Phương Sai Cực Đại

Giả sử ta có ma trận dữ liệu $\mathbf{X} \in \mathbb{R}^{n \times p}$ đã được căn giữa về 0 (centered), tức trung bình của mỗi cột bằng 0: $\sum_{i=1}^n x_{ij} = 0$.

Thành phần chính thứ nhất (First Principal Component - $Z_1$) là một tổ hợp tuyến tính của $p$ đặc trưng:

$$z_{i1} = \phi_{11} x_{i1} + \phi_{21} x_{i2} + \dots + \phi_{p1} x_{ip} = \mathbf{x}_i^T \boldsymbol{\phi}_1$$

Các hệ số $\boldsymbol{\phi}_1 = (\phi_{11}, \phi_{21}, \dots, \phi_{p1})^T$ được gọi là vector tải trọng (loading vector) của thành phần chính thứ nhất. Để nghiệm không bùng nổ vô tận, ta áp đặt ràng buộc chuẩn hóa:

$$\sum_{j=1}^p \phi_{j1}^2 = \|\boldsymbol{\phi}_1\|_2^2 = 1$$

Vector $\boldsymbol{\phi}_1$ định nghĩa một hướng đường thẳng đi qua gốc tọa độ trong không gian $p$ chiều sao cho phương sai mẫu của các điểm chiếu $z_{11}, \dots, z_{n1}$ đạt giá trị lớn nhất:

$$\max_{\boldsymbol{\phi}_1} \left\{ \frac{1}{n} \sum_{i=1}^n z_{i1}^2 \right\} = \max_{\boldsymbol{\phi}_1} \left\{ \frac{1}{n} \sum_{i=1}^n \left( \sum_{j=1}^p \phi_{j1} x_{ij} \right)^2 \right\} \quad \text{với điều kiện} \quad \sum_{j=1}^p \phi_{j1}^2 = 1$$

Các giá trị $z_{11}, \dots, z_{n1}$ được gọi là điểm số thành phần chính (principal component scores) của $n$ quan sát.

Trục Z₁ (Max Var) Trục Z₂ (Trực giao) Sai số chiếu dᵢ Đặc trưng X₁ (Đã căn giữa) Đặc trưng X₂ Độ dốc của trục Z₁ được xác định bởi vector tải trọng φ₁ = (φ₁₁, φ₂₁)ᵀ sao cho φ₁₁² + φ₂₁² = 1
Hình 12.1. Trực quan hóa hình học của Phân tích Thành phần Chính (PCA) trên mặt phẳng 2 chiều. Trục $Z_1$ (xanh dương) là hướng mà dữ liệu có độ trải rộng (phương sai) lớn nhất. Đồng thời, khoảng cách chiếu vuông góc từ các điểm tới trục $Z_1$ (đoạn màu đỏ) là nhỏ nhất. Trục $Z_2$ (đỏ đứt nét) trực giao hoàn toàn với $Z_1$.

12.2.2. Các Thành Phần Chính Tiếp Theo và Tính Trực Giao

Sau khi đã tìm được $Z_1$, thành phần chính thứ hai ($Z_2$) là tổ hợp tuyến tính $\mathbf{x}_i^T \boldsymbol{\phi}_2$ có phương sai lớn nhất trong số tất cả các hướng vuông góc (trực giao) với $\boldsymbol{\phi}_1$:

$$\boldsymbol{\phi}_2^T \boldsymbol{\phi}_1 = \sum_{j=1}^p \phi_{j2} \phi_{j1} = 0, \qquad \|\boldsymbol{\phi}_2\|_2^2 = 1$$

Tính trực giao này đảm bảo rằng $Z_2$ hoàn toàn không tương quan (uncorrelated) với $Z_1$. Ta tiếp tục quy trình này để trích xuất tối đa $\min(n - 1, p)$ thành phần chính. Về mặt đại số tuyến tính, các vector tải trọng $\boldsymbol{\phi}_1, \dots, \boldsymbol{\phi}_p$ chính là các vector riêng (eigenvectors) của ma trận hiệp phương sai mẫu $\mathbf{X}^T \mathbf{X} / n$, và phương sai của từng thành phần chính chính là giá trị riêng (eigenvalue) tương ứng.

12.2.3. Góc Nhìn Hình Học: Siêu Phẳng Xấp Xỉ Tối Ưu

Ngoài góc nhìn "tối đa hóa phương sai", PCA còn sở hữu một góc nhìn hình học tương đương tuyệt đẹp: Thành phần chính xác định siêu phẳng tuyến tính $M$ chiều đi gần nhất với toàn bộ $n$ điểm dữ liệu.

Cụ thể, mặt phẳng tạo bởi $\boldsymbol{\phi}_1$ và $\boldsymbol{\phi}_2$ là mặt phẳng 2 chiều tối thiểu hóa tổng bình phương khoảng cách Euclid từ các điểm dữ liệu gốc đến hình chiếu vuông góc của chúng lên mặt phẳng:

$$\min_{\boldsymbol{\phi}_1, \boldsymbol{\phi}_2, \mathbf{z}_1, \dots, \mathbf{z}_n} \sum_{i=1}^n \left\| \mathbf{x}_i - \left( z_{i1} \boldsymbol{\phi}_1 + z_{i2} \boldsymbol{\phi}_2 \right) \right\|_2^2$$

Sự Tương Đương Kỳ Diệu trong Đại Số

Tổng khoảng cách bình phương từ gốc tọa độ đến mỗi điểm dữ liệu là một hằng số cố định: $\sum \|\mathbf{x}_i\|^2$. Theo định lý Pytago, tổng này được phân rã thành hai thành phần vuông góc: $$\sum_{i=1}^n \|\mathbf{x}_i\|^2 = \sum_{i=1}^n \|\text{Hình chiếu}\|^2 + \sum_{i=1}^n \|\text{Sai số chiếu}\|^2$$ Do đó, tối đa hóa phương sai hình chiếu chính là tối thiểu hóa sai số tái tạo. Hai góc nhìn tuy xuất phát điểm khác nhau nhưng dẫn tới cùng một nghiệm duy nhất.

Phòng thí nghiệm 18 · 3D
PCA trong 3D: nghiêng một mặt phẳng, nhìn bóng của đám mây — rồi thử với cuộn Thuỵ Sĩ
Kéo để xoay · hai thanh trượt nghiêng mặt phẳng chiếu
Đám mây điểm 3D và mặt phẳng chiếu (vàng) — chấm rỗng là hình chiếu của từng điểm
Bóng trên mặt phẳng — toạ độ 2D sau khi nén
0°
0°
Hai góc này định hướng mặt phẳng; phương sai giữ lại chỉ phụ thuộc vào pháp tuyến.
Phương sai giữ lại—
Tốt nhất có thể—
Sai số tái tạo—
λ₁ : λ₂ : λ₃—
Diễn giải

—

Việc cần làm: ① Bộ ellipsoid: kéo hai thanh góc cho tới khi Phương sai giữ lại tụt xuống thấp nhất — khoảng 17%, khi pháp tuyến trùng trục dài nhất: bóng bẹp dí, các quan sát chồng lên nhau. ② Bấm Nhảy tới mặt phẳng PCA: 97,2% (λ = 10,9 : 1,9 : 0,4) — đúng bằng $(\lambda_1+\lambda_2)/(\lambda_1+\lambda_2+\lambda_3)$, tỷ lệ phương sai giải thích PVE của hai thành phần đầu. Hai trục của bóng là các vectơ tải trọng $\boldsymbol{\phi}_1, \boldsymbol{\phi}_2$, toạ độ là điểm số $z_{i1}, z_{i2}$. ③ Bật đường gióng: đây chính là góc nhìn hình học ở mục 12.2.3 — mặt phẳng PCA là siêu phẳng $M = 2$ chiều đi gần mọi quan sát nhất, tổng bình phương độ dài các đoạn gióng nhỏ nhất; định lý Pytago nối hai cách nhìn thành một nghiệm. ④ Đổi sang cuộn Thuỵ Sĩ: ngay cả mặt phẳng PCA tốt nhất (86%) cũng chỉ chụp cuộn từ trên xuống — hai vòng kề nhau cách 6 đơn vị trong bóng nhưng 50–70 đơn vị dọc theo tấm. Bấm Trải phẳng để thấy điều mà phép chiếu tuyến tính không làm được; đó là lý do các phương pháp phi tuyến (t-SNE, UMAP) tồn tại.

12.2.4. Tỷ Lệ Phương Sai Giải Thích (PVE) và Biểu Đồ Scree Plot

Tổng biến thiên (phương sai) của toàn bộ tập dữ liệu mẫu được tính bởi:

$$\text{TSS} = \sum_{j=1}^p \text{Var}(X_j) = \sum_{j=1}^p \frac{1}{n} \sum_{i=1}^n x_{ij}^2 = \sum_{m=1}^{\min(n-1, p)} \text{Var}(Z_m)$$

Tỷ lệ phương sai giải thích (Proportion of Variance Explained - PVE) của thành phần chính thứ $m$ là:

$$\text{PVE}_m = \frac{\sum_{i=1}^n z_{im}^2}{\sum_{j=1}^p \sum_{i=1}^n x_{ij}^2}$$

  • $\text{PVE}_m \in [0, 1]$ và $\sum_{m} \text{PVE}_m = 1$.
  • Biểu đồ Scree Plot: Đồ thị biểu diễn $\text{PVE}_m$ hoặc PVE tích lũy theo chỉ số $m$. Người phân tích thường dùng quy tắc khuỷu tay (elbow rule) — chọn số chiều $M$ tại điểm mà đồ thị bắt đầu thoai thoải đi ngang (khuỷu tay), biểu thị rằng việc thêm các thành phần chính sau đó không mang lại thêm nhiều thông tin hữu ích.

Tầm Quan Trọng Tuyệt Đối của Việc Chuẩn Hóa Đặc Trưng (Scaling)

Các vector tải trọng của PCA phụ thuộc hoàn toàn vào đơn vị đo lường của các biến. Nếu một biến được đo bằng đơn vị có độ biến thiên lớn (ví dụ: Thu nhập tính bằng VND so với Tuổi tính bằng năm), phương sai của biến đó sẽ áp đảo hoàn toàn các biến còn lại, khiến trục $Z_1$ chỉ phản ánh duy nhất một biến đó. Vì vậy, luôn phải chuẩn hóa tất cả các biến về trung bình bằng 0 và độ lệch chuẩn bằng 1 trước khi chạy PCA, trừ khi các biến vốn dĩ đã có cùng đơn vị đo lường vật lý.


12.3. Dữ Liệu Khuyết và Hoàn Thiện Ma Trận (Matrix Completion)

Trong thực tế, nhiều ma trận dữ liệu bị khuyết thiếu (missing values) ở tỷ lệ rất cao. Ví dụ kinh điển là bài toán Hệ thống Gợi ý (Recommender Systems) như cuộc thi Netflix Prize: ma trận người dùng $\times$ phim có kích thước $n \times p$ khổng lồ, nhưng một người dùng chỉ xem và đánh giá một vài bộ phim, khiến hơn $99\%$ số ô trong ma trận bị bỏ trống.

Nếu ta giả định rằng sở thích của con người và thể loại phim bị chi phối bởi một số ít $M$ nhân tố tiềm ẩn (latent factors — ví dụ: hành động, lãng mạn, hài hước), thì ma trận hoàn chỉnh $\mathbf{X}$ có thể được xấp xỉ tốt bằng một ma trận hạng thấp (low-rank matrix):

$$\mathbf{X} \approx \mathbf{A} \mathbf{B}^T$$

Trong đó $\mathbf{A} \in \mathbb{R}^{n \times M}$ và $\mathbf{B} \in \mathbb{R}^{p \times M}$ với $M \ll \min(n, p)$.

Gọi $\mathcal{O}$ là tập hợp các cặp chỉ số $(i, j)$ mà phần tử $X_{ij}$ đã được quan sát. Bài toán Hoàn thiện Ma trận (Matrix Completion) tìm kiếm ma trận xấp xỉ hạng thấp để khớp tốt nhất trên các phần tử đã quan sát:

$$\min_{\mathbf{A}, \mathbf{B}} \left\{ \sum_{(i, j) \in \mathcal{O}} \left( X_{ij} - (\mathbf{A}\mathbf{B}^T)_{ij} \right)^2 + \lambda \left( \|\mathbf{A}\|_F^2 + \|\mathbf{B}\|_F^2 \right) \right\}$$

Trong đó $\|\cdot\|_F$ là chuẩn Frobenius đóng vai trò số hạng phạt điều hòa Ridge nhằm chống quá khớp. Thuật toán Soft-Impute lặp đi lặp lại hai bước:

  1. Điền các ô khuyết bằng giá trị dự đoán từ xấp xỉ hạng thấp hiện tại.
  2. Áp dụng phép phân rã SVD rút gọn (truncated SVD) trên ma trận vừa điền đầy để cập nhật xấp xỉ hạng thấp mới.

12.4. Các Phương Pháp Phân Cụm (Clustering Methods)

Phân cụm (Clustering) là tập hợp các kỹ thuật nhằm phân chia $n$ quan sát thành các nhóm (cụm - clusters) riêng biệt sao cho:

  • Các quan sát trong cùng một nhóm có mức độ tương đồng rất cao.
  • Các quan sát thuộc hai nhóm khác nhau có mức độ khác biệt rất lớn.

Có hai phương pháp phân cụm kinh điển thống trị trong thực hành: Phân cụm K-Means và Phân cụm Phân cấp (Hierarchical Clustering).

12.4.1. Phân Cụm K-Means

Phân cụm K-Means phân hoạch $n$ quan sát thành $K$ cụm rời rạc và vét cạn $C_1, C_2, \dots, C_K$:

  1. $C_1 \cup C_2 \cup \dots \cup C_K = \{1, \dots, n\}$.
  2. $C_k \cap C_{k'} = \emptyset$ với mọi $k \neq k'$.

Mục tiêu là cực tiểu hóa tổng biến thiên nội cụm (Within-Cluster Variation) trên toàn bộ $K$ cụm:

$$\min_{C_1, \dots, C_K} \sum_{k=1}^K W(C_k)$$

Độ biến thiên nội cụm chuẩn mực sử dụng khoảng cách bình phương Euclid:

$$W(C_k) = \frac{1}{|C_k|} \sum_{i, i' \in C_k} \sum_{j=1}^p (x_{ij} - x_{i'j})^2 = 2 \sum_{i \in C_k} \sum_{j=1}^p (x_{ij} - \bar{x}_{kj})^2$$

Trong đó $\bar{\mathbf{x}}_k = \frac{1}{|C_k|} \sum_{i \in C_k} \mathbf{x}_i$ là trọng tâm (centroid) của cụm $C_k$.

Thuật Toán Lloyd Từng Nửa Bước (Lloyd's Algorithm)

Vì số lượng cách phân chia $n$ phần tử vào $K$ cụm là cực kỳ khổng lồ ($K^n$), việc tìm kiếm nghiệm tối ưu toàn cục là bài toán NP-khó. Thuật toán Lloyd giải quyết bằng một quy trình lặp hai nửa bước đơn giản mà hiệu quả:

  1. Khởi tạo: Chọn ngẫu nhiên $K$ điểm trong không gian làm các tâm cụm ban đầu.
  2. Lặp lại cho đến khi tâm cụm không còn đổi chỗ:
    • Nửa bước 1 (Gán điểm): Gán mỗi quan sát vào cụm có trọng tâm gần nó nhất theo khoảng cách Euclid: $$c_i = \arg\min_{k} \|\mathbf{x}_i - \bar{\mathbf{x}}_k\|_2^2$$
    • Nửa bước 2 (Cập nhật tâm): Tính toán lại trọng tâm của từng cụm là giá trị trung bình mẫu của tất cả các quan sát vừa được gán vào cụm đó: $$\bar{\mathbf{x}}_k = \frac{1}{|C_k|} \sum_{i: c_i = k} \mathbf{x}_i$$

Tính Hội Tụ Đơn Điệu và Cực Tiểu Địa Phương (Local Minima)

Tại mỗi nửa bước của thuật toán Lloyd, hàm mục tiêu $\sum W(C_k)$ luôn được đảm bảo giảm đơn điệu hoặc giữ nguyên. Do số lượng phân hoạch hữu hạn, thuật toán chắc chắn hội tụ sau một số hữu hạn bước. Tuy nhiên, thuật toán chỉ hội tụ về một cực tiểu địa phương (local minimum) chứ không đảm bảo đạt được cực tiểu toàn cục. Để giải quyết, trong thực tế ta luôn phải chạy K-Means với nhiều lần khởi tạo ngẫu nhiên khác nhau (ví dụ n_init=20) và chọn phân hoạch có tổng $W(C_k)$ nhỏ nhất.

Phòng thí nghiệm 07
K-Means Từng Nửa Bước & Xoay Trục Thành Phần Chính PCA
Chạy từng nửa bước thuật toán Lloyd hoặc xoay trục phương sai cực đại trong không gian 2D
Không gian dữ liệu 2 chiều: Các điểm dữ liệu và Trực quan hóa Thuật toán
3
Số cụm cần phân hoạch.
Thuật toán Lloyd bằng NumPy — dòng sáng là dòng vừa chạy 1import numpy as np 2def kmeans(X, K, iters=50): 3 rng = np.random.default_rng(0) 4 mu = X[rng.choice(len(X), K, replace=False)] # tâm ban đầu: K điểm ngẫu nhiên 5 z = np.zeros(len(X), dtype=int) 6 for it in range(iters): 7 d = ((X[:, None, :] - mu[None, :, :]) ** 2).sum(-1) # khoảng cách² tới từng tâm 8 z = d.argmin(axis=1) # NỬA BƯỚC 1: gán mỗi điểm vào tâm gần nhất 9 mu_new = np.stack([X[z == k].mean(0) for k in range(K)]) # NỬA BƯỚC 2: dời tâm về trọng tâm 10 if np.abs(mu_new - mu).max() < 1e-3: break # tâm không nhúc nhích nữa → hội tụ 11 mu = mu_new 12 W = sum(((X[z == k] - mu[k]) ** 2).sum() for k in range(K)) # W(C): tổng bình phương trong cụm 13 return z, mu, W
Giai đoạnGán điểm vào tâm
Vòng lặp0
Biến thiên W(C)0.00
Trạng tháiĐang lặp
Diễn giải

Ở chế độ K-Means: Thuật toán luân phiên giữa Nửa bước 1 (Gán điểm vào tâm gần nhất) và Nửa bước 2 (Dời tâm về trọng tâm trung bình). Sau mỗi bước, hàm mất mát W(C) giảm đơn điệu! Khung mã NumPy bên trên tô sáng đúng dòng vừa chạy: nửa bước 1 là một argmin, nửa bước 2 là một mean.

Việc cần làm: ① Trong tab K-Means: Bấm Nửa Bước Kế Tiếp từng lần để tận mắt theo dõi hai bước nhảy của thuật toán Lloyd cho tới khi hội tụ hoàn toàn. ② Thử bấm Khởi tạo lại nhiều lần để thấy K-Means có thể bị kẹt ở các cụm địa phương khác nhau. ③ Chuyển sang tab Xoay Trục PCA: Kéo thanh trượt góc xoay từ 0° đến 180° để chứng kiến thời điểm Phương sai hình chiếu đạt cực đại thì Sai số chiếu RSS rơi về cực tiểu!


12.4.2. Phân Cụm Phân Cấp (Hierarchical Clustering)

Một nhược điểm lớn của K-Means là ta phải chọn trước số lượng cụm $K$. Phân cụm Phân cấp (Hierarchical Clustering) giải quyết hạn chế này bằng cách xây dựng một biểu đồ dạng cây phân cấp lồng nhau từ dưới lên trên, được gọi là Biểu đồ Cây (Dendrogram).

Biểu Đồ Cây Dendrogram và Cách Diễn Giải
  • Mỗi chiếc lá ở đáy đại diện cho một quan sát riêng lẻ.
  • Khi đi ngược lên trên thân cây, các quan sát tương đồng nhất sẽ được gộp lại với nhau thành từng nhánh nhỏ, rồi các nhánh nhỏ lại gộp thành nhánh lớn hơn.
  • Chiều cao thẳng đứng (vertical height) nơi hai nhánh gộp lại phản ánh mức độ khác biệt (khoảng cách) giữa hai nhánh đó: chiều cao gộp càng lớn, hai nhóm càng khác biệt.
  • Cách xác định cụm: Ta chỉ cần thực hiện một nhát cắt ngang (horizontal cut) qua cây ở một độ cao mong muốn. Số lượng đường thẳng đứng bị cắt qua chính là số lượng cụm thu được!
Chiều cao (Khoảng cách) 1 2 3 4 5 6 7 Cắt tại h = 90 → K = 2 cụm So Sánh Cơ Chế Tính Khoảng Cách Linkage Cụm A Cụm B Single Linkage (Cặp gần nhất - Min) Complete Linkage (Cặp xa nhất - Max) Average: Trung bình toàn bộ | Centroid: Khoảng cách giữa 2 trọng tâm
Hình 12.2. Trái: Biểu đồ cây Dendrogram biểu diễn tiến trình phân cụm phân cấp từ dưới lên. Một nhát cắt ngang màu đỏ tại độ cao $h = 90$ chia tập dữ liệu thành 2 cụm lớn: $\{1, 2, 3\}$ và $\{4, 5, 6, 7\}$. Phải: Khác biệt cốt lõi giữa các kiểu liên kết (Linkage) khi đo khoảng cách giữa hai tập hợp điểm.
4 Kiểu Liên Kết (Linkage) Giữa Hai Cụm

Để gộp hai cụm gồm nhiều điểm dữ liệu lại với nhau, ta cần định nghĩa khoảng cách giữa hai tập hợp điểm $A$ và $B$. Có 4 kiểu liên kết chủ đạo:

Kiểu Liên Kết (Linkage) Định Nghĩa Toán Học Đặc Tính & Hình Thái Cụm
Hoàn Toàn (Complete) $d(A, B) = \max_{i \in A, i' \in B} d(x_i, x_{i'})$ Khoảng cách lớn nhất giữa một cặp điểm bất kỳ (đường kính tối đa). Cho các cụm chặt chẽ, hình cầu cân đối. Được khuyến nghị dùng phổ biến nhất.
Đơn Lẻ (Single) $d(A, B) = \min_{i \in A, i' \in B} d(x_i, x_{i'})$ Khoảng cách nhỏ nhất giữa một cặp điểm bất kỳ. Dễ bị hiện tượng xâu chuỗi hạt dài (chaining), gom các điểm rải rác vào một cụm khổng lồ.
Trung Bình (Average) $d(A, B) = \frac{1}{\|A\| \cdot \|B\|} \sum_{i \in A} \sum_{i' \in B} d(x_i, x_{i'})$ Trung bình của toàn bộ các khoảng cách giữa từng cặp điểm. Cho kết quả cân bằng và ổn định cao.
Trọng Tâm (Centroid) $d(A, B) = \|\bar{\mathbf{x}}_A - \bar{\mathbf{x}}_B\|_2$ Khoảng cách giữa hai trọng tâm trung bình. Có nguy cơ bị lỗi đảo ngược (inversion) — hai cụm gộp sau lại có khoảng cách nhỏ hơn hai cụm gộp trước.
Khoảng Cách Euclid vs Khoảng Cách Dựa Trên Tương Quan
  • Khoảng cách Euclid: Đo lường sự khác biệt về độ lớn tuyệt đối giữa các quan sát.
  • Khoảng cách dựa trên tương quan (Correlation-based distance: $1 - r$): Đo lường sự khác biệt về hình thái xu hướng (profile) bất kể độ lớn tuyệt đối. Hai khách hàng có cùng tỷ lệ mua sắm giữa các mặt hàng (dù một người mua 10 sản phẩm và một người mua 100 sản phẩm) sẽ có khoảng cách tương quan bằng 0. Đây là độ đo tối quan trọng trong phân tích biểu hiện gen microarray.

12.5. Các Vấn Đề Thực Tế Cần Lưu Tâm Trong Phân Cụm

  1. Chuẩn hóa biến số: Có nên chuẩn hóa mỗi biến về phương sai bằng 1? Nếu các biến có đơn vị đo khác nhau (Tuổi, Chi tiêu, Cân nặng), việc chuẩn hóa là bắt buộc để tránh một biến thống trị toàn bộ khoảng cách.
  2. Độ nhạy với điểm ngoại lai: Cả K-Means và Hierarchical clustering đều rất nhạy cảm với các điểm ngoại lai (outliers) vì chúng có thể kéo lệch trọng tâm hoặc ép sinh ra một cụm chỉ chứa một điểm đơn độc.
  3. Cạm bẫy "Ép Cụm": Thuật toán phân cụm luôn trả về $K$ cụm cho dù dữ liệu thực tế là một đám mây phân phối đều hoàn toàn ngẫu nhiên không có cụm nào! Cần sử dụng các kiểm định thống kê độ tin cậy (như kỹ thuật lấy mẫu lặp bootstrap) để xác nhận cụm tìm được là thực tế khách quan.

12.6. Thực Hành Python: Dữ Liệu Tế Bào Ung Thư NCI60

Bộ dữ liệu NCI60 bao gồm thông tin biểu hiện của 6.830 gen trên 64 dòng tế bào ung thư thuộc 14 loại bệnh khác nhau (Bạch cầu, Ung thư vú, U hắc tố Melanoma, v.v.).

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from scipy.cluster.hierarchy import dendrogram, linkage
from ISLP import load_data

# 1. Tải dữ liệu NCI60
nci_data = load_data('NCI60')['data']
nci_labs = load_data('NCI60')['labels']
print(f"Kích thước ma trận gen: {nci_data.shape}") # (64, 6830)

# 2. Chuẩn hóa đặc trưng (Mean 0, Std 1)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(nci_data)

# 3. Phân tích Thành phần Chính (PCA)
pca = PCA()
Z = pca.fit_transform(X_scaled)

# Tỷ lệ phương sai giải thích
pve = pca.explained_variance_ratio_
print(f"PVE của 4 thành phần đầu: {np.round(pve[:4], 3)}")

# Vẽ biểu đồ Scree plot
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].plot(np.arange(1, 21), pve[:20], '-o', color='#2C5A8A')
ax[0].set_title("Biểu đồ Scree Plot (PVE)")
ax[0].set_xlabel("Thành phần chính")
ax[0].set_ylabel("PVE")

ax[1].plot(np.arange(1, 21), np.cumsum(pve[:20]), '-s', color='#0E7F66')
ax[1].set_title("PVE Tích Lũy")
ax[1].set_xlabel("Thành phần chính")
ax[1].set_ylabel("PVE Tích lũy")
plt.show()

# 4. Phân cụm Phân cấp với Liên kết Hoàn toàn (Complete Linkage)
fig, ax = plt.subplots(figsize=(14, 6))
link_complete = linkage(X_scaled, method='complete')
dendrogram(link_complete, labels=nci_labs.values.flatten(), leaf_rotation=90, ax=ax)
ax.set_title("Biểu đồ Cây Dendrogram (Complete Linkage): 64 Dòng Tế Bào Ung Thư")
ax.set_ylabel("Khoảng cách Euclid")
plt.tight_layout()
plt.show()

# 5. Phân cụm K-Means với K = 4
kmeans = KMeans(n_clusters=4, n_init=20, random_state=42)
km_labels = kmeans.fit_predict(X_scaled)
ct = pd.crosstab(index=nci_labs.iloc[:, 0], columns=km_labels, rownames=['Loại Ung Thư'], colnames=['Cụm K-Means'])
print("Bảng chéo đối sánh Cụm K-Means và Loại bệnh thực tế:")
print(ct.head(10))

13Chương 13: Kiểm Định Đa Giả Thuyết (Multiple Testing)

Trong kỷ nguyên khoa học hiện đại — từ công nghệ giải trình tự gen sinh học, nghiên cứu hình ảnh cộng hưởng từ não bộ (fMRI), tài chính định lượng cho đến thử nghiệm A/B testing quy mô lớn tại các tập đoàn công nghệ — các nhà nghiên cứu thường xuyên phải thực hiện hàng nghìn, thậm chí hàng triệu phép kiểm định giả thuyết cùng một lúc.

Tuy nhiên, các quy tắc kiểm định thống kê truyền thống được thiết kế cho tình huống kiểm tra một giả thuyết duy nhất. Khi áp dụng ngây thơ quy tắc đó đồng thời cho hàng nghìn giả thuyết, chúng ta sẽ rơi vào một cơn bão các phát hiện sai (false positives), đe dọa trực tiếp tính liêm chính và khả năng tái lập của các công trình khoa học. Chương này trình bày nền tảng toán học và các phương pháp hiện đại để giải quyết bài toán cốt tử này.


13.1. Ôn Tập Nhanh Về Kiểm Định Giả Thuyết Cổ Điển (Hypothesis Testing)

Xét bài toán so sánh xem một gen cụ thể có biểu hiện khác biệt giữa nhóm bệnh nhân ung thư và nhóm người khỏe mạnh hay không:

  • Giả thuyết không (Null Hypothesis - $H_0$): Không có sự khác biệt thực sự về mức độ biểu hiện gen giữa hai nhóm ($\mu_1 = \mu_2$).
  • Giả thuyết đối (Alternative Hypothesis - $H_a$): Có sự khác biệt thực sự ($\mu_1 \neq \mu_2$).

13.1.1. Thống Kê Kiểm Định và Trị Số $p$ ($p$-value)

Để đưa ra phán quyết, ta tính toán một thống kê kiểm định (test statistic) từ dữ liệu mẫu, thông dụng nhất là thống kê $t$-Student hai mẫu:

$$T = \frac{\bar{X}_1 - \bar{X}_2}{s_p \sqrt{\frac{1}{n_1} + \frac{1}{n_2}}}$$

Trị số $p$-value là xác suất quan sát được một thống kê kiểm định có độ lớn bằng hoặc cực đoan hơn giá trị $T$ thực tế quan sát được, với giả định rằng giả thuyết không $H_0$ là đúng:

$$p\text{-value} = \Pr(|Z| \ge |T| \mid H_0 \text{ đúng})$$

  • Nếu $p$-value rất nhỏ (ví dụ $p < \alpha = 0.05$), điều này cho thấy dữ liệu quan sát được là cực kỳ khó xảy ra nếu $H_0$ đúng. Do đó, ta bác bỏ $H_0$ và tuyên bố phát hiện có ý nghĩa thống kê (statistically significant discovery).
  • Dưới giả thuyết $H_0$, $p$-value là một biến ngẫu nhiên tuân theo phân phối đều liên tục trên đoạn $[0, 1]$: $\Pr(p \le u \mid H_0) = u$ với mọi $u \in [0, 1]$.

13.1.2. Hai Loại Sai Lầm trong Kiểm Định

Khi đưa ra quyết định dựa trên ngưỡng ý nghĩa $\alpha$, ta đối mặt với hai nguy cơ:

Phán Quyết Thực Tế $H_0$ Đúng (Không có tác dụng) $H_0$ Sai ($H_a$ đúng - Có tác dụng)
Không Bác Bỏ $H_0$ Quyết định đúng ($1 - \alpha$) Sai lầm Loại II ($\beta$ - Bỏ sót)
Bác Bỏ $H_0$ (Phát Hiện) Sai lầm Loại I ($\alpha$ - Báo động giả) Quyết định đúng ($1 - \beta$ - Lực kiểm định)
  • Sai lầm Loại I (Type I Error / False Positive): Khẳng định gen có liên quan đến ung thư trong khi thực tế gen đó vô hại. Xác suất xảy ra được kiểm soát bởi ngưỡng $\alpha$ (thường là $0.05$).
  • Sai lầm Loại II (Type II Error / False Negative): Bỏ sót một gen thực sự gây bệnh.
  • Lực kiểm định (Statistical Power): Xác suất phát hiện thành công một hiệu ứng thực sự: $\text{Power} = 1 - \beta$.

13.2. Thách Thức Khi Kiểm Định Đồng Thời Hàng Nghìn Giả Thuyết

Hãy tưởng tượng bạn đo lường mức độ biểu hiện của $m = 10.000$ gen trên hai nhóm bệnh nhân. Giả sử trong kịch bản cực đoan nhất: không có bất kỳ gen nào thực sự liên quan đến bệnh (tức toàn bộ $10.000$ giả thuyết không $H_{01}, \dots, H_{0m}$ đều đúng).

Nếu bạn kiểm định từng gen độc lập ở ngưỡng ý nghĩa truyền thống $\alpha = 0.05$:

  • Số lượng phát hiện sai kỳ vọng là: $$\mathbb{E}(\text{Số sai lầm Loại I}) = m \times \alpha = 10.000 \times 0.05 = 500$$ Bạn sẽ công bố rằng mình tìm thấy 500 gen gây bệnh, nhưng toàn bộ 500 gen đó hoàn toàn là rác ngẫu nhiên!

  • Xác suất có ít nhất một phát hiện sai trên toàn bộ $m$ kiểm định là: $$\Pr(\text{ít nhất một phát hiện sai}) = 1 - (1 - \alpha)^m = 1 - (1 - 0.05)^{10.000} \approx 1 - 10^{-223} = 100\%$$

Cạm Bẫy $p$-Hacking và Bòn Mót Dữ Liệu (Data Dredging)

Nếu một nhà nghiên cứu thử nghiệm 100 giả thuyết khác nhau trên cùng một bộ dữ liệu, chắc chắn sẽ có khoảng 5 giả thuyết ngẫu nhiên cho $p$-value $< 0.05$ thuần túy do may rủi. Nếu nhà nghiên cứu chỉ chọn đúng các kết quả "có ý nghĩa" đó để viết bài báo mà che giấu 95 kiểm định thất bại còn lại, đây chính là hành vi $p$-hacking. Trong học máy, việc thử hàng trăm đặc trưng hoặc siêu tham số mà không hiệu chỉnh kiểm định đa giả thuyết sẽ dẫn tới việc báo cáo độ chính xác ảo tưởng không thể tái lập.

13.2.1. Bảng Tiếp Liên Phân Loại Toàn Cục $m$ Giả Thuyết

Khi kiểm định đồng thời $m$ giả thuyết, ta có bảng tổng kết kết quả:

Thực Tế Khách Quan Không Bác Bỏ $H_0$ Bác Bỏ $H_0$ (Phát hiện) Tổng Số
$H_0$ Đúng ($m_0$ trường hợp) $U$ (Đúng) $V$ (Phát hiện sai) $m_0$
$H_0$ Sai ($m_1$ trường hợp) $T$ (Bỏ sót) $S$ (Phát hiện đúng) $m_1$
Tổng Cộng $m - R$ $R$ (Tổng số bác bỏ) $m$

Trong bảng trên:

  • $m$ là số lượng giả thuyết (đã biết trước).
  • $R$ là tổng số giả thuyết bị bác bỏ (ta quan sát được từ kết quả tính toán).
  • $m_0, m_1, U, V, T, S$ là các đại lượng tiềm ẩn chưa biết.
  • Mục tiêu của thống kê học là kiểm soát số lượng phát hiện sai $V$ ở mức an toàn trong khi vẫn tối đa hóa số phát hiện đúng $S$.

13.3. Tỷ Lệ Lỗi Theo Họ (Family-Wise Error Rate - FWER)

Cách tiếp cận khắt khe truyền thống là kiểm soát Tỷ Lệ Lỗi Theo Họ (Family-Wise Error Rate - FWER). FWER được định nghĩa là xác suất mắc phải ít nhất một sai lầm Loại I trong toàn bộ tập hợp $m$ kiểm định:

$$\text{FWER} = \Pr(V \ge 1)$$

Chúng ta mong muốn tìm quy tắc bác bỏ sao cho $\text{FWER} \le \alpha$ (ví dụ $\alpha = 0.05$).

13.3.1. Hiệu Chỉnh Bonferroni (The Bonferroni Correction)

Phương pháp kinh điển nhất do Carlo Bonferroni đề xuất: Chia ngưỡng ý nghĩa $\alpha$ cho tổng số kiểm định $m$. Ta chỉ bác bỏ $H_{0j}$ nếu:

$$p_j \le \frac{\alpha}{m}$$

Hoặc tương đương, tính toán $p$-value hiệu chỉnh Bonferroni: $\tilde{p}_j = \min(m \cdot p_j, 1)$ và so sánh với $\alpha$.

Chứng Minh Toán Học Đẹp Đẽ Dựa Trên Bất Đẳng Thức Boole

Gọi $\mathcal{H}_0$ là tập các chỉ số mà $H_{0j}$ thực sự đúng ($|\mathcal{H}_0| = m_0 \le m$). Áp dụng bất đẳng thức Boole (xác suất của hội không vượt quá tổng các xác suất): $$\text{FWER} = \Pr(V \ge 1) = \Pr\left( \bigcup_{j \in \mathcal{H}_0} \left\{ p_j \le \frac{\alpha}{m} \right\} \right) \le \sum_{j \in \mathcal{H}_0} \Pr\left( p_j \le \frac{\alpha}{m} \right)$$ Vì với mỗi $j \in \mathcal{H}_0$, $p_j \sim U[0, 1]$ nên $\Pr(p_j \le \alpha / m) = \alpha / m$. Do đó: $$\text{FWER} \le \sum_{j \in \mathcal{H}_0} \frac{\alpha}{m} = m_0 \frac{\alpha}{m} \le m \frac{\alpha}{m} = \alpha$$ Chứng minh này hoàn toàn không đòi hỏi các kiểm định phải độc lập — Bonferroni luôn bảo đảm kiểm soát FWER dưới mọi cấu trúc tương quan phức tạp!

Nhược điểm chí mạng của Bonferroni: Khi $m = 10.000$ và $\alpha = 0.05$, ngưỡng cắt trở thành $\frac{0.05}{10.000} = 0.000005$. Ngưỡng này quá bảo thủ (overly conservative), dẫn tới việc triệt tiêu gần như toàn bộ lực kiểm định (power), khiến ta bỏ sót vô số phát hiện quan trọng có thực trong tự nhiên.

13.3.2. Phương Pháp Holm Từng Bước (Holm's Step-Down Procedure)

Sture Holm (1979) đã phát minh một phương pháp từng bước luôn mang lại lực kiểm định cao hơn Bonferroni mà vẫn bảo đảm chặt chẽ $\text{FWER} \le \alpha$:

  1. Sắp xếp $m$ giá trị $p$-value theo thứ tự tăng dần từ nhỏ nhất đến lớn nhất: $$p_{(1)} \le p_{(2)} \le \dots \le p_{(m)}$$ Với các giả thuyết tương ứng là $H_{(1)}, H_{(2)}, \dots, H_{(m)}$.

  2. So sánh lần lượt từng $p_{(k)}$ với ngưỡng động $\frac{\alpha}{m - k + 1}$:

    • Bước 1: Nếu $p_{(1)} \le \frac{\alpha}{m}$, bác bỏ $H_{(1)}$ và tiếp tục sang bước 2. Ngược lại, dừng lại và không bác bỏ giả thuyết nào.
    • Bước $k$: Nếu $p_{(k)} \le \frac{\alpha}{m - k + 1}$, bác bỏ $H_{(k)}$ và tiếp tục sang bước $k+1$.
    • Quy tắc dừng: Dừng lại ngay tại chỉ số $L$ đầu tiên mà: $$p_{(L)} > \frac{\alpha}{m - L + 1}$$ Ta bác bỏ toàn bộ các giả thuyết $H_{(1)}, \dots, H_{(L-1)}$ và chấp nhận toàn bộ các giả thuyết còn lại.

Phương pháp Holm đồng đều mạnh hơn (uniformly more powerful) so với Bonferroni vì các mẫu số $m - k + 1$ giảm dần, khiến ngưỡng cắt ngày càng nới lỏng hơn cho các bậc sau.


13.4. Tỷ Lệ Phát Hiện Sai: Kiểm Soát FDR (False Discovery Rate)

Khi $m$ lên đến hàng vạn hoặc hàng triệu (như trong GWAS hoặc Big Data), mục tiêu FWER "không được phép có dù chỉ một phát hiện sai duy nhất" trở nên quá khắt khe và phi thực tế.

Năm 1995, hai nhà thống kê học Yoav Benjamini và Yosef Hochberg đã tạo nên một cuộc cách mạng tư duy khi giới thiệu khái niệm Tỷ Lệ Phát Hiện Sai (False Discovery Rate - FDR).

13.4.1. Trực Giác Cốt Lõi Về FDR

Định nghĩa tỷ số phát hiện sai $Q$:

$$Q = \frac{V}{R} = \frac{\text{Số phát hiện sai}}{\text{Tổng số phát hiện}}$$

(Với quy ước $Q = 0$ nếu $R = 0$). Tỷ lệ phát hiện sai (FDR) là kỳ vọng toán học của tỷ số này:

$$\text{FDR} = \mathbb{E}(Q) = \mathbb{E}\left[ \frac{V}{\max(R, 1)} \right]$$

Triết Lý Khám Phá Khoa Học của FDR

Thay vì đòi hỏi sự an toàn tuyệt đối không tì vết ($\text{FWER} \le 0.05$ — điều khiến bạn chỉ dám công bố 1 hoặc 2 phát hiện), nhà khoa học sẵn sàng chấp nhận một tỷ lệ tạp chất nhỏ trong danh sách khám phá của mình. Nếu bạn tìm ra 100 gen tiềm năng và kiểm soát $\text{FDR} \le 0.05$, điều đó đồng nghĩa với việc bạn kỳ vọng có khoảng 5 gen là báo động giả, nhưng đổi lại bạn thu được tới 95 gen thực sự có giá trị để tiến hành các thí nghiệm sinh học chuyên sâu tiếp theo!

Kiểm Soát FWER (Bonferroni / Holm) Mục tiêu: Pr(V ≥ 1) ≤ α — Không cho phép bất kỳ sai lầm nào Ngưỡng α/m cực nhỏ Phát hiện đúng duy nhất Hậu quả: Bỏ sót vô số phát hiện thực tế (Lực kiểm định sụt giảm) Kiểm Soát FDR (Benjamini–Hochberg) Mục tiêu: E[V / max(R, 1)] ≤ q* — Chấp nhận tỷ lệ tạp chất cố định Tập Hợp R = 100 Phát Hiện Công Bố ~5% Báo động giả (V) trong tầm kiểm soát Lợi ích: Thu được 95 phát hiện đúng thực tế để mở rộng nghiên cứu
Hình 13.1. So sánh triết lý kiểm soát sai lầm trong kiểm định đa giả thuyết. Trái (FWER): Kiểm soát tuyệt đối không để lọt dù chỉ 1 phát hiện sai, nhưng cánh cổng quá hẹp khiến hầu hết hiệu ứng thực sự bị bỏ sót. Phải (FDR): Cho phép một tỷ lệ tạp chất cố định $q^*$ (ví dụ 5%) trong tập phát hiện, đổi lại thu hoạch được gần như toàn bộ các gen thực sự có giá trị.

13.4.2. Quy Trình Benjamini–Hochberg (BH Procedure)

Để kiểm soát $\text{FDR} \le q^*$ tại mức mong muốn $q^*$ (ví dụ $q^* = 0.10$ hoặc $0.05$), quy trình Benjamini–Hochberg (BH) thực hiện như sau:

  1. Sắp xếp $m$ giá trị $p$-value theo thứ tự tăng dần: $$p_{(1)} \le p_{(2)} \le \dots \le p_{(m)}$$

  2. Xác định chỉ số lớn nhất $k$ thỏa mãn bất đẳng thức: $$p_{(k)} \le \frac{k}{m} q^*$$

  3. Bác bỏ toàn bộ $k$ giả thuyết đầu tiên có $p$-value nhỏ nhất: $$\text{Bác bỏ } H_{(1)}, H_{(2)}, \dots, H_{(k)}$$

Minh Họa Hình Học Tuyệt Vời Của Đường Chéo BH
  • Vẽ đồ thị các điểm $(k, p_{(k)})$ trên mặt phẳng với trục hoành là thứ tự $k = 1, \dots, m$ và trục tung là giá trị $p$-value.
  • Vẽ đường thẳng đi qua gốc tọa độ nối tới điểm $(m, q^*)$: phương trình đường thẳng là $y = \frac{q^*}{m} x$.
  • Tìm điểm nằm dưới đường thẳng có chỉ số hoành độ $k$ lớn nhất. Toàn bộ các điểm từ $1$ đến $k$ đó đều được tuyên bố là các phát hiện có ý nghĩa!
Phòng thí nghiệm 08
Kiểm Soát Tỷ Lệ Phát Hiện Sai (FDR) Theo Quy Trình Benjamini–Hochberg
Kéo ngưỡng q* để tìm điểm giao cắt lớn nhất trên đường chéo và quan sát sự vượt trội so với Bonferroni
Biểu đồ p-values đã sắp xếp k = 1..m: Đường chéo BH (đỏ), Ngưỡng Bonferroni (vàng) và Các phát hiện (xanh ngọc)
0.10
Tỷ lệ phát hiện sai chấp nhận tối đa.
15%
Tỷ lệ giả thuyết đối Ha thực sự đúng.
Tổng kiểm định (m)200
Số phát hiện BH (R)25
Phát hiện đúng (S)23
Báo động giả (V)2
FDR thực tế (V/R)8.0%
Phát hiện Bonferroni3
Diễn giải

Đường chéo màu đỏ là ngưỡng Benjamini-Hochberg: y = (k / m) · q*. Quy trình BH tìm điểm p(k) lớn nhất còn nằm dưới đường chéo này (chỉ số k*) và bác bỏ toàn bộ k* giả thuyết đầu tiên. Nhờ đó, ta thu được nhiều phát hiện gấp nhiều lần Bonferroni trong khi FDR vẫn được bảo đảm ≤ q*!

Việc cần làm: ① Kéo tăng Ngưỡng FDR (q*) từ 0.05 lên 0.20: Quan sát đường chéo nâng dốc lên, kết nạp thêm nhiều phát hiện mới màu xanh ngọc. ② So sánh số phát hiện của BH với chỉ số Phát hiện Bonferroni: Bonferroni cực kỳ khắt khe chỉ tìm được 2-3 gen và bỏ sót gần hết! ③ Bấm Sinh Mẫu Mới để kiểm nghiệm định lý toán học: FDR thực tế luôn được ghìm dưới ngưỡng q* qua các lần lấy mẫu.

Benjamini và Hochberg đã chứng minh định lý toán học nền tảng: Nếu $m$ kiểm định là độc lập (hoặc có tương quan dương dạng PRDS), quy trình BH luôn bảo đảm:

$$\text{FDR} \le \frac{m_0}{m} q^* \le q^*$$


13.5. Tiếp Cận Lấy Lại Mẫu (Resampling / Permutation Approach)

Trong nhiều bài toán y sinh học phức tạp, phân phối lý thuyết của thống kê kiểm định $T$ chưa được biết, kích thước mẫu $n$ nhỏ khiến định lý giới hạn trung tâm không áp dụng được, hoặc các biến có cấu trúc tương quan phi tuyến chặt chẽ. Khi đó, phương pháp Kiểm định Hoán vị (Permutation Test) cung cấp một giải pháp phi tham số mạnh mẽ:

  1. Giả thuyết $H_0$ ngẫu nhiên: Dưới $H_0$, nhãn nhóm (ví dụ: Bệnh nhân vs Đối chứng) không có mối liên hệ nào với vector đặc trưng biểu hiện gen.
  2. Xáo trộn nhãn: Ta xáo trộn (hoán vị) ngẫu nhiên các nhãn nhóm $B$ lần (ví dụ $B = 1.000$ hoặc $10.000$ lần), giữ nguyên ma trận dữ liệu đặc trưng.
  3. Phân phối không thực nghiệm (Empirical Null): Tại mỗi lần hoán vị $b$, tính toán lại thống kê kiểm định $T_j^{(b)}$ cho tất cả các gen. Tập hợp các giá trị này phản ánh phân phối của thống kê kiểm định thuần túy do ngẫu nhiên sinh ra.
  4. Ước lượng FDR bằng hoán vị: Với bất kỳ ngưỡng cắt $c$ nào, số lượng phát hiện quan sát được trên dữ liệu thực tế là $R(c) = \sum_{j=1}^m I(|T_j| \ge c)$. Số lượng phát hiện sai kỳ vọng được ước lượng trực tiếp bằng trung bình số phát hiện vượt ngưỡng qua $B$ lần hoán vị: $$\widehat{\text{FDR}}(c) = \frac{\frac{1}{B} \sum_{b=1}^B \sum_{j=1}^m I(|T_j^{(b)}| \ge c)}{R(c)}$$

13.6. Thực Hành Python: Kiểm Định Đa Giả Thuyết với scipy & statsmodels

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import ttest_ind
from statsmodels.stats.multitest import multipletests

# 1. Mô phỏng dữ liệu biểu hiện gen: m = 2.000 gen, n = 40 mẫu (20 nhóm A, 20 nhóm B)
# Giả sử: 1.800 gen vô dụng (H0 đúng), 200 gen thực sự có tác dụng (H0 sai)
np.random.seed(42)
m = 2000
m0 = 1800
m1 = 200
n_samples = 20

# Dữ liệu nhóm A và nhóm B
X_A = np.random.normal(loc=0.0, scale=1.0, size=(m, n_samples))
X_B = np.random.normal(loc=0.0, scale=1.0, size=(m, n_samples))
# Bổ sung hiệu ứng thực sự cho 200 gen đầu tiên ở nhóm B
X_B[:m1, :] += np.random.normal(loc=1.2, scale=0.3, size=(m1, n_samples))

# 2. Thực hiện kiểm định t-Student độc lập cho từng gen
p_values = np.zeros(m)
for j in range(m):
    stat, p = ttest_ind(X_A[j, :], X_B[j, :])
    p_values[j] = p

# Kiểm tra nếu dùng ngưỡng ngây thơ alpha = 0.05
raw_reject = p_values < 0.05
print(f"Kiểm định đơn lẻ (alpha = 0.05): Phát hiện {np.sum(raw_reject)} gen "
      f"(trong đó {np.sum(raw_reject[m1:])} là phát hiện sai / rác!)")

# 3. Hiệu chỉnh Bonferroni (Kiểm soát FWER <= 0.05)
bonf_reject, bonf_p, _, _ = multipletests(p_values, alpha=0.05, method='bonferroni')
print(f"Hiệu chỉnh Bonferroni: Phát hiện {np.sum(bonf_reject)} gen "
      f"(Phát hiện đúng: {np.sum(bonf_reject[:m1])}, Báo động giả: {np.sum(bonf_reject[m1:])})")

# 4. Phương pháp Holm (Kiểm soát FWER <= 0.05)
holm_reject, holm_p, _, _ = multipletests(p_values, alpha=0.05, method='holm')
print(f"Phương pháp Holm: Phát hiện {np.sum(holm_reject)} gen "
      f"(Phát hiện đúng: {np.sum(holm_reject[:m1])}, Báo động giả: {np.sum(holm_reject[m1:])})")

# 5. Quy trình Benjamini-Hochberg (Kiểm soát FDR <= 0.10)
fdr_reject, fdr_p, _, _ = multipletests(p_values, alpha=0.10, method='fdr_bh')
print(f"Quy trình Benjamini-Hochberg (q* = 0.10): Phát hiện {np.sum(fdr_reject)} gen "
      f"(Phát hiện đúng: {np.sum(fdr_reject[:m1])}, Báo động giả: {np.sum(fdr_reject[m1:])})")

# 6. Vẽ biểu đồ đường chéo Benjamini-Hochberg
sorted_indices = np.argsort(p_values)
sorted_p = p_values[sorted_indices]
ranks = np.arange(1, m + 1)
bh_threshold = (ranks / m) * 0.10

plt.figure(figsize=(9, 5))
plt.plot(ranks[:300], sorted_p[:300], 'o', markersize=3, color='#2C5A8A', label='p-values đã sắp xếp')
plt.plot(ranks[:300], bh_threshold[:300], '--', color='#B23B26', linewidth=2, label='Đường chéo BH (q* = 0.10)')
plt.axhline(0.05 / m, color='#8A6D25', linestyle=':', label='Ngưỡng Bonferroni')
plt.title("Trực quan hóa Quy trình Benjamini-Hochberg cho Kiểm soát FDR")
plt.xlabel("Thứ tự sắp xếp k")
plt.ylabel("p-value")
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()