数学系列:XXX
Copyright © 1900-2016, NORYES, All Rights Reserved.
http://www.cnblogs.com/noryes/
欢迎转载,请保留此版权声明。
---------------------------------------------------------------------------------------
问题
随机抽样问题表示如下:
要求从N个元素中随机的抽取k个元素,其中N无法确定。
这种应用的场景一般是数据流的情况下,由于数据只能被读取一次,而且数据量很大,并不能全部保存,因此数据量N是无法在抽样开始时确定的;但又要保持随机性,于是有了这个问题。所以搜索网站有时候会问这样的问题。
这里的核心问题就是“随机”,怎么才能是随机的抽取元素呢?我们设想,买彩票的时候,由于所有彩票的中奖概率都是一样的,所以我们才是“随机的”买彩票。那么要使抽取数据也随机,必须使每一个数据被抽样出来的概率都一样。
解答
解决方案就是蓄水库抽样(reservoir sampling)。主要思想就是保持一个集合(这个集合中的每个数字出现),作为蓄水池,依次遍历所有数据的时候以一定概率替换这个蓄水池中的数字。
其伪代码如下:
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的更多相关文章
- [数]数学系列预习->补水题ver.
---恢复内容开始--- 话说要学反演了,contest一题都搞不定,整理题目暂且搁置,数学笨蛋来学一下数学_(:з」∠)_ ---恢复内容结束--- 是的,预习看了半天教学,没有整理,做题又都不会, ...
- Python解释数学系列——分位数Quantile
跳转到我的博客 1. 分位数计算案例与Python代码 案例1 Ex1: Given a data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36],求Q1, ...
- 少儿编程|Scratch编程教程系列合集,总有一款适合你
如果觉得资源不错,友情转发,贵在分享!!! 少儿编程Scratch: 少儿编程Scratch第一讲:Scratch完美的初体验少儿编程Scratch第二讲:奇妙的接球小游戏少儿编程Scratch第三讲 ...
- 收集一些关于OI/ACM的奇怪的东西……
一.代码: 1.求逆元(原理貌似就是拓展欧几里得,要求MOD是素数): int inv(int a) { if(a == 1) return 1; return ((MOD - MOD / a) * ...
- 【分享】SAS统计分析软件学习教程电子书合集下载
SAS是著名的统计分析软件,全称为Statistics Analysis System,最早由北卡罗来纳大学的两位生物统计学研究生编制,并于1976年成立了SAS软件研究所,正式推出了SAS软件. 转 ...
- Alink漫谈(十九) :源码解析 之 分位点离散化Quantile
Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 目录 Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 0x00 摘要 0x01 背景概念 1.1 离散化 1 ...
- Luatools v2烧录教程(适用于2G、4G Cat.1、4G Cat.4模块)
目录,可以根据需要直接点击跳转: 下载LuaTools工具 2G模块烧写教程(Air2xx系列.Air8xx系列) 连接模块 刷入AT版本的lod 刷入任意的lod固件 下载lua脚本文件 [4G 模 ...
- Java基础语法与流程控制
Java基础语法与流程控制 跟着狂神学Java的第二天O(∩_∩)O~,养成一个总结的习惯 志同道合的小伙伴可以一起学习狂神的视频 本节地址:https://www.kuangstudy.com/co ...
- 【函数】Oracle函数系列(2)--数学函数及日期函数
[函数]Oracle函数系列(2)--数学函数及日期函数 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不 ...
随机推荐
- 判断iframe加载完成
一.js判断 var parFrame = document.getElementById("oIframe"); if(parFrame.attachEvent){ parFra ...
- validate表单验证插件
1.引入validate.js包 <script src="xx/xx/jquery.validate.min.js"></script> 2.表单验证 / ...
- 接口返回值中数组中包含多个json对象形式
返回数据Json: { "code": , "msg": "成功", "departmentlist": [ { &qu ...
- webapi-创建项目
- PowerShell Notes
1. 概要 - PowerShell 是cmdlet(command-let)的指令集合,类似unix的bash. - IDE: Windows PowerShell ISE,不区分大小写,可以用命 ...
- TaskCompletionSource<TResult>
参考:https://blogs.msdn.microsoft.com/pfxteam/2009/06/02/the-nature-of-taskcompletionsourcetresult/
- 360浏览器遇到文档模式是IE7的解决办法
这段时间遇到了360浏览器在加载java项目时,默认的文档模式是IE7,使得网页加载下拉框出现问题. 解决的方法是: 在显示的jsp页面加上 <meta http-equiv="X-U ...
- 利用exp/imp备份恢复数据库实例
用exp/imp备份数据库: Oracle数据导入导出imp/exp功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的 ...
- showPrompt弹框提示
工作中会有很多的弹框,用来添加模板,用来信息提示,,我现在用的模板有dialog(用来添加数据模板内容),还有一个就是自写的showPrompt用来判断错误或者正确的信息~~ 样子大概就是这样的,, ...
- EventBus
EventBus GitHub 上的地址 https://github.com/greenrobot/EventBus EventBus干的事情可以概括来说 别人可以根据某一个事件订阅我,但是他得去实 ...