分类目录:《机器学习中的数学》总目录
蓄水池抽样算法(Reservoir Sampling Algorithm)解决了未知长度数据的均匀抽样问题,即:给定一个数据流,数据流长度很大,且
直到处理完所有数据之前都不可知,请问如何在只遍历一遍数据的情况下,能够随机选取出
个不重复的数据,且每个数据被取到的概率都为
?
这个问题有3个主要难点:
- 数据流长度
很大且不可知,不能一次性存入内存
- 算法时间复杂度为
- 随机选取
个数,每个数被选中的概率为
第1点主要说明由于我们无法直接确定,导致我们无法直接求出每个数被取到的概率
,也就不能直接取
内的
个随机数,然后按索引取出数据。第2点限制了不能先遍历一遍得到数据总量
,然后分块存储数据,再随机选取。第3点是数据选取绝对随机的保证。
蓄水池抽样算法(Reservoir Sampling Algorithm)
输入:数组
( 1 )初始化长度为结果数组
( 2 )初始化数组读入索引
( 3 ) while 数组未遍历到末尾
( 4 )if
( 5 )将
加入到结果数组
( 6 )else
( 7 )在
随机取一个整数
,若
在
范围内,则将
存入
( 8 )![]()
( 9 )return 数组
蓄水池抽样算法(Reservoir Sampling Algorithm)的精妙之处在于,对于未知长度的数组,其每个数被选中的概率都为
。设
为未知长度数组的数据索引(从0开始),则:
- 若
:这些数据直接被存入结果数组
,遍历结束时仍留在结果数组
的概率为:
- 若
:这些数据被存入数组的概率为
,被存入数组的概率为且遍历结束时仍留在结果数组
的概率为:
若数据量过于庞大,需要使用台机器处理数据,则可以使用分布式蓄水池抽样算法:
分布式蓄水池抽样算法
输入:数据流;机器总数
( 1 )将数据流分成份:
、
、
、
或依次向
台机器输入数据
( 2 )每台机器单独使用蓄水池抽样算法,抽样个数据
、
、
、
,并统计单台机器的数据总量
、
、
、
( 3 ) 计算数据总量并初始化长度为
最终结果数组
( 4 ) for
( 5 )在
随机取一个整数
( 6 )若
,则从
中无放回的随机抽取一个数据放入最终结果数组
;若
,则从
中无放回的随机抽取一个数据放入最终结果数组
;
;若
,则从
中无放回的随机抽取一个数据放入最终结果数组
( 7 )return 最终结果数组
我们现在来验证一下分布式蓄水池抽样算法每个数据被抽到的概率是否为:
- 对于第
台机器中的数据,被抽中到第
台机器的结果数组
的概率为
次循环后,每个数据被选入最终结果数组
的概率为