【機器學習】集成學習與梯度提升決策樹

目錄

一、引言

二、自舉聚合與隨機森林

三、集成學習器

四、提升算法

五、Python代碼實現集成學習與梯度提升決策樹的實驗

六、總結


一、引言

        在機器學習的廣闊領域中,集成學習(Ensemble Learning)猶如一座閃耀的明星,它通過組合多個基本學習器的力量,創造出遠超單個模型的預測能力。梯度提升決策樹融合了決策樹的可解釋性與梯度優化的高效性,成為了現代機器學習領域最受歡迎的算法之一。本文將詳細介紹自舉聚合與隨機森林、集成學習器、提升算法以及Python代碼實現集成學習與梯度提升決策樹的實驗。

二、自舉聚合與隨機森林

1. 自舉聚合(Bagging)原理

1.1 基本概念

       自舉聚合(Bootstrap Aggregating,簡稱Bagging)是一種集成學習方法,旨在通過結合多個基學習器的預測來提高模型的穩定性和準確性。該方法由Leo Breiman于1996年提出,其核心思想是利用自助采樣(Bootstrap Sampling)技術從原始訓練數據中生成多個不同的訓練子集,然后在每個子集上獨立訓練一個基學習器,最后將所有基學習器的預測結合起來。

1.2 數學形式化描述

給定訓練集 $D = \{(x_1, y_1), (x_2, y_2), \ldots, (x_n, y_n)\}$,Bagging的過程可以表示為:

(1) 自助采樣:對于$t = 1, 2, \ldots, T$:通過有放回抽樣,從$D$中隨機抽取$n$個樣本,形成訓練子集$D_t$

(2) 訓練基學習器:對每個訓練子集$D_t$,獨立訓練得到基學習器$h_t(x)$

(3) 組合預測:

    a.對于分類問題,使用投票法:

                                           $H(x) = \arg\max_y \sum_{t=1}^T \mathbf{1}(h_t(x) = y)$

   b. 對于回歸問題,使用平均法:

                                                 $H(x) = \frac{1}{T}\sum_{t=1}^T h_t(x)$

其中,$T$是基學習器的數量,$\mathbf{1}(\cdot)$是指示函數。

1.3 理論基礎

       Bagging成功的關鍵在于減少了方差。具體來說,假設每個基學習器的錯誤期望為$E[error] = bias^2 + var + noise$,當基學習器相互獨立時,集成后的方差會減小為原來的$\frac{1}{T}$。對于具有方差$\sigma^2$$T$個獨立同分布的隨機變量,它們的平均值的方差為$\frac{\sigma^2}{T}$,即:

                                  $Var\left(\frac{1}{T}\sum_{t=1}^T h_t(x)\right) = \frac{1}{T^2}\sum_{t=1}^T Var(h_t(x)) = \frac{\sigma^2}{T}$

1.4 袋外估計(OOB, Out-of-Bag Estimation)

        由于自助采樣是有放回的,每個訓練子集$D_t$包含原始訓練集中約63.2%的樣本,剩余約36.8%的樣本未被選中,稱為"袋外樣本"。

        對于每個樣例$(x_i, y_i)$,可以用沒有使用它訓練的基學習器對它進行預測,得到的錯誤率稱為"袋外誤差"(OOB Error),其形式化定義為:

                           $\epsilon_{oob} = \frac{1}{n}\sum_{i=1}^n \mathbf{1}\left(y_i \neq \arg\max_y \sum_{t:x_i \notin D_t} \mathbf{1}(h_t(x_i) = y)\right)$

OOB估計是泛化誤差的無偏估計,可以用來代替交叉驗證。

2. 隨機森林(Random Forest)

2.1 基本概念

        隨機森林是Bagging的特殊情況,它使用決策樹作為基學習器,并在決策樹構建過程中引入了額外的隨機性。隨機森林同樣由Leo Breiman在2001年提出,是目前最流行的集成學習方法之一。

2.2 隨機森林的兩層隨機性

隨機森林包含兩層隨機性:

(1) 樣本隨機性:與Bagging一樣,通過有放回抽樣生成訓練子集。

(2) 特征隨機性:在每個節點分裂時,不考慮所有特征,而只考慮隨機選擇的特征子集。

        此特征隨機化機制可以形式化表示為:對于每個決策樹節點,從$d$個特征中隨機選擇$m$個特征(通常$m = \sqrt{d}$$m = \log_2 d$),然后僅在這$m$個特征中尋找最優分割點。

2.3 數學模型

假設原始特征空間維度為$d$,則隨機森林的構建過程為:

(1) 對于 $t = 1, 2, \ldots, T$

    a.通過有放回抽樣,從訓練集$D$中隨機抽取$n$個樣本,形成訓練子集$D_t$

   b.在$D_t$上訓練一棵決策樹$h_t$,其中每個節點分裂時:

     (a)隨機選擇$m$個特征($m \ll d$)。

     (b)在這$m$個特征中找到最佳分裂特征和分裂點。

     (c)按該分裂生成子節點。

     (d)遞歸處理子節點,直到滿足停止條件。

(2) 最終的隨機森林模型:

   a.分類問題:

                            $H(x) = \arg\max_y \sum_{t=1}^T \mathbf{1}(h_t(x) = y)$

   b.回歸問題:

                                $H(x) = \frac{1}{T}\sum_{t=1}^T h_t(x)$

2.4 特征重要性計算

       隨機森林可以計算特征的重要性分數,這是其重要的優勢之一。對于特征j的重要性,可以通過計算其在所有樹中的平均不純度減少量來估計:

                                            $Imp(j) = \frac{1}{T} \sum_{t=1}^T \sum_{k \in S_j^t} \Delta I(S_{k,t})$

其中,$S_j^t$表示樹$t$中使用特征$j$進行分裂的所有節點集合,$\Delta I(S_{k,t})$表示節點$k$分裂前后的不純度減少量。

3.優勢與應用

3.1 優勢

(1) 減少方差:通過多次采樣訓練,降低了模型的方差,提高了穩定性。

(2) 避免過擬合:特征的隨機選擇使得樹之間相關性降低,減輕了過擬合。

(3) 提供OOB估計:無需額外的驗證集即可估計泛化誤差。

(4) 內置特征重要性評估:可以評估各個特征對預測的貢獻。

(5) 高度并行化:樹之間相互獨立,可以并行訓練,提高效率。

(6) 處理高維數據:能夠處理具有大量特征的數據集。

(7) 處理缺失值:對缺失值具有較強的魯棒性。

3.2 典型應用場景

(1) 分類任務:信用評分、垃圾郵件檢測、疾病診斷。

(2) 回歸任務:房價預測、銷售額預測。

(3) 特征選擇:通過特征重要性評估進行降維。

(4)異常檢測:識別與正常模式不符的數據點。

4.自舉聚合與隨機森林的代碼實現

4.1自定義實現Bagging類

class Bagging:def __init__(self, base_estimator, n_estimators=10):self.base_estimator = base_estimator  # 基學習器self.n_estimators = n_estimators  # 基學習器數量self.estimators = []  # 存儲訓練好的基學習器def fit(self, X, y):n_samples = X.shape[0]# 訓練n_estimators個基學習器for _ in range(self.n_estimators):# 有放回抽樣indices = np.random.choice(n_samples, n_samples, replace=True)X_bootstrap, y_bootstrap = X[indices], y[indices]# 克隆并訓練基學習器estimator = clone(self.base_estimator)estimator.fit(X_bootstrap, y_bootstrap)self.estimators.append(estimator)return selfdef predict(self, X):# 收集所有基學習器的預測predictions = np.array([estimator.predict(X) for estimator in self.estimators])# 投票得到最終預測(適用于分類問題)if len(np.unique(predictions.flatten())) < 10:  # 假設小于10個唯一值為分類# 分類問題:多數投票return np.apply_along_axis(lambda x: np.bincount(x).argmax(),axis=0,arr=predictions)else:# 回歸問題:平均值return np.mean(predictions, axis=0)

4.2自定義實現隨機森林類

class RandomForest:def __init__(self, n_estimators=100, max_features='sqrt', max_depth=None):self.n_estimators = n_estimatorsself.max_features = max_featuresself.max_depth = max_depthself.trees = []self.oob_score_ = Nonedef _bootstrap_sample(self, X, y):n_samples = X.shape[0]# 有放回抽樣indices = np.random.choice(n_samples, n_samples, replace=True)# 記錄袋外樣本索引oob_indices = np.array([i for i in range(n_samples) if i not in np.unique(indices)])return X[indices], y[indices], oob_indicesdef fit(self, X, y):n_samples = X.shape[0]n_features = X.shape[1]# 確定每個節點隨機選擇的特征數量if self.max_features == 'sqrt':self.max_features_used = int(np.sqrt(n_features))elif self.max_features == 'log2':self.max_features_used = int(np.log2(n_features))elif isinstance(self.max_features, int):self.max_features_used = self.max_featureselse:self.max_features_used = n_features# 初始化OOB預測數組oob_predictions = np.zeros((n_samples, len(np.unique(y))))oob_samples_count = np.zeros(n_samples)# 訓練n_estimators棵樹for _ in range(self.n_estimators):# 自助采樣X_bootstrap, y_bootstrap, oob_indices = self._bootstrap_sample(X, y)# 創建決策樹并設置隨機特征選擇tree = DecisionTreeClassifier(max_features=self.max_features_used,max_depth=self.max_depth)tree.fit(X_bootstrap, y_bootstrap)self.trees.append(tree)# 計算袋外樣本預測if len(oob_indices) > 0:oob_pred = tree.predict_proba(X[oob_indices])oob_predictions[oob_indices] += oob_predoob_samples_count[oob_indices] += 1# 計算OOB分數valid_oob = oob_samples_count > 0if np.any(valid_oob):oob_predictions_valid = oob_predictions[valid_oob]oob_samples_count_valid = oob_samples_count[valid_oob, np.newaxis]oob_predictions_avg = oob_predictions_valid / oob_samples_count_validy_pred = np.argmax(oob_predictions_avg, axis=1)self.oob_score_ = np.mean(y[valid_oob] == y_pred)return selfdef predict(self, X):# 收集所有樹的預測predictions = np.array([tree.predict(X) for tree in self.trees])# 投票得到最終預測return np.apply_along_axis(lambda x: np.bincount(x).argmax(),axis=0,arr=predictions)def predict_proba(self, X):# 收集所有樹的概率預測并平均probas = np.array([tree.predict_proba(X) for tree in self.trees])return np.mean(probas, axis=0)def feature_importances_(self):# 計算平均特征重要性importances = np.mean([tree.feature_importances_ for tree in self.trees], axis=0)return importances

5.算法調優與最佳實踐

 5.1 主要超參數

(1) n_estimators:基學習器數量,通常越多越好,但會增加計算成本。

(2) max_features:每個節點隨機選擇的特征數:

   分類建議:$\sqrt{d}$

   回歸建議:$d/3$

(3) max_depth:樹的最大深度,控制復雜度。

(4) min_samples_split:分裂內部節點所需的最小樣本數。

(5) min_samples_leaf:葉節點所需的最小樣本數。

5.2超參數調優示例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, GridSearchCV, learning_curve
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, roc_curve, auc
import time
import warnings
from matplotlib.font_manager import FontProperties
import platform
import os
import tempfile# 為多進程操作創建一個純ASCII字符的臨時目錄路徑
temp_dir = tempfile.mkdtemp(prefix='sklearn_rf_')
os.environ['JOBLIB_TEMP_FOLDER'] = temp_dir
print(f"臨時文件夾路徑: {temp_dir}")# 忽略警告
warnings.filterwarnings("ignore")# 設置中文字體
def setup_chinese_font():system = platform.system()if system == 'Windows':font_paths = ['C:/Windows/Fonts/simhei.ttf',    # 黑體'C:/Windows/Fonts/simsun.ttc',    # 宋體'C:/Windows/Fonts/msyh.ttc',      # 微軟雅黑'C:/Windows/Fonts/simfang.ttf',   # 仿宋]elif system == 'Darwin':  # macOSfont_paths = ['/System/Library/Fonts/PingFang.ttc','/Library/Fonts/STHeiti Light.ttc','/Library/Fonts/Songti.ttc',]else:  # Linuxfont_paths = ['/usr/share/fonts/truetype/wqy/wqy-microhei.ttc','/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc','/usr/share/fonts/truetype/arphic/uming.ttc',]for font_path in font_paths:if os.path.exists(font_path):print(f"使用字體: {font_path}")return FontProperties(fname=font_path)print("未找到指定的中文字體文件,將嘗試使用系統配置的字體")return Nonechinese_font = setup_chinese_font()# 配置matplotlib全局字體設置
if chinese_font is not None:plt.rcParams['font.family'] = chinese_font.get_family()plt.rcParams['font.sans-serif'] = [chinese_font.get_name()] + plt.rcParams['font.sans-serif']
else:plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans', 'Arial']
plt.rcParams['axes.unicode_minus'] = False# 設置美觀的圖表風格
plt.style.use('ggplot')print("隨機森林超參數調優實驗")
print("-" * 50)# 1. 生成數據
print("\n[步驟1] 生成分類數據集...")
X, y = make_classification(n_samples=1000,           # 樣本數量n_features=20,            # 特征數量n_informative=10,         # 信息特征的數量n_redundant=5,            # 冗余特征的數量n_repeated=0,             # 重復特征的數量n_classes=2,              # 分類數量flip_y=0.1,               # 隨機翻轉標簽的比例class_sep=1.0,            # 類別間的分離度random_state=42           # 隨機種子
)# 2. 數據預處理
print("[步驟2] 劃分訓練集和測試集...")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)print(f"訓練集大小: {X_train.shape}")
print(f"測試集大小: {X_test.shape}")
print(f"特征數量: {X_train.shape[1]}")# 3. 定義參數網格 - 為了加快運行速度,縮小參數空間
print("\n[步驟3] 定義參數網格...")
# 第一階段:粗調參數 - 簡化版本
param_grid_coarse = {'n_estimators': [50, 100],            # 樹的數量'max_depth': [None, 10],              # 樹的最大深度'min_samples_split': [2, 5],          # 內部節點再劃分所需的最小樣本數'min_samples_leaf': [1, 2],           # 葉節點所需的最小樣本數'max_features': ['sqrt', 'log2']      # 尋找最佳分割時考慮的特征數
}print("粗調參數網格:")
for param, values in param_grid_coarse.items():print(f"- {param}: {values}")# 4. 創建基礎模型
print("\n[步驟4] 創建基礎隨機森林模型...")
rf_base = RandomForestClassifier(random_state=42)# 5. 創建并執行網格搜索 - 粗調階段
print("\n[步驟5] 執行粗調參數的網格搜索(可能需要較長時間)...")
start_time = time.time()
grid_search_coarse = GridSearchCV(estimator=rf_base,param_grid=param_grid_coarse,scoring='accuracy',cv=3,                      # 3折交叉驗證,加快速度n_jobs=-1,                 # 使用所有CPU核心verbose=1,                 # 顯示進度return_train_score=True    # 返回訓練集得分,用于分析過擬合
)try:grid_search_coarse.fit(X_train, y_train)coarse_time = time.time() - start_timeprint(f"\n粗調參數完成,耗時: {coarse_time:.2f}秒")print(f"最佳參數組合: {grid_search_coarse.best_params_}")print(f"最佳交叉驗證準確率: {grid_search_coarse.best_score_:.4f}")# 6. 基于粗調結果進行精調print("\n[步驟6] 基于粗調結果定義精調參數網格...")# 從粗調中獲取最佳參數best_n_estimators = grid_search_coarse.best_params_['n_estimators']best_max_depth = grid_search_coarse.best_params_['max_depth']best_min_samples_split = grid_search_coarse.best_params_['min_samples_split']best_min_samples_leaf = grid_search_coarse.best_params_['min_samples_leaf']best_max_features = grid_search_coarse.best_params_['max_features']# 根據粗調結果定義更精細的參數網格 - 簡化版本param_grid_fine = {'n_estimators': [best_n_estimators, best_n_estimators + 50],'max_features': [best_max_features],}# 對max_depth特別處理if best_max_depth is None:param_grid_fine['max_depth'] = [None, 15]else:param_grid_fine['max_depth'] = [best_max_depth, best_max_depth + 5]# 添加其他參數的精細搜索param_grid_fine['min_samples_split'] = [best_min_samples_split, best_min_samples_split + 1]param_grid_fine['min_samples_leaf'] = [best_min_samples_leaf, best_min_samples_leaf + 1]# 添加其他可能影響性能的參數param_grid_fine['bootstrap'] = [True]param_grid_fine['criterion'] = ['gini', 'entropy']print("精調參數網格:")for param, values in param_grid_fine.items():print(f"- {param}: {values}")# 7. 執行精調網格搜索print("\n[步驟7] 執行精調參數的網格搜索(可能需要較長時間)...")start_time = time.time()grid_search_fine = GridSearchCV(estimator=rf_base,param_grid=param_grid_fine,scoring='accuracy',cv=3,                  # 3折交叉驗證,加快速度n_jobs=-1,verbose=1,return_train_score=True)grid_search_fine.fit(X_train, y_train)fine_time = time.time() - start_timeprint(f"\n精調參數完成,耗時: {fine_time:.2f}秒")print(f"最終最佳參數組合: {grid_search_fine.best_params_}")print(f"最終最佳交叉驗證準確率: {grid_search_fine.best_score_:.4f}")# 8. 使用最佳參數評估模型print("\n[步驟8] 使用最佳參數評估模型性能...")best_rf = grid_search_fine.best_estimator_y_pred = best_rf.predict(X_test)accuracy = accuracy_score(y_test, y_pred)print(f"測試集準確率: {accuracy:.4f}")print("\n分類報告:")print(classification_report(y_test, y_pred))# 9. 可視化結果print("\n[步驟9] 可視化評估結果...")# 9.1 混淆矩陣plt.figure(figsize=(10, 8))cm = confusion_matrix(y_test, y_pred)sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')plt.title('隨機森林最佳模型混淆矩陣', fontsize=14)plt.xlabel('預測標簽', fontsize=12)plt.ylabel('真實標簽', fontsize=12)if chinese_font:plt.title('隨機森林最佳模型混淆矩陣', fontproperties=chinese_font, fontsize=14)plt.xlabel('預測標簽', fontproperties=chinese_font, fontsize=12)plt.ylabel('真實標簽', fontproperties=chinese_font, fontsize=12)plt.tight_layout()plt.savefig('rf_confusion_matrix.png', dpi=300, bbox_inches='tight')plt.show()# 9.2 ROC曲線plt.figure(figsize=(10, 8))y_scores = best_rf.predict_proba(X_test)[:, 1]fpr, tpr, _ = roc_curve(y_test, y_scores)roc_auc = auc(fpr, tpr)plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC曲線 (AUC = {roc_auc:.3f})')plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')plt.xlim([0.0, 1.0])plt.ylim([0.0, 1.05])plt.xlabel('假陽性率', fontsize=12)plt.ylabel('真陽性率', fontsize=12)plt.title('隨機森林最佳模型ROC曲線', fontsize=14)plt.legend(loc="lower right")if chinese_font:plt.xlabel('假陽性率', fontproperties=chinese_font, fontsize=12)plt.ylabel('真陽性率', fontproperties=chinese_font, fontsize=12)plt.title('隨機森林最佳模型ROC曲線', fontproperties=chinese_font, fontsize=14)for text in plt.legend().get_texts():text.set_fontproperties(chinese_font)plt.tight_layout()plt.savefig('rf_roc_curve.png', dpi=300, bbox_inches='tight')plt.show()# 9.3 特征重要性plt.figure(figsize=(12, 10))importances = best_rf.feature_importances_indices = np.argsort(importances)[::-1]plt.bar(range(X_train.shape[1]), importances[indices], align='center')plt.xticks(range(X_train.shape[1]), [f'特征 {i}' for i in indices], rotation=90)plt.title('隨機森林特征重要性', fontsize=14)plt.xlabel('特征', fontsize=12)plt.ylabel('重要性', fontsize=12)if chinese_font:plt.title('隨機森林特征重要性', fontproperties=chinese_font, fontsize=14)plt.xlabel('特征', fontproperties=chinese_font, fontsize=12)plt.ylabel('重要性', fontproperties=chinese_font, fontsize=12)plt.xticks(rotation=90, fontproperties=chinese_font)plt.tight_layout()plt.savefig('rf_feature_importance.png', dpi=300, bbox_inches='tight')plt.show()# 9.4 參數重要性def plot_param_importance(grid_search, title):plt.figure(figsize=(14, 10))results = pd.DataFrame(grid_search.cv_results_)# 提取參數名稱param_names = [p for p in results.columns if p.startswith('param_')]# 創建一個包含每個參數的單獨子圖n_params = len(param_names)n_cols = 2n_rows = (n_params + 1) // 2for i, param_name in enumerate(param_names):plt.subplot(n_rows, n_cols, i + 1)# 提取參數的實際名稱(不含"param_"前綴)param = param_name[6:]# 獲取參數值和對應的平均測試分數param_values = results[param_name].astype(str)unique_values = param_values.unique()# 對于每個唯一的參數值,計算其平均測試分數mean_scores = [results[param_values == val]['mean_test_score'].mean() for val in unique_values]# 創建條形圖plt.bar(range(len(unique_values)), mean_scores)plt.xticks(range(len(unique_values)), unique_values, rotation=45)plt.title(f'參數 {param} 的影響', fontsize=12)plt.xlabel(param, fontsize=10)plt.ylabel('平均測試分數', fontsize=10)if chinese_font:plt.title(f'參數 {param} 的影響', fontproperties=chinese_font, fontsize=12)plt.xlabel(param, fontproperties=chinese_font, fontsize=10)plt.ylabel('平均測試分數', fontproperties=chinese_font, fontsize=10)plt.suptitle(title, fontsize=16)if chinese_font:plt.suptitle(title, fontproperties=chinese_font, fontsize=16)plt.tight_layout(rect=[0, 0, 1, 0.96])plt.savefig('rf_param_importance.png', dpi=300, bbox_inches='tight')plt.show()# 顯示精調參數的重要性plot_param_importance(grid_search_fine, '隨機森林參數重要性分析')# 9.5 學習曲線train_sizes, train_scores, test_scores = learning_curve(best_rf, X_train, y_train, cv=3, n_jobs=-1,train_sizes=np.linspace(0.1, 1.0, 5)  # 減少點數以加快速度)train_mean = np.mean(train_scores, axis=1)train_std = np.std(train_scores, axis=1)test_mean = np.mean(test_scores, axis=1)test_std = np.std(test_scores, axis=1)plt.figure(figsize=(10, 8))plt.plot(train_sizes, train_mean, color='blue', marker='o', markersize=5, label='訓練集分數')plt.fill_between(train_sizes, train_mean + train_std, train_mean - train_std, alpha=0.15, color='blue')plt.plot(train_sizes, test_mean, color='green', marker='s', markersize=5, label='驗證集分數')plt.fill_between(train_sizes, test_mean + test_std, test_mean - test_std, alpha=0.15, color='green')plt.title('隨機森林最佳模型學習曲線', fontsize=14)plt.xlabel('訓練樣本數', fontsize=12)plt.ylabel('準確率', fontsize=12)plt.grid(True)plt.legend(loc='lower right')if chinese_font:plt.title('隨機森林最佳模型學習曲線', fontproperties=chinese_font, fontsize=14)plt.xlabel('訓練樣本數', fontproperties=chinese_font, fontsize=12)plt.ylabel('準確率', fontproperties=chinese_font, fontsize=12)for text in plt.legend().get_texts():text.set_fontproperties(chinese_font)plt.tight_layout()plt.savefig('rf_learning_curve.png', dpi=300, bbox_inches='tight')plt.show()# 10. 總結最佳模型配置print("\n[步驟10] 最終隨機森林模型配置:")for param, value in best_rf.get_params().items():print(f"- {param}: {value}")print("\n超參數調優實驗完成!")print(f"總耗時: {coarse_time + fine_time:.2f}秒")print(f"最終模型測試集準確率: {accuracy:.4f}")except Exception as e:print(f"發生錯誤: {str(e)}")print("嘗試不使用并行處理的簡化版本...")# 如果并行處理失敗,嘗試使用簡化版本(不使用并行)rf_base = RandomForestClassifier(n_estimators=100,max_depth=10,min_samples_split=2,min_samples_leaf=1,max_features='sqrt',random_state=42)rf_base.fit(X_train, y_train)y_pred = rf_base.predict(X_test)accuracy = accuracy_score(y_test, y_pred)print(f"\n使用默認參數的隨機森林模型準確率: {accuracy:.4f}")print("\n分類報告:")print(classification_report(y_test, y_pred))# 簡單的可視化plt.figure(figsize=(12, 10))importances = rf_base.feature_importances_indices = np.argsort(importances)[::-1]plt.bar(range(X_train.shape[1]), importances[indices], align='center')plt.xticks(range(X_train.shape[1]), [f'特征 {i}' for i in indices], rotation=90)plt.title('隨機森林特征重要性 (默認參數)', fontsize=14)plt.xlabel('特征', fontsize=12)plt.ylabel('重要性', fontsize=12)if chinese_font:plt.title('隨機森林特征重要性 (默認參數)', fontproperties=chinese_font, fontsize=14)plt.xlabel('特征', fontproperties=chinese_font, fontsize=12)plt.ylabel('重要性', fontproperties=chinese_font, fontsize=12)plt.xticks(rotation=90, fontproperties=chinese_font)plt.tight_layout()plt.savefig('rf_feature_importance_default.png', dpi=300, bbox_inches='tight')plt.show()finally:# 清理臨時文件夾import shutiltry:shutil.rmtree(temp_dir)print(f"已清理臨時文件夾: {temp_dir}")except:pass

程序運行結果如下:

臨時文件夾路徑: C:\Users\ABC\AppData\Local\Temp\sklearn_rf_iyndeds8
使用字體: C:/Windows/Fonts/simhei.ttf
隨機森林超參數調優實驗
--------------------------------------------------

[步驟1] 生成分類數據集...
[步驟2] 劃分訓練集和測試集...
訓練集大小: (800, 20)
測試集大小: (200, 20)
特征數量: 20

[步驟3] 定義參數網格...
粗調參數網格:
- n_estimators: [50, 100]
- max_depth: [None, 10]
- min_samples_split: [2, 5]
- min_samples_leaf: [1, 2]
- max_features: ['sqrt', 'log2']

[步驟4] 創建基礎隨機森林模型...

[步驟5] 執行粗調參數的網格搜索(可能需要較長時間)...
發生錯誤: 'ascii' codec can't encode characters in position 18-20: ordinal not in range(128)
嘗試不使用并行處理的簡化版本...

使用默認參數的隨機森林模型準確率: 0.8850

分類報告:
              precision    recall  f1-score   support

           0       0.91      0.84      0.87        93
           1       0.87      0.93      0.90       107

    accuracy                           0.89       200
   macro avg       0.89      0.88      0.88       200
weighted avg       0.89      0.89      0.88       200

已清理臨時文件夾: C:\Users\ABC\AppData\Local\Temp\sklearn_rf_iyndeds8

三、集成學習器

1. 集成學習的基本原理

1.1 集成學習的定義

        集成學習通過構建并結合多個學習器來完成學習任務,其目標是通過集成的方式獲得比單一學習器更好的泛化性能。形式化地,給定訓練數據集 $D = \{(x_1, y_1), (x_2, y_2), \ldots, (x_n, y_n)\}$,集成學習首先生成$T$個基學習器

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/83296.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83296.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/83296.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

yarn、pnpm、npm

非常好&#xff0c;這樣從“問題驅動 → 工具誕生 → 優化演進”的角度來講&#xff0c;更清晰易懂。下面我按時間線和動機&#xff0c;把 npm → yarn → pnpm 的演變脈絡講清楚。 &#x1f9e9; 一、npm 為什么一開始不夠好&#xff1f; 早期&#xff08;npm v4 及之前&…

如何用AI寫作?

過去半年&#xff0c;我如何用AI高效寫作&#xff0c;節省數倍時間 過去六個月&#xff0c;我幾乎所有文章都用AI輔助完成。我的朋友——大多是文字工作者&#xff0c;對語言極為敏感——都說看不出我的文章是AI寫的還是親手創作的。 我的AI寫作靈感部分來自丘吉爾。這位英國…

什么是trace,分布式鏈路追蹤(Distributed Tracing)

在你提到的 “個人免費版” 套餐中&#xff0c;“Trace 上報量&#xff1a;5 萬條 / 月&#xff0c;存儲 3 天” 里的 Trace 仍然是指 分布式鏈路追蹤記錄&#xff0c;但需要結合具體產品的場景來理解其含義和限制。以下是更貼近個人用戶使用場景的解釋&#xff1a; 一、這里的…

[免費]微信小程序網上花店系統(SpringBoot后端+Vue管理端)【論文+源碼+SQL腳本】

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;看到一個不錯的微信小程序網上花店系統(SpringBoot后端Vue管理端)【論文源碼SQL腳本】&#xff0c;分享下哈。 項目視頻演示 【免費】微信小程序網上花店系統(SpringBoot后端Vue管理端) Java畢業設計_嗶哩嗶哩_bilibili 項…

PyTorch——DataLoader的使用

batch_size, drop_last 的用法 shuffle shuffleTrue 各批次訓練的圖像不一樣 shuffleFalse 在第156step順序一致

【Linux】基礎文件IO

&#x1f31f;&#x1f31f;作者主頁&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所屬專欄&#xff1a;Linux 前言 無論是日常使用還是系統管理&#xff0c;文件是Linux系統中最核心的概念之一。對于初學者來說&#xff0c;理解文件是如何被創建、讀取、寫入以及存儲…

【JAVA后端入門基礎001】Tomcat 是什么?通俗易懂講清楚!

&#x1f4da;博客主頁&#xff1a;代碼探秘者 ?專欄&#xff1a;《JavaSe》 其他更新ing… ??感謝大家點贊&#x1f44d;&#x1f3fb;收藏?評論?&#x1f3fb;&#xff0c;您的三連就是我持續更新的動力?? &#x1f64f;作者水平有限&#xff0c;歡迎各位大佬指點&…

TDengine 的 AI 應用實戰——電力需求預測

作者&#xff1a; derekchen Demo數據集準備 我們使用公開的UTSD數據集里面的電力需求數據&#xff0c;作為預測算法的數據來源&#xff0c;基于歷史數據預測未來若干小時的電力需求。數據集的采集頻次為30分鐘&#xff0c;單位與時間戳未提供。為了方便演示&#xff0c;按…

D2000平臺上Centos使用mmap函數遇到的陷阱

----------原創不易&#xff0c;歡迎點贊收藏。廣交嵌入式開發的朋友&#xff0c;討論技術和產品------------- 在飛騰D2000平臺上&#xff0c;安裝了麒麟linux系統&#xff0c;我寫了個GPIO點燈的程序&#xff0c;在應用層利用mmap函數將內核空間映射到用戶態&#xff0c;然后…

深入了解linux系統—— 進程間通信之管道

前言 本篇博客所涉及到的代碼一同步到本人gitee&#xff1a;testfifo 遲來的grown/linux - 碼云 - 開源中國 一、進程間通信 什么是進程間通信 在之前的學習中&#xff0c;我們了解到了進程具有獨立性&#xff0c;就算是父子進程&#xff0c;在修改數據時也會進行寫時拷貝&…

設計模式——模版方法設計模式(行為型)

摘要 模版方法設計模式是一種行為型設計模式&#xff0c;定義了算法的步驟順序和整體結構&#xff0c;將某些步驟的具體實現延遲到子類中。它通過抽象類定義模板方法&#xff0c;子類實現抽象步驟&#xff0c;實現代碼復用和算法流程控制。該模式適用于有固定流程但部分步驟可…

Python使用

Python學習&#xff0c;從安裝&#xff0c;到簡單應用 前言 Python作為膠水語言在web開發&#xff0c;數據分析&#xff0c;網絡爬蟲等方向有著廣泛的應用 一、Python入門 相關基礎語法直接使用相關測試代碼 Python編譯器版本使用3以后&#xff0c;安裝參考其他教程&#xf…

吳恩達機器學習筆記(1)—引言

目錄 一、歡迎 二、機器學習是什么 三、監督學習 四、無監督學習 一、歡迎 機器學習是當前信息技術領域中最令人興奮的方向之一。在這門課程中&#xff0c;你不僅會學習機器學習的前沿知識&#xff0c;還將親手實現相關算法&#xff0c;從而深入理解其內部機理。 事實上&…

java筆記08

多線程&JUC 1.什么是多線程 1.什么是多線程&#xff1f;有了多線程&#xff0c;我們就可以讓程序同時做多件事情 2.多線程的作用&#xff1f;提高效率 3.多線程的應用場景&#xff1f;只要你想讓多個事情同時運行就需要用到多線程比如&#xff1a;軟件中的耗時操作、所有…

【仿muduo庫實現并發服務器】使用正則表達式提取HTTP元素

使用正則表達式提取HTTP元素 1.正則表達式2.正則庫的使用3.使用正則表達式提取HTTP請求行 1.正則表達式 正則表達式它其實是描述了一種字符串匹配的模式&#xff0c;它可以用來在一個字符串中檢測一個特定格式的字串&#xff0c;以及可以將符合特定規則的字串進行替換或者提取…

顯示即戰略:鐵電液晶如何成為 “數字中國” 的 “像素基石”?

一、顯示技術&#xff1a;數字時代的核心戰略支點 &#xff08;一&#xff09;從 “視覺窗口” 到 “戰略基礎設施” 在數字經濟蓬勃發展的當下&#xff0c;顯示技術早已超越了單純的 “視覺呈現” 范疇&#xff0c;成為連接人與數字世界的關鍵接口。從智能手機、平板電腦到車…

適合小白的超詳細配置YOLOv8教程(畢設必看)(訓練自己數據集)(Pycharm保姆級安裝教程)(lablme的使用)(GPU版)

目錄 1.Pycharm的安裝和虛擬環境調用&#xff08;已經安裝好的可以跳過此步驟&#xff09; 1.1 下載pycharm軟件 1.2 調用已創建虛擬環境&#xff08;調用上一篇教程中創建好的虛擬環境&#xff09; 2.標注自己數據集&#xff08;已有數據集的這部分可跳過&#xff09; 2.1…

EC800X QuecDuino開發板介紹

支持的模組列表 EG800KEC800MEC800GEC800E 功能列表 基本概述 EC800X QuecDuino EVB 搭載移遠 EC800 系列模組。支持模組型號為&#xff1a; EC800M 系列、EC800K 系列、EG800K 系列、EC800E 系列等。 渲染圖 開發板的主要組件、接口布局見下圖 資料下載 EC800X-QuecDui…

Unity + HybirdCLR熱更新 入門篇

官方文檔 HybridCLR | HybridCLRhttps://hybridclr.doc.code-philosophy.com/docs/intro 什么是HybirdCLR? HybridCLR&#xff08;原名 huatuo&#xff09;是一個專為 Unity 項目設計的C#熱更新解決方案&#xff0c;它通過擴展 IL2CPP 運行時&#xff0c;使其支持動態加載和…

類 Excel 數據填報

類 Excel 填報模式&#xff0c;滿足用戶 Excel 使用習慣 數據填報&#xff0c;可作為獨立的功能模塊&#xff0c;用于管理業務流程、匯總采集數據&#xff0c;以及開發各類數據報送系統&#xff0c;因此&#xff0c;對于報表工具而言&#xff0c;其典型場景之一就是利用報表模…