Hugging Face Datasets train_test_split 怎样按标签分层拆分训练集与测试集
如果一个带标签的数据集直接调用 train_test_split(test_size=0.2),默认只是随机抽取测试集;当类别分布不均衡时,测试集可能偶然偏向某个标签。要让切分尽量保持类别比例,应把标签列名传给 stratify_by_column,再用固定的 seed 让同一份输入可以复现。
官方地址:https://huggingface.co/docs/datasets/
下面用人工构造的短文本和整数标签演示完整流程。示例只解释 API 的参数关系,不把图示或代码片段冒充已经在本机执行的输出。
先确认标签列和切分目标
开始前先回答三个问题:哪一列代表类别、测试集需要占多少比例、是否需要每次得到相同的行划分。stratify_by_column 接收的是列名,不是列中某一个标签值;test_size 可以使用比例,也可以使用固定行数。
from datasets import Dataset
# 使用人工样本演示二分类;真实项目替换为自己的数据加载过程。
rows = {
"text": [
"样本一:设备运行正常。",
"样本二:发现轻微抖动。",
"样本三:设备运行正常。",
"样本四:发现轻微抖动。",
"样本五:设备运行正常。",
"样本六:发现轻微抖动。",
"样本七:设备运行正常。",
"样本八:设备运行正常。",
"样本九:发现轻微抖动。",
"样本十:设备运行正常。",
],
# 0 和 1 是演示标签;生产数据应先确认标签编码含义。
"label": [0, 1, 0, 1, 0, 1, 0, 0, 1, 0],
}
dataset = Dataset.from_dict(rows)
# 先确认列名和样本量,避免把 text 写成标签列。
print(dataset.column_names)
print(dataset.num_rows)
这里的标签列叫 label,而且每个类别都有多条样本。若标签列不存在、列名拼写错误,或者某个类别只有一条记录,分层切分就可能失败;这不是把 test_size 调小就一定能修好的问题。
用 stratify_by_column 执行分层切分
把 stratify_by_column="label" 传入后,Datasets 会使用该列参与分层抽样,返回一个包含 train 和 test 的 DatasetDict。它仍然可能受到总行数、标签类别数量和取整方式影响,所以“保持比例”应理解为在可分配条件下尽量保持,而不是承诺每个 split 的小数比例完全相等。

# test_size=0.2 表示把约两成样本放入测试集。
# stratify_by_column 指向列名,让切分参考每条记录的 label。
splits = dataset.train_test_split(
test_size=0.2,
stratify_by_column="label",
seed=42,
)
# 返回对象按名称访问两个 Dataset split。
train_ds = splits["train"]
test_ds = splits["test"]
print(train_ds.num_rows, test_ds.num_rows)
print(splits.keys())
不要把返回值当成两个普通列表,也不要继续对原始 dataset 误读为“已经切分”。后续训练使用 splits["train"],评估使用 splits["test"],这样数据边界会留在返回的 DatasetDict 中。
用 seed 固定可复现边界
seed 控制随机过程。相同的数据内容、相同的参数和相同的种子,才有机会得到同一组行划分;如果重新加载的数据顺序已变、样本有增删,固定种子也不能把不同输入变成同一结果。

def split_once(ds):
# 将所有影响切分的参数集中,避免训练脚本和评估脚本各写一套。
return ds.train_test_split(
test_size=0.2,
shuffle=True,
stratify_by_column="label",
seed=2026,
)
first = split_once(dataset)
second = split_once(dataset)
# 用稳定字段比较前几行;这里只检查切分逻辑,不比较对象地址。
assert first["test"]["text"] == second["test"]["text"]
assert first["test"]["label"] == second["test"]["label"]
生产流水线可以把种子写进配置或实验记录,并同时记录原始数据版本、列名和 test_size。只保存一个整数种子而不保存输入数据快照,仍不足以完整复盘一次实验。
检查比例、稀有标签与失败原因
分层切分的排查顺序应该先看列,再看每类数量,最后看 split 结果。不要只看总行数相加是否等于原数据,因为那只能证明没有明显丢行,不能证明类别分布符合预期。
from collections import Counter
def label_counts(ds):
# Counter 让训练集和测试集的标签构成可以直接对照。
return Counter(ds["label"])
print("all:", label_counts(dataset))
print("train:", label_counts(splits["train"]))
print("test:", label_counts(splits["test"]))
# 先确认两部分合计仍等于原始样本数。
assert splits["train"].num_rows + splits["test"].num_rows == dataset.num_rows
| 现象 | 优先检查 | 处理方向 |
|---|---|---|
| 提示找不到列 | stratify_by_column 是否写成真实列名 | 先打印 dataset.column_names |
| 类别比例明显偏移 | 是否漏传 stratify_by_column,或样本量过小 | 检查每类数量与测试集目标行数 |
| 分层切分失败 | 稀有类别是否没有足够记录分到两边 | 补充数据、调整切分策略或明确合并边界 |
| 两次结果不同 | 输入顺序、过滤步骤和 seed 是否一致 | 固定预处理顺序并记录输入版本 |
把参数写成一份可交接配置
最终建议把切分决策和数据快照一起记录:标签列叫什么、测试集比例是多少、是否打乱、使用了哪个种子、每个 split 的行数和标签计数是多少。这样换机器或重跑训练时,问题会落在明确的输入差异上,而不是一句“随机切分不稳定”。
简要记忆:默认随机切分解决的是“分成两份”,stratify_by_column 解决的是“尽量保持标签构成”,seed 解决的是“相同输入下可复现”。三者职责不同,不能用固定种子替代分层,也不能用分层参数替代数据版本记录。
只有一个标签类别时还能做分层切分吗?
技术上可以切分行,但分层没有提供类别平衡价值。若任务本来就是单类别数据,应明确记录这一事实,而不是把 stratify_by_column 当作通用稳定性开关。
test_size 能保证测试集严格占 20% 吗?
它表达目标比例或固定数量,实际行数还会受总行数、整数取整和标签可分配条件影响。小数据集更应该检查最终行数和类别计数。
固定 seed 后为什么换数据文件仍然不同?
种子只固定随机过程,不固定输入内容。样本增删、顺序改变、过滤条件改变,都会让相同随机过程作用在不同序列上。
Redis GEOSEARCH 怎样在矩形区域与圆形区域查询之间选择
- 上一篇
- Redis GEOSEARCH 怎样在矩形区域与圆形区域查询之间选择
- 下一篇
- CNCF 新调查关注虚拟机与 AI,共存工作负载透露哪些部署需求
-
- 科技周边 · 人工智能 | 43分钟前 |
- Hugging Face Datasets 怎样随本地数据保存描述与引用信息
- 268浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 | 人工智能 · 结构化输出 vLLM JSON Schema OpenAI兼容服务 structured_outputs
- vLLM OpenAI 兼容服务怎样用 JSON Schema 约束结构化输出
- 240浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 |
- OpenAI Responses API 工具调用工具参数校验失败时怎样保留可诊断信息为什么结果为空或不符合预期
- 354浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 |
- Anthropic Claude tool use怎样把tool_use和tool_result配成一轮可继续的对话
- 158浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 | python · openai · 参数校验 JSON Schema 工具调用 OpenAI Responses API
- OpenAI Responses API 工具调用工具参数校验失败时怎样保留可诊断信息怎样完成一个可复用的最小示例
- 106浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 |
- Hugging Face Datasets streaming怎样用shuffle的buffer_size打散大语料并保持每轮可复现
- 113浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 |
- Hugging Face Datasets streaming大数据集怎样流式读取而不一次载入内存怎样完成一个可复用的最小示例
- 306浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 |
- ONNX Runtime 量化怎样比较动态量化与静态量化的部署差异怎样在批处理代码中减少额外分配
- 139浏览 收藏
-
- 科技周边 · 人工智能 | 4小时前 |
- ONNX Runtime 量化怎样比较动态量化与静态量化的部署差异为什么结果为空或不符合预期
- 242浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- ONNX Runtime 量化怎样比较动态量化与静态量化的部署差异怎样完成一个可复用的最小示例
- 374浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- 多模态模型评测怎样分别记录图像理解与文本生成指标怎样在批处理代码中减少额外分配
- 442浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 966次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 967次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1077次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1057次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 888次使用
-
- CodeGeeX for Jetbrains IDEs正式上线!
- 2023-01-17 284浏览
-
- 技术阿里云实现ocr批量图片和pdf文件表格图片转换excel文档/支持票据图片提取/普通图片文字提取处理
- 2023-01-18 387浏览
-
- 直播预告|FeatureStore Meetup V2
- 2023-01-10 328浏览
-
- 深入浅出特征工程 – 基于 OpenMLDB 的实践指南(上)
- 2023-02-25 426浏览
-
- 开源机器学习数据库OpenMLDB v0.4.0产品介绍
- 2023-01-10 147浏览

