I、概率抽样:
概率抽样的原则:(随机性原则)
总体中的每一个样本被选中的概率相等。概率抽样之所以能够保证样本对总体的代表性,其原理就在于它能够很好的按总体内在结构中所蕴含的各种随机事件的概率来构成样本,使样本成为总体的缩影。
1.简单随机抽样:
按照等概率的原则,直接从含有N个元素的总体中抽取n个元素组成的样本(N>n)
2.系统抽样(等距抽样或机械抽样):
把总体的单位进行排序,再计算出抽样距离,然后按照这一固定的抽样距离抽取样本。第一个样本采用简单随机抽样的办法抽取。
K(抽样距离)=N(总体规模)/n(样本规模)
前提条件:总体中个体的排列对于研究的变量来说,应是随机的,即不存在某种与研究变量相关的规则分布。可以在调查允许的条件下,从不同的样本开始抽样,对比几次样本的特点。如果有明显差别,说明样本在总体中的分布承某种循环性规律,且这种循环和抽样距离重合。(举例)
3.分层抽样(类型抽样):
先将总体中的所有单位按照某种特征或标志(性别、年龄等)划分成若干类型或层次,然后再在各个类型或层次中采用简单随机抽样或系统抽样的办法抽取一个子样本,最后,将这些子样本合起来构成总体的样本。
两种方法:1、先以分层变量将总体划分为若干层,再按照各层在总体中的比例从各层中抽取。2、先以分层变量将总体划分为若干层,再将各层中的元素按分层的顺序整齐排列,最后用系统抽样的方法抽取样本。
分层抽样是把异质性较强的总体分成一个个同质性较强的子总体,再抽取不同的子总体中的样本分别代表该子总体,所有的样本进而代表总体。
分层标准:
⑴以调查所要分析和研究的主要变量或相关的变量作为分层的标准。
⑵以保证各层内部同质性强、各层之间异质性强、突出总体内在结构的变量作为分层变量。
⑶以那些有明显分层区分的变量作为分层变量。
分层的比例问题:
⑴按比例分层抽样:根据各种类型或层次中的单位数目占总体单位数目的比重来抽取子样本的方法。
⑵不按比例分层抽样:有的层次在总体中的比重太小,其样本量就会非常少,此时采用该方法,主要是便于对不同层次的子总体进行专门研究或进行相互比较。如果要用样本资料推断总体时,则需要先对各层的数据资料进行加权处理,调整样本中各层的比例,使数据恢复到总体中各层实际的比例结构。
4.整群抽样:
抽样的单位不是单个的个体,而是成群的个体。它是从总体中随机抽取一些小的群体,然后由所抽出的若干个小群体内的所有元素构成调查的样本。对小群体的抽取可采用简单随机抽样、系统抽样和分层抽样的方法。
优点:简便易行、节省费用,特别是在总体抽样框难以确定的情况下非常适合。
缺点:样本分布比较集中、代表性相对较差。
一般来说,类别相对较多、每一类中个体相对较少的做法效果较好。
分层抽样与整群抽样的区别:
分层抽样要求各子群体之间的差异较大,而子群体内部差异较小;整群抽样要求各子群体之间的差异较小,而子群体内部的差异性很大。换句话说,分层抽样是用代表不同子群体的子样本来代表总体中的群体分布;整群抽样是用子群体代表总体,再通过子群体内部样本的分布来反映总体样本的分布。
多阶抽样(分段抽样):
按照元素的隶属关系后层次关系,把抽样过程分为几个阶段进行。适用于总体规模特别大,或者总体分布的范围特别广时。
类别与个体之间的平衡问题:
⑴各个抽样阶段中的子总体同质性程度
⑵各层子总体的人数
⑶研究所能提供的人力和经费
缺陷:每级抽样时都会产生误差
措施:增加开头阶段的样本数,同时适当的减少最后阶段的样本数。
II、非概率抽样:
不是按照等概率原则,而是根据人们的主观经验或其他条件来抽取样本。常用于探索性研究。
偶遇抽样:并非简单随机抽样,概率不等
判断抽样(立意抽样):抽样标准取决于调查者的主观选择
配额抽样:尽可能的根据那些影响研究变量的各种因素来对总体分层,并找出不同特征的成员在总体中所占的比例。配额抽样实际上要求在抽样前对样本在总体中的分布有准确的了解。
配额抽样与分层抽样:
前者注重的是样本与总体在结构比例上的表面一致性;后者一方面要提高各层间的异质性与同层的同质性,另一方面也是为了照顾到某些比例小的层次,使得所抽样本的代表性进一步提高,误差进一步减小。
在概率上,前者是按照事先规定的条件,有目的地寻找;后者是客观地、等概率地到各层中进行抽样。
滚雪球抽样
-----------------------
蓄水库抽样(reservoid sampling)
怎样随机从N个元素中选择一个元素,你依次遍历每个元素,但不知道N多大。
将N个元素用[1、2、...、N]编号。如果在知道N的大小,我们可以从[1、N]中随机选择一个数作为选择对象。
但是现在不知道N的大小,要使每一个元素被取的概率相等(随机)。这个概念叫蓄水池抽样。
Solution:以1/i的概率取第i个元素。
证明:数学归纳法。当i=1时:第1个元素以1/1=1的概率被取,符合条件。
设i=k时符合条件,即前k个元素都以1/k的概率被取。
则i=k+1时:对于第k+1个元素,被取概率为1/(k+1),符合条件。
对于前k个元素,每个元素被取的概率=被取并且没被第k+1个元素替换的概率=(1/k)*(1−1/(k+1))=1/(k+1)符合条件。
综上所述:得证。
将问题扩展:给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)。
这次与上面唯一的不同是:总共需要取k个元素。仿照即可得出解决方案。
Solution:以1的概率取前k个元素,从i=k+1开始,以k/i的概率取第i个元素,若被取,以均等的概率替换先前被取的k个元素。
证明:同样数学归纳法。当i=k+1时:第k+1个元素以k/k+1概率被取,前k个元素被取的概率=1 - 被第k+1个元素替换的概率=1−k/(k+1)*1/k=k/(k+1) 符合条件。
设i=p时符合条件,即前p个元素都以k/p的概率被取。
则i=p+1时:对第p+1个元素,被取概率为k/(p+1)符合条件。
对于前p个元素,每个元素被取的概率=被取并且没有被第p+1个元素替换的概率=
k/p*((1−k/(p+1))+k/(p+1)*(1−1/k))=k/p+1同样符合条件。
综上所述:得证。
另外还有一种方法:给每个元素随机生成一个固定区间(如[0,1])的权重。用一个大小为k的堆来选取权重较大的k个元素。仿照也可解决最开始的取1个的问题。
数据工程师必知算法:蓄水池抽样
引言:众所周知,想要面试一个统计学家和软件工程师的合体——数据工程师——是件很难的事情。我在面试中常使用的方法是:提出即需要算法设计,又需要一些概率论知识的问题,来考察面试者的功底。下面就是在硅谷非常流行的例子:
“给出一个数据流,这个数据流的长度很大或者未知。并且对该数据流中数据只能访问一次。请写出一个随机选择算法,使得数据流中所有数据被选中的概率相等。”
当面对这样一个问题的时候,我们首先应该做的是:镇静。你的面试官并没有玩你,相反他可能特别想雇你。他可能正在为无尽的分析请求烦恼,他的ETL流水线已经不在工作,已有的机器学习模型也不再适合。他正想要你这样一个聪明人进来帮忙,他希望你答出来。
第二件要做的事情是:不要在没有深入思考的情况下盲目作答。假设你的面试官读过Daniel Tunkelang的关于数据工程师的面试建议,那么这个面试题很可能就是他工作中实际遇到的问题。所以如果像下面一样随便回答,很可能会令你的面试官失望。
“我会首先将输入存到一个列表中,统计出数据流中数据的个数,在读取结束之后随机选取一个”(大哥, 你没看见题目已经说了,数据流长度很大或者未知么,不怕你的内存装不下?)
第三件要做的事情是:从小例子开始分析。大部分的人都更容易解决具体问题(而不是抽象问题),最开始你设计的小例子可能和最后的问题之间相去甚远,但是却能启发你对问题的理解,给你灵感。
蓄水池算法
如前面所说,对这个问题我们首先从最简单的例子出发:数据流只有一个数据。我们接收数据,发现数据流结束了,直接返回该数据,该数据返回的概率为1。看来很简单,那么我们试试难一点的情况:假设数据流里有两个数据。
我们读到了第一个数据,这次我们不能直接返回该数据,因为数据流没有结束。我们继续读取第二个数据,发现数据流结束了。因此我们只要保证以相同的概率返回第一个或者第二个数据就可以满足题目要求。因此我们生成一个0到1的随机数R,如果R小于0.5我们就返回第一个数据,如果R大于0.5,返回第二个数据。
接着我们继续分析有三个数据的数据流的情况。为了方便,我们按顺序给流中的数据命名为1、2、3。我们陆续收到了数据1、2和前面的例子一样,我们只能保存一个数据,所以必须淘汰1和2中的一个。应该如何淘汰呢?不妨和上面例子一样,我们按照二分之一的概率淘汰一个,例如我们淘汰了2。继续读取流中的数据3,发现数据流结束了,我们知道在长度为3的数据流中,如果返回数据3的概率为1/3,那么才有可能保证选择的正确性。也就是说,目前我们手里有1,3两个数据,我们通过一次随机选择,以1/3的概率留下数据3,以2/3的概率留下数据1.那么数据1被最终留下的概率是多少呢?
- 数据1被留下:(1/2)*(2/3) = 1/3
- 数据2被留下概率:(1/2)*(2/3) = 1/3
- 数据3被留下概率:1/3
这个方法可以满足题目要求,所有数据被留下返回的概率一样!
因此,我们做一下推论:假设当前正要读取第n个数据,则我们以1/n的概率留下该数据,否则留下前n-1个数据中的一个。以这种方法选择,所有数据流中数据被选择的概率一样。简短的证明:假设n-1时候成立,即前n-1个数据被返回的概率都是1/n-1,当前正在读取第n个数据,以1/n的概率返回它。那么前n-1个数据中数据被返回的概率为:(1/(n-1))*((n-1)/n)= 1/n,假设成立。
这就是所谓的蓄水池抽样算法。它在分析一些大数据集的时候非常有用。你可以在这里找到Greg写的关于蓄水池抽样的算法介绍。本文后面会介绍一下在Cloudera ML中使用的两种:分布式蓄水池抽样和加权分布式蓄水池抽样。
(注:Cloudera ML是基于hadoop的数据分析和挖掘开源项目)
蓄水池抽样在Cloudera ML上的应用
分布式蓄水池抽样是Greg讨论的第一种算法。可以从前面的讨论中发现,基本的蓄水池抽样要求对数据流进行顺序读取。要进行容量为k的分布式蓄水池抽样(前面讨论的容量都为1)我们使用mapreduce 模拟sql中的ORDER BY RAND (随机抽取)。对于集合中的每一个元素,都产生一个0-1的随机数,之后选取随机值最大的前k个元素。这种方法在对大数据集进行分层抽样的时候非常管用。这里每一个分层都都是一些分类变量如性别,年龄,地理信息等的组合。注意如果输入的数据集分布极端的不均匀,那么抽样可能不能覆盖到所有的层级。为了对每种分类的组合进行抽样,cloudera ML 提供了sample命令,它可以操作纯文本或者hive中的表。
第二个算法更加好玩:加权分布式蓄水池抽样。这里集合中的数据是有权重的,算法希望数据被抽样选中的概率和该数据的权重成比例。实际上这个问题之前并不一定有解,直到2005年pavlos efraimidis和paul spirakis的论文《weighted random sampling with a reservoir》。他们的解法既简单又优雅,基本思想和上面的分布式蓄水池抽样一致:对于每个数据计算一个0-1的值R,并求r的n次方根作为该数据的新的R值。这里的n就是该数据的权重。最终算法返回前k个R值最高的数据然后返回。根据计算规则,权重越大的数据计算所得的R值越接近1,所以越有可能被返回。
在cloudera ML项目中,为了更好地使用k-means++算法(K-均值++算法),我们会首先使用加权的蓄水池抽样算法对输入数据进行抽样。ksketch命令会为k-means++算法进行初始化–在输入数据上进行迭代操作,选择样本抽样。每次选取过程,数据被选入样本的概率和该数据与当前样本中最短距离节点的距离成比例。通过使用加权的蓄水池抽样算法,只需扫描数据一遍就能决定样本组成(一般方法需要首先遍历一次以计算出聚类的总代价,之后第二次遍历根据第一次的计算结果进行样本选择)。
要读的一些书目
很多有趣的算法都不止对写分布式文件系统或者搜索引擎的工程师有用,它们有时对于大规模数据分析和一些统计问题也特别有帮助。接下来,我会再写几篇关于算法博客。但在这之前我的说,高德纳老爷子的书常读常新,大家先去看看《计算机程序设计艺术》上面的算法吧~