一文讲清楚人工智能K折交叉验证

477 阅读7分钟

前言简介

K折交叉验证(K-Fold Cross-Validation)是一种常用的模型评估技术,其被广泛应用于机器学习和统计学中。它的主要目的是为了更好地评估模型的性能,避免过拟合和欠拟合。我第一次认识了解到该技术是在SMP情感分析大赛中。一支队伍使用的微调BERT模型并佐以多种小技术优化模型,其中就用到了K折交叉验证来处理对应数据集。

一、 什么是K折交叉验证

K折交叉验证是将数据集分成K个等大小的子集(folds),然后进行K次训练和测试。在每次训练和测试中,选择一个子集作为测试集,其余K-1个子集作为训练集。这样,每个子集都有一次作为测试集的机会。最终的模型性能是K次测试结果的平均值。

二、 K折交叉验证的步骤

  1. 数据集划分:将整个数据集随机分成K个等大小的子集。

  2. 循环训练和测试

    • 对于每一个子集(第 i 个子集):

      • 将第i个子集作为测试集。
      • 将剩余的K-1个子集合并作为训练集。
      • 使用训练集训练模型。
      • 使用测试集评估模型性能,并记录结果。
  3. 计算平均性能:将K次测试结果的性能指标(如准确率、F1分数、均方误差等)进行平均,得到最终的模型评估结果。

1R-C.jpg

K折交叉验证原理与结构图

三、 为什么我们选用K折交叉验证

相信有小伙伴们在刚认识这个技术的时候肯定会有一个和笔者当初也思考过的问题,那就是既然K折交叉验证是多次训练利用同一个数据集,那么此举不应该增加过拟合风险吗为何反而有减少过拟合的功能 ?

没错,K折交叉验证是在多数次地训练和利用同一个数据集,但是并不是无脑地改变参数使其对输入的数据样本僵硬化,相反,因为K折交叉验证的充分利用各部分的数据集的特性,反而能让模型更全面地学习和吸收到这个数据集中的特征,增强了模型的泛化能力,从而实现对新输入的数据进行较好地预测和分析。以下是几个原因解释为什么K折交叉验证有助于减少过拟合:

  1. 泛化能力评估:K折交叉验证通过在不同的数据子集上重复训练和测试模型,提供了对模型泛化能力的更全面评估。这意味着模型必须在多个不同的数据集上表现良好,而不仅仅是在单一的训练集上。

  2. 避免数据泄露:在K折交叉验证中,每次训练和测试都是在不同的数据子集上进行的,确保了训练数据和测试数据之间没有重叠。这有助于防止模型学习到特定于训练数据的噪声或异常值,从而减少过拟合。

  3. 稳健性:由于模型在K个不同的数据子集上进行了评估,最终的性能估计是基于所有这些评估的平均值。这种平均化过程减少了由于数据集特定特征导致的偶然性能波动,提供了一个更稳健的性能估计。

  4. 模型选择和超参数调整:K折交叉验证常用于模型选择和超参数优化。通过在不同的数据子集上评估不同模型或超参数设置的性能,可以帮助我们选择出最佳的模型配置,这通常会导致更好的泛化性能。

四、 技术实战

下面是我使用K折交叉验证的示例,使用的是scikit-learn库中的cross_val_score函数,使用的模型是随机森林:

import numpy as np
import pandas as pd
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

# 加载数据集,这里以鸢尾花数据集为例
iris = load_iris()
X = iris.data
y = iris.target

# 初始化随机森林分类器
rf = RandomForestClassifier(n_estimators=100, random_state=42)

# 设置K折交叉验证的参数
kfold = KFold(n_splits=5, shuffle=True, random_state=42)

# 使用cross_val_score进行K折交叉验证
scores = cross_val_score(rf, X, y, cv=kfold)

# 打印每次交叉验证的准确率
print("Accuracy scores for each fold:", scores)

# 计算平均准确率
average_score = np.mean(scores)
print("Average accuracy:", average_score)

在这个例子中:

  1. 加载数据集:使用sklearn.datasets中的load_iris函数加载鸢尾花数据集。

  2. 初始化模型:创建一个RandomForestClassifier实例作为分类器。

  3. 设置K折交叉验证:使用KFold类创建交叉验证分割策略,其中n_splits=5表示数据集将被分成5个子集。

  4. 执行交叉验证:使用cross_val_score函数执行K折交叉验证。cv=kfold参数指定了交叉验证的分割策略。

  5. 输出结果:打印每次交叉验证的准确率,并计算平均准确率。

最终啊,这个示例展示如何使用K折交叉验证来评估随机森林分类器在鸢尾花数据集上的性能。通过这种方法,你也可以得到模型在不同数据子集上的性能指标,从而更好地估计模型的泛化能力。

五、其他注意点

1. 不足之处

  • 计算量大:需要进行K次模型训练和测试,计算量较大,尤其是对于大数据集和复杂模型。(因此K折交叉验证推荐用于数据集较小的模型,如果你没有算力担忧,当我没说)
  • 不适用于时间序列数据:对于时间序列数据,随机划分数据集可能会破坏时间顺序,导致评估结果不准确。

2. K的选择(分隔数量)

  • 常见的K值:常用的K值有5和10。5折和10折交叉验证在实践中表现良好,计算量适中。
  • 特殊情况:在数据量较小的情况下,可以选择较大的K值(如留一法交叉验证,K等于数据集大小),但计算量会显著增加。

六. 总结

  • K折交叉验证是一种强大的模型评估技术,通过多次训练和测试,可以更稳定地评估模型的性能,减少过拟合风险。尽管计算量较大,但在实际应用中广泛使用,尤其适用于数据量适中且希望获得稳定评估结果的场景。

  • 然而,需要注意的是,K折交叉验证并不能保证完全消除过拟合,但它确实是一种有效的技术来减少过拟合的风险。此外,如果模型在K折交叉验证中的所有折上都表现出高度一致的性能,这通常是一个好的迹象,表明模型不太可能过拟合。

  • 最后,K折交叉验证的实现需要谨慎,以确保数据分割的随机性和代表性,特别是在处理不平衡数据集时,可能需要采用分层抽样等技术来确保每个折中的类别分布与整个数据集保持一致。因此,具体还是视情况而定。

素材来源: 必应图片

技术借鉴: SKLearn 中文技术社区--scikit-learn.org.cn/view/6.html

以上就是笔者关于K折交叉验证技术的总结和解释,欢迎大家点赞,收藏,交流和关注 !!!蟹蟹O(∩_∩)O谢谢!