背景
机器学习和深度学习的应用中,评估模型的性能至关重要,模型的表现对实际应用有着直接影响,为了全面了解模型在不同群体中的表现,可以通过亚组分析来进行更加细致的评估
本期内容,如何使用ROC曲线来展示不同亚组对模型性能的影响。通过亚组分析,可以清晰地看到模型在各类群体中的分类效果,帮助识别哪些群体是模型的强项,哪些则可能是模型的弱项
参考图示:图表c(来源于LUNAI-fCT测试数据集的亚组分析)展示了不同亚组(吸烟状态、年龄、治疗阶段等)对模型性能的影响。图中清晰地反映了每个亚组在预测模型中取得的AUC和其置信区间,提供了在不同群体中模型表现的直观对比
从图中可以看到,随着不同亚组的引入,模型的AUC有所变化,揭示了在不同组别下模型表现的细微差异
代码实现
模型构建
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
import warnings
# 忽略所有警告
warnings.filterwarnings("ignore")
from sklearn.model_selection import train_test_split
df = pd.read_excel('2025-1-24公众号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'])
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV, StratifiedKFold
from sklearn.metrics import accuracy_score
# 定义 XGBoost 二分类模型
model_xgb = XGBClassifier(use_label_encoder=False, eval_metric='logloss', random_state=8)
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1, 0.2],
'subsample': [0.8, 1.0],
'colsample_bytree': [0.8, 1.0]
}
# 定义 K 折交叉验证 (Stratified K-Fold)
kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=8)
# 使用网格搜索寻找最佳参数
grid_search = GridSearchCV(estimator=model_xgb, param_grid=param_grid, scoring='accuracy',
cv=kfold, verbose=1, n_jobs=-1)
# 拟合模型
grid_search.fit(X_train, y_train)
# 使用最优参数训练模型
xgboost = grid_search.best_estimator_
使用XGBoost进行二分类模型训练,采用网格搜索(GridSearchCV)和5折交叉验证(StratifiedKFold)来调优模型的超参数,并在训练集上找到最佳的超参数配置
模型测试集ROC绘制
# 预测测试集的概率
y_test_score = xgboost.predict_proba(X_test)[:, 1]
# 计算测试集的 ROC 曲线
fpr_test, tpr_test, _ = roc_curve(y_test, y_test_score)
roc_auc_test, ci= compute_auc_with_ci(y_test, y_test_score)
# 获取测试集样本数量
n_samples_test = X_test.shape[0]
# 绘制测试集 ROC 曲线
plt.figure(dpi=1200)
plt.plot(fpr_test, tpr_test, color='red', lw=2, label=f'ECG-SMART (AUC = {roc_auc_test:.3f}, CI = [{ci[0]:.3f}, {ci[1]:.3f}])', alpha=0.6)
plt.plot([0, 1], [0, 1], color='gray', lw=2, linestyle='--')
plt.xlim([-0.02, 1.02])
plt.ylim([-0.02, 1.02])
plt.xlabel('1 - Specificity')
plt.ylabel('Sensitivity')
plt.title(f'XGBoost: Testing set (n = {n_samples_test})')
plt.legend(loc="lower right")
plt.savefig('test_roc.pdf', format='pdf', bbox_inches='tight')
plt.show()
使用compute_auc_with_ci自定义函数计算测试集的 AUC 值和置信区间,并绘制ROC曲线,显示模型在测试集上的表现及其AUC和置信区间
亚组ROC绘制
# 分组:X_1 > 60 和 X_1 <= 60
group_older = X_test[X_test['X_1'] > 60]
group_younger = X_test[X_test['X_1'] <= 60]
# 预测每一组的概率
y_test_score_older = xgboost.predict_proba(group_older)[:, 1]
y_test_score_younger = xgboost.predict_proba(group_younger)[:, 1]
# 计算每一组的 ROC 曲线和 AUC
fpr_older, tpr_older, thresholds_older = roc_curve(y_test[group_older.index], y_test_score_older)
roc_auc_older, ci_older = compute_auc_with_ci(y_test[group_older.index], y_test_score_older)
fpr_younger, tpr_younger, thresholds_younger = roc_curve(y_test[group_younger.index], y_test_score_younger)
roc_auc_younger, ci_younger = compute_auc_with_ci(y_test[group_younger.index], y_test_score_younger)
# 计算每组的样本量
n_older = len(group_older)
n_younger = len(group_younger)
# 绘制 ROC 曲线
plt.figure(dpi=1200)
# 绘制 X_1 <= 60 的 ROC 曲线
plt.plot(fpr_younger, tpr_younger, color='green', lw=2,
label=f'Age ≤ 60: AUC = {roc_auc_younger:.3f} (95%CI: {ci_younger[0]:.3f}-{ci_younger[1]:.3f}) n = {n_younger}', marker='o')
# 绘制 X_1 > 60 的 ROC 曲线
plt.plot(fpr_older, tpr_older, color='blue', lw=2,
label=f'Age > 60: AUC = {roc_auc_older:.3f} (95%CI: {ci_older[0]:.3f}-{ci_older[1]:.3f}) n = {n_older}', marker='o')
# 绘制随机猜测的对角线,并加入图例
plt.plot([0, 1], [0, 1], color='gray', lw=2, linestyle='--', label='Random Guessing')
plt.xlim([-0.02, 1.02])
plt.ylim([-0.02, 1.02])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title(f'XGBoost: ROC Curve by Age Group')
plt.legend(loc="lower right")
plt.savefig('age_group_roc.pdf', format='pdf', bbox_inches='tight')
plt.show()
根据年龄(大于60岁和小于等于60岁)对测试集进行分组,分别计算每组的 ROC 曲线和 AUC 值,并绘制带有图例的 ROC 曲线图,同时显示每组的 AUC、置信区间和样本量信息
当分组信息不直接包含在模型的输入特征中时,仍然可以根据外部条件或样本的索引对测试集进行分组。例如,可以根据一些额外的规则(如年龄、大于某个特定值的特征、或者其他外部信息)来划分测试集中的样本。通过这种方法,可以在没有显式分组特征的情况下,根据样本的索引来对测试集进行分组,并绘制每个组别的ROC曲线,评估模型在不同群体中的表现
往期推荐
聚类与解释的结合:利用K-Means聚类辅助SHAP模型解释并可视化
期刊配图:SHAP可视化改进依赖图+拟合线+边缘密度+分组对比
期刊配图:SHAP蜂巢图与柱状图多维组合解读特征对模型的影响
基于mRMR筛选和递归特征选择的多模型性能评估与AUC可视化对比
期刊配图:SHAP可视化进阶蜂巢图与特征重要性环形图的联合展示方法
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考