当前位置:首页 > 文章列表 > 文章 > python教程 > Python数据采样:随机与分层抽样全解析

Python数据采样:随机与分层抽样全解析

2025-08-07 10:44:09 0浏览 收藏

一分耕耘,一分收获!既然打开了这篇文章《Python数据采样方法:随机与分层抽样详解》,就坚持看下去吧!文中内容包含等等知识点...希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友们多留言评论,多给建议!谢谢!

随机抽样使用pandas的sample方法,分层抽样使用scikit-learn的train_test_split函数并设置stratify参数;1. 随机抽样操作简单,适用于数据分布均匀场景;2. 分层抽样确保类别比例一致,适用于类别不平衡数据;3. 常见挑战包括稀有类别导致分割失败、连续变量误用作分层变量、多标签分层不支持,需通过合并稀有类别、数据分箱或自定义策略解决,使用时需根据数据特性谨慎处理以确保样本代表性。

Python怎样实现数据采样?随机与分层抽样

Python中实现数据采样,特别是随机抽样和分层抽样,核心在于选择合适的工具和理解其背后的逻辑。简单来说,随机抽样可以使用Pandas库的sample方法,它直接、方便;而分层抽样则更常依赖Scikit-learn库中的train_test_split函数,通过其stratify参数来确保数据集中各类别比例在抽样后依然保持一致。选择哪种方法,很大程度上取决于你的数据特性、分析目标以及对样本代表性的要求,尤其是在处理那些类别分布不均衡的数据集时,分层抽样几乎是不可或缺的。

解决方案

说起数据采样,无论是为了后续的模型训练、做一些探索性统计分析,还是仅仅想从海量数据里快速抓取一部分来预览,Python都提供了非常趁手的工具。核心思路其实就是从一个大的数据集里,按照某种规则或者概率,抽取出一个小一点的子集。这个子集呢,我们希望它能尽可能地代表原始数据的某些特征,或者至少是满足我们特定分析需求的。

对于最直接的随机抽样,我们通常会用到pandas这个库,它的DataFrame对象自带一个sample方法,用起来非常直观,几行代码就能搞定。

而分层抽样,这玩意儿就稍微复杂一点,但对于处理那些类别不平衡的数据集,或者当你需要确保某个关键特征(比如目标变量)的比例在抽样后不被破坏时,它简直是救星。scikit-learn库里的model_selection模块提供了强大的支持,特别是train_test_split函数,它的stratify参数就是为分层抽样而生的。它能让你在划分数据集(比如训练集和测试集)时,自动保持指定特征的比例。

随机抽样在Python中如何操作?

随机抽样,顾名思义,就是从数据里随机抓取一些样本。这就像你从一大堆扑克牌里,闭着眼睛随便抽几张出来。在Python里,pandasDataFrame.sample()方法是实现这个最直接、最常用的方式。它简单到你几乎不需要思考太多。

import pandas as pd
import numpy as np

# 随便搞个数据集,方便演示
data = {'feature_A': np.random.rand(100) * 100,
        'feature_B': np.random.randint(0, 50, 100),
        'category': np.random.choice(['Red', 'Green', 'Blue', 'Yellow'], 100, p=[0.4, 0.3, 0.2, 0.1])}
df = pd.DataFrame(data)

print("原始数据前5行:\n", df.head())
print("\n原始数据 'category' 分布:\n", df['category'].value_counts(normalize=True))

# 1. 随机抽取固定数量的行
# 比如,我想随机抽取10行数据看看
sample_10_rows = df.sample(n=10, random_state=42) # random_state保证每次运行结果一致
print("\n随机抽取10行数据:\n", sample_10_rows)

# 2. 随机抽取指定比例的数据
# 比如,我想要原始数据的20%作为样本
sample_20_percent = df.sample(frac=0.2, random_state=42)
print("\n随机抽取20%的数据:\n", sample_20_percent.shape[0], "行数据")

# 3. 带放回的随机抽样(可以用于自助法Bootstrap)
# 这种情况下,同一个样本可能会被抽到多次
sample_with_replacement = df.sample(n=100, replace=True, random_state=42)
print("\n带放回的随机抽样(前5行,可能重复):\n", sample_with_replacement.head())

这种方法用起来确实方便,特别是当你数据集特别大,想先用小部分数据做个初步探索,或者只是想快速验证某个想法时。但话说回来,它也有个潜在的“坑”:如果你的数据集中某个类别非常稀少(比如,在分类任务里,欺诈交易、罕见疾病的样本),纯随机抽样搞不好就把这些稀有样本给漏掉了,或者抽到的比例严重失衡。这对于后续的模型训练可不是什么好事,模型很可能就学不好识别那些稀有情况了。

分层抽样与随机抽样有何不同,何时需要分层抽样?

分层抽样和随机抽样最大的区别在于,它不是简单地“抓阄”,而是先根据数据的某个关键特征(通常是你的目标变量,或者你特别关注的某个分类特征)把数据分成不同的“层”,然后再从每一层里按比例抽取样本。这样做的目的,就是为了确保样本集能更好地反映原始数据中各层级的分布情况。

不同点:

  • 随机抽样: 对数据集中所有样本一视同仁,完全随机选择,不考虑任何内部结构或类别分布。
  • 分层抽样: 先将总体数据根据某个特征(分层变量)划分为若干互不重叠的“层”,然后从每一层中独立地进行随机抽样,以确保各层在样本中的比例与总体中保持一致。

何时需要分层抽样呢? 我个人觉得,只要你的目标变量是分类的,并且存在类别不平衡(比如,正样本远少于负样本),或者你特别关心每个类别的表现(不希望某个类别在样本中“消失”),那么分层抽样几乎是你的首选。

举个例子,你要预测用户是否会流失,通常流失的用户是少数;或者你要识别图片中的猫狗,但猫的图片比狗的少很多。这时候,如果用纯随机抽样,你的训练集里可能就没几只“猫”,或者流失用户样本少得可怜,模型自然就学不好识别猫或者预测流失了。分层抽样就能很好地解决这个问题,它会保证训练集和测试集里“猫”和“狗”的比例,或者流失与未流失用户的比例,都和原始数据集大致相同。

Python里,scikit-learntrain_test_split函数是实现分层抽样的利器。它有一个stratify参数,你只需要把要分层的列传进去就行了。

from sklearn.model_selection import train_test_split

# 继续用上面的df,假设我们要根据'category'列进行分层
X = df[['feature_A', 'feature_B']] # 特征
y = df['category'] # 目标变量,用来分层

print("原始数据 'category' 分布:\n", y.value_counts(normalize=True))

# 对比:不分层(随机)划分训练集和测试集
X_train_rand, X_test_rand, y_train_rand, y_test_rand = train_test_split(X, y, test_size=0.3, random_state=42)
print("\n随机抽样后目标变量分布(训练集):\n", y_train_rand.value_counts(normalize=True))
print("随机抽样后目标变量分布(测试集):\n", y_test_rand.value_counts(normalize=True))

# 分层划分训练集和测试集
# 注意:stratify=y,就是告诉函数根据y的类别分布来分层
X_train_strat, X_test_strat, y_train_strat, y_test_strat = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
print("\n分层抽样后目标变量分布(训练集):\n", y_train_strat.value_counts(normalize=True))
print("分层抽样后目标变量分布(测试集):\n", y_test_strat.value_counts(normalize=True))

你会发现,分层抽样后的训练集和测试集中,category类别的比例会非常接近原始数据的比例。这对于模型训练的稳定性和泛化能力至关重要,特别是当你处理的数据类别分布不均时,分层抽样能大大提高你模型的可靠性。我个人在做分类任务时,如果不是数据量特别巨大且类别分布极其均匀,基本都会考虑分层抽样。

实现分层抽样时可能遇到哪些挑战或常见错误?

分层抽样虽好,但实际操作起来也并非一帆风顺,总会遇到一些小坑。我印象最深的有这么几个:

1. 分层列中样本过少,导致无法分割: 这是最常见的报错之一。如果你用来分层的那个列(stratify参数指定的那一列)中,某个类别只有一两个样本,而你的test_size又设置得比较大,或者你尝试进行K折交叉验证(比如StratifiedKFold),导致某个折里某个类别没有样本,scikit-learn就会报错。它会告诉你某个类别的样本数少于你期望的分割数(比如,测试集需要至少1个样本,但该类别只有0个)。

解决办法嘛,通常是检查一下你的分层列,看看有没有极端稀有的类别。如果这种类别对你的分析不重要,可以考虑将其合并到其他类别中(比如,把所有样本数小于5的类别都归为“其他”);或者调整你的test_size,确保每个层至少能分到一份。有时候,这可能意味着你需要收集更多的数据,或者重新考虑你的分层策略。

2. 非数值或非分类数据作为分层依据:stratify参数通常期望的是分类标签(比如整数、字符串)或者可以被视为分类的数值。如果你不小心把一个连续的数值型特征(比如年龄、收入)传进去了,它会试图把它当成很多个独立的类别(每个不同的值都是一个类别),结果可能不是你想要的,甚至因为类别太多而导致上述的“样本过少”问题。

这种情况下,你需要先对连续数据进行分箱(binning),把它转换成离散的类别,然后再进行分层。比如,把年龄分成“青年”、“中年”、“老年”等几个区间。Pandas的cut函数在这里就非常有用。

3. 多标签或多输出分层:train_test_splitstratify参数是为单标签分类设计的。如果你的任务是多标签分类(一个样本可以有多个标签,比如一篇文章同时属于“科技”和“教育”两个类别),或者多输出(同时预测多个目标变量),直接用stratify=y可能就不行了。因为stratify需要一个单一的、离散的数组来计算分布。

这种场景下,就没有一个像stratify这么直接的万能参数了。你可能需要寻找更高级的策略,比如先对标签进行组合编码(把所有标签组合看作一个新的单一标签),或者使用专门为多标签/多输出设计的交叉验证器(虽然Scikit-learn里直接支持的比较少,可能需要自己实现或寻找第三方库,例如iterstrat库的MultilabelStratifiedShuffleSplit)。不过,对于大多数日常的单标签分类问题,stratify已经足够强大了。

总的来说,分层抽样是个非常实用的工具,但使用时要多留意数据的特性,特别是稀有类别的处理。别指望一个参数就能解决所有问题,有时候还是得手动干预一下数据,或者多思考一下数据背后的真实分布。

本篇关于《Python数据采样:随机与分层抽样全解析》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

Golang集成KeycloakOIDC认证教程Golang集成KeycloakOIDC认证教程
上一篇
Golang集成KeycloakOIDC认证教程
Prometheus监控Java应用指标采集指南
下一篇
Prometheus监控Java应用指标采集指南
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    511次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    498次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 千音漫语:智能声音创作助手,AI配音、音视频翻译一站搞定!
    千音漫语
    千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
    119次使用
  • MiniWork:智能高效AI工具平台,一站式工作学习效率解决方案
    MiniWork
    MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
    118次使用
  • NoCode (nocode.cn):零代码构建应用、网站、管理系统,降低开发门槛
    NoCode
    NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
    131次使用
  • 达医智影:阿里巴巴达摩院医疗AI影像早筛平台,CT一扫多筛癌症急慢病
    达医智影
    达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
    126次使用
  • 智慧芽Eureka:更懂技术创新的AI Agent平台,助力研发效率飞跃
    智慧芽Eureka
    智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
    128次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码