You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于GridSearchCV与Pipeline绘制RepeatedStratifiedKFold各折及平均ROC曲线

交叉验证折ROC、平均ROC与测试集ROC的叠加绘制

核心思路

GridSearchCV默认仅保留最优参数训练的最终模型,不会存储交叉验证过程中每个折的模型与验证集预测结果。因此需要手动遍历交叉验证的每个折,用最优参数训练模型并获取验证集概率,进而计算并绘制各折ROC、平均ROC,最后叠加测试集ROC。

具体实现步骤

1. 导入依赖库与准备数据

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, RepeatedStratifiedKFold, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, auc
# 生成示例数据(替换为你的真实数据)
X, y = make_classification(n_samples=1000, n_classes=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

2. 定义Pipeline与参数网格

# 构建包含标准化与分类器的Pipeline
pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('classifier', SVC(probability=True, random_state=42))
])

# 设置参数搜索网格(替换为你的参数范围)
param_grid = {
    'classifier__C': [0.1, 1, 10],
    'classifier__kernel': ['linear', 'rbf']
}

3. 网格搜索获取最优参数

# 定义重复分层交叉验证策略
cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=42)

# 执行网格搜索,以ROC-AUC为评分标准
grid_search = GridSearchCV(pipe, param_grid, cv=cv, scoring='roc_auc', n_jobs=-1)
grid_search.fit(X_train, y_train)
best_params = grid_search.best_params_

4. 遍历交叉验证折,收集ROC数据

fprs = []  # 存储每个折的假阳性率
tprs = []  # 存储每个折的真阳性率
aucs = []  # 存储每个折的AUC值

# 遍历每个交叉验证折
for train_idx, val_idx in cv.split(X_train, y_train):
    X_tr, X_val = X_train[train_idx], X_train[val_idx]
    y_tr, y_val = y_train[train_idx], y_train[val_idx]
    
    # 用最优参数训练模型
    best_pipe = pipe.set_params(**best_params)
    best_pipe.fit(X_tr, y_tr)
    
    # 预测验证集的正类概率
    y_val_proba = best_pipe.predict_proba(X_val)[:, 1]
    
    # 计算当前折的ROC曲线与AUC
    fpr, tpr, _ = roc_curve(y_val, y_val_proba)
    roc_auc = auc(fpr, tpr)
    
    fprs.append(fpr)
    tprs.append(tpr)
    aucs.append(roc_auc)

5. 计算平均ROC曲线

由于每个折的FPR点数量不一致,需插值到统一的横坐标点上:

# 生成0到1之间的100个均匀FPR点
mean_fpr = np.linspace(0, 1, 100)

# 对每个折的TPR进行插值,匹配mean_fpr
interp_tprs = []
for fpr, tpr in zip(fprs, tprs):
    interp_tpr = np.interp(mean_fpr, fpr, tpr)
    interp_tpr[0] = 0.0  # 强制起点为(0,0)
    interp_tprs.append(interp_tpr)

# 计算平均TPR、平均AUC及标准差
mean_tpr = np.mean(interp_tprs, axis=0)
mean_tpr[-1] = 1.0  # 强制终点为(1,1)
mean_auc = auc(mean_fpr, mean_tpr)
std_auc = np.std(aucs)

6. 绘制所有ROC曲线

plt.figure(figsize=(8, 6))

# 绘制每个交叉验证折的灰色ROC曲线(低透明度避免重叠)
for fpr, tpr in zip(fprs, tprs):
    plt.plot(fpr, tpr, color='gray', alpha=0.3)

# 绘制交叉验证平均ROC曲线
plt.plot(mean_fpr, mean_tpr, color='blue', 
         label=f'交叉验证平均ROC (AUC = {mean_auc:.2f} ± {std_auc:.2f})', 
         lw=2)

# 绘制测试集ROC曲线
y_test_proba = grid_search.best_estimator_.predict_proba(X_test)[:, 1]
test_fpr, test_tpr, _ = roc_curve(y_test, y_test_proba)
test_auc = auc(test_fpr, test_tpr)
plt.plot(test_fpr, test_tpr, color='red', 
         label=f'测试集ROC (AUC = {test_auc:.2f})', 
         lw=2)

# 绘制随机猜测基准线
plt.plot([0, 1], [0, 1], color='black', linestyle='--')

# 设置图表属性
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('假阳性率(FPR)')
plt.ylabel('真阳性率(TPR)')
plt.title('ROC曲线:交叉验证折、平均与测试集')
plt.legend(loc="lower right")
plt.show()

关键说明

  • 若需要使用交叉验证过程中每个折自行搜索到的最优参数(而非全局最优参数),只需在遍历折时,针对当前折的训练数据执行GridSearchCV,再用该折的最优模型预测验证集即可。
  • 灰色曲线的透明度alpha可根据折的数量调整,折数越多则设置越小,避免画面杂乱。

内容的提问来源于stack exchange,提问作者moe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:35:28