为什么要进行抽样?
网上有很多文章分析,最接地气的一点:无法获得总体或获得总体成本高,这时候就需要抽样。这个成本不仅包括经济成本还包括时间成本,很多时候我们迭代一个项目,需要快速验证效果。
抽样还可以解决样本不均衡,比如通过过采样,欠采样来解决样本不均衡的问题。
如何进行抽样?
抽样方法从整体上分为非概率抽样和概率抽样两种。非概率抽样不是按照等概率的原则进行抽样,而是根据人类的主观经验和状态进行判 断;概率抽样则是以数学概率论为基础,按照随机的原则进行抽样。
抽样方法的介绍
简单随机抽样
该抽样方法是按等概率原则直接从总中抽取n个样本,这种随机样 本方法简单,易于操作;但是它并不能保证样本能完美代表总体,这种 抽样的基本前提是所有样本个体都是等概率分布的,但真实情况却是很 多数样本都不是或无法判断是否是等概率分布的。在简单随机抽样中, 得到的结果是不重复的样本集,还可以使用有放回的简单随机抽样,这样得到的样本集中会存在重复数据。该方法适用于个体分布均匀的场景。
等距抽样
等距抽样是先将总体中的每个个体按顺序编号,然后计算出抽样间 隔,再按照固定抽样间隔抽取个体。这种操作方法易于理解、简便易 行,但当总体样本的分布呈现明显的分布规律时容易产生偏差,例如增减趋势、周期性规律等。
该方法适用于个体分布均匀或呈现明显的均匀 分布规律,无明显趋势或周期性规律的数据。
分层抽样
分层抽样是先将所有个体样本按照某种特征划分为几个类别,然后 从每个类别中使用随机抽样或等距抽样的方法选择个体组成样本。这种 操作方法能明显降低抽样误差,并且便于针对不同类别的数据样本进行 单独研究,因此是一种较好的实现方法。该方法适用于带有分类逻辑的 属性、标签等特征的数据。
抽样样本量的选择
以时间为维度分布的,至少包含一个能满足预测的完整业务周 期。例如做月度销售预测的,至少包含12个月的数据;做日销售预测 的,至少包含30天的数据,如果一天中包含特定周期,则需要重复多个 周期。同时,时间性特征的要充分考虑季节性、波动性、节假日等特殊
规律,这些都要尽量包含在抽样数据中。
做预测(包含分类和回归)分析建模的,需要考虑特征数量和特征值域(非数值型)的分布,通常数据记录数要同时是特征数量和特征 值域的100倍以上。例如数据集有5个特征,假如每个特征有2个值域, 那么数据记录数需要至少在1000(100×5×2)条以上。
做关联规则分析建模的,根据关联前后项的数量(每个前项或后 项可包含多个要关联的主体,例如品牌+商品+价格关联),每个主体需 要至少1000条数据。例如只做单品销售关联,那么单品的销售记录需要 在1000条以上;如果要同时做单品+品牌的关联,那么需要至2000条 数据。
对于异常检测类分析建模的,无论是监督式还是非监督式建模, 由于异常数据本来就是小概率分布的,因此异常数据记录一般越多越 好。
如何使用SQL进行抽样分析
在ABtest测试上,通常会将用户群按照特定的条件分成若干组,然后取每组一定数量的用户(例如从总体中随机取5000个,或者随机取10%),发送对应的内容,最后查看效果。刚开始遇见这种业务上的问题时,一般按照规则提取出用户,建立对应的表,之后用union all来进行连接形成样本的测试数据。
unio
n all可以实现很多场景,比如将A渠道,B渠道,A+B渠道汇总结果放在一起进行呈现,再比如类似1-5号为一组,2-6号为一组,3-7号为一组,由于SQL的日期不可交叠性,就只能通过unio
n all来实现。
user_active 含有两个字段:user_id 和 active_date 激活日期。
(1)每个激活日期随机取1000个用户
select user_id
,active_date
,rn
from (
SELECT user_id
,acitve_date
,row_number() over(partition by acitve_date order by rand()) as rn
from user_active
) a
where rn <=1000
(2)每个激活日期随机取10%用户
select user_id
,active_date
,rn
from (
SELECT user_id
,acitve_date
,percent_rank() over(partition by acitve_date order by rand()) as rn
from user_active
) a
where rn <=0.1
(3)随机均分成100组,每组取1000个用户
ntile函数:
这是个切片分组函数,如ntile(3) over(partition by classroom order by student_id)
就是在每个班级内进行分组,同时按照学号排序,将每个班级的同学分为三组。
select user_id
,nt
,rn
from (
SELECT user_id
,nt
,row_number() over(partition by nt order by rand()) as rn --从100组中每组取1000个
from (
select user_id
,ntile(100) over (order by rand()) as nt --随机分成100组
from user_active
) a
) b
where rn <=1000
(4) 随机均分成100组,每组取10%个用户
select user_id
,nt
,rn
from (
SELECT user_id
,nt
,percent_rank() over(partition by nt order by rand()) as rn --从100组中每组取1000个
from (
select user_id
,ntile(100) over (order by rand()) as nt --随机分成100组
from user_active
) a
) b
where rn <=0.1
如何利用python进行抽样分析
(1)简单随机抽样
import random
import numpy as np
import pandas as pd
data_sample=np.random.random_sample(2000,) # 一个括号代表一维
np.savetxt(r"C:\Users\DELL\Downloads\a.txt",data_sample) # 将数据导出成txt文件
# 简单随机抽样
data = np.loadtxt(r"C:\Users\DELL\Downloads\a.txt") # 导入普通数据文件
print(type(data)) # data 是一个多维数组
data=list(data)
data_sample = random.sample(data, 2000) # 从指定数据集中随机抽取2000个样本 ,要求data是list
print (data_sample[:2]) # 打印输出前2条数据
print (len(data_sample)) # 打印输出抽样样本量
输出
<class numpy.ndarray>
[0.2829366322387824, 0.47523607958514047]
2000
(2)等距抽样
# 等距抽样
data = np.loadtxt(r"C:\Users\DELL\Downloads\a.txt") # 导入普通数据文件
sample_cnt = 2000 # 指定抽样数量
record_cnt=data.shape[0] # shape[0] 代表行数;shape[1] 代表列数
width= int(record_cnt / sample_cnt) # 计算抽样间距
print(width)
data_sample=[] # 初始化空白列表,用来存放抽样结果数据
i=0
while len(data_sample) <=sample_cnt and (i*width <= record_cnt -1):
data_sample.append(data[i*width]) # 新增样本 ,只能填写整数且不能超过范围,如果width是float那么且相乘结果也是float
i+=1
print(data_sample[:2])
print(len(data_sample))
(3) 分层抽样
# 分层抽样还可以借助 pandas 中的groupby方法
data = pd.read_excel(r"C:\Users\DELL\Downloads\分层抽样.xlsx") # 导入带有分层逻辑的数据
gbr=data.groupby("TYPE") # 按照TYPE列分组,将data按照TYPE值拆分成若干个dataframe,返回一个内存地址
typicalFracDict = {
"A": 0.4,
"B": 0.6,
}
def typicalSampling(group, typicalFracDict):
name = group.name
frac = typicalFracDict[name]
return group.sample(frac=frac)
result = data.groupby(
TYPE, group_keys=False
).apply(typicalSampling, typicalFracDict)
(4)训练测试集的划分
# sklearn中自带抽样方法
from sklearn.model_selection import train_test_split
#随机抽取 33% 的数据作为测试集,其余为训练集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
不知不觉专栏文章快要到100篇了,我想任何一件事坚持做下去,都会获得初衷之外的收获,并且时间越长收益越大。
事后总结坚持下来的原因有二:一是从专栏受益,二是读者朋友的关注点赞。
近一年时间写了Excel,可视化,SQL笔试,Python数据分析,机器学习模型,统计学,这些知识都是入行数据分析的基本技能,基本涵盖了数据分析师三年以内的知识框架,以后在这个框架内继续迭代就可。当然,想成为一名高级数据分析师更多的是分析思维和分析思路的突破,这才是优秀的分析师的内功所在。
即将100篇了,求关注,求点赞呀!