使用 Python 将数据集拆分为训练集、验证集和测试集

1,224 阅读6分钟

什么是 ML 中的训练验证测试拆分

训练-测试-验证拆分是将数据集划分为三个独立子集的过程:训练集、测试集和验证集。

将数据集拆分为训练集、验证集和测试集是机器学习和深度学习过程中的重要一步。通过为训练、验证和测试设置单独的集合,我们可以更好地评估模型的性能,防止过度拟合或欠拟合,并确保模型具有泛化到不可见数据的能力。

  • 训练集:训练集用于训练模型,调整其参数以最适合数据。该集合应该足够大以捕获数据中的模式,但又不能大到模型过度拟合数据。通常,60-90% 的数据用于训练。
  • 验证集:验证集用于评估模型的性能并调整其超参数,例如学习率和隐藏层数。验证集充当测试集的代理,不应将其用于模型选择或超参数调整。这个集合应该足够大以提供对模型的有意义的评估,但又不能大到显着影响模型的训练。通常,10-30% 的数据用于验证。
  • 测试集:测试集用于评估最终模型的性能并估计其泛化到未见数据的能力。该集应该独立于训练集和验证集,并且应该只用于评估最终模型。通常,10-30% 的数据用于测试。

请务必注意,数据集应随机拆分,以确保训练集、验证集和测试集代表整个数据集。这有助于防止出现无法准确反映模型真实性能的偏斜测试集的风险。

最后,重要的是在训练过程中保持测试集隐藏,只用它来评估最终模型。这有助于防止过度拟合测试集的风险,这会对模型在未见数据上的性能给出过于乐观的估计。

分裂的用途

通过为训练、验证和测试设置单独的集合,我们可以防止过度拟合和欠拟合。当模型过于复杂并记住训练数据时会发生过度拟合,从而导致在看不见的数据上表现不佳。当模型太简单并且没有捕获数据中的潜在模式时,就会发生欠拟合,从而导致训练和测试数据的性能不佳。

拥有单独的验证集和测试集还提供了不受模型选择过程影响的模型泛化性能的估计,使我们能够更好地了解模型的真实性能。

最佳训练、验证、测试分流比

没有单一的最佳训练-验证-测试拆分率,因为它取决于多个因素,例如数据集的大小、模型的复杂性和项目的目标。但是,行业中有一些常用的比率:

  • 60–20–20 拆分:此拆分将数据分为 60% 用于训练,20% 用于验证,20% 用于测试。当数据集很大且模型相对简单时,这是一个常见的比率。
  • 70–15–15 split:这种拆分将数据分为 70% 用于训练,15% 用于验证,15% 用于测试。当数据集比较小或者模型比较复杂的时候可以使用这个比例。
  • 80–10–10 分割:这种分割将数据分成 80% 用于训练,10% 用于验证,10% 用于测试。当数据集非常大或模型非常复杂时,可以使用此比率。

最终,最佳的训练-测试-验证拆分比率将取决于项目的具体情况,并且可能需要使用不同的比率进行即插即用实验以找到最适合您需求的比率。

使用 Python 的 scikit-learn 实现 60–20–20 拆分

以下是使用 Python 的 scikit-learn 库将数据集拆分为训练集、验证集和测试集的示例代码:

Python3

from sklearn.model_selection import train_test_split # 假设    你有一个数据集

“X”和标签“ y 
” train_test_split(     X_train, y_train, test_size= 0.25 , random_state= 42 ) # X_train, y_train 是训练数据# X_val, y_val 是验证数据# X_test, y_test 是测试数据# 假设你有一个数据集 'X' 和标签 ' y' X_train, X_test, y_train, y_test = train_test_split(     X, y, test_size= 0.2 , random_state=








42)
X_train,X_val,y_train,y_val = train_test_split(
    X_train,y_train,test_size= 0.25,random_state= 42

上述代码中,两次使用train_test_split函数,先将数据拆分为测试大小为20%的训练集和测试集,然后将训练数据拆分为测试大小为25%的训练集和验证集。random_state 参数用于确保每次运行代码时都进行相同的拆分。

通用实现

下面的代码用于以任何给定的比例拆分数据集。

Python3

import numpy as np 
import pandas as pd 


def  train_test_val_split (数据, train_ratio= 0.8 , test_ratio= 0.1 , val_ratio= 0.1 ): 
    np.random.seed( 0 ) 
    perm = np.random.permutation(data.index) 
    m = len (数据) 
    train_end = int (train_ratio * m) 
    test_end = int ((train_ratio + test_ratio) * m) 
    train = data.iloc[perm[:train_end]] 
    test = data.iloc[perm[train_end:test_end]] 
    val = data .iloc[perm[test_end:]]
    return train, test, val 


data = pd.read_csv( "data.csv" )   # 用实际文件路径替换"data.csv"
 train, test, val = train_test_val_split( 
    data, train_ratio, test_ratio, val_ratio)

上面的代码是一个示例,说明如何使用 Pandas 库在 Python 中将数据集拆分为训练集、测试集和验证集。

函数 train_test_val_split 接受输入数据集数据和每个分割在训练、测试和验证数据方面的期望比率。默认的训练比率、测试比率和验证比率分别设置为 0.8、0.1 和 0.1,但可以根据需要调整这些值。

该函数的第一步是通过使用 np.random.permutation 创建数据索引的排列来打乱数据行。这对于确保生成的拆分是随机的并代表原始数据很重要。

接下来,使用 m = len(data) 计算数据的长度,并使用指定比率作为输入的整数除法计算训练集、测试集和验证集的结束索引。

最后,使用 Pandas DataFrame 的 .iloc 索引方法和计算出的索引将数据分为训练集、测试集和验证集,并将这些集作为函数的输出返回。

请注意,此代码假定数据存储在 pandas DataFrame 中,并且数据的索引在划分为训练集、测试集和验证集之前进行了混洗。设置随机数生成器的种子以确保可重复性。

结论

总之,训练-验证-测试拆分是机器学习工作流程中必不可少的一步,有助于确保模型的稳健性和通用性。通过将数据分成单独的集合进行训练、验证和测试,可以评估模型在不同数据子集上的性能,防止对训练数据的过度拟合,并估计模型泛化到看不见的能力数据。

拆分的确切比例取决于数据集的大小、模型的复杂性和项目的目标,但常见的比例包括 60–20–20、70–15–15 和 80–10–10。

可以使用 NumPy 和 Pandas 等各种库在 Python 中实现训练-验证-测试拆分。无论具体实施如何,重要的是要确保以随机和有代表性的方式执行拆分,以最大限度地提高结果的准确性和可靠性。