探索数据集分割策略:使用合成数据的Python技术和实现

2023年12月01日 由 alex 发表 231 0

介绍


在数据科学和机器学习领域,划分数据集是一个基本步骤。它对于以现实和无偏见的方式评估模型性能至关重要。目标是确保模型不仅能够很好地拟合现有数据,还能推广到新的、未见过的数据。本文讨论了划分数据集的各种方法,每种方法都有其优势和需要考虑的因素。


1


在数据科学复杂的舞蹈中,首先通常是最关键的一步 —— 划分数据集。就像主厨小心翼翼地分开食材以增强菜肴的风味,数据科学家必须明智地拆分他们的数据集,确保每个子集 —— 训练集、验证集和测试集都是整体的代表性缩影。这种一丝不苟的分割不仅仅是一项初步任务,而是奠定模型从天真学习到洞察力预测旅程的基础行为,呼应了永恒的真理:在数据的分割中体现了知识的统一。


随机划分


最常见的方法是随机划分,数据点随机分配给训练集、验证集和测试集。通常,数据按70-15-15的比例或类似的变体分成训练集、验证集和测试集。这种方法确保了每个集合中都有良好的数据点混合,并且执行起来直接。然而,对于类别不平衡的数据集或时间序列数据,这可能不适用。


分层划分


分层划分用于维持每个子集中类别的比例。这种方法对于类别分布不平衡的数据集特别有用。通过确保每个类别在训练集、验证集和测试集中按比例代表,我们可以防止模型偏向多数类。


基于时间的划分


对于时间序列数据,基于时间的划分是必不可少的。数据根据时间划分,确保训练集包含早期的数据,测试集则包含后期的数据。这种方法对于需要基于过去数据预测未来事件的模型至关重要,因为它模仿了在模型训练期间未来数据不可用的真实世界场景。


交叉验证


交叉验证包括将数据集划分成k个子集或折叠。模型在k-1个折叠上进行训练,在剩下的折叠上进行验证。这个过程重复k次,每个折叠轮流作为验证集一次。交叉验证提供了对模型性能的全面评估,特别是在处理小型数据集时非常有用。


特定领域的划分


在某些领域,划分数据可能需要特定的方法。例如,在医学影像中,确保同一患者的图像不在训练集和测试集中都出现至关重要。这种方法,称为患者间划分,避免了数据泄露并确保模型能够在不同患者之间具有泛化能力。


LOO和LPO


留一法(LOO)和留P法(LPO)是穷尽的交叉验证方法。在LOO中,模型在所有数据点上训练,除了一个用于测试的数据点。这个过程对每个数据点重复。LPO通过留出p个数据点来扩展这一点。虽然这些方法全面,但它们计算密集且对于大型数据集可能不太实际。


代码


创建合成数据集并在Python中展示各种数据集划分方法既有教育意义又实用。下面是实现这一点的分步指南,连同代码片段。


步骤1: 创建合成数据集


我们将使用scikit-learn生成一个适合分类问题的合成数据集。


from sklearn.datasets import make_classification
import pandas as pd
# Create a synthetic dataset
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
# Convert to a DataFrame for easier manipulation
df = pd.DataFrame(X)
df['target'] = y


步骤2:使用不同方法分割数据集


2.1 随机分割


from sklearn.model_selection import train_test_split
# Randomly split the dataset
train_set, test_set = train_test_split(df, test_size=0.2, random_state=42)


2.2 分层抽样


# Stratified split
strat_train_set, strat_test_set = train_test_split(df, test_size=0.2, random_state=42, stratify=df['target'])


2.3 基于时间的拆分(模拟)


假设数据集具有类似时间的特征,我们将对此进行模拟。


# Add a time-like feature
df['time'] = range(len(df))
# Time-based split
time_threshold = int(len(df) * 0.8)
time_train_set = df[df['time'] < time_threshold]
time_test_set = df[df['time'] >= time_threshold]


 步骤3:可视化分割


为了可视化分割,我们将使用matplotlib。


绘制类别的分布图


这幅图将帮助我们理解每个分割中类别是如何分布的。


import matplotlib.pyplot as plt.pyplot as plt
def plot_class_distribution(sets, labels):
    plt.figure(figsize=(10, 6))
    for i, dataset in enumerate(sets):
        plt.subplot(1, len(sets), i+1)
        plt.title(labels[i])
        plt.hist(dataset['target'])
        plt.xlabel('Class')
        plt.ylabel('Frequency')
    plt.tight_layout()
    plt.show()
# Plotting
plot_class_distribution([train_set, strat_train_set, time_train_set], 
                        ['Random Split', 'Stratified Split', 'Time-based Split'])


步骤4:执行


执行此代码:


  • 确保你已安装Python。
  • 如果尚未安装,安装必要的库(pandas、scikit-learn、matplotlib)。
  • 在Python环境中运行代码(如Jupyter Notebook或脚本)。


2


这段代码将生成一个合成数据集,使用不同的方法对其进行拆分,然后绘制每个拆分中类别的分布。这种视觉表示将帮助你理解每种拆分方法的差异和含义。


结论


选择合适的数据集拆分方法取决于数据的性质、手头的问题和可用的资源。对于平衡的数据集,随机拆分可能就足够了,但对于不平衡或时间序列数据,分层或基于时间的拆分则更为合适。交叉验证技术提供了对模型的全面评估,但需要更多的计算资源。最终,选定的方法应旨在最大化模型对新数据的泛化能力,同时最小化偏差或过拟合。


文章来源:https://medium.com/@evertongomede/exploring-dataset-splitting-strategies-techniques-and-implementations-in-python-with-synthetic-515ddacb5c1c
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消