K折交叉验证:明明只分割了训练集和测试集,为何还能提供验证集评价指标?

机器学习大数据算法

picture.image

✨ 欢迎关注Python机器学习AI ✨

本节介绍:如何理解k折交叉验证。数据采用模拟数据,作者根据个人对机器学习的理解进行代码实现与图表输出,仅供参考。

详细数据和代码将在稍后上传至交流群,付费成员可在交流群中获取下载。需要的朋友可关注公众文末提供的购买方式。

购买前请咨询,避免不必要的问题。

✨ 背景 ✨

picture.image

这里是接下来模拟实现的数据集信息,是一个五折交叉验证的示意图,图中展示了数据集如何被划分成不同的部分。可以从图示中提取出以下几个要点:

  • 训练集:数据集被划分为五个部分(如图中显示的五个绿色块最后变为黄色块)。每次训练模

型时,使用其中四个子集作为训练集,而剩下的一个子集作为验证集

  • 内部验证集:每次交叉验证中,都会使用其中一个子集作为验证集(图中的黄色块)。这个验证集用于评估模型的性能
  • 外部测试集:这部分数据(灰色块)是与交叉验证过程无关的,它用于在交叉验证完成后进行最终的测试,确保模型能够在完全未见过的数据上进行预测
  • n=179:表示总共有179个数据点被用于五折交叉验证的过程,也就是所划分的训练集样本量
  • n=77:表示在五折交叉验证之外,额外有77个数据点被用作最终的测试集

在五折交叉验证的每一轮中,模型使用训练集(四个部分)进行训练,使用验证集(一个部分)进行评估(该验证集也就是最开始划分的训练集的一部分)。这五次验证会为模型提供五个不同验证集下的评估指标,最后可以对这些评估结果进行平均,从而得到模型的平均表现。最终的测试集(外部测试集)用于检验模型在未见过的数据上的泛化能力。通过这种方式,五折交叉验证能够有效评估模型的稳定性和泛化能力,同时避免了数据划分的偶然性对评估结果的影响。

5折交叉验证(k=5) 其实就是将训练集划分为5个部分,每次用其中4个部分进行训练,剩下的1个部分作为验证集,重复这个过程5次,而k折交叉验证的“k”值是一个可调的超参数,可以是任意正整数。在k折验证中,训练集会被划分为k份,每次训练时使用k-1个子集进行训练,剩下的1个子集作为验证集,整个过程会重复k次。接下来从代码角度解读这个过程,以及为什么要用k折验证

✨ 代码实现 ✨


          
import pandas as pd
          
import numpy as np
          
import matplotlib.pyplot as plt
          
import warnings
          
warnings.filterwarnings("ignore")
          

          
# 设置 Matplotlib 的默认字体为 Times New Roman,避免乱码
          
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-3-28公众号Python机器学习AI.xlsx')
          

          
# 划分特征和目标变量
          
# X 包含所有的特征变量,去掉目标列 'y'
          
X = df.drop(['Electrical_cardioversion'], axis=1)
          

          
# y 包含目标变量,这里假设目标变量是 'y'
          
y = df['Electrical_cardioversion']
          

          
# 划分训练集和测试集
          
# train_test_split 会随机划分数据集,test_size=0.3 表示 30% 的数据用于测试集,70% 用于训练集
          
# random_state=42 保证结果可重复
          
# stratify=df['y'] 保证训练集和测试集中的目标变量比例一致
          
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, 
          
                                                    random_state=42, stratify=df['Electrical_cardioversion'])
          

          
# 输出数据集的前几行,查看拆分后的数据
          
df.head()
      

picture.image

加载数据文件,并将数据集按7:3的比例拆分为训练集和测试集,同时将目标变量与特征数据分开,为机器学习模型的训练做准备,这里的

7就是下面的n=179,3就是下面的n=77测试集

picture.image


          
from sklearn.model_selection import KFold
          
from sklearn.metrics import roc_auc_score
          
from sklearn.ensemble import RandomForestClassifier
          
# 初始化 K折交叉验证(5折交叉验证)
          
kf = KFold(n_splits=5, shuffle=True, random_state=1314520)
          

          
# 初始化一个随机森林分类器
          
model = RandomForestClassifier(random_state=42)
          

          
# 存储每一折的AUC得分
          
auc_scores = []
          

          
# 使用K折交叉验证进行训练和评估
          
for train_index, val_index in kf.split(X_train):
          
    X_train_fold, X_val_fold = X_train.iloc[train_index], X_train.iloc[val_index]
          
    y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]
          

          
    # 在当前折上训练模型
          
    model.fit(X_train_fold, y_train_fold)
          

          
    # 获取验证集的预测概率
          
    y_val_pred_prob = model.predict_proba(X_val_fold)[:, 1]
          

          
    # 计算AUC分数
          
    auc = roc_auc_score(y_val_fold, y_val_pred_prob)
          
    auc_scores.append(auc)
          
    
          
 # 绘制AUC得分的柱状图,并在柱子顶部添加连线及具体AUC值,y轴范围从0.6到1
          
plt.figure(figsize=(8, 6))
          
bars = plt.bar(range(1, 6), auc_scores, color='skyblue')
          
plt.xlabel('Fold Number', fontsize=14)
          
plt.ylabel('AUC Score', fontsize=14)
          
plt.title('AUC Scores for Each Fold of 5-Fold Cross Validation', fontsize=16)
          
plt.xticks(range(1, 6))
          

          
# 设置y轴范围
          
plt.ylim(0.6, 1)
          

          
# 在每个柱状图顶部添加AUC值和连线
          
for i, bar in enumerate(bars):
          
    yval = bar.get_height()
          
    plt.text(bar.get_x() + bar.get_width() / 2, yval + 0.01, round(yval, 3), ha='center', va='bottom', fontsize=12)
          
    if i > 0:
          
        plt.plot([bars[i-1].get_x() + bars[i-1].get_width() / 2, bar.get_x() + bar.get_width() / 2],
          
                 [auc_scores[i-1], yval], color='black', linestyle='--', linewidth=1)
          

          
plt.tight_layout()
          
plt.show()   
      

picture.image

使用5折交叉验证和随机森林模型对训练集进行评估,计算每一折的AUC得分,并绘制柱状图,显示每一折的AUC值,同时在柱子顶部添加AUC得分和连线,以便直观比较不同折的AUC表现。结果显示了5折交叉验证中的AUC得分,并通过图表直观展示了每一折的得分变化。

可以发现,虽然模型的参数没有变化,但由于K折交叉验证中验证集不断变化,导致每一折的AUC值有所不同。这说明数据集的分割会影响模型的性能。我们不希望通过调整数据集的分割(如随机种子调参)来获得最优性能这是错误的,因为理想的模型应当在不同的分割情况下表现稳定。因此,K折交叉验证的结果最后通过各折的评价指标均值来评估,而不仅仅是单独观察每一折的表现,所以会发现k折交叉验证往往结合网格搜索实现


          
from sklearn.model_selection import GridSearchCV, KFold
          
from sklearn.metrics import roc_auc_score, make_scorer
          

          
# 定义超参数搜索空间
          
param_grid = {
          
    'n_estimators': [100, 200],
          
    'max_depth': [None, 5, 10],
          
    'min_samples_split': [2, 5],
          
    'min_samples_leaf': [1, 2]
          
}
          

          
# 设置AUC作为评分标准
          
auc_scorer = make_scorer(roc_auc_score, needs_proba=True)
          

          
# 初始化模型
          
model = RandomForestClassifier(random_state=42)
          

          
# 定义K折交叉验证
          
kf = KFold(n_splits=5, shuffle=True, random_state=1314520)
          

          
# 使用GridSearchCV进行网格搜索和交叉验证
          
grid_search = GridSearchCV(estimator=model,
          
                           param_grid=param_grid,
          
                           scoring=auc_scorer,
          
                           cv=kf,
          
                           n_jobs=-1,  # 并行加速
          
                           verbose=1)
          

          
# 拟合模型
          
grid_search.fit(X_train, y_train)
          

          
# 输出最优参数和对应的AUC分数
          
print("最优参数:", grid_search.best_params_)
          
print("最优AUC得分:", grid_search.best_score_)
      

picture.image

使用网格搜索结合5折交叉验证,以AUC作为评分标准,在给定的超参数组合中找到使平均AUC得分最高的随机森林模型最优参数组合;最优参数是通过遍历所有参数组合,并在每一组合下进行K折交叉验证后,选取平均AUC得分最高的那组参数

所以通过以上代码就能了解到K折交叉验证的作用是通过将数据集划分为多个折,轮流作为训练集和验证集进行模型训练和评估,从而减少因单一数据分割带来的偶然性影响,全面而稳定地评估模型的泛化能力。这种方法帮助我们更准确地了解模型在不同数据划分下的表现,并在模型调参时避免过拟合,最终选择出在多次验证中都能稳定表现的最优参数

✨ 该文章案例 ✨

picture.image

在上传至交流群的文件中,像往期文章一样,将对案例进行逐步分析,确保读者能够达到最佳的学习效果。内容都经过详细解读,帮助读者深入理解模型的实现过程和数据分析步骤,从而最大化学习成果。

同时,结合提供的免费AI聚合网站进行学习,能够让读者在理论与实践之间实现融会贯通,更加全面地掌握核心概念。

✨ 购买介绍 ✨

本节介绍到此结束,有需要学习数据分析和Python机器学习相关的朋友欢迎到 淘宝店铺:Python机器学习AI,或添加作者微信deep_ML联系 ,购买作者的公众号合集。截至目前为止,合集已包含200多篇文章,购买合集的同时,还将提供免费稳定的AI大模型使用,包括但不限于ChatGPT、Deepseek、Claude等。

更新的内容包含数据、代码、注释和参考资料。

作者仅分享案例项目,不提供额外的答疑服务。项目中将提供详细的代码注释和丰富的解读,帮助您理解每个步骤

购买前请咨询,避免不必要的问题。

✨ 群友反馈 ✨

picture.image

✨ 淘宝店铺 ✨

picture.image

请大家打开淘宝扫描上方的二维码,进入店铺,获取更多Python机器学习和AI相关的内容,或者添加作者微信 deep_ML联系

避免淘宝客服漏掉信息

,希望能为您的学习之路提供帮助!

往期推荐

GeoShapley算法:基于地理数据的Shapley值在空间效应测量中的应用——位置重要性与特征交互作用分析

期刊配图:基于‘UpSet图’展示不同数据预处理对模型性能的影响

期刊配图:结合残差分析的模型预测性能可视化

J Clean Prod:结合K-means聚类确定样本分组方式再结合shap初步解释模型的模拟实现

文献配图:如何通过雷达图全面评估机器学习模型的预测性能

nature communications:结合LightGBM特征选择与RF模型的机器学习方法及SHAP解释

期刊配图:SHAP特征重要性与相关系数的联合可视化

期刊配图:结合lightgbm回归模型与K折交叉验证的特征筛选可视化

Nature新算法:准确的小数据预测与表格基础模型TabPFN分类实现及其模型解释

Nature新算法:准确的小数据预测与表格基础模型TabPFN回归实现及其模型解释

picture.image

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
大规模高性能计算集群优化实践
随着机器学习的发展,数据量和训练模型都有越来越大的趋势,这对基础设施有了更高的要求,包括硬件、网络架构等。本次分享主要介绍火山引擎支撑大规模高性能计算集群的架构和优化实践。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论