Chương 2·Bài 2.6

Random forest

Một cây quyết định rất nhạy với dữ liệu: đổi vài mẫu huấn luyện là ngưỡng ở các nút có thể đổi, và dự đoán đổi theo. Random forest huấn luyện nhiều cây, mỗi cây trên một bản lấy mẫu khác của dữ liệu và chỉ xét một phần đặc trưng ở mỗi nút, rồi gộp dự đoán của các cây. Bài này giải thích vì sao gộp nhiều cây giúp dự đoán ổn định hơn, và vì sao các cây phải khác nhau thì gộp mới có tác dụng.

Vì sao trung bình giúp ích

Bài 2.5 kết luận cây có variance cao: đổi dữ liệu một chút là cây đổi hẳn. Giả sử có BB mô hình, mỗi cái có phương sai σ2\sigma^2, và hai mô hình bất kỳ có hệ số tương quan ρ\rho. Phương sai của trung bình là

Var⁡ ⁣(1B∑b=1Bfb)=ρ σ2+1−ρB σ2.\operatorname{Var}\!\left(\frac{1}{B}\sum_{b=1}^{B} f_b\right) = \rho\,\sigma^2 + \frac{1 - \rho}{B}\,\sigma^2.

Khi B→∞B \to \infty, số hạng thứ hai biến mất nhưng số hạng đầu thì còn nguyên. Nhiều cây hơn chỉ giúp đến một mức; muốn giảm tiếp thì phải làm các cây ít giống nhau hơn, tức giảm ρ\rho.

Với σ2=1\sigma^2 = 1 và B=100B = 100: nếu ρ=0.5\rho = 0.5 thì phương sai còn 0.5050.505; nếu ρ=0.1\rho = 0.1 thì còn 0.1090.109. Giảm tương quan có lợi hơn nhiều so với thêm cây. Khi ρ=0\rho = 0 thì phương sai chia đều cho BB: chụp 8 tấm cùng một cảnh tối rồi lấy trung bình từng điểm ảnh, nhiễu ngẫu nhiên triệt tiêu bớt còn cảnh đứng yên được giữ nguyên.

Thêm cây chỉ kéo phương sai về mức sàn ρσ²; giảm tương quan mới hạ được sàn.00.250.50.7511255075100số cây Bρ = 0.5ρ = 0.1sàn ρσ²
Thêm cây chỉ kéo phương sai về mức sàn ρσ²; giảm tương quan mới hạ được sàn.

Hỏi nhanh

Lấy σ2=1\sigma^2 = 1. Rừng A có 50 cây, ρ=0.1\rho = 0.1. Rừng B có 500 cây, ρ=0.4\rho = 0.4. Theo công thức trên, rừng nào có phương sai của trung bình nhỏ hơn?

Hai nguồn ngẫu nhiên

Random forest (Breiman, 2001) làm các cây khác nhau bằng hai cách:

  1. Bagging (bootstrap aggregating): mỗi cây học trên một tập bootstrap, tức nn mẫu rút có hoàn lại từ nn mẫu gốc.
  2. Chọn ngẫu nhiên đặc trưng ở mỗi nút: chỉ xét một tập con ngẫu nhiên gồm max_features đặc trưng khi tìm phép chia tốt nhất. Nếu có một đặc trưng rất mạnh, bagging thuần túy vẫn cho mọi cây chia ở gốc bằng đặc trưng đó và các cây vẫn giống nhau. Che bớt đặc trưng buộc các cây phải tìm đường khác.

Mỗi cây được mọc sâu, gần như không cắt tỉa: bias thấp, variance cao, rồi trung bình hóa để kéo variance xuống. Phân loại thì lấy trung bình xác suất (hoặc bỏ phiếu); hồi quy thì lấy trung bình giá trị, 1B∑bTb(x)\frac1B\sum_b T_b(\mathbf{x}). Các cây học độc lập, có thể học song song; boosting ở bài 2.7 thì dựng cây nối tiếp, cây sau sửa lỗi cây trước.

Hai cách gộp không luôn đồng ý. Ba cây cho xác suất lớp 1 của cùng một mẫu là 0.90.9, 0.40.4, 0.40.4. Trung bình xác suất là (0.9+0.4+0.4)/3≈0.57(0.9 + 0.4 + 0.4)/3 \approx 0.57, dự đoán lớp 1; bỏ phiếu thì chỉ 1 trên 3 cây chọn lớp 1, dự đoán lớp 0. Một cây rất chắc chắn thắng hai cây lưỡng lự. scikit-learn dùng cách thứ nhất, và khi cần xác suất để tính log loss hay AUC thì đó cũng là cách nên dùng.

Trung bình xác suất chọn lớp 1; bỏ phiếu chọn lớp 0.00.51xác suất lớp 1cây 10.9cây 20.4cây 30.4trung bình0.57 → lớp 1bỏ phiếu: 1 trên 3→ lớp 0
Trung bình xác suất chọn lớp 1; bỏ phiếu chọn lớp 0.
Mỗi cây học một tập bootstrap nên ranh giới khác nhau; trung bình 200 cây mượt hơn.cây 1cây 2cây 3rừng 200 cây
Mỗi cây học một tập bootstrap nên ranh giới khác nhau; trung bình 200 cây mượt hơn.
Random forest trên cùng bài đoán màu: mỗi cây học một mẫu bootstrap nên sai theo kiểu riêng; lấy trung bình nhiều cây thì ảnh mượt hơn và sai số trên điểm chưa thấy giảm.

Hỏi nhanh

“Bootstrap nn mẫu từ nn mẫu gốc” nghĩa là gì?

Out-of-bag: validation miễn phí

Xác suất một mẫu không được chọn lần nào trong nn lần rút có hoàn lại là

(1−1n)n  →  n→∞    e−1≈0.368.\left(1 - \frac{1}{n}\right)^{n} \;\xrightarrow{\;n\to\infty\;}\; e^{-1} \approx 0.368.

Vậy mỗi cây “chưa thấy” khoảng 37% dữ liệu. Dự đoán mỗi mẫu bằng các cây không dùng nó, ta được điểm out-of-bag (OOB): một ước lượng gần như cross-validation mà không tốn thêm lần huấn luyện nào. Mỗi mẫu nhận phiếu đa số của riêng các cây không thấy nó; lỗi OOB là tỉ lệ mẫu bị đoán sai, tính theo mẫu chứ không theo từng phiếu.

Ví dụ 5 mẫu, đánh số 1 đến 5, rừng có 3 cây:

Cây Tập bootstrap Mẫu out-of-bag
1 1, 1, 3, 4, 4 2, 5
2 2, 2, 3, 5, 5 1, 4
3 1, 2, 2, 4, 5 3

Điểm OOB của mẫu 1 chỉ do cây 2 chấm, mẫu 3 chỉ do cây 3 chấm, và cứ thế. Với n=5n = 5, xác suất một mẫu nằm ngoài một tập bootstrap là (4/5)5≈0.33(4/5)^5 \approx 0.33, đã khá gần 0.3680.368.

Ô nét đứt là mẫu cây đó chưa thấy, dùng để chấm OOB.mẫu 1mẫu 2mẫu 3mẫu 4mẫu 5cây 1×2OOB×1×2OOBcây 2OOB×2×1OOB×2cây 3×1×2OOB×1×1
Ô nét đứt là mẫu cây đó chưa thấy, dùng để chấm OOB.

Hỏi nhanh

Train có 1000 mẫu. Với một cây trong rừng, khoảng bao nhiêu mẫu nằm ngoài tập bootstrap của nó, và trong tập ấy có khoảng bao nhiêu mẫu khác nhau?

Các tham số

Tham số Ý nghĩa Gợi ý
n_estimators Số cây Nhiều cây hơn thường bớt dao động; đo validation, RAM và thời gian trước khi tăng.
max_features Số đặc trưng xét ở mỗi nút Phân loại thường d\sqrt{d}; nhỏ hơn thì cây đa dạng hơn
min_samples_leaf Số mẫu tối thiểu ở lá 1–5; tăng lên khi dữ liệu nhiễu
max_depth Độ sâu Thường để không giới hạn

Biến thể Extra Trees (extremely randomized trees) chọn luôn ngưỡng ngẫu nhiên thay vì tìm ngưỡng tốt nhất: nhanh hơn, cây còn khác nhau hơn nữa, đôi khi tốt hơn trên dữ liệu nhiễu.

Hỏi nhanh

Muốn từng cây chính xác hơn, một bạn đặt max_features bằng toàn bộ dd feature. Lỗi tổng quát của rừng có xu hướng thế nào?

Phỏng theoCMU 10-601 · Exam 3 Practice · Q6.2(c)

Tự nhìn một lần bootstrap

Đừng hiểu bootstrap là lấy một tập con không lặp. Với nn mẫu, mỗi cây rút nn lần có hoàn lại: một mẫu có thể xuất hiện nhiều lần, mẫu khác không xuất hiện lần nào. Ta nhìn ngay một lượt rút nhỏ trước khi dùng cả rừng.

Python
import numpy as np

rng_boot = np.random.default_rng(7)
draw = rng_boot.integers(0, 5, size=5)
seen = np.unique(draw)
oob = np.setdiff1d(np.arange(5), seen)
print("rút:", draw.tolist())
print("đã thấy:", seen.tolist(), "OOB:", oob.tolist())
probabilities = np.array([0.9, 0.4, 0.4])
print("trung bình:", round(float(probabilities.mean()), 3))
print("phiếu lớp 1:", int(np.sum(probabilities > 0.5)))

Đọc dòng “đã thấy”: số mẫu phân biệt có thể nhỏ hơn 5 dù đã rút đủ 5 lần. Với nhiều cây, mẫu 0 chỉ được chấm OOB bằng những cây không thấy mẫu 0. Có một cây không dùng nó không đủ để điểm OOB ổn định; cần nhiều cây và phải kiểm cảnh báo mẫu thiếu dự đoán OOB.

Một lượt bootstrap: mẫu 3, 4 lặp hai lần; mẫu 0, 1 không được rút nên là OOB.rút43342mẫu0×01×02×13×24×2OOB của cây này0, 1
Một lượt bootstrap: mẫu 3, 4 lặp hai lần; mẫu 0, 1 không được rút nên là OOB.

Hỏi nhanh

Một cây có tập bootstrap gồm các chỉ số [0, 0, 2, 3, 3], lấy từ dữ liệu có 5 mẫu. Những mẫu nào là OOB?

Trung bình giảm nhiễu có điều kiện

Công thức phương sai ở trên giả sử các dự đoán có cùng phương sai σ2\sigma^2 và mọi cặp có cùng tương quan ρ\rho. Nó là một mô hình để thấy tác dụng của sự đa dạng, không phải cách dự đoán chính xác metric của bất kỳ rừng nào. Với các dự đoán thật, ta không được tự gán ρ=0\rho=0 chỉ vì các cây được train bằng seed khác nhau: chúng vẫn dùng chung một nguồn dữ liệu và cùng những đặc trưng mạnh.

Random forest bớt biến động nhờ trung bình hóa, nhưng không chữa được việc toàn bộ dữ liệu train sai phân phối hay một cột rò rỉ target. Tăng số cây chủ yếu làm dự đoán ổn định hơn; validation có thể dao động và một rừng lớn vẫn overfit. Tăng min_samples_leaf hoặc hạn chế độ sâu làm từng cây mượt hơn, còn giảm max_features làm các cây đa dạng hơn nhưng cũng có thể làm từng cây yếu đi. Ta chọn cân bằng bằng validation.

Hỏi nhanh

100 cây được học với 100 seed khác nhau. Có thể coi dự đoán của chúng là độc lập, tức ρ=0\rho = 0, để tính phương sai theo công thức trên không?

OOB rất tiện với các mẫu độc lập cùng phân phối. Nếu cùng một học sinh có nhiều bản ghi, cây không thấy một bản ghi nhưng có thể thấy các bản ghi khác của người đó. OOB theo hàng lúc này không thay thế group split. Với dự báo tương lai, bootstrap cũng không thay thế validation theo thời gian. Một lần chạy có OOB score cao chưa chứng minh mô hình dùng được ngoài lớp học.

Dùng thư viện

Python
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeClassifier

X, y = load_breast_cancer(return_X_y=True)
tree = DecisionTreeClassifier(random_state=0)
forest = RandomForestClassifier(n_estimators=80, oob_score=True, n_jobs=1, random_state=0)
print("một cây:", round(cross_val_score(tree, X, y, cv=5).mean(), 3))
print("rừng:   ", round(cross_val_score(forest, X, y, cv=5).mean(), 3))
print("OOB:    ", round(forest.fit(X, y).oob_score_, 3))

Rừng hơn một cây khoảng 4.6 điểm CV. OOB 0.9680.968 và CV 0.9630.963 là hai ước lượng khác nhau của cùng một thứ, và ở đây chúng gần nhau.

OOB accuracy theo số cây: sau khoảng 80 cây gần như đứng yên.0.910.930.950.97080160240320số câymax_features = √dxét mọi feature (bagging)OOB accuracy
OOB accuracy theo số cây: sau khoảng 80 cây gần như đứng yên.

Hỏi nhanh

Điểm OOB của rừng là 0.9680.968, còn cross-validation 5 fold cho 0.9630.963. Hiểu chênh lệch này thế nào?

Khi đi thi

  • Bài dữ liệu bảng thì chạy random forest sớm làm baseline: không cần chuẩn hóa, ít khi hỏng.
  • Điểm OOB chỉ đáng tin khi các hàng độc lập; dữ liệu theo nhóm hay theo thời gian thì dùng cách chia riêng.
  • Thêm cây mà validation đứng yên thì thử max_features hoặc feature mới, đừng tăng cây tiếp.

Tóm tắt

  • Trung bình hóa nhiều mô hình giảm variance, nhưng chỉ khi chúng ít tương quan.
  • Random forest = bagging + chọn ngẫu nhiên đặc trưng ở mỗi nút; mỗi cây sâu, cả rừng ổn định.
  • Khoảng 37% dữ liệu nằm ngoài mỗi tập bootstrap, cho điểm OOB miễn phí.
  • Thêm cây chủ yếu ổn định việc trung bình hóa, không thay thế kiểm validation; tham số quan trọng nhất là max_features và min_samples_leaf.

Kiểm tra cuối bài

Mười câu kiểm cả cách hiểu, phép tính và quy trình. Câu sai chỉ ra phần cần đọc lại; hãy làm trước khi mở lời giải.

Câu 1

Có n=4n = 4 mẫu train. Một cây rút 4 lần độc lập, đều xác suất, có hoàn lại. Xác suất một mẫu cụ thể không được rút lần nào là bao nhiêu?

Câu 2

Random forest chuẩn có dùng bootstrap. So với bagging các cây xét mọi feature ở mỗi nút, random forest giảm tương quan giữa các cây bằng cách nào?

Câu 3

Giả sử BB cây có phương sai dự đoán σ2=4\sigma^2 = 4, và mọi cặp cây có cùng tương quan ρ=0.25\rho = 0.25. Với B=20B = 20, phương sai của trung bình dự đoán bằng bao nhiêu?

Câu 4

Rừng 5 cây học trên 7 mẫu và gộp kết quả bằng đa số phiếu. Bảng ghi dự đoán của những cây không thấy từng mẫu.

Mẫu Thật Dự đoán OOB của các cây không thấy mẫu
1 Không Không
2 Không Không, Có, Có
3 Có Có
4 Có Có
5 Không Không
6 Có Không
7 Có Không, Không

Lỗi OOB của rừng bằng bao nhiêu?

Phỏng theoCMU 10-601 · Exam 3 Practice · Q6.2(a)

Câu 5

Trong bảng của câu trước, có một cây đúng mọi mẫu OOB của nó, và một cây khác sai mọi mẫu. Khi dự đoán một mẫu mới, random forest chuẩn cho cây nào trọng số cao nhất?

Phỏng theoCMU 10-601 · Exam 3 Practice · Q6.2(b)

Câu 6

Rừng hồi quy học giá nhà từ những căn có giá 1 đến 5 tỷ. Một căn mới rộng gấp đôi căn lớn nhất trong train. Rừng sẽ dự đoán ra sao?

Câu 7

Mỗi bệnh nhân có 4 bản ghi, và mục tiêu là dự đoán cho bệnh nhân mới. Nhưng OOB tính theo hàng vẫn để một bản ghi được chấm bởi những cây đã học các bản ghi khác của cùng người. Ta nên đánh giá bổ sung thế nào?

Câu 8

Tăng n_estimators từ 100 lên 1000. Accuracy trên train tăng từ 99.2% lên 99.8%, trên validation vẫn đứng ở 87.3%, còn thời gian chạy tăng gấp 10. Nhận định nào phù hợp?

Phỏng theoNOAI 2026 Singapore · Chung kết · Câu 2

Câu 9

classes_ của rừng là ["fraud", "normal"], và metric cần score của lớp fraud. Dòng nào lấy đúng score ấy?

Câu 10

Rừng tìm ra một cột chứa sẵn đáp án của validation, và điểm rất cao. Điểm cao ấy chứng tỏ điều gì?

Đọc thêm

  • James, Witten, Hastie, Tibshirani — An Introduction to Statistical Learning, mục 8.2. Bagging, random forest và OOB với ví dụ đọc kết quả.
  • Géron — Hands-On Machine Learning, chương 7. Ensemble, bagging, random forest và Extra Trees bằng scikit-learn.
  • Galton (1907) — Vox Populi, Nature 75. Câu chuyện đám đông đoán cân nặng con bò: trung bình nhiều phỏng đoán độc lập chính xác hơn từng người.
  • Breiman — Random Forests. Bài gốc về random forest, sự đa dạng và out-of-bag.
  • scikit-learn — Forests of randomized trees. Tham số, phân loại bằng trung bình xác suất và chi phí song song.

Nguồn ảnh: ảnh tháp là ảnh mẫu china.jpg kèm scikit-learn (danielbuechele, Flickr, CC BY 2.0).