import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel('氣象、環境、火災燒毀.xlsx')
# 劃分特征和目標變量
X = df.drop(['month', 'day', 'area'], axis=1)
y = df['area']
# 劃分訓練集和測試集
# 注意:random_state=42 是為了確保結果的可復現性,并且針對該數據集進行了特定處理。讀者在使用自己的數據時,可以自由修改此參數。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42)
df.head()
“這個數據集包含了氣象、環境和火災信息,其中X、Y表示地理位置,month和day是日期信息,FFMC、DMC、DC、ISI是火災相關的氣象指數,temp表示溫度,RH是濕度,wind是風速,rain是降雨量,area是火災燒毀的面積,在建模時,我們未使用日期信息(month 和 day)
import xgboost as xgb
from sklearn.model_selection import GridSearchCV
# XGBoost回歸模型參數
params_xgb = {
'learning_rate': 0.02, # 學習率,控制每一步的步長,用于防止過擬合。典型值范圍:0.01 - 0.1
'booster': 'gbtree', # 提升方法,這里使用梯度提升樹(Gradient Boosting Tree)
'objective': 'reg:squarederror', # 損失函數,這里使用平方誤差,適用于回歸任務
'max_leaves': 127, # 每棵樹的葉子節點數量,控制模型復雜度
'verbosity': 1, # 控制 XGBoost 輸出信息的詳細程度,0表示無輸出,1表示輸出進度信息
'seed': 42, # 隨機種子,用于重現模型的結果
'nthread': -1, # 并行運算的線程數量,-1表示使用所有可用的CPU核心
'colsample_bytree': 0.6, # 每棵樹隨機選擇的特征比例,用于增加模型的泛化能力
'subsample': 0.7, # 每次迭代時隨機選擇的樣本比例,用于增加模型的泛化能力
'eval_metric': 'rmse' # 評價指標,這里使用均方根誤差(rmse)
}
# 初始化XGBoost回歸模型
model_xgb = xgb.XGBRegressor(**params_xgb)
# 定義參數網格,用于網格搜索
param_grid = {
'n_estimators': [100, 200, 300, 400, 500], # 樹的數量
'max_depth': [3, 4, 5, 6, 7], # 樹的深度
'learning_rate': [0.01, 0.02, 0.05, 0.1], # 學習率
}
# 使用GridSearchCV進行網格搜索和k折交叉驗證
grid_search = GridSearchCV(
estimator=model_xgb,
param_grid=param_grid,
scoring='neg_mean_squared_error', # 評價指標為負均方誤差
cv=5, # 5折交叉驗證
n_jobs=-1, # 并行計算
verbose=1 # 輸出詳細進度信息
)
# 訓練模型
grid_search.fit(X_train, y_train)
# 輸出最優參數
print("Best parameters found: ", grid_search.best_params_)
print("Best RMSE score: ", (-grid_search.best_score_) ** 0.5) # 還原RMSE
# 使用最優參數訓練模型
best_model_xgboost = grid_search.best_estimator_
使用網格搜索(GridSearchCV)和5折交叉驗證來優化XGBoost模型的超參數(如樹的數量、深度、學習率等),然后輸出最優參數和通過負均方誤差評估得到的最小均方根誤差(RMSE),最后使用最優參數訓練模型
# 獲取XGBoost模型的特征貢獻度(重要性)
feature_importances = best_model_xgboost.feature_importances_
# 將特征和其重要性一起排序
sorted_indices = np.argsort(feature_importances)[::-1] # 逆序排列,重要性從高到低
sorted_features = X_train.columns[sorted_indices]
sorted_importances = feature_importances[sorted_indices]
# 打印排序后的特征及其重要性
for feature_name, importance in zip(sorted_features, sorted_importances):
print(f"Feature: {feature_name}, Importance: {importance:.4f}")
從訓練好的XGBoost模型中提取特征的重要性,并將這些特征按重要性從高到低進行排序。首先,通過best_model_xgboost.feature_importances_ 獲取各特征的貢獻度,然后利用np.argsort() 對貢獻度進行排序,接著將特征名稱和對應的重要性值按順序存儲,最后,代碼通過for循環打印出每個特征及其貢獻度,幫助我們識別出模型中對預測結果影響最大的特征
# 繪制按重要性排序的特征貢獻性柱狀圖
plt.figure(figsize=(10, 6), dpi=1200)
plt.barh(sorted_features, sorted_importances, color='steelblue')
plt.xlabel('Importance', fontsize=14)
plt.ylabel('Features', fontsize=14)
plt.title('Sorted Feature Importance', fontsize=16)
plt.gca().invert_yaxis()
plt.savefig("Sorted Feature Importance.pdf", format='pdf',bbox_inches='tight')
# 顯示圖表
plt.show()
通過 plt.barh() 繪制了按重要性排序的特征貢獻柱狀圖,并將其保存為 PDF 文件,該圖展示了各個特征對 XGBoost 模型在預測火災面積時的相對重要性
從圖中可以看出,RH(相對濕度)、temp(溫度) 和 DMC(濕潤度代碼) 是對火災面積預測貢獻最大的特征,表明這些環境因素對火災的影響最為顯著。而 rain(降雨量) 對模型的貢獻最小,這意味著在這個數據集中,降雨量對火災面積的預測起到的作用相對較小
在之前的文章中,我們探討了如何通過隨機森林模型的特征貢獻度來衡量各個特征在預測中的重要性,然而,特征貢獻度不僅適用于隨機森林,像?XGBoost、CatBoost和??LightGBM等強大的樹模型同樣可以為我們揭示特征對模型的貢獻度,因此,我將推出一個系列文章,逐步講解如何從這些不同的樹模型中提取特征貢獻度,讓你學會在不同算法中挖掘最重要的特征
細心的讀者可能已經注意到,XGBoost 的特征貢獻度與隨機森林有顯著的區別,正是這些差異,讓我們對特征有了不同的見解和理解,最終,我們的目標是通過多模型特征貢獻度的可視化,幫助你直觀地比較各個模型對同一特征的不同看法,最終可以將多種模型的特征貢獻度整合在一張圖中,輕松地對比每個模型對特征的不同判斷,從而更好地理解模型的行為和特征的重要性