蓄水池抽样
2016-11-18 14:49
267 查看
背景:从n个元素中随机抽取k个元素,但n的个数无法事先确定。在实际应用中,往往会遇到很大数据流的情况。因此,我们无法先保存整个数据流然后再从中选取,而是期望有一种将数据流遍历一遍就得到所选取的元素,并且保证得到的元素是随机的算法。
问题:在时间复杂度为O(n)下对大批量甚至未知大小的数据(N)等概率随机抽取k个数。
抽样过程:顺序遍历数据N,遍历的前k个数据抽取出放入容量为k的“蓄水池”(称之为K),从第k+i(i>0)数据开始,以k/(k+i)的概率选择该数据并等概率随机替换K中元素。直到遍历结束。
先不多说,撸一串代码(从0到999这一千个整数随机抽取10个):
理解:
1、遍历的前k个元素直接选中抽样;
2、第k+1个元素:
(1)抽样的概率为k/(k+1),不抽样的概率为1/(k+1);
(2)对于前k个元素(如某元素x),x被抽样的概率为第k+1元素不被抽样的概率(1/(k+1))加上k+1元素被抽样且元素x不被选中替换的概率[k/(k+1)]*[(k-1)/k]:
3、第m个元素(m>k+1):
(1)抽样的概率为k/m,不抽样的概率为(m-k)/m;
(2)对于前k个元素(如某元素x),x被抽样概率为上一轮x已被抽样且第m元素不被抽样概率([k/(m-1)]*[(m-k)/m])加上 第m元素被抽样且上一轮x已被抽样且此轮不被选中替换的概率(k/m)*[k/(m-1)]*[(k-1)/k]:
问题:在时间复杂度为O(n)下对大批量甚至未知大小的数据(N)等概率随机抽取k个数。
抽样过程:顺序遍历数据N,遍历的前k个数据抽取出放入容量为k的“蓄水池”(称之为K),从第k+i(i>0)数据开始,以k/(k+i)的概率选择该数据并等概率随机替换K中元素。直到遍历结束。
先不多说,撸一串代码(从0到999这一千个整数随机抽取10个):
def sampling(k=10, N=np.arange(1000)): fetch = N[:k] for i in range(k, len(N)): rand = random.randint(0, i) if rand < k: fetch[rand] = N[i] print fetch return fetch
理解:
1、遍历的前k个元素直接选中抽样;
2、第k+1个元素:
(1)抽样的概率为k/(k+1),不抽样的概率为1/(k+1);
(2)对于前k个元素(如某元素x),x被抽样的概率为第k+1元素不被抽样的概率(1/(k+1))加上k+1元素被抽样且元素x不被选中替换的概率[k/(k+1)]*[(k-1)/k]:
3、第m个元素(m>k+1):
(1)抽样的概率为k/m,不抽样的概率为(m-k)/m;
(2)对于前k个元素(如某元素x),x被抽样概率为上一轮x已被抽样且第m元素不被抽样概率([k/(m-1)]*[(m-k)/m])加上 第m元素被抽样且上一轮x已被抽样且此轮不被选中替换的概率(k/m)*[k/(m-1)]*[(k-1)/k]:
相关文章推荐
- 68. 蓄水池抽样(Reservoir Sampling)
- 蓄水池抽样算法
- 大数据工程师必备之蓄水池抽样算法
- 蓄水池抽样
- 数据工程师必知算法:蓄水池抽样
- 蓄水池抽样算法
- Reservoir Sampling - 蓄水池抽样
- 有关蓄水池抽样(Reservoir Sampling)和自己的一些思考
- Reservoir Sampling 蓄水池抽样 海量数据不知道总数只能遍历一次随机抽样问题
- python实现蓄水池抽样问题
- Reservoir Sampling 蓄水池抽样
- leetcode--蓄水池抽样
- Leetcode Linked List Random Node C++(蓄水池抽样算法)
- 蓄水池抽样算法 & 随机洗牌算法
- 蓄水池抽样算法 (Reservoir Sampling Algorithm)
- 蓄水池抽样
- 谷歌面试题:从无穷尽的流中随机的选取1000个关键字(蓄水池抽样)
- 蓄水池抽样及实现
- 蓄水池抽样
- 概率事件 rand5 产生 rand3 以及在未知n大小情况以1/n的概率取数 蓄水池抽样