一、集成學習概述
集成學習(ensemble learning)通過構建并結合多個個體學習器來完成學習任務,核心思想是 “集眾家之長”—— 就像多個專家共同判斷往往比單個專家更可靠。其關鍵在于如何生成多樣化的個體學習器并設計有效的結合策略。
結合策略
- 簡單平均法:對多個學習器的輸出取平均值(適用于回歸任務)。
- 加權平均法:為不同學習器分配不同權重,權重之和為 1,更信任性能好的學習器。
- 投票法:“少數服從多數”,適用于分類任務,多個學習器投票決定最終類別。
二、集成算法分類
根據個體學習器的生成方式,集成算法可分為三類:
算法類型 | 特點 | 代表算法 |
---|---|---|
Bagging | 個體學習器并行生成,無強依賴關系 | 隨機森林 |
Boosting | 個體學習器串行生成,后一個依賴前一個 | AdaBoost |
Stacking | 分階段集成,第一階段用多種學習器生成結果,第二階段用這些結果訓練新模型 | 多模型堆疊 |
三、典型集成算法詳解
1. Bagging 與隨機森林
Bagging 原理:通過 bootstrap 抽樣(有放回采樣)生成多個不同的訓練集,并行訓練多個分類器,最終用投票法(分類)或平均法(回歸)結合結果。
隨機森林:在 Bagging 基礎上增加 “雙重隨機性”:
- 數據采樣隨機(bootstrap);
- 特征選擇隨機(每個決策樹僅用部分特征訓練)。
隨機森林優勢:
- 處理高維數據無需特征選擇;
- 可評估特征重要性;
- 并行化訓練,速度快;
- 結果易可視化分析。
核心參數(
RandomForestClassifier
):n_estimators
:樹的數量(默認 100);oob_score
:是否用袋外數據評估(默認 False,True 時等效交叉驗證);bootstrap
:是否有放回采樣(默認 True)。
2. Boosting 與 AdaBoost
- Boosting 原理:串行生成學習器,后一個學習器會針對前一個的錯誤進行優化,通過加權調整樣本和學習器的重要性。
- AdaBoost 流程:
- 初始化樣本權重(所有樣本權重相同);
- 訓練弱分類器,分錯的樣本權重提高,分對的降低;
- 重復訓練新分類器,聚焦前一輪的錯誤樣本;
- 最終結合所有弱分類器,性能好的分類器權重更高。
3. Stacking
- 原理:分階段集成多種學習器(如 KNN、SVM、隨機森林等):
- 第一階段:用不同學習器對數據訓練,得到各自的預測結果;
- 第二階段:將第一階段的結果作為新特征,訓練一個元模型(如邏輯回歸),輸出最終結果。
四、代碼實現:隨機森林實現葡萄酒分類
以葡萄酒數據集為例,用隨機森林完成分類任務:
python
運行
# 導入必要的庫
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report# 1. 加載數據集
wine = load_wine()
X = wine.data # 特征數據(13個特征,如酒精含量、蘋果酸等)
y = wine.target # 標簽(3種葡萄酒類別)
print("特征名稱:", wine.feature_names)
print("樣本數量:", X.shape[0], ",類別數量:", len(set(y)))# 2. 劃分訓練集和測試集(7:3)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42 # 固定隨機種子,保證結果可復現
)# 3. 初始化隨機森林模型
rf = RandomForestClassifier(n_estimators=100, # 100棵決策樹oob_score=True, # 用袋外數據評估模型bootstrap=True, # 啟用有放回采樣random_state=42
)# 4. 訓練模型
rf.fit(X_train, y_train)# 5. 模型評估
# 預測測試集
y_pred = rf.predict(X_test)# 計算準確率
accuracy = accuracy_score(y_test, y_pred)
print(f"\n測試集準確率:{accuracy:.4f}")# 詳細分類報告(精確率、召回率、F1值)
print("\n分類報告:")
print(classification_report(y_test, y_pred, target_names=[f"類別{i}" for i in range(3)]))# 查看特征重要性
feature_importance = dict(zip(wine.feature_names, rf.feature_importances_))
print("\n特征重要性:")
for feature, importance in sorted(feature_importance.items(), key=lambda x: x[1], reverse=True):print(f"{feature}: {importance:.4f}")
代碼說明
- 數據集:
load_wine()
包含 178 個樣本,13 個特征(如酒精含量、蘋果酸等),分為 3 類葡萄酒。 - 模型參數:使用 100 棵決策樹,啟用袋外數據評估,確保結果可靠。
- 評估指標:通過準確率和分類報告判斷模型性能,隨機森林在該數據集上通常能達到 95% 以上的準確率。
- 特征重要性:隨機森林可輸出各特征對分類的貢獻度,例如 “proline(脯氨酸)” 通常是區分葡萄酒類別的重要特征。
我還自己嘗試了以下乳腺癌案例
# 導入必要的庫
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
# 加載并查看數據集信息
cancer = load_breast_cancer()
X = cancer.data ?# 特征數據(30個特征,如腫瘤半徑、紋理等)
y = cancer.target ?# 標簽(0=惡性,1=良性)
# 打印數據集基本信息
print("數據集信息:")
print(f"特征數量:{X.shape[1]}(特征名稱:{', '.join(cancer.feature_names[:5])}...)")
print(f"樣本數量:{X.shape[0]}(其中良性樣本:{sum(y)},惡性樣本:{len(y)-sum(y)})")
# 劃分訓練集和測試集(7:3)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42 ?# 固定隨機種子,保證結果可復現
)
# 初始化隨機森林模型并設置參數
rf_cancer = RandomForestClassifier(
n_estimators=150, ?# 決策樹數量(增加樹數量可提升穩定性)
max_depth=8, ? ? ? # 限制樹深度,防止過擬合
oob_score=True, ? ?# 使用袋外數據評估模型性能
bootstrap=True, ? ?# 啟用有放回抽樣(Bagging核心機制)
random_state=42 ? ?# 固定隨機種子,確保結果一致
)
# 訓練模型
rf_cancer.fit(X_train, y_train)
print(f"\n袋外數據評估準確率:{rf_cancer.oob_score_:.4f}") ?# 輸出袋外得分
# 模型評估
# 預測測試集結果
y_pred = rf_cancer.predict(X_test)
# 計算準確率
accuracy = accuracy_score(y_test, y_pred)
print(f"\n測試集準確率:{accuracy:.4f}")
# 打印混淆矩陣(直觀展示分類錯誤情況)
print("\n混淆矩陣(行=真實標簽,列=預測標簽):")
print("(0=惡性,1=良性)")
print(confusion_matrix(y_test, y_pred))
# 詳細分類報告(包含精確率、召回率、F1值)
print("\n分類報告:")
print(classification_report(
y_test, y_pred,
target_names=["惡性腫瘤", "良性腫瘤"] ?# 為標簽添加中文說明
))
# 特征重要性分析(前10名)
print("\nTop 10 重要特征(對腫瘤分類的貢獻度):")
# 按重要性排序并取前10
top_features = sorted(
zip(cancer.feature_names, rf_cancer.feature_importances_),
key=lambda x: x[1], reverse=True
)[:10]
# 格式化輸出
for i, (name, imp) in enumerate(top_features, 1):
print(f"{i}. {name}: {imp:.4f}({imp*100:.2f}%)")
五、學習總結
集成學習通過組合多個學習器有效提升了模型性能,其中:
- 隨機森林適合處理高維數據,訓練高效且結果穩定,是工業界常用的 “萬能模型”;
- AdaBoost 專注于修正錯誤樣本,適合處理非線性問題,但對噪聲較敏感;
- Stacking 靈活性高,可融合多種模型的優勢,但實現較復雜。
在實際應用中,需根據數據特點選擇合適的集成策略,并通過調參(如隨機森林的樹數量、AdaBoost 的迭代次數)進一步優化性能。