问题描述分析:
采样问题经常会被遇到,比如:
-
从 100000 份调查报告中抽取 1000 份进行统计;
-
从一本很厚的电话簿中抽取 1000 人进行姓氏统计;
-
从 Google 搜索 “Ken Thompson”,从中抽取 100 个结果查看哪些是今年的。
既然说到采样问题,最重要的就是做到公平,也就是保证每个元素被采样到的概率是相同的。所以可以想到要想实现这样的算法,就需要掷骰子,也就是随机数算法。(这里就不具体讨论随机数算法了,假定我们有了一套很成熟的随机数算法了)
对于第一个问题,还是比较简单,通过算法生成 [0,100000−1)
[0,100000−1) 间的随机数 1000 个,并且保证不重复即可。再取出对应的元素即可。
但是对于第二和第三个问题,就有些不同了,在我们不知道数据总体规模N多大,然后需要随机选取一定数量n的测试样本,我们一般不能先算出整体数量N,然后采用N中随机选取n个样本,这样成本太高,所以,采用蓄水池算法
蓄水池算法过程:
-
假设数据序列的规模为 n,需要采样的数量的为 k。
-
首先构建一个可容纳 k 个元素的数组,将序列的前 k 个元素放入数组中。
-
然后从第 k+1 个元素开始,以 k/n 的概率来决定该元素最后是否被留在数组中(每进来一个新的元素,数组中的每个旧元素被替换的概率是相同的)。 当遍历完所有元素之后,数组中剩下的元素即为所需采取的样本。
水塘抽样由于空间小,时间复杂度低,可以用于大数据流中的随机抽样问题。
参考链接:
https://blog.youkuaiyun.com/wwxy1995/article/details/102974566