海量数据随机选取

转自更详细的大神博客

问题1:在不知道文件总行数的情况下,如何从文件中随机的抽取一行,并且每行被抽中的概率相等?
问题2:在不知道文件总行数的情况下,如何从文件中随机的抽取 k 行,并且每行被抽中的概率相等?

问题一:抽取一行

在知道文件行数的情况下,直接用 rand 函数就可以
不知道文件行数的时候,我们需要一个概念来使得对每一行取出的概率相等,也即随机。这个概念即蓄水池抽样
解决方案:

  1. 直接选取第一行作为我们的最后选择:choice
  2. 1/2 的概率,将choice换成第二行
  3. 1/3 的概率,将choice换成第三行
  4. 。。。
  5. 1/i 的概率,将choice换成第 i 行
  6. 。。。
  7. 1/n 的概率,将choice换成第 n 行

为什么这样可以呢,是有数学方面严格证明的
证明如下:

其实知道每行被选取的概率的公式之后,自己就可以推导

海量数据随机选取

问题二:抽取 K 行(问题一的扩展)

当理解了问题一,其实问题二就很好理解,可以将 k 行数据看做一个整体
解题思路:

  1. 读取第 i 行,以 k/i 概率决定是否要把它换入蓄水池,
  2. 如果要换入,换入时随机的选取一个作为替换项(这时候池子里面有 k 项,可以使用 rand 函数)

这样的话,对于任意的 n ,都能保证每个数的选取概率都为 k/n,每个数选取概率相等,即随机。

证明如下:

重点在于每行被选取的概率的公式,理解之后,稍微化简一下就可以推导出来。

海量数据随机选取

相关文章: