Copyright © 1900-2016, NORYES, All Rights Reserved.

http://www.cnblogs.com/noryes/

欢迎转载,请保留此版权声明。

---------------------------------------------------------------------------------------

问题

随机抽样问题表示如下:

要求从N个元素中随机的抽取k个元素,其中N无法确定。

这种应用的场景一般是数据流的情况下,由于数据只能被读取一次,而且数据量很大,并不能全部保存,因此数据量N是无法在抽样开始时确定的;但又要保持随机性,于是有了这个问题。所以搜索网站有时候会问这样的问题。

这里的核心问题就是“随机”,怎么才能是随机的抽取元素呢?我们设想,买彩票的时候,由于所有彩票的中奖概率都是一样的,所以我们才是“随机的”买彩票。那么要使抽取数据也随机,必须使每一个数据被抽样出来的概率都一样。

解答

    解决方案就是蓄水库抽样(reservoir sampling)。主要思想就是保持一个集合(这个集合中的每个数字出现),作为蓄水池,依次遍历所有数据的时候以一定概率替换这个蓄水池中的数字。

其伪代码如下:

Init : a reservoir with the size: k
        for    i= k+1 to N
            M=random(1, i);
            if( M <= k)
                 SWAP the Mth value and ith value
       end for

解释一下:程序的开始就是把前k个元素都放到水库中,然后对之后的第i个元素,以k/i的概率替换掉这个水库中的某一个元素,所以每个元素被替换的概率是 1/i。

证明

用数学归纳法证明,我们的初始状态是i = k + 1

我们取了前k个数,显然初始状态这k个数的存在概率是1。
    当i = k + 1时,k+1这个数以k/(k+1) 被选中去替换前k个数中的某一个。这个操作已经保证k+1这个数字是以概率k/(k+1)被保留。所以我们要证明的就是前k个数也是以k/(k+1)的概率被保留。对于这k个数中的任意一个都有两种情况,1.替换发生(k+1这个数被选中了)  2.替换没发生

我们随意取 1=< j <= k 来求第j个数的保留概率。那么根据全概率公式

P(j) = P(j | 替换发生) * P(替换发生)+  P(j | 替换没发生) * P(替换没发生)

P(替换发生) = k/(k+1)   P(替换没发生) = 1/(k+1)

P(j | 替换发生) = (k-1)/k   因为在替换发生的条件下有1/k的概率j被替换掉了

P(j | 替换没发生) =  1   原来前k个数都以1概率存在

所以

P(j) = P(j | 替换发生) * P(替换发生)+  P(j | 替换没发生) * P(替换没发生)

=  (k-1)/k  *   k/(k+1)  +   1 * 1/(k+1)

=  k / (k+1)

因为j是任意取值的所以得证。

接下来我们假设 i = n 时成立, 我们来证明i = n + 1的情况

既然i = n 时成立,所以 i = n 时任意一个数 1 <= j <= n 都以概率 k/n 出现在结果集中。

同理因为第n + 1个数以概率k/(n+1) 选中,所以无需考虑第n + 1 这个数,我们只要考虑前n个数中的任一个1 <= j <= n 在结果集中出现的概率

依然还是:

P(j) = P(j | 替换发生) * P(替换发生)+  P(j | 替换没发生) * P(替换没发生)

P(替换发生) = k/(n+1)   P(替换没发生) = (n+1-k)/(n+1)

P(j | 替换发生) = k/n * (k-1)/k   因为在替换发生的条件下有1/k的概率j被替换掉了

P(j | 替换没发生) =  k/n   前n个数都以k/n概率存在

P(j) = P(j | 替换发生) * P(替换发生)+  P(j | 替换没发生) * P(替换没发生)

=   k/(n+1) * k/n * (k-1)/k +  k/n * (n+1-k)/(n+1)

=  k*(k-1)/(n*(n+1)) + k*(n+1-k)/(n*(n+1))

=  k*(k-1+n+1-k)/(n*(n+1))

=  k/(n+1)

数学系列:XXX的更多相关文章

  1. [数]数学系列预习->补水题ver.

    ---恢复内容开始--- 话说要学反演了,contest一题都搞不定,整理题目暂且搁置,数学笨蛋来学一下数学_(:з」∠)_ ---恢复内容结束--- 是的,预习看了半天教学,没有整理,做题又都不会, ...

  2. Python解释数学系列——分位数Quantile

    跳转到我的博客 1. 分位数计算案例与Python代码 案例1 Ex1: Given a data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36],求Q1, ...

  3. 少儿编程|Scratch编程教程系列合集,总有一款适合你

    如果觉得资源不错,友情转发,贵在分享!!! 少儿编程Scratch: 少儿编程Scratch第一讲:Scratch完美的初体验少儿编程Scratch第二讲:奇妙的接球小游戏少儿编程Scratch第三讲 ...

  4. 收集一些关于OI/ACM的奇怪的东西……

    一.代码: 1.求逆元(原理貌似就是拓展欧几里得,要求MOD是素数): int inv(int a) { if(a == 1) return 1; return ((MOD - MOD / a) * ...

  5. 【分享】SAS统计分析软件学习教程电子书合集下载

    SAS是著名的统计分析软件,全称为Statistics Analysis System,最早由北卡罗来纳大学的两位生物统计学研究生编制,并于1976年成立了SAS软件研究所,正式推出了SAS软件. 转 ...

  6. Alink漫谈(十九) :源码解析 之 分位点离散化Quantile

    Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 目录 Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 0x00 摘要 0x01 背景概念 1.1 离散化 1 ...

  7. Luatools v2烧录教程(适用于2G、4G Cat.1、4G Cat.4模块)

    目录,可以根据需要直接点击跳转: 下载LuaTools工具 2G模块烧写教程(Air2xx系列.Air8xx系列) 连接模块 刷入AT版本的lod 刷入任意的lod固件 下载lua脚本文件 [4G 模 ...

  8. Java基础语法与流程控制

    Java基础语法与流程控制 跟着狂神学Java的第二天O(∩_∩)O~,养成一个总结的习惯 志同道合的小伙伴可以一起学习狂神的视频 本节地址:https://www.kuangstudy.com/co ...

  9. 【函数】Oracle函数系列(2)--数学函数及日期函数

    [函数]Oracle函数系列(2)--数学函数及日期函数 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不 ...

随机推荐

  1. Linux学习笔记<五>

    管道命令(pipe) 1.把一个命令的输出作为另一个命令的输入 ls -al /etc | less 2.选取命令:cut和grep cut命令可以将一段消息的某段切出来. -d接分隔符,-f是取出第 ...

  2. 移动端 Web 开发前端知识整理

    文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...

  3. thinkphp 3.2 join

    $res2 = M('stat_info a') ->join(C('DB_PREFIX').'stock b ON a.goods_id = b.goods_id') ->field(' ...

  4. 一道Apple公司(中国)的面试题目

    Apple在中国(上海)有公司业务,但是感觉主要是做测试工作的部门,主要是保障Apple的产品质量QE.面试的时候,面试官出了一道题目,我貌似曾今开过类似的题目,但是由于当场发挥不佳没有答出来.题目大 ...

  5. showPrompt弹框提示

    工作中会有很多的弹框,用来添加模板,用来信息提示,,我现在用的模板有dialog(用来添加数据模板内容),还有一个就是自写的showPrompt用来判断错误或者正确的信息~~ 样子大概就是这样的,, ...

  6. C#大数据文本高效去重

    C#大数据文本高效去重 转载请注明出处 http://www.cnblogs.com/Huerye/ TextReader reader = File.OpenText(@"C:\Users ...

  7. java时间类型操作

    java中Date类型与字符串相互转化 Date date = new Date();        System.out.println(date);        //DateFormat类为一个 ...

  8. 决策树-ID3

    id3:无法直接处理数值型数据,可以通过量化方法将数值型数据处理成标称型数据,但涉及太多特征划分,不建议 决策树:的最大优点在于可以给出数据的内在含义,数据形式非常容易理解: 决策树介绍:决策树分类器 ...

  9. 搭建zookeeper集群

    简介: Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置 ...

  10. JS 深浅拷贝

    首先理解概念 浅拷贝: 只复制对象的基本类型, 对象类型, 仍属于原来的引用. 深拷贝: 不紧复制对象的基本类, 同时也复制原对象中的对象.就是说完全是新对象产生的. 首先看浅拷贝 //浅拷贝 var ...