惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
S
SegmentFault 最新的问题
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
爱范儿
爱范儿
月光博客
月光博客
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog
T
Tailwind CSS Blog
美团技术团队
D
Docker
V
Visual Studio Blog
Martin Fowler
Martin Fowler
博客园 - 聂微东
The Cloudflare Blog

又见苍岚

COLMAP PatchMatch Stereo 算法详解 事件驱动的状态机框架:从理论到工程实践 Git 在国内网络环境下无法 Push 的排查与修复 —— 配置 Clash 代理 分段五次多项式插值原理详解 路径插值方法深度对比研究 Claude Code 使用指南 OpenClaw 记忆管理与技能创建指南 CBS(Conflict-Based Search)算法详解 A* 算法及其变种详解 OpenClaw 配置多 Agents Windows Powershell 无法加载文件,因为在此系统上禁止运行脚本问题的解决方案 MaxClaw 安装流程 大模型 AI 名词介绍 AList 网盘聚合工具简介 Protobuf 简介与测试 Claude Code 简介以及 GLM 4.7 模型接入 Github 歌词下载工具 163MusicLyrics Python __getattr__ 懒加载 Python TypedDict 机器人仿真平台 Gazebo 安装记录 机器人仿真平台 Gazebo 简介 多机器人路径规划问题(Multi-Agent Path Finding, MAPF)简介 Python exifread 读取修改过的 jpeg 信息错误问题修复 3D 坐标系变换的理解 3D 旋转矩阵基本概念 MongoDB Compass 介绍 Python 环境管理工具 uv Flutter 开发指南 Snipaste 安装下载与黑屏问题解决方案 全局路径规划算法记录
Reservoir Sampling 蓄水池采样算法
Yiwei Zhang · 2023-07-14 · via 又见苍岚

长数据流的随机采样可以使用蓄水池采样算法,本文记录相关内容。

简介

问题描述:给定一串很长的数据流,对该数据流中数据只能访问一次,使得数据流中所有数据被选中的概率相等。

解决类似这样的问题,就可以利用 蓄水池算法(Reservoir Sampling)。

基本原理

假设需要采样的数量为 $ k $ 。

  1. 首先构建一个 $ k $ 个元素的数组,将序列的前 $ k $ 个元素放入数组中。
  2. 对于从第 $j $ 个元素 $(j>k)$ ,以 $\frac{k}{j}$ 的概率来决定该元素是否被替换到数组中,数组中的 $k$ 个元素被替换的概率是相同的。
  3. 当遍历完所有元素之后,数组中剩下的元素即为采样样本

证明

假设我们真的按照 $\frac{k}{j}$ 的概率来决定该元素是否被替换到数组中,有如下结论:

  1. 对于第 $i$ 个元素 $(i \le k)$ :

    • 在 $k$ 步之前,被选中的概率为 1。

    • 当走到第 $k+1$ 步时

      第 i 个元素被第 k+1 个元素替换的概率 $=$ 第 k+1 个元素被选中的概率 $\times$ 第 i 个元素被选中替换的概率

      即:
      $$
      \frac{k}{k+1} \times \frac{1}{k}=\frac{1}{k+1}
      $$
      那么,第 $i$ 个元素不被第 $k+1$ 个元素替换的概率为 : $1-\frac{1}{k+1}=\frac{k}{k+1} $

      以此类推,第 $i$ 个元素不被第 $t$ ($t>k$)个元素替换掉的概率: $1-\frac{1}{t}=\frac{t-1}{t} $

    • 当来到第 $n$ 个元素时:

      第 i 个元素被保留在水池中的概率 = 第 k+1 个元素被选中的概率 $\times$ 第 k+1 个元素不被替换的概率
      $$
      p_i = 1\times \frac{k}{k+1} \times \frac{k+1}{k+2} \times \frac{k+2}{k+3} \ldots \times \frac{n-1}{n}=\frac{k}{n}
      $$

  2. 对于第 $j$ 个元素 $(j>k)$:

    • 在第 $j$ 步被选中的概率: $\frac{k}{j}$

    • 第 $j+1$ 步没有被替换掉的概率: $1-\frac{k}{j+1} \times \frac{1}{k}=\frac{j}{j+1} $

    • 当递推到第 $n$ 个元素时: 被保留的概率 = 被选中的概率 $\times$ 不被替换的概率,即:
      $$
      p_j= \frac{k}{j} \times \frac{j}{j+1} \times \frac{j+1}{j+2} \ldots \times \frac{n-1}{n}=\frac{k}{n}
      $$

  3. 因此对于每个元素,被保留的概率都是 $\frac{k}{n}$

应用示例

考虑长度为 $n$ 的数组,设定目标 $t$ ,要求便利数组过程中挑出和 $t$ 值相等的数字的下标,使得每个等于 $t$ 的值被选中的概率相等。

应用

遍历长度为n的数组。当第 $i$ 次遇到 $t$ 的元素时,随机选择区间 $[0, i)$ 内的一个整数,如果其等于0,则将返回值置为该元素的下标,否则返回值不变(也就是判定是否触发了 $\frac{1}{i}$ 的概率)

证明

设数组中有 $k$ 个值为 $t$ 的元素,该算法会保证这 $k$ 个元素的下标最终返回值概率均为 $1/k$ ,证明:

第i次遇到值为target的元素下标成为最终返回值的概率 = 第i次随机选择的值=0的概率 x 第 i+1 次随机选择的值!=0的概率x … x 第k次随机选择的值!=0的概率
$$
p_i= \frac{1}{i} \times\left(1-\frac{1}{i+1}\right) \times \ldots \times\left(1-\frac{1}{k}\right)=\frac{1}{i} \times \frac{i}{i+1} \times \ldots \times \frac{k-1}{k}=\frac{1}{k}
$$

参考资料

文章链接:
https://www.zywvvd.com/notes/study/probability/reservoir-sampling/reservoir-sampling/