[Tech Blog #26 | Data Science] Random Forest & Sức Mạnh Của Ensemble Learning: "Trí Tuệ Đám Đông" Đánh Bại Overfitting
![[Tech Blog #26 | Data Science] Random Forest & Sức Mạnh Của Ensemble Learning: "Trí Tuệ Đám Đông" Đánh Bại Overfitting](/uploads/ai-images/cover-random-forest-ensemble-learning.png)
1. Đặt vấn đề: Câu chuyện "Đoán cân nặng con bò" & Trí tuệ đám đông
Vào năm 1906, nhà thống kê học nổi tiếng Francis Galton tham dự một hội chợ gia súc tại Anh. Tại đây có một trò chơi cá cược: người tham gia phải đoán chính xác cân nặng của một con bò đực sau khi mổ thịt.
Gần 800 người đã tham gia, từ các chuyên gia đồ tể, nông dân cho đến những người dân thường:
- Có người đoán quá cao (do nhìn từ xa thấy con bò đồ sộ).
- Có người đoán quá thấp (do con bò đứng khom người).
- Hầu như không có một cá nhân nào đoán trúng con số thật.
Thế nhưng, khi Galton thu thập toàn bộ 800 phiếu đoán và tính giá trị trung bình cộng, con số thu được là 1.197 pounds. Cân nặng thực tế của con bò là 1.198 pounds – tức là phán đoán của số đông chỉ lệch vỏn vẹn 0.08% so với sự thật! Hiện tượng kỳ diệu này được gọi là Trí tuệ đám đông (Wisdom of the Crowds).
Trong [Tech Blog #14], chúng ta đã biết một Cây quyết định (Decision Tree) đơn lẻ rất dễ bị "học vẹt" (Overfitting) và thiếu ổn định.
Để giải quyết bài toán này, các nhà khoa học máy tính đã áp dụng chính nguyên lý trí tuệ đám đông để tạo ra thuật toán Random Forest (Rừng ngẫu nhiên): Thay vì tin vào 1 cái cây duy nhất, ta hãy trồng một khu rừng gồm hàng trăm cây quyết định và để chúng cùng biểu quyết!
2. Giải mã 2 trụ cột tạo nên sức mạnh của Random Forest
Random Forest thuộc nhóm phương pháp Ensemble Learning (Học tăng cường tập hợp) – tức là kết hợp nhiều mô hình dự đoán yếu (Weak Learners) để tạo thành một mô hình tổng thể siêu mạnh (Strong Learner).
Sức mạnh của Random Forest nằm ở 2 chữ: "Random" (Ngẫu nhiên) và "Forest" (Rừng cây):
[TẬP DỮ LIỆU GỐC (N dòng, D cột)]
│
┌────────────────────────────────┼────────────────────────────────┐
▼ ▼ ▼
[Bootstrap Mẫu 1] [Bootstrap Mẫu 2] [Bootstrap Mẫu 100]
(Chọn ngẫu nhiên có lặp) (Chọn ngẫu nhiên có lặp) (Chọn ngẫu nhiên có lặp)
│ │ │
▼ ▼ ▼
[Cây Quyết Định 1] [Cây Quyết Định 2] [Cây Quyết Định 100]
(Chỉ chọn d < D cột ngẫu nhiên)(Chỉ chọn d < D cột ngẫu nhiên)(Chỉ chọn d < D cột ngẫu nhiên)
│ │ │
▼ ▼ ▼
[Dự đoán: A] [Dự đoán: A] [Dự đoán: B]
│ │ │
└────────────────────────────────┼────────────────────────────────┘
│
▼
[BIỂU QUYẾT ĐA SỐ (VOTING)]
│
▼
[KẾT QUẢ CUỐI CÙNG: NHÃN A (Thắng áp đảo)]
2.1. Trụ cột 1: Bootstrap Aggregating (Bagging)
- Thay vì cho mọi cây học trên cùng một tập dữ liệu, thuật toán rút thăm ngẫu nhiên có hoàn lại (Sampling with replacement) để tạo ra các tập con khác nhau cho từng cây.
- Có những dòng dữ liệu xuất hiện 2 lần trong 1 cây, và có khoảng 37% số dòng hoàn toàn không được cây đó nhìn thấy (gọi là dữ liệu Out-of-Bag - OOB).
2.2. Trụ cột 2: Feature Randomness (Ngẫu nhiên hóa đặc trưng)
- Nếu trong dữ liệu có một cột quá mạnh (ví dụ:
Thu_nhap), thì 100 cây đều sẽ chọn cột đó làm câu hỏi đầu tiên ở nút gốc Các cây sẽ trở nên giống hệt nhau và cùng mắc chung một sai lầm. - Để các cây thực sự độc lập, tại mỗi lần rẽ nhánh, thuật toán chỉ bốc thăm ngẫu nhiên một nhóm nhỏ các cột (thường là ) để cây lựa chọn. Điều này buộc các cây phải học thêm các đặc trưng phụ khác, giúp khu rừng đa dạng góc nhìn (Decorrelated Trees).
3. Bảng so sánh: Decision Tree vs. Random Forest
| Tiêu chí | Single Decision Tree (Một cây đơn lẻ) | Random Forest (Khu rừng ngẫu nhiên) |
|---|---|---|
| Nguy cơ Overfitting | 🔴 Rất cao, dễ bị nhiễu của tập Train dẫn dắt. | 🟢 Cực thấp, cơ chế biểu quyết trung hòa hoàn toàn các sai số ngẫu nhiên. |
| Độ chính xác (Accuracy) | Trung bình, dao động mạnh khi dữ liệu thay đổi nhỏ. | Vượt trội, luôn là một trong những mô hình mạnh nhất trên dữ liệu dạng bảng. |
| Tốc độ huấn luyện | Rất nhanh (chỉ dựng 1 cây). | Chậm hơn (phải dựng 100–500 cây, nhưng có thể chạy song song đa nhân CPU). |
| Tính khả giải thích | Dễ vẽ thành sơ đồ flowchart để đọc hiểu từng bước. | Hộp đen phức tạp, không thể vẽ 100 cái cây ra giấy (nhưng xem được Feature Importance). |
| Xử lý dữ liệu nhiễu (Noise) | Kém, một vài Outlier có thể bẻ cong toàn bộ cây. | Rất tốt, các Outlier bị số đông phớt lờ. |
4. Thực hành thực chiến: Đo lường sự vượt trội của Random Forest bằng Python
Đoạn mã Python dưới đây sử dụng Scikit-Learn để so sánh trực tiếp một Cây quyết định đơn lẻ với một Khu rừng ngẫu nhiên trên cùng một tập dữ liệu có độ nhiễu cao, đồng thời trích xuất chỉ số Độ quan trọng của đặc trưng (Feature Importance):
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 1. Tạo tập dữ liệu mô phỏng bài toán Rủi ro Tín dụng (Có nhiều yếu tố nhiễu)
np.random.seed(42)
n_samples = 1000
income = np.random.uniform(10, 100, n_samples)
credit_score = np.random.uniform(300, 850, n_samples)
debt_ratio = np.random.uniform(0.1, 0.8, n_samples)
age = np.random.randint(20, 65, n_samples)
# Quy luật: Điểm tín dụng tốt và tỷ lệ nợ thấp -> Khách hàng an toàn (0), ngược lại có rủi ro (1)
# Thêm 15% nhiễu ngẫu nhiên vào nhãn để thử thách độ bền vững của mô hình
noise = np.random.rand(n_samples) < 0.15
default_risk = (((credit_score < 580) | (debt_ratio > 0.5)) ^ noise).astype(int)
df = pd.DataFrame({
"income": income,
"credit_score": credit_score,
"debt_ratio": debt_ratio,
"age": age,
"default_risk": default_risk
})
X = df[["income", "credit_score", "debt_ratio", "age"]]
y = df["default_risk"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
# ==============================================================================
# 2. HUẤN LUYỆN SINGLE DECISION TREE (1 CÂY ĐƠN LẺ)
# ==============================================================================
dt_model = DecisionTreeClassifier(random_state=42)
dt_model.fit(X_train, y_train)
dt_train_acc = accuracy_score(y_train, dt_model.predict(X_train))
dt_test_acc = accuracy_score(y_test, dt_model.predict(X_test))
print("--- 1. HIỆU SUẤT CỦA SINGLE DECISION TREE ---")
print(f"Train Accuracy: {dt_train_acc * 100:.2f}% (Bị Overfitting, học vẹt cả 15% nhiễu)")
print(f"Test Accuracy : {dt_test_acc * 100:.2f}%\n")
# ==============================================================================
# 3. HUẤN LUYỆN RANDOM FOREST (KHU RỪNG 100 CÂY)
# ==============================================================================
# n_estimators=100: Rừng gồm 100 cây
# n_jobs=-1: Tận dụng toàn bộ nhân CPU máy tính để huấn luyện song song các cây
rf_model = RandomForestClassifier(
n_estimators=100,
max_depth=6,
random_state=42,
n_jobs=-1,
oob_score=True # Bật tính năng chấm điểm Out-of-Bag
)
rf_model.fit(X_train, y_train)
rf_train_acc = accuracy_score(y_train, rf_model.predict(X_train))
rf_test_acc = accuracy_score(y_test, rf_model.predict(X_test))
print("--- 2. HIỆU SUẤT CỦA RANDOM FOREST ---")
print(f"Train Accuracy: {rf_train_acc * 100:.2f}%")
print(f"Test Accuracy : {rf_test_acc * 100:.2f}% (Vượt trội hơn hẳn so với 1 cây!)")
print(f"OOB Score : {rf_model.oob_score_ * 100:.2f}% (Độ tin cậy nội bộ không cần tập val)")
# ==============================================================================
# 4. TRÍCH XUẤT ĐỘ QUAN TRỌNG CỦA ĐẶC TRƯNG (FEATURE IMPORTANCE)
# ==============================================================================
print("\n--- 3. ĐỘ QUAN TRỌNG CỦA CÁC ĐẶC TRƯNG (FEATURE IMPORTANCE) ---")
importance_df = pd.DataFrame({
"Feature": X.columns,
"Importance (%)": (rf_model.feature_importances_ * 100).round(2)
}).sort_values("Importance (%)", ascending=False)
print(importance_df.to_string(index=False))
# Kết quả cho thấy rõ: credit_score và debt_ratio chi phối mạnh nhất, đúng với quy luật thực tế!
5. Câu hỏi phỏng vấn thực tế (Interview Q&A)
Câu 1 (Mức độ: Entry / Junior)
Câu hỏi: "Bagging (Bootstrap Aggregating) giúp Random Forest giảm phương sai (Variance) mà không làm tăng độ chệch (Bias) như thế nào?"
Gợi ý trả lời:
"Theo lý thuyết thống kê, mỗi Cây quyết định riêng lẻ phát triển sâu thường có độ chệch thấp (Low Bias - vì nó học rất chi tiết cấu trúc dữ liệu) nhưng lại có phương sai rất cao (High Variance - rất nhạy cảm với dữ liệu nhiễu).
Khi chúng ta lấy trung bình cộng (hoặc biểu quyết đa số) kết quả của cây độc lập được huấn luyện qua phương pháp Bagging, phương sai của mô hình tổng thể sẽ giảm đi xấp xỉ lần, trong khi độ chệch trung bình vẫn được giữ nguyên ở mức thấp.
Nhờ đó, Random Forest giữ được khả năng nắm bắt quy luật phức tạp nhưng lại loại bỏ hoàn toàn căn bệnh học vẹt của từng cây đơn lẻ."
Câu 2 (Mức độ: Junior / Mid-level)
Câu hỏi: "Out-of-Bag (OOB) Score trong Random Forest là gì? Nó giúp ích gì cho quy trình làm việc của Data Scientist?"
Gợi ý trả lời:
"Khi thực hiện lấy mẫu có lặp lại (Bootstrap), về mặt toán học, mỗi cây chỉ được huấn luyện trên khoảng 63.2% lượng dữ liệu gốc; 36.8% lượng dữ liệu còn lại không được cây đó nhìn thấy và được gọi là các mẫu Out-of-Bag (OOB).
Đối với mỗi điểm dữ liệu, chúng ta có thể tập hợp tất cả các cây KHÔNG nhìn thấy điểm đó trong lúc train để dự đoán cho nó. Điểm số đánh giá trên toàn bộ các mẫu này chính là OOB Score.
Lợi ích thực tế: OOB Score đóng vai trò tương đương như một tập kiểm định chéo (Cross-Validation). Nhờ OOB Score, chúng ta có thể đánh giá ngay độ chính xác của mô hình trên dữ liệu chưa từng thấy mà không cần tốn thời gian chia thêm tập Validation riêng biệt, giúp tiết kiệm tối đa dữ liệu huấn luyện khi tập dữ liệu bị khan hiếm."
6. Key Takeaways (Ghi nhớ nhanh)
- Một cây không làm nên non, trăm cây chụm lại thành Random Forest: Vận dụng nguyên lý trí tuệ đám đông để triệt tiêu phương sai và chống Overfitting.
- Hai bí quyết ngẫu nhiên: Rút mẫu ngẫu nhiên có hoàn lại (Bagging) và chọn tập con các đặc trưng ngẫu nhiên (Feature Randomness) để các cây thực sự đa dạng.
- Mô hình nền tảng số 1 cho dữ liệu bảng: Khi tiếp cận một bài toán dữ liệu bảng (Tabular Data) mới, hãy luôn chọn Random Forest làm mô hình Baseline đầu tiên.
- Hiểu được đóng góp của biến: Sử dụng
feature_importances_để biết chính xác cột nào quan trọng nhất, hỗ trợ đắc lực cho việc giải trình với các phòng ban kinh doanh.