蓄水池抽样算法及其python实现
来源:互联网 发布:java基础教程 免费下载 编辑:程序博客网 时间:2024/04/28 22:43
蓄水池抽样算法
蓄水池抽样是个很有趣的问题,这个问题的来源是关于等概率抽样的一种思考,问题是,如何能在不知道总体对象数量(或者数量巨大)的情况下抽取k个对象,使得每个对象被抽取到的概率相同。解决问题的思路:考虑最终一定要抽取到k个对象,所以先任意抽出k个,然后对剩下的对象分别以某种概率概率,使得最终每个对象被抽到的概率相同。(根据分步分类计数原理即可证明)
算法流程:
- 输入:长度为N的数组L(N未知或者很大);输出:被等可能抽出的长度为k的数组l
- 对输入L取前k个数组成的数组作为蓄水池
- 对于L的第i(i=k+1,k+2,…,N)个数,任取r为0~i-1之间的整数,若r>k-1,则不进行替换,若r<=k-1,则用第i个数去替换蓄水池中第r个数
- 遍历一遍L,取到的l中的每个元素都是以概率k/n等可能取到的
python实现如下:
#coding=utf-8'''Created on 2016年9月15日Reservoir sampling的python实现@author: whz'''import numpy as npimport matplotlib.pyplot as pltdef pool(L,k): arr = L[:k] for i,e in enumerate(L[k:]): r = np.random.randint(0,k+i+1) if r<=k-1: arr[r] = e return arrdef count(q,n): L = array("d") l1 = array("d") l2 = array("d") for e in q: L.append(e) for e in range(n): l1.append(L.count(e)) for e in l1: l2.append(e/sum(l1)) return l1,l2if __name__ == '__main__': a = np.array([[i]*10000000 for i in range(3)])#生成等量的0,1,2 a.shape = 1,-1 L = a[0] k = 300000#设置要抽取的样本的数量,一般远小于总体数量 p = pool(L, k) l1 = ['value=%d'% x for x in range(3)] plt.pie(count(p,3)[0],labels=l1,labeldistance=0.1,autopct='%1.2f%%') plt.title("Reservoir sampling") plt.show()
以上代码设计了一个实验来验证蓄水池算法的准确性:总体是由0,1,2各一千万个组成的三千万个数的数组,从中抽取三十万个数,来观察抽出样本的统计特征,如下图:
验证了这种抽样方法在一定精度上能够实现等概率抽样。
0 0
- 蓄水池抽样算法及其python实现
- python实现蓄水池抽样问题
- 蓄水池抽样算法
- 蓄水池抽样算法
- 蓄水池抽样 分类: 算法
- Sampling 蓄水池抽样算法
- 蓄水池抽样算法
- 蓄水池抽样算法
- 蓄水池抽样算法
- 蓄水池抽样算法证明
- 蓄水池随机抽样算法
- 蓄水池抽样算法
- 随机抽样-蓄水池算法
- 蓄水池抽样算法
- 蓄水池抽样算法
- 蓄水池抽样及实现
- Reservoir Sampling 蓄水池抽样算法,经典抽样
- Reservior Sampling (蓄水池抽样算法)
- 微信公共平台 “token验证失败”的一个原因
- 在vs2012中使用libusb-1.0库
- 用fork创建进程时,在子进程中 使用getppid 得到的返回值为啥总是1
- 常用网站
- 一些常见HTTP状态码
- 蓄水池抽样算法及其python实现
- 51nod 1073 约瑟夫环
- 神经网络“动物园”
- svn提交忽略文件或文件夹
- linux 在多网卡下的设备的UDP 组播问题总结
- scala-problem26-30
- ubuntu16.4.sudoer
- 简单模拟Sping MVC
- Hadoop: CDH 5--不同步的 JournalNode