1。何时需要抽样在数据采集量小或处理大量数据困难的时期,抽样工作非常流行。这主要是由于以下原因:数据计算资源不足。计算机硬件和软件的局限性是抽样的基本原因之一,尤其是在数据密集型生物、科学和工程等领域,如果不抽样往往无法计算海量数据。数据收集限制。在很多情况下,采样已经从数据采集端开始了。例如,社会调查必须采用抽样的方法进行研究,因为不可能对所有人群进行调查。时效要求。抽样带来了局部反映全局的思想。如果方法正确,只需极少量的数据计算就可以实现对整体数据的统计分析,时效性将大大增强。具备上述条件或类似强制性要求的,仍需抽样。但是,在当前数据化运营的背景下,数据计算资源充足,数据采集终端可以通过多种方式采集更多的数据,满足时效性要求,采样工作是不是就没有必要了?其实不是的,即使满足了上述约束条件,还有很多场景还是需要使用抽样的方法来解决具体的问题。用于快速概念验证的采样。数据工作可能包括创新或常识项目。快速验证、迭代和交付此类项目的结论通常是概念验证的关键。采样方式不仅提高了计算效率,还提高了前期数据准备、数据预处理、算法实现等方面的开发,以及服务器和硬件配套方案部署的可行性、简化性和可操作性。抽样是用来解决样本不平衡问题的。不平衡问题通过欠采样、过采样和组合/积分来解决。这个过程使用抽样方法。无法实现覆盖所有样本的数据化操作场景。典型场景包括市场调研、客户线下调研分析、产品质量检测、用户电话满意度调查等,在这些场景中,不可能对所有样本进行采集、分析、处理和建模。这项工作需要进行定性分析。在定性分析工作中,通常不需要定量分析的完整假设、精确的数据和复杂的统计分析过程,更多的是采用访谈、观察和文献的方法,通过主观认识和定性分析来收集数据,寻找问题的答案。该研究主要依靠人的能力而不是密集的计算机能力来完成研究工作。如果不使用抽样方法,将很难进行定性分析。2如何抽样抽样方法一般分为两种:非概率抽样和概率抽样。非概率抽样不是按照等概率原则进行抽样,而是根据人的主观经验和状态进行判断;概率抽样是基于数学概率论,按照随机性原则进行抽样。本节其余部分描述的抽样方法是概率抽样。1.简单随机抽样这种抽样方法是根据等概率原则,直接从总样本中抽取n个样本。这种随机抽样的方法简单易行,但不保证样本能完美代表整体。这种抽样的基本前提是所有样本个体均等概率分布,但现实情况是大部分样本不是或无法判断其是否等概率分布。在简单随机抽样中,结果是一个不重复的样本集,也可以采用有放回的简单随机抽样,这样得到的样本集中就会有重复数据。这种方法适用于个体分布均匀的场景。2.等距抽样等距抽样是对种群中的每个个体依次编号,然后计算抽样间隔,然后按照固定的抽样间隔选择个体。这种操作方法简单易懂,易于实施,但当整体样本的分布表现出明显的分布规律时,容易产生偏差,如增减趋势、周期规律等。这种方法适用于具有均匀个体分布或明显均匀分布规律,无明显趋势或周期规律的数据。3.分层抽样分层抽样是先将所有个体样本按照一定的特征分为若干类,然后采用随机抽样或等距抽样的方法从每一类中选取个体组成样本。这种操作方法可以显着减少抽样误差,便于对不同类型的数据样本进行单独研究,是一种较好的实现方法。这种方法适用于具有属性、标签等分类逻辑特征的数据。4.整群抽样整群抽样是先将所有样本分成若干小组,然后随机抽取若干小组来代表总体。这种操作方法与前面三种方法的区别在于,这种方法提取的是一个小组集合,而不是每个数据个体本身。这种方法虽然简单易行,但样本分布受到小群体划分的限制,抽样误差较大。这种方法适用于小群体特征差异比较小的数据,对小群体的划分要求较高。三、抽样应注意的几个问题1、数据抽样要能反映业务背景。数据能正确反映运营背景。这看起来很简单,但实际上只有数据工作者非常熟悉操作环节和流程才有可能实现。以下是抽样不反映操作环境的常见情况。数据时效性问题:使用过时的数据(比如1年前的数据)来分析当前的经营状况。关键因素数据缺失:运行分析涉及的主要因素产生的数据未纳入抽样数据,导致无法根据主要因素得出有效结论,模型效果较差,例如,大规模促销活动带来的销售增长不在抽样范围内。不具有业务随机性:有意/无意地提取或覆盖特定的数据场景,使数据趋向于特定的分布模式,例如在进行社会调查时,用北京的抽样数据来代表全国。不考虑业务增长:在成长型公司中,公司的发展并不总是呈线性趋势,而往往呈指数趋势。这时候就需要让业务根据这个趋势来满足不同成长阶段的分析需求,而不仅仅是关注成长爆发区间。不考虑数据源的多样性:只从某一源中选取数据进行采样,使数据的分布受到数据源的限制。例如,在做各分店的销售分析时,只抽取了北方地区的数据,而忽略了其他地区的数据,结果必然有偏差。业务数据的可行性:在很多情况下,由于资金、权限和职责的限制,无法按照数据工作的要求进行数据抽样。此时应根据实际操作情况进行调整。这一点往往被很多数据工作者所忽视。2、数据采样必须满足数据分析和建模的要求数据采样必须考虑到后续的其他数据处理工作,特别是分析和建模的要求。这时,我们需要注意以下几个方面。(1)抽样样本量问题对于大多数数据分析和建模来说,数据量越大,模型拟合结果越准确。但是如何定义数据量的大小,笔者根据不同类型的数据应用,归纳出以下几个维度:时间分布至少包含一个完整的业务周期,可以满足预测。例如,对于月度销售预测,至少包括12个月的数据;对于每日销售预测,至少包含30天的数据。如果一天中包含一个特定的周期,则需要重复多个周期。同时,时间特征应充分考虑季节性、波动性、节假日等特殊规律,并尽可能包含在抽样数据中。对于预测(包括分类和回归)分析和建模,需要考虑特征个数的分布和特征值的范围(非数值)。通常,数据记录的数量必须大于特征数量和特征值范围的100倍。例如,数据集有5个特征。如果每个特征有2个取值范围,则数据记录数至少需要1000条(100×5×2)。对于关联规则分析和建模,每个主题根据关联项的数量至少需要1000条数据(每个项可以包含多个要关联的主题,例如品牌+产品+价格关联)。比如只做单品销售关联,那么单品销售记录需要1000条以上;如果同时做单品+品牌联想,那么至少需要2000条数据。对于异常检测分析和建模,无论是监督建模还是非监督建模,由于异常数据本来就是以小概率分布的,异常数据记录越多越好。以上数据记录的条数不固定。在实际工作中,如果没有具体的时间要求,笔者一般会选择适中的样本量进行分析。此时要综合考虑特征的个数、特征值域分布的个数、模型算法的适应性。、造型要求等;如果是面向机器计算的工作项,一般会选择尽可能多的数据参与计算,算法的实时性和效率相关的问题需要技术和运维人员来实现,如改进服务器配置、扩大分布式集群规模、优化底层程序代码、使用实时计算引擎和机制等。(2)不同类别采样样本的分布在做分类分析和建模问题时,数据不同类别下的样本需要均匀分布。抽样样本能准确代表所有的整体特征:非数值特征值范围的分布(如各值的相对频数比、取值范围范围等)需要与整体保持一致。数值特征的数据分布区间和各种统计量(如均值、方差、偏度等)需要与整体数据分布区间保持一致。缺失值、异常值、重复值等特殊数据的分布要与整体数据分布保持一致。异常检测类数据处理:对于异常检测类的应用,需要包含所有的异常样本。对于异常检测的分析和建模,异常数据非常稀缺,因此在采样时应首先包含异常数据。对于需要去除非业务因素的数据异常,如果存在类别特征,需要与类别特征分布保持一致;如果没有类别特征,属于无监督学习,需要与整体分布一致。4.代码实践:在Python数据采样的例子中,会使用random包和自定义代码来实现采样处理。数据源文件data2.txt、data3.txt和data4.txt位于“attachment-chapter3”中。整个示例代码分为5个部分。Part1:导入所需库importrandom#导入标准库importnumpyasnp#导入第三方库这里用到了Python自带的标准库random和第三方库Numpy。前者用于随机抽样,后者用于读取文件和制作数据。切片使用。第二部分:实现简单的随机采样data=np.loadtxt('data3.txt')#导入普通数据文件data_sample=data[random.sample([iforiinrange(len(data))],2000)]#随机抽取2000个Asampleprint(data_sample[:2])#打印出前2条数据print(len(data_sample))#打印出samplesamplesize首先通过Numpy的loadtxt方法读取数据文件。然后使用Random库中的sample方法做数据采样。由于样本库要求抽取的对象是一个序列或者集合,所以这里使用了一个列表推导,直接根据数据数据集中的记录数生成一个索引列表,然后返回样本进行随机抽样2000个;最后,从数据中直接根据指标得到随机抽样的结果。打印出前2条数据和总样本量。返回结果如下:[[-4.595013488.827416534.400965993.40332532-6.54589933]][-7.23173404-8.926925196.828308733.03780054.64450399]]2000我们使用列表推导公式生成列表索引。传统方法的实现可以这样写:ind=[]foriinrange(len(data)):ind.append(i)和这里的列表推导[iforiinrange(len(data))]exceptin语法除了更加简洁优雅外,性能也会有所提升。我们通过做下面的实验来做一个简单的测试,对0到1000000之间的每个数字进行平方并将其添加到列表中。两种方法如下:#方法一:传统方法importtimet0=time.time()#starttimeind=[]foriinrange(1000000):sqr_values=i*iind.append(sqr_values)t1=time.time()#结束时间print(t1-t0)#打印时间#方法二:列表理解importtimet0=time.time()#开始时间sqr_values=[i*iforiinrange(1000000)]t1=time.time()#结束时间print(t1-t0)#Printtime以上代码执行后输出结果为:0.392022371292114260.12700724601745605以上只是简单的计算逻辑,数据量不大。如果结合大量的数据和更复杂的操作,效率会大大提高。同样,生成器表达式和字典推导式都是非常Python化的实现方式。第三部分:实现等距采样data=np.loadtxt('data3.txt')#导入普通数据文件sample_count=2000#指定样本个数record_count=data.shape[0]#获取最大样本量width=record_count/sample_count#计算采样间隔data_sample=[]#初始化一个空白列表存放采样结果数据i=0#增加count得到对应的索引值whilelen(data_sample)<=sample_countandi*width<=record_count-1:#当样本量小于等于指定样本数且矩阵索引在有效范围内时data_sample.append(data[int(i*width)])#新样本i+=1#自增print(data_sample[:2])#打印出前2条Bar的数据print(len(data_sample))#打印出输出的样本编号首先使用Numpy的loadtxt方法读取数据文件;然后指定采样样本量为2000,通过读取原始数据的形状找到最大样本量边界,可以作为循环的终止条件之一;然后用抽样样本量除以最大样本量得到抽样区间;创建一个空列表存放最终的采样结果数据,用一个变量i进行循环增长,用于指标递增,然后进入采样条件判断过程。当样本量小于或等于指定采样数且矩阵索引在有效范围内时,需要注意的是索引从0开始,所以最大数值减1得到循环边界,否则索引会报溢出错误。通过列表的append方法,不断添加通过spacing得到的新样本。在本节后面的方法中,也会提到列表添加的extend方法。前者用于一次追加一个元素,后者用于批量追加多个。元素。i+=1指的是每次循环加1,可以写成i=i+1。最后打印出前2条数据和采样样本量。返回的结果如下:[阵列([-3.0805779,8.09020329,2.02732982,2.92353937,-6.06318211]).loadtxt('data2.txt') #导入数据带分层逻辑each_sample_count=200 #定义每个分层的样本数label_data_unique=np.unique(data2[:,-1]) #定义层次值域sample_data=[] #定义一个空列表,用于存储最终的采样数据sample_dict={} #定义一个空字典,用于显示每个分层的样本数forlabel_datainlabel_data_unique: #遍历每一个分层labelsample_list=[] #定义一个空列表用于存储临时分层数据fordata_tmpindata2: #读取每条数据ifdata_tmp[-1]==label_data: #如果最后一列数据的等于标签sample_list.append(data_tmp) #将数据添加到分层数据中each_sample_data=random.sample(sample_list,each_sample_count)#对每一层数据随机采样sample_data.extend(each_sample_data) #将采样数据追加到整体样本集sample_dict[label_data]=len(each_sample_data) #样本集统计结果print(sample_dict) #打印输出样本集的统计结果首先使用Numpy的loadtxt方法导入具有层次逻辑的Data。在此示例中,类标签作为最后一列包含在读取数据文件中。列分类标签用于分层抽样的标识。然后通过unique方法得到图层(类别标签)的取值范围,用于后续循环处理。然后定义一个空列表和一个空字典,用于存储临时分层数据、最终抽样数据,并显示每一层的样本数。下面进入正式的主循环流程,实现分层抽样:遍历各个层级标签,对数据进行层级划分。数据分为两种类型的标签(0和1)。读取每条数据,判断数据的层级标签是否与层级标签相同,如果相同则将数据添加到每个层级数据列表中。当每一个层级标签被处理时,都会得到该层级标签下的所有数据。此时使用Python内置的random库的sample方法进行采样。由于采样结果是一个列表,所以这里使用extend(而不是append)来批量追加到最终的采样数据列表中。然后通过len方法根据每层label得到的样本数统计list的长度,打印出每一层对应的样本数。结果为各层按指定数量抽取样本,输出如下:{0.0:200,1.0:200}第五部分:实现聚类抽样data3=np.loadtxt('data4.txt') #导入已经分簇的数据集label_data_unique=np.unique(data3[:,-1]) #定义簇标签取值范围print(label_data_unique) #打印出所有簇标签sample_label=随机的。sample(set(label_data_unique),2)#随机选择2个簇sample_data=[] #定义一个空列表来存放最终的采样数据foreach_labelinsample_label: #遍历每个簇标签值域fordata_tmpindata3: #遍历每个样本ifdata_tmp[-1]==each_label: #判断样本是否属于采样簇sample_data.append(data_tmp) #样本加入到最终的采样数据集print(sample_label) #打印输出样本簇标签print(len(sample_data)) #打印输出样本数据记录总数首先使用Numpy的loadtxt方法导入已经分簇的数据集。本例中,读取数据文件的最后一列存储了不同簇的标识,簇一共分为4组,标识分别为0、1、2、3。然后通过unique方法得到聚类标签的取值范围,用于聚类抽样。打印结果如下:[0.1.2.3.]然后使用Randomsample方法从簇标签中采样,这里我们定义抽取2个簇。最后,读取并追加所有属于抽取簇的数据,得到最终的样本集,打印出样本集的簇标签和样本总数。结果如下:[3.0,1.0]502由于是随机概率抽样,所以读者使用代码抽取的样本很可能与作者的例子不一致,属于正常现象。此外,读者可能会通过多次随机抽样程序获得不同的结果。上述过程中,需要考虑的重点是:如何根据不同的数据特??征、建模需求、业务背景综合考虑采样方式,得到最合适的结果码实践总结:在本节的例子中,有几个主要用到的知识点:使用Numpy的loadtxt方法读取数据文件。使用内置标准库Random库中的sample方法进行数据采样。列表通过index截取,通过len方法统计长度,通过append和extend追加。字典赋值操作。使用Numpy的unique方法获取唯一值。通过for和while循环,遍历一个可迭代对象。if条件语句的使用,尤其是单条件和多条件判断。
