import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
df = pd.read_csv('Chabuhou.csv')
# 劃分特征和目標(biāo)變量
X = df.drop(['Electrical_cardioversion'], axis=1)
y = df['Electrical_cardioversion']
# 劃分訓(xùn)練集和測(cè)試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42, stratify=df['Electrical_cardioversion'])
df.head()
讀取數(shù)據(jù),將其分為特征(X)和目標(biāo)變量(y),然后將數(shù)據(jù)集按80%訓(xùn)練集和20%測(cè)試集進(jìn)行劃分,使用的是一個(gè)心臟電復(fù)律的數(shù)據(jù)集包含46個(gè)特征變量一個(gè)目標(biāo)變量為二分類任務(wù)。
from sklearn.ensemble import RandomForestClassifier
from boruta import BorutaPy
# 初始化隨機(jī)森林模型
rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)
# 初始化Boruta特征選擇器
boruta_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=42)
# 對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行特征選擇
boruta_selector.fit(X_train.values, y_train.values)
# 檢查選中的特征
selected_features = X_train.columns[boruta_selector.support_].to_list()
# 打印被選擇的特征
print("Selected Features: ", selected_features)
# 打印被剔除的特征
rejected_features = X_train.columns[~boruta_selector.support_].to_list()
print("Rejected Features: ", rejected_features)
# 打印有待定性的特征
tentative_features = X_train.columns[boruta_selector.support_weak_].to_list()
print("Tentative Features: ", tentative_features)
初始化隨機(jī)森林分類器模型用于評(píng)估特征重要性,并通過Boruta特征選擇器與影子特征進(jìn)行對(duì)比,確定哪些特征是重要的,隨后對(duì)訓(xùn)練數(shù)據(jù)應(yīng)用Boruta算法,以篩選出對(duì)模型預(yù)測(cè)最有用的特征,Boruta算法默認(rèn)在內(nèi)部迭代100次,如需更改迭代次數(shù),可通過添加參數(shù)max_iter進(jìn)行調(diào)整。
# 獲取特征排名
feature_ranks = boruta_selector.ranking_
# 將特征名稱和排名結(jié)合成一個(gè)DataFrame
feature_importance_df = pd.DataFrame({
'Feature': X_train.columns,
'Rank': feature_ranks
})
feature_importance_df
使用boruta_selector.ranking_獲取每個(gè)特征的排名,這個(gè)排名表示了特征的重要性,數(shù)值越小代表特征越重要,這里只展示部分特征,最后確定重要的特征為[‘Type_of_atrial_fibrillation’, ‘BMI’, ‘Left_atrial_diameter’, ‘Systolic_blood_pressure’, ‘NtproBNP’]。
# 初始化隨機(jī)森林模型
rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)
# 初始化存儲(chǔ)特征排名的 DataFrame
ranking_df = pd.DataFrame(index=range(1, 21), columns=X_train.columns)
# 運(yùn)行 Boruta 20 次
for i in range(20):
print(f"Iteration {i+1}")
# 初始化Boruta特征選擇器
boruta_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=i, max_iter=50)
# 對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行特征選擇
boruta_selector.fit(X_train.values, y_train.values)
# 獲取特征排名
feature_ranks = boruta_selector.ranking_
# 將特征排名保存到 DataFrame 中
ranking_df.loc[i+1] = feature_ranks
ranking_df
多次運(yùn)行Boruta算法,以不同的隨機(jī)種子生成特征排名,并將每次的排名結(jié)果保存到一個(gè)DataFrame中,用于分析特征排名的一致性,并且指定max_iter=50不在是默認(rèn)的100,提高運(yùn)行速度。
# 確保數(shù)據(jù)集中只有數(shù)值列
numeric_ranking_df = ranking_df.apply(pd.to_numeric, errors='coerce')
# 計(jì)算每個(gè)特征的中位數(shù)
median_values = numeric_ranking_df.median()
# 根據(jù)中位數(shù)對(duì)列進(jìn)行排序
sorted_columns = median_values.sort_values().index
# 設(shè)置繪圖風(fēng)格
plt.figure(figsize=(15, 8))
sns.set(style="whitegrid")
# 繪制箱線圖
sns.boxplot(data=numeric_ranking_df[sorted_columns], palette="Greens")
plt.xticks(rotation=90)
plt.title("Sorted Feature Ranking Distribution by Boruta", fontsize=16)
plt.xlabel("Attributes", fontsize=14)
plt.ylabel("Importance", fontsize=14)
plt.tight_layout()
plt.show()
從圖表中可以看出,最左側(cè)的特征(Type_of_atrial_fibrillation、BMI等)在多次迭代中排名較高,表明它們是模型中較為重要的特征,而最右側(cè)的特征(如COPD、Amiodarone等)則在多次迭代中排名較低,說明它們?cè)谀P椭斜徽J(rèn)為不太重要,與前面單次運(yùn)行Boruta算法的結(jié)果一致,但是相比于單次運(yùn)行,通過這個(gè)可視化可以發(fā)現(xiàn)某些特征在個(gè)別迭代中的重要性排名與大多數(shù)迭代結(jié)果不同,從而判斷這些特征的重要性是否穩(wěn)定,圖中位于須線外的點(diǎn)正是代表了這些異常的排名結(jié)果,如果過多這種情況出現(xiàn)作者認(rèn)為需要著重去考慮這種特征。
文章轉(zhuǎn)自微信公眾號(hào)@Python機(jī)器學(xué)習(xí)AI
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)