前言
在数据科学和机器学习领域,处理海量数据是一项常见的挑战。而数据采样则是一种常用的技术,可以从大规模数据集中提取出代表性样本,以便进行分析和建模。
由于工作数据量较大,训练模型很少直接单机python,一般都采用SparkML,最近把SparkML的工作使用python简单的写了一下,先写个上下采样,最终目的是为了让正负样本达到均衡(有人问:正负样本必须是1:1吗?1:1效果就一定最好吗?答:不一定)
数据采样的意义和目的
在大数据场景下,处理全部数据可能会十分耗时、消耗资源,而且有时并不需要所有数据,只需要从数据集中采样一部分数据即可。数据采样的主要目的是:
- 降低计算和存储成本
通过对数据集进行采样,可以大大减少需要处理的数据量,从而降低计算和存储的成本。 - 加快算法迭代速度
在机器学习中,使用数据采样可以加快算法的迭代速度,提高模型的训练效率。 - 评估模型性能
通过采样数据进行模型训练和评估可以更快地了解模型的性能和表现。
数据准备
共20条数据,正样本1共有5条,负样本0共有15条。
基础知识准备
- 如何获取dataframe的行数
pandas.DataFrame.shape 返回数据帧的形状
df.shape[0] 返回行数
de.shape[1] 返回列数
或者直接使用
len(df)
当然如果要统计每个字段不同类别的数量,可以类似于SQL中的count(*) group by 操作
df.groupby('字段名').size()
- 创建一个数据结构和之前一致,但空的dataframe
方法1:
df = df.iloc[0:0].copy()
方法2:
df.drop(df.index, inplace=True)
方法3:
df_1 = df.drop(range(len(df)),axis=0)
读取数据和获取正负样本数量
import pandas as pd
data = pd.read_csv('./test.csv')
# 获取正样本的数量
z = data[data['label'] == 1]
# 获取负样本的数量
f = data[data['label'] == 0]
上采样
就是不断复制样本少的数据达到和样本多的数据平衡
frac = int(len(f) / len(z))
# 创建一个数据结构和之前一致,但空的dataframe
zcopy = z.iloc[0:0].copy()
# 上采样就是复制少量的样本直到和多量的达到平衡
for i in range(frac):
if i != frac:
zcopy = zcopy.append(z)
sample_data = pd.concat([zcopy,f])
查看采样的结果:
下采样
下采样就是从多量的样本中抽取一部分数据直到和少量的样本达到平衡
- 利用dataframe的sample方法
frac = float(len(z) / len(f))
# 下采样就是从多量的样本中抽取一部分数据直到和少量的样本达到平衡
sample_data = pd.concat([f.sample(frac=frac),z])
结果:
2. 利用np.random.choice() (个人感觉有点繁琐,不推荐)
import numpy as np
# 得到所有正样本的索引
z_index = np.array(z.index)
# 下采样就是从多量的样本中抽取一部分数据直到和少量的样本达到平衡,并取其索引
random_f_index = np.random.choice(f.index,len(z),replace = False)
random_f_index = np.array(random_f_index)
# 有了正样本负样本后把它们的索引都拿到手
under_sample_indices = np.concatenate([z_index,random_f_index])
# 根据索引得到下采样所有样本点
under_sample_data = data.iloc[under_sample_indices,:]
结果:
后记
这篇博客主要讲解上下采样的操作。这里在补充一些采样相关知识:
采样常用方法
- 简单随机采样
简单随机采样是最基本的采样方法,即从数据集中随机选择一定数量的样本。Python中可以使用random.sample函数进行简单随机采样,示例如下:
import random
sampled_data = random.sample(data, sample_size)
其中,data是原始数据集,sample_size是需要采样的样本数量。
2. 分层采样
分层采样是一种根据目标特征对数据集进行划分,并在各个划分层中进行采样的方法。这样可以保证在采样过程中样本的分布与原始数据集的分布相似。例如,在一个客户数据集中,可以根据年龄段将用户划分为不同的层,并在每个年龄段中进行采样。Python中可以使用stratified_sample库进行分层采样,示例如下:
from stratified_sample import stratified_sample
stratified_sampled_data = stratified_sample(data, target_variable, sample_size)
其中,data是原始数据集,target_variable是划分层的目标特征,sample_size是需要采样的样本数量。
3. 系统采样
系统采样是一种按照固定间隔从数据集中选择样本的方法,适用于大规模的数据集。例如,可以按照每隔10个样本选择一个样本的方式进行系统采样。Python中可以使用切片操作来实现系统采样,示例如下:
system_sampled_data = data[::10]
其中,data是原始数据集,10是采样间隔。
采样注意事项
- 样本的代表性
采样样本应该尽可能地代表原始数据集的分布和特征,以减少采样偏差。 - 采样数量的确定
样本的数量需要根据具体情况来确定,过少的样本可能导致模型过拟合,而过多的样本可能增加计算和存储成本。 - 采样方法的选择
根据问题的要求和数据的特点,选择合适的采样方法。简单随机采样适用于一般情况,而分层采样和系统采样更适用于特定需求。