蓄水池抽样

背景:从n个元素中随机抽取k个元素,但n的个数无法事先确定。在实际应用中,往往会遇到很大数据流的情况。因此,我们无法先保存整个数据流然后再从中选取,而是期望有一种将数据流遍历一遍就得到所选取的元素,并且保证得到的元素是随机的算法。

问题:在时间复杂度为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]:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值