Notes

Reservoir Sampling

June 30, 2022

抽样问题

当我们需要从 n 个元素中随机抽取 k 个元素,且 n 非常大,无法将所有数据一次性载入内存。

此时可以采用 Reservior Sampling 算法。

抽样方法

  1. 读取 $$k$$ 个元素,存入数组 $$R$$。

  2. 对于 $$x_k$$ 之后的每个元素 $$x_i$$,生成一个随机数 $$j \in [1, i]$$。

    a. 如果 $$j \in [1, k]$$,则更新数组中的元素 $$R[j]$$ 为 $$x_i$$。

    b. 否则丢弃 $$x_i$$。

归纳证明

  1. 当 $$n = k$$ 时,所有元素都会被抽取。概率为 $$1 = \frac{k}{n}$$。

  2. 增加 $$n$$ 至 $$n + 1$$,按照算法 $$x_{n+1}$$ 被抽中的概率为 $$\frac{k}{n + 1}$$。

    对于前面的 $$n$$ 个元素,没有加入 $$x_{n+1}$$ 之前,被抽中的概率为 $$\frac{k}{n}$$。

    加入 $$x_{n+1}$$ 后,被抽中的概率为 $$\frac{k}{n} \times (1 - \frac{1}{n + 1}) = \frac{k}{n + 1}$$。

参考资料

  1. https://en.wikipedia.org/wiki/Reservoir_sampling