海量数据随机抽样问题(蓄水池问题)

2023-11-02

海量数据随机抽样问题(蓄水池问题)
随机抽样问题表示如下:
要求从N个元素中随机的抽取k个元素,其中N无法确定。
这种应用的场景一般是数据流的情况下,由于数据只能被读取一次,而且数据量很大,并不能全部保存,因此数据量N是无法在抽样开始时确定的;但又要保持随机性,于是有了这个问题。所以搜索网站有时候会问这样的问题。
这里的核心问题就是“随机”,怎么才能是随机的抽取元素呢?我们设想,买彩票的时候,由于所有彩票的中奖概率都是一样的,所以我们才是“随机的”买彩票。那么要使抽取数据也随机,必须使每一个数据被抽样出来的概率都一样。
【解决】
解决方案就是蓄水库抽样(reservoid sampling)。主要思想就是保持一个集合(这个集合中的每个数字出现),作为蓄水池,依次遍历所有数据的时候以一定概率替换这个蓄水池中的数字。
其伪代码如下:
[cpp]  view plain copy
  1. Init : a reservoir with the size: k  
  2.        for    i= k+1 to N  
  3.            M=random(1, i);  
  4.            if( M < k)  
  5.                 SWAP the Mth value and ith value  
  6.       end for  
 解释一下:程序的开始就是把前k个元素都放到水库中,然后对之后的第i个元素,以k/i的概率替换掉这个水库中的某一个元素。
下面来具体证明一下:每个水库中的元素出现概率都是相等的。
【证明】
(1)初始情况。出现在水库中的k个元素的出现概率都是一致的,都是1。这个很显然。
(2)第一步。第一步就是指,处理第k+1个元素的情况。分两种情况:元素全部都没有被替换;其中某个元素被第k+1个元素替换掉。
我们先看情况2:第k+1个元素被选中的概率是k/(k+1)(根据公式k/i),所以这个新元素在水库中出现的概率就一定是k/(k+1)(不管它替换掉哪个元素,反正肯定它是以这个概率出现在水库中)。下面来看水库中剩余的元素出现的概率,也就是1-P(这个元素被替换掉的概率)。水库中任意一个元素被替换掉的概率是:(k/k+1)*(1/k)=1/(k+1),意即首先要第k+1个元素被选中,然后自己在集合的k个元素中被选中。那它出现的概率就是1-1/(k+1)=k/(k+1)。可以看出来,旧元素和新元素出现的概率是相等的。
情况1:当元素全部都没有替换掉的时候,每个元素的出现概率肯定是一样的,这很显然。但具体是多少呢?就是1-P(第k+1个元素被选中)=1-k/(k+1)=1/(k+1)。
(3)归纳法:重复上面的过程,只要证明第i步到第i+1步,所有元素出现的概率是相等的即可。

看到一个问题:怎样随机从N个元素中选择一个元素,你依次遍历每个元素,但不知道N多大。
将N个元素用[1、2、...、N]编号。如果在知道N的大小,我们可以从[1、N]中随机选择一个数作为选择对象。
但是现在不知道N的大小,要使每一个元素被取的概率相等(随机)。这个概念叫蓄水池抽样。

Solution:以1/i的概率取第i个元素。
证明:数学归纳法。当i=1时:第1个元素以1/1=1的概率被取,符合条件。
设i=k时符合条件,即前k个元素都以1/k的概率被取。
则i=k+1时:对于第k+1个元素,被取概率为1/(k+1),符合条件。
对于前k个元素,每个元素被取的概率=被取并且没被第k+1个元素替换的概率=(1/k)*(1−1/(k+1))=1/(k+1)符合条件。
综上所述:得证。

将问题扩展:给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)。
这次与上面唯一的不同是:总共需要取k个元素。仿照即可得出解决方案。
Solution:以1的概率取前k个元素,从i=k+1开始,以k/i的概率取第i个元素,若被取,以均等的概率替换先前被取的k个元素。
证明:同样数学归纳法。当i=k+1时:第k+1个元素以k/k+1概率被取,前k个元素被取的概率=1 - 被第k+1个元素替换的概率=1−k/(k+1)*1/k=k/(k+1) 符合条件。
设i=p时符合条件,即前p个元素都以k/p的概率被取。
则i=p+1时:对第p+1个元素,被取概率为k/(p+1)符合条件。
对于前p个元素,每个元素被取的概率=被取并且没有被第p+1个元素替换的概率=
k/p*((1−k/(p+1))+k/(p+1)*(1−1/k))=k/p+1同样符合条件。
综上所述:得证。

另外还有一种方法:给每个元素随机生成一个固定区间(如[0,1])的权重。用一个大小为k的堆来选取权重较大的k个元素。仿照也可解决最开始的取1个的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海量数据随机抽样问题(蓄水池问题) 的相关文章

  • mybatis怎么忽略映射字段

    TableField exist false 表示该属性不为数据库表字段 但又是必须使用的 TableField exist true 表示该属性为数据库表字段 Mybatis Plus 插件有这个功能 可以看一下 TableName Ta
  • selenium+python切换浏览器窗口--详细讲解

    在浏览器页面打开窗口后 有时点击按钮会打开新的页面 我们需要切换到新的窗口才能去定位操作 不然无法操作 切换窗口代码如下 获取当前窗口信息及当前url current window driver current window handle
  • 如何优雅的备份MySQL数据?

    为什么要备份数据 先说一下为什么需要备份MySQL数据 一句话总结就是 为了保证数据的安全性 如果我们把数据只存储在一个地方 如果物理机器损坏 会导致数据丢失 无法恢复 还有就是我们每次手动修改线上数据之前 为了安全起见 都需要先备份数据
  • linux日志管理--rsyslog/journalctl/Logrotate

    本文针对centos系统 一 系统日志服务rsyslog 程序包 rsyslog 主程序 usr sbin rsyslogd CentOS 6 service rsyslog start stop restart status CentOS

随机推荐

  • java面向对象----抽象类 && 接口

    目录 抽象类与抽象方法 概念 抽象类应用 接 口 概念 接口的特点 接口应用举例 Java 8中关于接口的改进 内部类 如何声明局部内部类 局部内部类的特点 匿名内部类 总结 抽象类与抽象方法 概念 随着继承层次中一个个新子类的定义 类变得
  • Python 的画图函数 seaborn 简介

    seaborn 简介 seanborn 是 Python 的另外一个常用工具包 它基于 matplotlib 但画出的图形更加美观些 并且与 Pandas 的数据类型结合地较好 Import seaborn import seaborn a
  • win服务器系统授权,win服务器系统授权

    win服务器系统授权 内容精选 换一换 为了更加安全高效的使用云监控服务提供的主机监控功能 我们提供了最新方式的Agent授权方法 在安装主机监控Agent前 仅需要一键式单击该区域的授权按钮或者在创建弹性云服务器页面勾选云监控Agent委
  • 观测线程状态

    package com kuang Demo05 观察线程的状态 public class TestState public static void main String args Thread thread new Thread gt
  • JAVA模拟堆

    堆的性质 堆是一种特殊的树 只要满足以下两点 它就是一个堆 堆是一个完全二叉树 堆中每一个节点的值都必须大于等于 或小于等于 其子树中每个节点的值 第一点 堆必须是一个完全二叉树 完全二叉树要求 除了最后一层 其他层的节点个数都是满的 最后
  • Android 性能优化之资源图

    目前很多美工图都是把切给IOS的图丢给Android开发 然后苦逼的Android开发就拿着这一套图进行撸 殊不知此时的地雷已经悄悄埋好 等待着有缘人去踩 梳理一下变成雷的原因 个人拙见 假如美工给了我们一套xxhdpi的资源图 我们将这张
  • postgis各版本离线包下载

    下载地址https www postgresql org ftp postgis
  • 基于顺序存储结构的图书信息表的创建和输出

    基于顺序存储结构的图书信息表的创建和输出 描述 定义一个包含图书信息 书号 书名 价格 的顺序表 读入相应的图书数据来完成图书信息表的创建 然后统计图书表中的图书个数 同时逐行输出每本图书的信息 输入 输入n 1行 其中前n行是n本图书的信
  • 设计模式——外观模式

    一 外观模式 1 1 概述 在现实生活中 常常存在办事较复杂的例子 如办房产证或注册一家公司 有时要同多个部门联系 这时要是有一个综合部门能解决一切手续问题就好了 有些人可能炒过股票 但其实大部分人都不太懂 这种没有足够了解证券知识的情况下
  • windows+vscode+git+github 保姆级使用教程

    windows vscode git github 保姆级使用教程 关于git和github 抛开官方定义 这里通俗地解释下他们的关系 我们常用github这个网站来存取代码 基本存取的方式是git 更便捷的存取的方式是vscode 举个例
  • 【实验报告】实验三 交换机的配置

    实验三 交换机的配置 第一个实验 用两台思科2960交换机构建如下拓扑结构的局域网 作业 1 请同学们参照上诉完成对另外一个交换机的相关配置 也划分初 vlan2 vlan3 和 vlan4 配置完毕后请同学们利用 PC0 ping PC1
  • 【pulsar学习】kafka存在的问题与pulsar应用场景

    文章目录 kafka存在的问题 pulsar的应用场景 kafka存在的问题 Kafka 很难进行扩展 因为 Kafka 把消息持久化在 broker 中 迁移主题分区时 需要把分区的数据完全复制到其他 broker 中 这个操作非常耗时
  • Flutter 通过命名路游跳转页面

    1 定义路由陆游 这里我们建一个存放路游的类 定义跳转页面使用 class Routers static String root splash static String login login static String work sor
  • 一文教你玩转Mybatis,超详细代码讲解与实战

    一 Mybatis 入门 1 1 什么是MyBatis MyBatis本是apache的一个开源项目iBatis 2010年这个项目由apache software foundation迁移到了google code 并且改名为MyBati
  • vue使用elementUI中日期选择器

    vue使用elementUI中日期选择器 需求 默认选中近一个月的 仅能选择今天到三年前的日期 今天以后的日期不可选
  • cisco: L2TP over ipsec的配置(1)

    用WINDOWS的L2TP客户端进行VPN连接时默认情况下是进行IPSEC加密的 当然通过更改注册表可以使L2TP不用IPSEC加密 不过在这里我们是要在CISCO路由器下进行L2TP OVER IPSEC的相关配置 使得用户可以在不更改注
  • 文件属性与目录

    目录 Linux 系统中的文件类型 7种 普通文件 目录文件 字符设备文件和块设备文件 符号链接文件 管道文件 套接字文件 stat 函数 struct stat 结构体 st mode 变量 struct timespec 结构体 练习
  • 有了这15款编程游戏,谁都可以学编程!

    1 Coding Games 一边玩游戏 一边挑战编程难题 Coding games支持包括PHP C JavaScript在内的20多种编程语言 用户界面功能强大 可以定制 例如 你可以选择你的代码编辑器的风格 Emacs Vim Cla
  • unity 2017.3 Tips 重置场景后变暗(丢失烘焙效果)

    Unity 2017 3重置游戏场景后场景变暗 这是重置场景的代码 其实就是重新载入本场景 SceneManager LoadScene int 原因 选择的光照模式是实时光照 编辑器在当前场景时 它的灯光是已经渲染好了 但重新加载的时候灯
  • 海量数据随机抽样问题(蓄水池问题)

    海量数据随机抽样问题 蓄水池问题 随机抽样问题表示如下 要求从N个元素中随机的抽取k个元素 其中N无法确定 这种应用的场景一般是数据流的情况下 由于数据只能被读取一次 而且数据量很大 并不能全部保存 因此数据量N是无法在抽样开始时确定的 但