
實(shí)時(shí)航班追蹤背后的技術(shù):在線飛機(jī)追蹤器的工作原理
在此基礎(chǔ)上,本文對(duì)其進(jìn)行擴(kuò)展,采用CatBoost、XGBoost、隨機(jī)森林等集成學(xué)習(xí)模型,對(duì)模型在訓(xùn)練集、驗(yàn)證集和測(cè)試集上的性能進(jìn)行全面對(duì)比分析,同時(shí),通過(guò)結(jié)合小提琴圖和折線圖的可視化方法,直觀地展示各個(gè)模型在不同數(shù)據(jù)集上的表現(xiàn),幫助更好地理解模型的泛化能力及其在不同條件下的穩(wěn)定性,詳細(xì)的圖形解讀放在代碼可視化輸出后,這里是回歸預(yù)測(cè)模型,分類模型作圖同理
數(shù)據(jù)讀取分割
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel('2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI.xlsx')
from sklearn.model_selection import train_test_split, KFold
X = df.drop(['待預(yù)測(cè)變量Y'],axis=1)
y = df['待預(yù)測(cè)變量Y']
# 劃分訓(xùn)練集和測(cè)試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
df.head()
加載Excel數(shù)據(jù)集,提取特征和目標(biāo)變量,并將數(shù)據(jù)集劃分為訓(xùn)練集和測(cè)試集,為后續(xù)機(jī)器學(xué)習(xí)模型的訓(xùn)練和測(cè)試做好準(zhǔn)備
模型構(gòu)建
catboost模型
from sklearn.metrics import r2_score
from catboost import CatBoostRegressor
from sklearn.model_selection import KFold
# CatBoost模型參數(shù)
params_cat = {
'learning_rate': 0.02, # 學(xué)習(xí)率,控制每一步的步長(zhǎng),用于防止過(guò)擬合。典型值范圍:0.01 - 0.1
'iterations': 1000, # 弱學(xué)習(xí)器(決策樹)的數(shù)量
'depth': 6, # 決策樹的深度,控制模型復(fù)雜度
'eval_metric': 'R2', # 評(píng)估指標(biāo),改為R2(擬合優(yōu)度)
'random_seed': 42, # 隨機(jī)種子,用于重現(xiàn)模型的結(jié)果
'verbose': 500 # 控制CatBoost輸出信息的詳細(xì)程度,每500次迭代輸出一次
}
# 準(zhǔn)備k折交叉驗(yàn)證
kf = KFold(n_splits=10, shuffle=True, random_state=42)
scores_train = []
scores_val = []
best_score = -np.inf # R2的最佳值越大越好
best_model = None
# 交叉驗(yàn)證
for fold, (train_index, val_index) in enumerate(kf.split(X_train, y_train)):
X_train_fold, X_val_fold = X_train.iloc[train_index], X_train.iloc[val_index]
y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]
model = CatBoostRegressor(**params_cat)
model.fit(X_train_fold, y_train_fold, eval_set=(X_val_fold, y_val_fold), early_stopping_rounds=100)
# 預(yù)測(cè)訓(xùn)練集和驗(yàn)證集
y_train_pred = model.predict(X_train_fold)
y_val_pred = model.predict(X_val_fold)
# 計(jì)算訓(xùn)練集和驗(yàn)證集的R2
score_train = r2_score(y_train_fold, y_train_pred)
score_val = r2_score(y_val_fold, y_val_pred)
scores_train.append(score_train)
scores_val.append(score_val)
print(f'第 {fold + 1} 折 訓(xùn)練集 R2: {score_train}, 驗(yàn)證集 R2: {score_val}')
# 保存得分最好的模型
if score_val > best_score: # R2 越大越好
best_score = score_val
best_model_cat = model
# 保存2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù)為DataFrame
df_scores_catboost = pd.DataFrame({
'catboost_train': scores_train,
'catboost_val': scores_val
})
df_scores_catboost
定義CatBoost回歸模型的參數(shù),使用10折交叉驗(yàn)證將訓(xùn)練數(shù)據(jù)分成10個(gè)子集,在每一折中訓(xùn)練模型并在驗(yàn)證集上評(píng)估性能,計(jì)算每一折訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù)(擬合優(yōu)度),同時(shí)記錄并保存驗(yàn)證集上表現(xiàn)最好的模型,最終將所有折的R2分?jǐn)?shù)存儲(chǔ)在一個(gè)DataFrame中用于后續(xù)分析
xgboost
import xgboost as xgb
# XGBoost回歸模型參數(shù)
params_xgb = {
'learning_rate': 0.02, # 學(xué)習(xí)率
'booster': 'gbtree', # 梯度提升樹
'objective': 'reg:squarederror', # 損失函數(shù)
'max_leaves': 127, # 控制模型復(fù)雜度
'verbosity': 1, # 控制輸出信息
'seed': 42, # 隨機(jī)種子
'nthread': -1, # 并行線程數(shù)量
'colsample_bytree': 0.6, # 每棵樹隨機(jī)選擇的特征比例
'subsample': 0.7, # 隨機(jī)選擇的樣本比例
'eval_metric': 'rmse' # 使用RMSE作為評(píng)價(jià)指標(biāo)
}
# 初始化XGBoost回歸模型
model_xgb = xgb.XGBRegressor(**params_xgb)
# 準(zhǔn)備10折交叉驗(yàn)證
kf = KFold(n_splits=10, shuffle=True, random_state=42)
# 準(zhǔn)備存儲(chǔ)每折訓(xùn)練集和驗(yàn)證集的擬合優(yōu)度分?jǐn)?shù)
scores_train_xgb = []
scores_val_xgb = []
# 初始化最好的模型和最高的驗(yàn)證集分?jǐn)?shù)
best_model = None
best_val_score = -np.inf # 因?yàn)槲覀兪褂玫氖?R2,越大越好,所以初始值設(shè)為-inf
# 交叉驗(yàn)證
for fold, (train_index, val_index) in enumerate(kf.split(X_train)):
X_train_fold, X_val_fold = X_train.iloc[train_index], X_train.iloc[val_index]
y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]
# 訓(xùn)練模型
model_xgb.fit(X_train_fold, y_train_fold)
# 預(yù)測(cè)訓(xùn)練集和驗(yàn)證集
y_train_pred = model_xgb.predict(X_train_fold)
y_val_pred = model_xgb.predict(X_val_fold)
# 計(jì)算訓(xùn)練集和驗(yàn)證集的R2
score_train_xgb = r2_score(y_train_fold, y_train_pred)
score_val_xgb = r2_score(y_val_fold, y_val_pred)
scores_train_xgb.append(score_train_xgb)
scores_val_xgb.append(score_val_xgb)
# 保存驗(yàn)證集分?jǐn)?shù)最好的2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI模型
if score_val_xgb > best_val_score:
best_val_score = score_val_xgb
best_model_xgb = model_xgb
print(f'第 {fold + 1} 折 訓(xùn)練集 R2: {score_train_xgb}, 驗(yàn)證集 R2: {score_val_xgb}')
# 保存XGBoost模型的訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù)為DataFrame
df_scores_xgb = pd.DataFrame({
'xgboost_train': scores_train_xgb,
'xgboost_val': scores_val_xgb
})
# 將CatBoost和XGBoost的結(jié)果合并
df_scores_combined = pd.concat([df_scores_catboost, df_scores_xgb], axis=1)
# 輸出最佳模型和它的驗(yàn)證集 R2 分?jǐn)?shù)
print('最佳模型:', best_model)
print(f'最佳驗(yàn)證集 R2: {best_val_score}')
df_scores_combined
定義XGBoost回歸模型的參數(shù),使用10折交叉驗(yàn)證對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行多次訓(xùn)練和驗(yàn)證,在每一折中計(jì)算訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù),記錄每一折的性能,并保存驗(yàn)證集上表現(xiàn)最好的模型,最后將XGBoost與之前的CatBoost模型的結(jié)果合并,綜合展示兩種模型在不同數(shù)據(jù)集上的表現(xiàn),以便比較模型的泛化能力和選擇最佳模型
RF
from sklearn.ensemble import RandomForestRegressor
# 隨機(jī)森林回歸模型參數(shù)
params_rf = {
'n_estimators': 100, # 樹的數(shù)量
'max_depth': 7, # 每棵樹的最大深度
'random_state': 42, # 隨機(jī)種子
'n_jobs': -1, # 并行計(jì)算,使用所有CPU核心
'min_samples_split': 2, # 內(nèi)部節(jié)點(diǎn)再分裂所需的最小樣本數(shù)
'min_samples_leaf': 1 # 葉子節(jié)點(diǎn)包含的最小樣本數(shù)
}
# 初始化隨機(jī)森林回歸模型
model_rf = RandomForestRegressor(**params_rf)
# 準(zhǔn)備10折交叉驗(yàn)證
kf = KFold(n_splits=10, shuffle=True, random_state=42)
# 準(zhǔn)備存儲(chǔ)每折訓(xùn)練集和驗(yàn)證集的擬合優(yōu)度分?jǐn)?shù)
scores_train_rf = []
scores_val_rf = []
# 初始化最好的模型2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI和最高的驗(yàn)證集分?jǐn)?shù)
best_model_rf = None
best_val_score_rf = -np.inf # 因?yàn)镽2越大越好,所以初始值設(shè)為-inf
# 交叉驗(yàn)證
for fold, (train_index, val_index) in enumerate(kf.split(X_train)):
X_train_fold, X_val_fold = X_train.iloc[train_index], X_train.iloc[val_index]
y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]
# 訓(xùn)練模型
model_rf.fit(X_train_fold, y_train_fold)
# 預(yù)測(cè)訓(xùn)練集和驗(yàn)證集
y_train_pred = model_rf.predict(X_train_fold)
y_val_pred = model_rf.predict(X_val_fold)
# 計(jì)算訓(xùn)練集和驗(yàn)證集的R2
score_train_rf = r2_score(y_train_fold, y_train_pred)
score_val_rf = r2_score(y_val_fold, y_val_pred)
scores_train_rf.append(score_train_rf)
scores_val_rf.append(score_val_rf)
# 保存驗(yàn)證集分?jǐn)?shù)最好的模型
if score_val_rf > best_val_score_rf:
best_val_score_rf = score_val_rf
best_model_rf = model_rf
print(f'第 {fold + 1} 折 訓(xùn)練集 R2: {score_train_rf}, 驗(yàn)證集 R2: {score_val_rf}')
# 保存隨機(jī)森林模型的訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù)為DataFrame
df_scores_rf = pd.DataFrame({
'rf_train': scores_train_rf,
'rf_val': scores_val_rf
})
# 將CatBoost、XGBoost和RF的結(jié)果合并
df_scores_combined = pd.concat([df_scores_combined, df_scores_rf], axis=1)
# 輸出最優(yōu)模型及其驗(yàn)證集 R2 分?jǐn)?shù)
print(f'最佳驗(yàn)證集 R2: {best_val_score_rf}')
print('最佳模型:', best_model_rf)
df_scores_combined
使用隨機(jī)森林回歸模型進(jìn)行10折交叉驗(yàn)證,定義了模型的參數(shù),如決策樹的數(shù)量和最大深度等,并通過(guò)訓(xùn)練模型在每一折中計(jì)算訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù),記錄每一折的表現(xiàn),保存在不同折上表現(xiàn)最佳的模型,最后將隨機(jī)森林的結(jié)果與之前的CatBoost和XGBoost結(jié)果合并,輸出最終的最優(yōu)模型及其對(duì)應(yīng)的驗(yàn)證集R2分?jǐn)?shù),用于比較不同模型的性能表現(xiàn)
lightgbm
import lightgbm as lgb
# LightGBM 回歸模型參數(shù)
params_lgb = {
'learning_rate': 0.02, # 學(xué)習(xí)率
'boosting_type': 'gbdt', # 提升方式,使用梯度提升樹
'objective': 'regression', # 回歸任務(wù)
'metric': 'rmse', # 評(píng)價(jià)指標(biāo)使用 RMSE
'n_estimators': 100, # 樹的數(shù)量
'max_depth': 7, # 樹的最大深度
'random_state': 42, # 隨機(jī)種子
'subsample': 0.7, # 每次2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI迭代時(shí)隨機(jī)選擇的樣本比例
'colsample_bytree': 0.6, # 每棵樹隨機(jī)選擇的特征比例
'n_jobs': -1 # 并行計(jì)算
}
# 初始化 LightGBM 回歸模型
model_lgb = lgb.LGBMRegressor(**params_lgb)
# 準(zhǔn)備10折交叉驗(yàn)證
kf = KFold(n_splits=10, shuffle=True, random_state=42)
# 準(zhǔn)備存儲(chǔ)每折訓(xùn)練集和驗(yàn)證集的擬合優(yōu)度分?jǐn)?shù)
scores_train_lgb = []
scores_val_lgb = []
# 初始化最好的模型和最高的驗(yàn)證集分?jǐn)?shù)
best_model_lgb = None
best_val_score_lgb = -np.inf # 因?yàn)镽2越大越好,所以初始值設(shè)為-inf
# 交叉驗(yàn)證
for fold, (train_index, val_index) in enumerate(kf.split(X_train)):
X_train_fold, X_val_fold = X_train.iloc[train_index], X_train.iloc[val_index]
y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]
# 訓(xùn)練模型
model_lgb.fit(X_train_fold, y_train_fold)
# 預(yù)測(cè)訓(xùn)練集和驗(yàn)證集
y_train_pred = model_lgb.predict(X_train_fold)
y_val_pred = model_lgb.predict(X_val_fold)
# 計(jì)算訓(xùn)練集和驗(yàn)證集的R2
score_train_lgb = r2_score(y_train_fold, y_train_pred)
score_val_lgb = r2_score(y_val_fold, y_val_pred)
scores_train_lgb.append(score_train_lgb)
scores_val_lgb.append(score_val_lgb)
# 保存驗(yàn)證集分?jǐn)?shù)最好的模型
if score_val_lgb > best_val_score_lgb:
best_val_score_lgb = score_val_lgb
best_model_lgb = model_lgb
print(f'第 {fold + 1} 折 訓(xùn)練集 R2: {score_train_lgb}, 驗(yàn)證集 R2: {score_val_lgb}')
# 保存 LightGBM 模型的訓(xùn)練集和驗(yàn)證集的 R2 分?jǐn)?shù)為 DataFrame
df_scores_lgb = pd.DataFrame({
'lgbm_train': scores_train_lgb,
'lgbm_val': scores_val_lgb
})
# 將 CatBoost、XGBoos2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AIt、RF 和 LightGBM 的結(jié)果合并
df_scores_combined = pd.concat([df_scores_combined, df_scores_lgb], axis=1)
# 輸出最優(yōu)模型及其驗(yàn)證集 R2 分?jǐn)?shù)
print(f'最佳驗(yàn)證集 R2: {best_val_score_lgb}')
print('最佳模型:', best_model_lgb)
df_scores_combined
使用LightGBM回歸模型進(jìn)行10折交叉驗(yàn)證,定義了模型參數(shù)(如學(xué)習(xí)率、樹的數(shù)量、最大深度等),在每一折中訓(xùn)練模型并計(jì)算訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù),將結(jié)果存儲(chǔ)到列表中,同時(shí)記錄驗(yàn)證集上R2分?jǐn)?shù)最高的最優(yōu)模型,最后將LightGBM的結(jié)果與之前的CatBoost、XGBoost和隨機(jī)森林模型的結(jié)果合并,綜合比較所有模型的性能表現(xiàn),并輸出LightGBM的最佳模型及其驗(yàn)證集R2分?jǐn)?shù)
bagging
from sklearn.ensemble import BaggingRegressor
# Bagging 回歸模型參數(shù)
params_bagging = {
'n_estimators': 100, # 基模型的數(shù)量
'random_state': 42, # 隨機(jī)種子
'n_jobs': -1 # 并行計(jì)算,使用所有 CPU 核心
}
# 初始化 Bagging 回歸模型
model_bagging = BaggingRegressor(**params_bagging)
# 準(zhǔn)備10折交叉驗(yàn)證
kf = KFold(n_splits=10, shuffle=True, random_state=42)
# 準(zhǔn)備存儲(chǔ)每2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI折訓(xùn)練集和驗(yàn)證集的擬合優(yōu)度分?jǐn)?shù)
scores_train_bagging = []
scores_val_bagging = []
# 初始化最好的模型和最高的驗(yàn)證集分?jǐn)?shù)
best_model_bagging = None
best_val_score_bagging = -np.inf # 因?yàn)?R2 越大越好,初始值設(shè)為負(fù)無(wú)窮
# 交叉驗(yàn)證
for fold, (train_index, val_index) in enumerate(kf.split(X_train)):
X_train_fold, X_val_fold = X_train.iloc[train_index], X_train.iloc[val_index]
y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]
# 訓(xùn)練模型
model_bagging.fit(X_train_fold, y_train_fold)
# 預(yù)測(cè)訓(xùn)練集和驗(yàn)證集
y_train_pred = model_bagging.predict(X_train_fold)
y_val_pred = model_bagging.predict(X_val_fold)
# 計(jì)算訓(xùn)練集和驗(yàn)證集的 R2
score_train_bagging = r2_score(y_train_fold, y_train_pred)
score_val_bagging = r2_score(y_val_fold, y_val_pred)
scores_train_bagging.append(score_train_bagging)
scores_val_bagging.append(score_val_bagging)
# 保存驗(yàn)證集分?jǐn)?shù)最好的模型
if score_val_bagging > best_val_score_bagging:
best_val_score_bagging = score_val_bagging
best_model_bagging = model_bagging
print(f'第 {fold + 1} 折 訓(xùn)練集 R2: {score_train_bagging}, 驗(yàn)證集 R2: {score_val_bagging}')
# 保存 Bagging 模型的訓(xùn)練集和驗(yàn)證集的 R2 分?jǐn)?shù)為 DataFrame
df_scores_bagging = pd.DataFrame({
'bagging_train': scores_train_bagging,
'bagging_val': scores_val_bagging
})
# 將 CatBoost、XGBoost、RF、LightGBM 和 Bagging 的結(jié)果合并
df_scores_combined = pd.concat([df_scores_combined, df_scores_bagging], axis=1)
# 輸出最優(yōu)模型及其驗(yàn)證集 R2 分?jǐn)?shù)
print(f'最佳驗(yàn)證集 R2: {best_val_score_bagging}')
print('最佳 Bagging 模型:', best_model_bagging)
df_scores_combined
使用Bagging回歸模型進(jìn)行10折交叉驗(yàn)證,定義了基模型的數(shù)量和并行計(jì)算等參數(shù),通過(guò)對(duì)每一折的數(shù)據(jù)進(jìn)行訓(xùn)練和驗(yàn)證,計(jì)算訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù),將每折的R2結(jié)果保存,記錄驗(yàn)證集中表現(xiàn)最好的模型,同時(shí)將Bagging的結(jié)果與之前的CatBoost、XGBoost、隨機(jī)森林和LightGBM的結(jié)果進(jìn)行合并,最終輸出Bagging模型的最佳驗(yàn)證集R2分?jǐn)?shù)及最佳模型,用于綜合比較所有模型的性能表現(xiàn)
數(shù)據(jù)整理
# 重新構(gòu)建用于繪制小提琴圖的數(shù)據(jù)格式
df_melted = pd.melt(df_scores_combined.reset_index(drop=True), var_name='Model_Dataset', value_name='R2')
# 分離模型名稱和2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI數(shù)據(jù)集(訓(xùn)練/驗(yàn)證)
df_melted['Model'] = df_melted['Model_Dataset'].apply(lambda x: x.split('_')[0])
df_melted['Dataset'] = df_melted['Model_Dataset'].apply(lambda x: 'Train' if 'train' in x else 'Val')
df_melted
將多個(gè)模型的訓(xùn)練集和驗(yàn)證集R2分?jǐn)?shù)的結(jié)果重新構(gòu)建為適合繪制小提琴圖的數(shù)據(jù)格式,分離出模型名稱和數(shù)據(jù)集類型(訓(xùn)練集或驗(yàn)證集)以便進(jìn)行可視化分析
from matplotlib.colors import to_rgba
import seaborn as sns
# 創(chuàng)建一個(gè)單獨(dú)的畫布
plt.figure(figsize=(12, 6), dpi=1200)
# 設(shè)置指定的顏色
palette = [to_rgba('#3c5397'), to_rgba('#f57065', alpha=0.7)]
# 繪制訓(xùn)練2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI集和驗(yàn)證集的小提琴圖,使用分開的模型位置
sns.violinplot(x='Model', y='R2', hue='Dataset', data=df_melted,
palette=palette,
split=False, dodge=True)
# 調(diào)整x軸標(biāo)簽,使其只顯示模型名稱,并居中顯示模型名
plt.xticks(ticks=plt.gca().get_xticks(), labels=df_melted['Model'].unique())
plt.title('Model Comparison based on R2 for Training and Validation Sets')
plt.ylabel('R2')
plt.xlabel('Model')
plt.ylim(0, 1)
plt.tight_layout()
plt.savefig("Model Comparison based on R2 for Training and Validation Sets.pdf", format='pdf',bbox_inches='tight')
plt.show()
使用Seaborn庫(kù)創(chuàng)建了一個(gè)小提琴圖,分別展示不同模型在訓(xùn)練集和驗(yàn)證集上的R2分?jǐn)?shù)分布,通過(guò)顏色區(qū)分訓(xùn)練集和驗(yàn)證集的表現(xiàn)
小提琴圖結(jié)合了 箱線圖 和 核密度圖,展示了數(shù)據(jù)的分布和集中趨勢(shì),它由以下幾個(gè)部分組成:
在這個(gè)圖中,通過(guò)兩種顏色來(lái)區(qū)分訓(xùn)練集和驗(yàn)證集的R2分?jǐn)?shù)分布
通過(guò)這個(gè)小提琴圖,直觀地分析不同模型在訓(xùn)練集和驗(yàn)證集上的性能,判斷模型是否存在過(guò)擬合、欠擬合以及模型的穩(wěn)定性
折線圖(測(cè)試集)可視化
數(shù)據(jù)整理
from sklearn.metrics import mean_squared_error
models = {
'CatBoost': best_model_cat,
'XGBoost': best_model_xgb,
'RandomForest': best_model_rf,
'LightGBM': best_model_lgb,
'Bagging': best_model_bagging
}
# 創(chuàng)建一個(gè)空列表,用于保存模型名和RMSE
rmse_list = []
# 遍歷模型,計(jì)2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI算每個(gè)模型在X_test上的RMSE
for model_name, model in models.items():
y_pred = model.predict(X_test) # 獲取預(yù)測(cè)結(jié)果
rmse = np.sqrt(mean_squared_error(y_test, y_pred)) # 計(jì)算RMSE
rmse_list.append([model_name, rmse]) # 添加到列表
rmse_df = pd.DataFrame(rmse_list, columns=['Model', 'RMSE'])
rmse_df
計(jì)算每個(gè)訓(xùn)練好的模型在測(cè)試集上的RMSE(均方根誤差),將模型名稱與對(duì)應(yīng)的RMSE值保存為一個(gè)DataFrame,為后續(xù)在訓(xùn)練集上繪制折線圖部分提供數(shù)據(jù)
可視化
plt.figure(figsize=(10, 6), dpi=1200)
plt.plot(rmse_df['Model'], rmse_df['RMSE'], marker='o', linestyle='-', color=(134/255, 171/255, 197/255))
plt.ylabel('RMSE', fontsize=12)
plt.tight_layout()
plt.savefig("RMSE of Different Models on X_test.pdf", format='pdf',bbox_inches='tight')
plt.show()
通過(guò)折線圖展示各個(gè)模型在測(cè)試集上的RMSE(均方根誤差)表現(xiàn),從圖中可以看出 CatBoost 模型的RMSE最小,表現(xiàn)最佳,結(jié)合前面的小提琴圖就可以全面解釋模型在訓(xùn)練集、驗(yàn)證集、測(cè)試集上的表現(xiàn),接下來(lái)進(jìn)行組合繪圖
組合小提琴圖、折線圖可視化
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
# 創(chuàng)建第一個(gè)圖 (violin plot2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI) 并將第二個(gè)圖作為 inset 放入其中
fig, ax = plt.subplots(figsize=(12, 6), dpi=1200)
# 設(shè)置指定的顏色
palette = [to_rgba('#3c5397'), to_rgba('#f57065', alpha=0.7)]
# 繪制訓(xùn)練集和驗(yàn)證集的小提琴圖
sns.violinplot(x='Model', y='R2', hue='Dataset', data=df_melted,
palette=palette, split=False, dodge=True, ax=ax)
# 調(diào)整x軸標(biāo)簽,使其只顯示模型名稱,并居中顯示模型名
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(df_melted['Model'].unique())
ax.set_title('Comparison of Model Performance: R2 on Training and Validation Sets, RMSE on Test Set', fontsize=14)
ax.set_ylabel('R2')
ax.set_ylim(0, 1)
# 創(chuàng)建 inset,用于嵌入第二個(gè)圖
inset_ax = inset_axes(ax, width="90%", height="90%",
bbox_to_anchor=(0.65, 0.1, 0.3, 0.4), # 控制位置和大小
bbox_transform=ax.transAxes)
# 繪制第二個(gè)圖 (折線圖) 在 inset 中,并給折線加上label用于圖例
inset_ax.plot(rmse_df['Model'], rmse_df['RMSE'], marker='o', linestyle='-', color=(134/255, 171/255, 197/255), label='Test RMSE')
inset_ax.set_ylabel('RMSE', fontsize=10)
inset_ax.set_xticklabels(rmse_df['Model'], fontsize=8)
# 在鑲嵌圖 (inset_ax) 中添加圖例
inset_ax.legend(loc='best', fontsize=8)
plt.tight_layout()
plt.savefig("Comparison_of_Model_Performance_R2_and_RMSE.pdf", format='pdf', bbox_inches='tight')
plt.show()
創(chuàng)建一個(gè)主圖(小提琴圖)和一個(gè)嵌入圖(折線圖),綜合展示各個(gè)模型在訓(xùn)練集、驗(yàn)證集和測(cè)試集上的性能表現(xiàn),當(dāng)然我這里只是結(jié)合文獻(xiàn)采用的RMSE,文獻(xiàn)只展示了它所謂的訓(xùn)練集和測(cè)試集,然后對(duì)測(cè)試集分別用了R2 和RMSE展示,可能出發(fā)點(diǎn)在于R2 用來(lái)評(píng)估模型的擬合優(yōu)度,而 RMSE 用來(lái)判斷模型的預(yù)測(cè)誤差大小,所以對(duì)于折線圖我也采用了RMSE,但是為了統(tǒng)一評(píng)價(jià)指標(biāo)接下來(lái)都采用R2 來(lái)評(píng)價(jià)訓(xùn)練集、驗(yàn)證集、測(cè)試集的性能
models = {
'CatBoost': best_model_cat,
'XGBoost': best_model_xgb,
'RandomForest': best_model_rf,
'LightGBM': best_model_lgb,
'Bagging': best_model_bagging
}
# 創(chuàng)建一個(gè)空列表,用于保存模型名和R2
r2_list = []
# 遍歷模型,計(jì)算每個(gè)模型在X_test上的R2
for model_name, model in models.items():
y_pred = model.predict(X_test) # 獲取預(yù)測(cè)結(jié)果
r2 = r2_score(y_test, y_pred) # 計(jì)算擬合優(yōu)度 (R2)
r2_list.append([model_name, r2]) # 添加到列表
r2_df = pd.DataFrame(r2_list, columns=['Model', 'R2'])
# 創(chuàng)建第一個(gè)圖 (violin2024-10-26-公眾號(hào)Python機(jī)器學(xué)習(xí)AI plot) 并將第二個(gè)圖作為 inset 放入其中
fig, ax = plt.subplots(figsize=(12, 6), dpi=1200)
# 設(shè)置指定的顏色
palette = [to_rgba('#3c5397'), to_rgba('#f57065', alpha=0.7)]
# 繪制訓(xùn)練集和驗(yàn)證集的小提琴圖
sns.violinplot(x='Model', y='R2', hue='Dataset', data=df_melted,
palette=palette, split=False, dodge=True, ax=ax)
# 調(diào)整x軸標(biāo)簽,使其只顯示模型名稱,并居中顯示模型名
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(df_melted['Model'].unique())
ax.set_title('Comparison of Model Performance: R2 on Training and Validation Sets.Test Set', fontsize=14)
ax.set_ylabel('R2')
ax.set_ylim(0, 1)
# 創(chuàng)建 inset,用于嵌入第二個(gè)圖
inset_ax = inset_axes(ax, width="90%", height="90%",
bbox_to_anchor=(0.65, 0.1, 0.3, 0.4), # 控制位置和大小
bbox_transform=ax.transAxes)
# 繪制第二個(gè)圖 (折線圖) 在 inset 中,并給折線加上label用于圖例
inset_ax.plot(r2_df['Model'], r2_df['R2'], marker='o', linestyle='-', color=(134/255, 171/255, 197/255), label='Test R2')
inset_ax.set_ylabel('R2', fontsize=10)
inset_ax.set_xticklabels(rmse_df['Model'], fontsize=8)
# 在鑲嵌圖 (inset_ax) 中添加圖例
inset_ax.legend(loc='best', fontsize=8)
plt.tight_layout()
plt.savefig("Comparison of Model Performance: R2 on Training and Validation Sets、Test Set.pdf", format='pdf', bbox_inches='tight')
plt.show()
最后這個(gè)結(jié)果顯示了各模型在訓(xùn)練集、驗(yàn)證集上的R2分?jǐn)?shù)(通過(guò)小提琴圖)和在測(cè)試集上的R2分?jǐn)?shù)(通過(guò)嵌入的折線圖),其中CatBoost 在訓(xùn)練集、驗(yàn)證集和測(cè)試集上都表現(xiàn)最好,泛化能力最強(qiáng)
本文章轉(zhuǎn)載微信公眾號(hào)@Python機(jī)器學(xué)習(xí)AI
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)