背景
这篇文献的特征筛选和模型训练方法可以概括为以下几点:
- 文献中提到,采用递归特征消除(RFE)方法来筛选最优的特征子集,RFE的目的是通过去除不重要的特征,最终获得一组能够最大化模型性能的特征组合
- 最终使用了随机森林(RF)模型作为核心模型来评估特征的重要性和筛选效果,图5中,蓝色柱状图代表不同特征的重要性,而红色和黑色曲线代表了累积AUC的变化,累积AUC表示根据特征重要性逐步增加特征对模型性能的贡献
- 使用了交叉验证方法(提到内部五折交叉验证)来评估模型性能,确保筛选出的特征组合具有稳健的预测效果
- 在特征选择完成后,这些特征被用作候选变量输入到模型中,以进一步区分短期预后良好和不良的患者
前面一期出过一篇文献类似的配图实现,当时文献采用了基于LightGBM(LGBM)分类器的方法来进行特征选择——期刊配图:变量重要性排序与顺序正向选择的特征筛选可视化。具体而言,它通过模型的特征重要性对变量进行排序,然后按照变量重要性由高到低的顺序,逐步加入特征(逐步特征添加策略)来评估模型性能,最终选择最佳特征组合。这种方法中,特征重要性的排序是基于对整个数据集的一次性固定计算,排名是静态的
而当前的文章使用了随机森林(RF)模型,并结合了递归特征消除(RFE)来完成特征选择。与前面的逐步特征添加方法不同,RFE是一种动态的特征筛选方法。每次运行都会训练模型,并根据当前特征集的排名剔除贡献度最低的特征。因此,特征的重要性排序会在每次迭代中重新计算,是一种动态排序过程。这使得RFE能够更精细地评估特征的重要性,并逐步找到最佳的特征子集
当然,两者的共同点都是基于特征排名进行特征筛选,只是由于同一个数据集剔除了一些特征后,在剩下的特征中重新进行排名时,可能会与上一次的排名存在一定差异
代码实现
数据读取整理
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
from sklearn.model_selection import train_test_split
df = pd.read_excel('2025-1-6公众号Python机器学习AI.xlsx')
# 划分特征和目标变量
X = df.drop(['y'], axis=1)
y = df['y']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=42, stratify=df['y'])
加载数据,划分特征(X)和目标变量(y),然后将数据按照 7:3 的比例分为训练集和测试集,并通过 分层抽样(stratify)确保目标变量的类别比例在训练集和测试集中保持一致
基于递归特征消除(RFE)和随机森林的特征选择(未加入交叉验证)
from sklearn.metrics import roc_auc_score
from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
# 初始化存储结果的DataFrame
selection_results = pd.DataFrame(columns=['Feature', 'Importance', 'ROC'])
# 创建随机森林分类器
rf_clf = RandomForestClassifier(random_state=42)
# 使用递归特征消除(RFE)
rfe = RFE(estimator=rf_clf, n_features_to_select=1, step=1) # 每次消除一个特征
rfe.fit(X_train, y_train)
# 获取特征排名
feature_ranking = rfe.ranking_
# 构建特征排名表
rfe_features = pd.DataFrame({
'Feature': X_train.columns,
'Ranking': feature_ranking
}).sort_values(by='Ranking')
# 初始化用于训练的特征列表
selected_features = []
# 根据RFE排序依次选择特征
for i in range(len(rfe_features)):
# 当前特征
current_feature = rfe_features.iloc[i]['Feature']
selected_features.append(current_feature)
# 训练模型(仅使用当前选定的特征)
X_train_subset = X_train[selected_features]
X_test_subset = X_test[selected_features]
# 创建并训练随机森林模型
rf_clf = RandomForestClassifier(random_state=42)
rf_clf.fit(X_train_subset, y_train)
# 获取特征重要性
importance = rf_clf.feature_importances_[len(selected_features) - 1]
# 预测并计算ROC AUC分数
y_pred_proba = rf_clf.predict_proba(X_test_subset)[:, 1] # 概率分数
roc_score = roc_auc_score(y_test, y_pred_proba)
# 保存结果
selection_results.loc[len(selection_results)] = [
current_feature,
importance,
roc_score
]
# 显示结果
selection_results
使用递归特征消除和随机森林分类器,按特征重要性动态筛选特征,并计算每个特征组合在测试集上的ROC AUC分数,以评估其对模型性能的贡献
强调一下,之所以没有直接获取selection_results,而是通过rfe.ranking_定义一个for循环去获取,是因为以下原因:
- RFE的作用是递归地选择特征,通过多次训练模型,在每次迭代中删除贡献度最低的特征,并对剩下的特征重新计算排名
- rfe.ranking_ 提供的是所有特征经过完整RFE过程后的最终排名,而不是逐步筛选特征组合的结果
- 因此,RFE本身并不会输出类似于selection_results的表格,它的输出是特征的静态排名
- 为了得到selection_results,代码逐步添加特征,每次用当前选定的特征子集训练模型并评估其在测试集上的性能(ROC AUC 分数)
- RFE的默认行为是直接选出目标数量的特征(n_features_to_select),而不是逐步记录每一步的特征组合对模型性能的影响。因此,必须手动实现逐步特征选择的逻辑
# 将 Importance 列百分比化并归一化
selection_results['Importance'] = (
selection_results['Importance'] / selection_results['Importance'].sum()
)
selection_results
对Importance列进行百分比化和归一化的作用是将特征重要性标准化为相对比例,便于可视化时更直观地展示各特征的重要性分布,使图表更加美观和易于解读
特征贡献度与累计AUC表现的可视化(突出前n个特征)
通过柱状图和折线图可视化特征的重要性(按贡献度排序)和对应的累计AUC表现,突出展示前n_features个特征的重要性和对模型性能的影响,这里由于没有加入K折交叉验证可能导致模型性能评估依赖于单一训练-测试划分,从而无法全面衡量特征选择的稳定性和泛化能力,评估结果可能因数据分割不同而产生偏差,下面通过加入
K折交叉验证
和在可视化中展示置信区间,可以更全面衡量特征选择的稳定性和泛化能力,避免因单一数据划分导致的模型性能评估偏差
通过递归特征消除(RFE)结合随机森林模型,根据特征重要性对特征进行逐步筛选,并利用K折交叉验证评估每次筛选后的模型性能(Mean AUC),同时计算每个特征组合的AUC置信区间(95%)。在可视化部分,采用柱状图展示特征贡献度(Importance),用折线图展示累计AUC(Mean AUC),并通过红色阴影标示置信区间,突出前11个特征的重要性和性能贡献,提供更加稳健和可信的特征筛选与性能评估结果, 完整 代码与数据集获取:如需获取本文的源代码和数据集,请添加作者微信联系
往期推荐
期刊配图:SHAP可视化改进依赖图+拟合线+边缘密度+分组对比
期刊配图:多种机器学习算法结合SHAP特征贡献在递归特征选择中的运用
复现SCI文章 SHAP 依赖图可视化以增强机器学习模型的可解释性
复现 Nature 图表——基于PCA的高维数据降维与可视化实践及其扩展
复现Nature图表——基于PCA降维与模型预测概率的分类效果可视化
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考