如何配置k折交叉验证

k 折交叉验证程序是估计机器学习算法在数据集上性能的标准方法。

k 的常见值为 10,但我们如何知道这个配置适合我们的数据集和算法呢?

一种方法是探索不同 k 值对模型性能估计的影响,并将其与理想测试条件进行比较。这有助于选择合适的 k 值。

一旦选择了 k 值,就可以用它来评估数据集上的一系列不同算法,并将结果的分布与使用理想测试条件评估同一算法的结果进行比较,以查看它们是否高度相关。如果相关,则证明所选配置是理想测试条件的稳健近似。

在本教程中,您将了解如何配置和评估 k 折交叉验证的配置。

完成本教程后,您将了解:

  • 如何使用 k 折交叉验证在数据集上评估机器学习算法。
  • 如何对 k 折交叉验证的 k 值进行敏感性分析。
  • 如何计算交叉验证测试设备与理想测试条件之间的相关性。

开始您的项目,阅读我的新书 Machine Learning Mastery With Python,其中包含分步教程和所有示例的Python源代码文件。

让我们开始吧。

How to Configure k-Fold Cross-Validation

如何配置k折交叉验证
照片由 Patricia Farrell 拍摄,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. k折交叉验证
  2. k 的敏感性分析
  3. 测试设备与目标的关联度

k折交叉验证

通常使用 k 折交叉验证在数据集上评估机器学习模型。

k 折交叉验证程序将有限的数据集划分为 k 个不重叠的折。k 折中的每一折都有机会被用作保留的测试集,而所有其他折则共同用作训练数据集。总共拟合和评估 k 个模型在 k 个保留的测试集上,并报告平均性能。

有关 k 折交叉验证程序的更多信息,请参阅教程

k 折交叉验证程序可以使用 scikit-learn 机器学习库轻松实现。

首先,让我们定义一个可用于本教程的合成分类数据集。

可以使用 make_classification() 函数 创建一个合成二元分类数据集。我们将配置它生成 100 个样本,每个样本有 20 个输入特征,其中 15 个与目标变量相关。

以下示例创建并总结了数据集。

运行示例将创建数据集并确认它包含 100 个样本和 10 个输入变量。

伪随机数生成器的固定种子确保我们每次生成数据集时都能获得相同的样本。

接下来,我们可以使用 k 折交叉验证在此数据集上评估模型。

我们将评估 LogisticRegression 模型,并使用 KFold 类来执行交叉验证,配置为随机打乱数据集并将 k 设置为 10,这是一个流行的默认值。

将使用 cross_val_score() 函数来执行评估,该函数接受数据集和交叉验证配置,并返回为每个折计算的分数列表。

完整的示例如下所示。

运行示例将创建数据集,然后使用 10 折交叉验证在其上评估逻辑回归模型。然后报告数据集上的平均分类准确率。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能不同。考虑运行几次示例并比较平均结果。

在这种情况下,我们可以看到该模型达到了约 85.0% 的估计分类准确率。

现在我们熟悉了 k 折交叉验证,让我们看看如何配置该过程。

k 的敏感性分析

k 折交叉验证的关键配置参数是 k,它定义了将给定数据集分割成的折数。

常见值为 k=3、k=5 和 k=10,在应用机器学习中用于评估模型的最流行值是 k=10。原因是进行了研究,发现 k=10 在计算成本低和模型性能估计偏差低之间取得了良好的权衡。

在评估我们自己的数据集上的模型时,我们如何知道使用哪个 k 值?

您可以选择 k=10,但您如何知道这对您的数据集有意义?

回答这个问题的一种方法是执行不同 k 值的敏感性分析。也就是说,使用不同的 k 值在相同数据集上评估同一模型的性能,并查看它们的比较情况。

期望的是,低 k 值将导致模型性能估计出现噪声,而高 k 值将导致模型性能估计的噪声更少。

但与什么相比的噪声?

我们不知道模型在对新/未见过的数据进行预测时的真实性能,因为我们无法访问新/未见过的数据。如果我们能做到,我们将在模型评估中使用它。

尽管如此,我们可以选择一个测试条件,该条件代表模型性能的“理想”或我们能达到的最佳“理想”估计。

一种方法是使用所有可用数据训练模型,并在一个单独的大型且具有代表性的保留数据集上估算性能。在此保留数据集上的性能将代表模型的“真实”性能,并且训练数据集上的任何交叉验证性能都将代表此分数的一个估计。

这很少可能,因为我们通常没有足够的数据将其一部分保留并用作测试集。Kaggle 机器学习竞赛是此的一个例外,在这种竞赛中,我们确实有一个保留的测试集,其中一部分通过提交进行评估。

相反,我们可以使用留一法交叉验证 (LOOCV) 来模拟这种情况,LOOCV 是一种计算成本很高的交叉验证版本,其中k=N,而N是训练数据集中的总示例数。也就是说,训练集中的每个样本都被单独用作测试评估数据集。它很少用于大型数据集,因为它计算成本很高,尽管它可以提供模型在给定可用数据上的良好性能估计。

然后,我们可以将不同 k 值的平均分类准确率与同一数据集上的 LOOCV 的平均分类准确率进行比较。分数之间的差异提供了 k 值如何近似理想模型评估测试条件的粗略代理。

让我们探讨一下如何实现 k 折交叉验证的敏感性分析。

首先,让我们定义一个创建数据集的函数。这样,如果您愿意,可以更改数据集。

接下来,我们可以定义一个函数来创建要评估的模型。

同样,这种分离允许您在需要时更改模型。

接下来,您可以定义一个函数来根据测试条件在数据集上评估模型。测试条件可以是配置了给定 k 值的 KFold 实例,也可以是我们理想测试条件的 LeaveOneOut 实例。

该函数返回平均分类准确率以及折的最小和最大准确率。我们可以使用最小和最大值来汇总分数分布。

接下来,我们可以使用 LOOCV 程序计算模型的性能。

然后我们可以定义要评估的 k 值。在这种情况下,我们将测试 2 到 30 之间的值。

然后我们可以逐个评估每个值并将结果存储起来。

最后,我们可以绘制结果以供解释。

将这些结合起来,完整的示例列在下面。

运行示例首先报告 LOOCV,然后报告每个 k 值的平均值、最小值和最大值。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能不同。考虑运行几次示例并比较平均结果。

在这种情况下,我们可以看到 LOOCV 的结果约为 84%,略低于 k=10 的结果 85%。

创建一个线图,将平均准确率分数与 LOOCV 结果进行比较,并使用误差线指示每个结果分布的最小和最大值。

结果表明,对于此数据集上的此模型,大多数 k 值低估了模型与理想情况相比的性能。结果表明,k=10 可能略微乐观,而 k=13 可能是更准确的估计。

Line Plot of Mean Accuracy for Cross-Validation k-Values With Error Bars (Blue) vs. the Ideal Case (red)

线图:交叉验证 k 值的平均准确率(带误差线,蓝色)与理想情况(红色)

这提供了一个模板,您可以使用它来对所选模型在数据集上相对于给定理想测试条件的 k 值的敏感性进行分析。

测试设备与目标的关联度

一旦选择了测试设备,另一个考虑因素是它在不同算法中与理想测试条件的匹配程度。

对于某些算法和某些配置,k 折交叉验证可能比其他算法和算法配置更接近理想测试条件。

我们可以明确地评估和报告这种关系。这可以通过计算一系列算法的 k 折交叉验证结果与同一算法在理想测试条件上的评估的匹配程度来实现。

可以计算两组分数之间的皮尔逊相关系数来衡量它们有多接近。也就是说,它们是否以相同的方式一起变化:当一种算法通过 k 折交叉验证看起来优于另一种算法时,这在理想测试条件上也成立吗?

我们期望看到分数之间存在很强的正相关,例如 0.5 或更高。低相关性表明需要更改 k 折交叉验证测试设备以更好地匹配理想测试条件。

首先,我们可以定义一个函数,该函数将创建一系列标准机器学习模型,以通过每个测试设备进行评估。

我们将 k=10 用于选择的测试设备。

然后我们可以枚举每个模型,并使用 10 折交叉验证和我们的理想测试条件(在本例中为 LOOCV)对其进行评估。

然后,我们可以计算 10 折交叉验证测试设备中的平均分类准确率与 LOOCV 测试设备之间的相关性。

最后,我们可以创建两个结果集散点图,并绘制最佳拟合线,以直观地了解它们如何协同变化。

将所有这些联系在一起,完整的示例如下。

运行示例会报告通过每种测试平台计算出的每种算法的平均分类准确率。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能不同。考虑运行几次示例并比较平均结果。

您可能会看到一些可以安全忽略的警告,例如

我们可以看到,对于某些算法,与留一法交叉验证相比,测试平台高估了准确率,而在其他情况下,它低估了准确率。这是可以预期的。

在运行结束时,我们可以看到报告了两个结果集之间的相关性。在这种情况下,我们可以看到报告了 0.746 的相关性,这是一个良好且强的正相关。结果表明,如通过 18 种流行机器学习算法计算所示,10 折交叉验证确实为该数据集上的留一法交叉验证测试平台提供了良好的近似。

最后,创建了散点图,比较了测试平台(x 轴)的平均准确率得分分布与留一法交叉验证(y 轴)的准确率得分。

绘制了一条红色的最佳拟合线,显示了强烈的线性相关性。

Scatter Plot of Cross-Validation vs. Ideal Test Mean Accuracy With Line of Best Fit

交叉验证与理想测试平均准确率散点图及最佳拟合线

这提供了一个平台,用于将您选择的测试平台与您自己数据集上的理想测试条件进行比较。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

教程

API

文章

总结

在本教程中,您学习了如何配置和评估 k 折交叉验证的配置。

具体来说,你学到了:

  • 如何使用 k 折交叉验证在数据集上评估机器学习算法。
  • 如何对 k 折交叉验证的 k 值进行敏感性分析。
  • 如何计算交叉验证测试设备与理想测试条件之间的相关性。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

发现 Python 中的快速机器学习!

Master Machine Learning With Python

在几分钟内开发您自己的模型

...只需几行 scikit-learn 代码

在我的新电子书中学习如何操作
精通 Python 机器学习

涵盖自学教程端到端项目,例如
加载数据可视化建模调优等等...

最终将机器学习带入
您自己的项目

跳过学术理论。只看结果。

查看内容

对“如何配置 k 折交叉验证”的 49 条回复

  1. Quentin Python 2020 年 7 月 31 日下午 5:29 #

    再次感谢,这是一篇非常好的教程!

    但是,在比较具有不同 n_splits 值的 kfold 结果时,我强烈建议使用除此处使用的误差以外的其他误差。
    代码行是框中的第 52 行,该框以“# sensitivity analysis of k in k-fold cross-validation”开头。
    事实上,正如您目前使用的 yerr=[mins, maxs] 一样,误差线的长度倾向于随着 n_splits 值的增加而增加,而我认为它实际上应该倾向于减小。我认为使用类似 yerr =[mean-std, mean+std] 的东西会更合适。如果您认为我错了,请告诉我。

  2. Mohamed 2020 年 8 月 1 日下午 6:34 #

    有可能解释强化学习吗?

  3. dexter 2020 年 8 月 5 日下午 12:02 #

    你好 Jason,

    这是否可以用于像 lstm 这样的时间序列方法?

  4. Anthony The Koala 2020 年 8 月 18 日晚上 10:09 #

    尊敬的Jason博士,
    在最后一个示例中,除了模型的平均值之外,

    我还计算了理想和交叉验证分数的标准差。

    结果和模型摘要,基于理想分数和交叉验证分数的标准差和平均值的最小/最大值

    结论
    可以看出,SVC 是模型的首选,其平均理想值为 0.9,交叉验证值为 0.80。相应的理想标准差为 0.3,交叉验证为 0.087。

    根据交叉验证分数的最小变异性,KFold 的变异性最小,为 0.087,而留一法交叉验证的变异性为 0.3。

    因此,对于该数据集,SVC 使用 KFold 交叉验证分数是最佳选择。

    谢谢你,
    悉尼的Anthony

  5. nkm 2020 年 8 月 21 日上午 1:22 #

    Jason先生您好,

    感谢您的大力支持。

    我想问一下,如何使用 keras 中的 Imagedatagenerator 和 flow from directory 执行 k 折交叉验证?任何示例代码都能更清楚地理解。请指导。

    此致
    nkm

    • Jason Brownlee 2020 年 8 月 21 日上午 6:32 #

      抱歉,我没有结合这两种方法的示例——我认为它们不兼容。

  6. Rabiah 2020 年 11 月 21 日上午 1:45 #

    嗨 Jason,您是否为每种超参数的可能组合运行 k 的敏感性分析?例如

    对于所有可能的超参数
    运行 Loocv
    运行 k 的敏感性分析

    谢谢 🙂

    • Jason Brownlee 2020 年 11 月 21 日上午 6:43 #

      不,使用 10。

      本教程旨在帮助您理解为什么在大多数情况下我们选择 3、5 或 10。

  7. Thomas 2020 年 12 月 14 日上午 8:38 #

    您好,谢谢 🙂

    我想知道,您是否对每个算法使用相同的“cv”对象?这是否意味着,在训练每个算法时(当您使用 cross_val_score() 时),训练/测试的拆分是每次都完全相同的?

    也就是说,逻辑回归将与高斯朴素贝叶斯等进行相同的 10 折训练和测试,对吗?

    谢谢你

    • Jason Brownlee 2020 年 12 月 14 日下午 1:35 #

      好问题。

      我想您说得对,为每个模型重新创建对象会更清晰。为了安全起见,我建议进行此更改。

  8. Paniz 2021 年 4 月 13 日上午 3:05 #

    嗨,Jason,

    感谢您提供的精彩教程和直觉。我在一个具有大约 1500 个特征(少于 10k 条记录)的数据集上试用了您的代码,它非常慢……我的意思是,处理了几天。所以我想知道我是否应该做些不同的事情,或者……它不适用于这样的数据集。谢谢

  9. The geek 2021 年 5 月 14 日上午 10:08 #

    您好,当您在每次 k 迭代中打印每个 k 的准确率时,您正在运行 k 折。这意味着总共有 k*k 折,而不仅仅是 k 折,对吗?如果我的问题有意义的话。

  10. Mohit 2021年6月2日凌晨1:22 #

    你好Jason,请告诉我,当我们使用k折交叉验证标准时,是否需要将模型拟合到完整的X和Y数据上,而不是将其拆分为训练集和测试集,对吗?其次,我在一些文章中看到人们在cross_val_score中使用xtrain和ytrain,而不是x和y,这有什么逻辑吗?

    • Jason Brownlee 2021年6月2日凌晨5:44 #

      是的,k折交叉验证用于替代训练/测试拆分。

      也许可以问问你正在阅读的其他教程的作者他们的原因。

  11. Bareera 2021年6月3日凌晨4:11 #

    如果我使用5折,我能从每一折中获得最大的测试准确率,然后将这5个最大准确率的平均值作为我的最终分数用于深度神经网络吗?

  12. ALEXIS MACHADO 2021年6月4日下午12:53 #

    你好,
    感谢这篇精彩的文章和整个博客!

    我仍然不确定我们是否应该使用LOOCV作为“地面真实”(即理想测试)来定义我们的最佳k。我特别困惑的是“结果表明,也许k=10本身有点乐观,而k=13可能是一个更准确的估计。”

    1)当我查看k=7的图表时,很难得出结论。在我看来,所有平均分数都接近红色曲线,并且显示出很大的变异性。

    2)由于我们没有显示LOOCV得分的最小值/最大值,所以我们不知道我们的模型(即ML方法+参数化)是否稳定(即使在这里可能不是这种情况)。

    此致 Alexis

    • Jason Brownlee 2021年6月5日凌晨5:22 #

      不客气。

      同意,这只是一个地面真实的方法。

  13. Swati Matwankar Shah 2021年7月5日下午2:48 #

    你好 Jason,

    非常感谢“machinelearningmastery.com”上的精彩系列文章。

    我正在使用python sci-kit learn进行信号处理实验。我有一个详细的问题,涉及到K折交叉验证和后续预测的多个步骤。我将在下面描述它们。

    我有8640个信号数据样本,我将其分为训练集(70%)和验证集(30%)。这给了我6048个训练样本和2592个验证样本。我将验证样本进一步细分——2500个样本用于K折交叉验证,92个样本作为未见过/实时信号。我的最终目标是正确预测所有92个未见过/实时样本。

    我将在下面提供一个代码片段。

    estimator = KerasClassifier(build_fn=lambda: model, epochs=350, batch_size=32, verbose=1)
    estimator.fit(X_train, Y_train) //这是6048个样本

    kfold = KFold(n_splits=10, shuffle=True)
    results = cross_val_score(estimator, X_test[0:2500,:], Y_test[0:2500], cv=kfold)
    print(“Accuracy: %.2f%% (%.2f%%)” % (results.mean()*100, results.std()*100))

    predictions = estimator.predict(X_test[2400:2492,:]) #这些是已经用于K折的测试样本
    print(predictions)

    predictions-2 = estimator.predict(X_test[2500:2592,:]) #这些是完全未见过的样本
    print(predictions-2)

    我的结果是
    1.准确率(K折交叉验证)= 70%
    2.准确率的标准差 = 29%
    3.从2400到2492的所有样本都已正确预测
    4.在2500到2592的样本中,只有12个样本被正确预测。

    我想知道,是不是我理解错了什么。为什么只有少数未见过的样本被正确预测,即使所有用于K折的样本都已正确预测?

    此致,
    斯瓦蒂。

    • Jason Brownlee 2021年7月6日凌晨5:47 #

      也许选择的测试框架不适合您的数据,您可以尝试其他配置?

      也许您正在使用的模型或数据准备对您的数据不是最有效的,也许您可以探索其他替代方案?

  14. Matvei Ts 2021年8月18日凌晨2:48 #

    好文!

    另外,我对这一行有点困惑,

    ´´´scores = cross_val_score(model, X, y, scoring=’accuracy’, cv=cv, n_jobs=-1)`

    我认为这模糊了k折交叉验证的功能和实际用法,并限制了代码的可定制性。
    所以我做了一些代码修改,以展示一个执行相同任务的“分步手动方法”。
    希望它能有所帮助。
    这是我的建议

    ´´´
    # 导入 ———————————————————————-
    import numpy as np # Math, Stat and Linear Algebra python library
    from sklearn.datasets import make_classification # Random generator for classification data
    from sklearn.model_selection import KFold # k-Fold module
    from sklearn.model_selection import cross_val_score # k-Fold Cross Validation fully automated module
    from sklearn.linear_model import LogisticRegression # Model: Logistic Regression module

    # 参数 ——————————————————————-
    k = 10 # 折数 (k折交叉验证中的“k”值)
    n_samples = 100 # 样本数
    n_features = 20 # 数据特征数

    # 定义数据集 —————————————————————
    X, y = make_classification(n_samples=n_samples, n_features=n_features, n_informative=15, n_redundant=5, random_state=1)
    # X的形状为(100, 20),y的形状为(100,)
    # -> X包含浮点数值
    # -> y仅包含0或1值
    # -> 示例:X_i -> y_i := [1.123, … , 0.123123] -> 0或1

    # 初始化逻辑回归模型和KFold ——————————————
    model = LogisticRegression()
    kfold = KFold(n_splits=k, random_state=1, shuffle=True)

    # 学习和k折交叉验证:全自动化 ———————————————
    # -> 所有操作都由sklearn模块“cross_val_score”完成
    scores = cross_val_score(model, X, y, scoring=’accuracy’, cv=kfold, n_jobs=-1)
    print(“全自动化方法: “)
    print(” 准确率: μ = {0}, σ = {1}”.format( round(np.mean(scores), 3), round(np.std(scores),3) ))

    # 学习和k折交叉验证:手动 ———————————————
    # -> k折交叉验证过程的分步分解
    scores = []
    for train_index, test_index in kfold.split(X)
    # 定义k折的测试和训练数据
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    # 在训练数据上训练逻辑回归模型
    model.fit(X_train, y_train)
    # 使用训练好的模型预测测试数据上的输出(y)
    y_pred = model.predict(X_test)
    # 计算模型在测试数据上的准确率
    n_correct_values = sum([ p == t for p, t in zip(y_pred, y_test) ])
    accuracy = n_correct_values / len(y_pred)
    scores.append(accuracy)
    scores = np.array(scores)
    print(“手动方法: “)
    print(” 准确率: μ = {0}, σ = {1}”.format( round(np.mean(scores), 3), round(np.std(scores),3) ))
    ´´´

    PS:我不知道如何在此网站上发布python代码。非常抱歉。

    • Adrian Tam
      Adrian Tam 2021年8月18日凌晨3:33 #

      我没有检查你的代码,但谢谢你的建议。

  15. ALI AHMED 2021年9月2日晚上8:12 #

    为什么(KFOLD)在执行时显示相同的结果?

    import os
    import time
    import re
    #import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from tqdm import tqdm

    from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
    from sklearn import preprocessing
    from sklearn.model_selection import train_test_split, StratifiedKFold, KFold

    from sklearn.naive_bayes import MultinomialNB
    from sklearn.linear_model import SGDClassifier
    from sklearn.linear_model import LogisticRegression
    from sklearn.svm import LinearSVC
    from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier

    from sklearn.metrics import classification_report
    from sklearn.metrics import confusion_matrix
    from sklearn.metrics import plot_confusion_matrix
    from sklearn.metrics import precision_recall_fscore_support as score

    df = pd.read_excel(‘/content/arabic (7).xlsx’)
    df.head()
    x = df[‘text’]
    y = df[‘sen’]

    from sklearn.feature_extraction.text import CountVectorizer
    count_vect = CountVectorizer()
    X_train_counts = count_vect.fit_transform(x)
    X_train_counts.shape
    from sklearn.feature_extraction.text import TfidfTransformer
    tfidf_transformer = TfidfTransformer()

    X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
    X_train_tfidf.shape
    from sklearn.preprocessing import LabelEncoder
    df=df.dropna()
    le=LabelEncoder()
    df[‘sen’]=le.fit_transform(df[‘sen’])
    df.head()
    y=df[‘sen’]
    model =LinearSVC()
    fold_no=10
    K=10
    skf = StratifiedKFold(n_splits=10)
    def training(train, test, fold_no)

    x_train = X_train_tfidf
    y_train=y
    x_test = X_train_tfidf
    y_test =y
    model.fit(x_train, y_train)
    score = model.score(x_test,y_test)
    print(‘For Fold {} the accuracy is {}’.format(str(fold_no),score))

    fold_no = 1
    acc_score = []
    for train_index,test_index in skf.split(x, y)
    train = df.iloc[train_index,:]
    test = df.iloc[test_index,:]
    training(train, test, fold_no)
    fold_no += 1

    ———-OUTPUT———-
    For Fold 1 the accuracy is 0.9251433994965543
    For Fold 2 the accuracy is 0.9251433994965543
    For Fold 3 the accuracy is 0.9251433994965543
    For Fold 4 the accuracy is 0.9251433994965543
    For Fold 5 the accuracy is 0.9251433994965543
    For Fold 6 the accuracy is 0.9251433994965543
    For Fold 7 the accuracy is 0.9251433994965543
    For Fold 8 the accuracy is 0.9251433994965543
    For Fold 9 the accuracy is 0.9251433994965543
    For Fold 10 the accuracy is 0.9251433994965543

    • Jason Brownlee 2021年9月3日凌晨5:31 #

      也许您的问题很简单,或者您的代码有错误。

  16. nkm 2021年11月23日晚上10:27 #

    感谢Jason博士的精彩博客。您能否帮助实现两个输入和一个输出的K折交叉验证?我的实现如下所示

    num_folds = 5
    kfold = StratifiedKFold(n_splits=num_folds, shuffle=True)
    for IDs_Train, IDs_Test in kfold.split(X_CXR,y_CXR)

    X1_train_cv, X2_train_cv = X_CT[IDs_Train], X_CXR[IDs_Train]
    y1_train_cv = y_CT[IDs_Train]

    X1_test_cv, X2_test_cv = X_CT[IDs_Test], X_CXR[IDs_Test]
    y1_test_cv = y_CT[IDs_Test]

    此外,我在model.fit中使用了validation_split = 0.2

    问题:我的验证准确率在初始的许多迭代中保持为0,并且增长非常缓慢,导致过拟合,尽管它在单折实现中没有过拟合(取得了良好的测试准确率)。

    恳请指导。

    此致

    • Adrian Tam
      Adrian Tam 2021年11月24日晚上1:08 #

      为什么不先将两个输入合并到一个数组或DataFrame中,然后再应用StratifiedKFold?

      • nkm 2021年11月25日晚上4:38 #

        感谢您的快速回复。它帮助很大。非常感谢。

  17. nkm 2021年11月28日凌晨3:02 #

    你好Adrian博士,

    我还有另一个疑问。当我进行5折交叉验证时,我是否需要为每一折重新初始化模型/网络的权重?我注意到,随着它从第一折进展到最后一折,过拟合会增加,这可能是由于权重溢出到下一折。

    如果答案是肯定的,我该如何做到?

    谢谢并致以问候

    • Adrian Tam
      Adrian Tam 2021年11月29日凌晨8:52 #

      是的。分别处理这5折,不要共享任何初始化等。
      只需在每一折循环的开始重新创建模型,并进行拟合和验证。

      • nkm 2021年11月30日凌晨2:54 #

        感谢您的快速回复。我正在尝试您的方法。此外,我只是在for循环的每一折结束时删除模型变量(del model)。这是正确的方法吗??

        再次感谢。

        • Adrian Tam
          Adrian Tam 2021年12月2日凌晨1:58 #

          正确。但您可能不需要删除模型,而只需在每个循环开始时创建一个新模型就足够了。

          • nkm 2021年12月6日晚上4:40 #

            非常感谢您快速而准确的解决方案。感谢您的支持,您是一位“真正的向导”。

  18. Fereshteh 2022年1月23日晚上3:37 #

    所以,每当我们使用交叉验证时,我们会提供整个数据集,它会为我们进行训练、测试和验证吗?对吗?
    下一个问题是,当我们使用交叉验证时,如何使用模型来预测新样本?有predict函数吗?
    任何回复都将受到赞赏。
    祝好,

  19. Shubhada 2022年3月11日晚上9:44 #

    谢谢

  20. _Pratiksh 2022年3月11日晚上9:45 #

    sa

  21. Koundinya 2022年10月21日晚上2:16 #

    skf = StratifiedKFold(n_splits=3, shuffle=True, random_state=1)
    lst_accu_stratified = []

    labels = {‘AD’:0, ‘SZP’:1, }
    ad_sz[‘class_number’] = ad_sz[‘target’]
    ad_sz.class_number = [labels[item] for item in ad_sz.class_number]

    ad_sz[‘class_number’] = ad_sz[‘class_number’].astype(np.float32)

    # 将目标转换为数值型
    # 定义输入和输出数据集
    input = ad_sz.iloc[:, 0]
    print(‘\n输入值是:’)
    print(input.head())
    output = ad_sz.loc[:, ‘class_number’]
    print(‘\n输出值是:’)
    print(output.head())

    input = torch.from_numpy(np.vstack(input).astype(np.float32)) # 创建张量
    print(‘\n输入格式: ‘, input.shape, input.dtype)
    output = torch.tensor(output.values) # 创建张量
    print(‘输出格式: ‘, output.shape, output.dtype)
    data_ = TensorDataset(input, output)

    model = LogisticRegression(solver=’lbfgs’,max_iter=1000)
    skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=1)
    lst_accu_stratified = []

    for train_index, test_index in skf.split(input, output)
    X_train_fold, X_test_fold = input[train_index], input[test_index]
    y_train_fold, y_test_fold = output[train_index], output[test_index]
    model.fit(X_train_fold, y_train_fold)
    lst_accu_stratified.append(model.score(X_test_fold, y_test_fold))

    print(‘最大准确率’,max(lst_accu_stratified))
    print(‘最小准确率:’,min(lst_accu_stratified))
    print(‘总体准确率:’,mean(lst_accu_stratified))

    from sklearn.metrics import plot_confusion_matrix
    plot_confusion_matrix(model, X_train_fold,y_train_fold)

    对于以上内容,我正在尝试遵循分层k折并打印准确率、灵敏度和特异性

    我卡在如何打印准确率、灵敏度和特异性上了,有什么想法吗?

  22. Murilo 2023年4月6日凌晨6:40 #

    有没有办法让验证集的大小始终为20%,而不考虑折数?

  23. Carlos 2023年8月25日凌晨6:08 #

    嗨,Jason,

    我如何将您的代码应用于CNN模型而不是随机森林?我定义了我的模型架构如下:

    def get_model()
    xinput=kl.Input((200,9,1))
    #添加高斯噪声以减少过拟合()
    xNoise=kl.GaussianNoise(.005)(xinput)
    #仅在时间序列方向上进行卷积(类似于过滤)
    x1=kl.Conv2D(NUMBER_FILTERS,(SIZE_FILTERS,1),kernel_regularizer=keras.regularizers.L1(l1=REG))(xNoise)
    #合并信息
    x1=kl.Conv2D(NUMBER_FILTERS,(SIZE_FILTERS,1),kernel_regularizer=keras.regularizers.L1(l1=REG),activation=’gelu’)(x1)
    xFeatures=kl.Conv2D(DIMENSION_SUBSPACE1,(1,1),kernel_regularizer=keras.regularizers.L1(l1=REG),activation=’gelu’)(x1)
    #全局池化(网络对平移不变)
    xP=tf.reduce_max(xFeatures,axis=1)
    #低维空间分类器
    x2=kl.Flatten()(xP)
    x2=kl.Dense(DIMENSION_SUBSPACE2,activation=’gelu’)(x2)
    xout=kl.Dense(1,activation=’sigmoid’)(x2)
    return keras.Model(xinput,xout)
    #model_Interpretation=keras.Model(xinput,xFeatures)

    这是摘要

    Model: “model”
    _________________________________________________________________
    层(类型) 输出形状 参数 #
    =================================================================
    input_1 (InputLayer) [(None, 200, 9, 1)] 0

    gaussian_noise (GaussianNo (None, 200, 9, 1) 0
    ise)

    conv2d (Conv2D) (None, 186, 9, 32) 512

    conv2d_1 (Conv2D) (None, 172, 9, 32) 15392

    conv2d_2 (Conv2D) (None, 172, 9, 3) 99

    tf.math.reduce_max (TFOpLa (None, 9, 3) 0
    mbda)

    flatten (Flatten) (None, 27) 0

    dense (Dense) (None, 3) 84

    dense_1 (Dense) (None, 1) 4

    =================================================================
    总参数:16091(62.86 KB)
    可训练参数:16091(62.86 KB)
    不可训练参数:0(0.00 Byte)

    这是编译和训练模型的代码行

    model.compile(optimizer=keras.optimizers.Adam(learning_rate=.001),loss=’binary_crossentropy’,metrics=’accuracy’)
    CB=[keras.callbacks.ReduceLROnPlateau(monitor=’loss’,patience=10),keras.callbacks.EarlyStopping(monitor=’loss’,patience=30,restore_best_weights=True)]
    model.fit(X,Y,batch_size=4,epochs=600,callbacks=CB)

    我一直在尝试实现您的代码,但我不知道如何操作。感谢您的任何帮助,并为我的蹩脚英语道歉。

    谢谢 🙂

    • James Carmichael 2023年8月25日晚上10:36 #

      你好Carlos……请提供您遇到的任何错误消息的文本。这将使我们能够更好地为您提供建议。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。