分类目录:《机器学习中的数学》总目录
蓄水池抽样算法(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 最终结果数组
我们现在来验证一下分布式蓄水池抽样算法每个数据被抽到的概率是否为:
- 对于第台机器中的数据,被抽中到第台机器的结果数组的概率为
- 次循环后,每个数据被选入最终结果数组的概率为