Algorithm 如何保持数据流的随机子集?

Algorithm 如何保持数据流的随机子集?,algorithm,sampling,Algorithm,Sampling,我的服务器中有一个事件流。对我来说,存储所有这些文件是不可行的,但我希望能够定期地对其中一些文件进行汇总处理。所以,我想保留流的一个子集,它是我所看到的所有内容的随机抽样,但被限制为最大大小 因此,对于每个新项,我需要一个算法来决定是将其添加到存储集中,还是丢弃它。如果我添加了它,并且我已经达到了极限,我需要一个算法来逐出其中一个旧项目 显然,只要我低于我的极限,这是很容易的(只要保存所有东西)。但是,一旦我超过了这个限制,我如何保持一个良好的随机抽样而不偏向旧的或新的项目呢 谢谢,虽然这不是您

我的服务器中有一个事件流。对我来说,存储所有这些文件是不可行的,但我希望能够定期地对其中一些文件进行汇总处理。所以,我想保留流的一个子集,它是我所看到的所有内容的随机抽样,但被限制为最大大小

因此,对于每个新项,我需要一个算法来决定是将其添加到存储集中,还是丢弃它。如果我添加了它,并且我已经达到了极限,我需要一个算法来逐出其中一个旧项目

显然,只要我低于我的极限,这是很容易的(只要保存所有东西)。但是,一旦我超过了这个限制,我如何保持一个良好的随机抽样而不偏向旧的或新的项目呢


谢谢,

虽然这不是您想要的,但它可能是您搜索的良好起点。

将样本存储在先进先出(FIFO)队列中

在样本之间设置如此多事件的采样率,或将其随机化一点-取决于事件的模式

保存每个第n个事件,或者在速率要求时保存,然后将其保留到队列的末尾


如果大小太大,请从顶部弹出一个。

指定记录每个事件的概率,并将事件存储在可索引的数据结构中。当结构的大小达到阈值时,删除一个随机元素并添加新元素。在Ruby中,您可以这样做:

@storage = []
prob = 0.002

while ( message = getnextMessage) do
    @storage.delete((rand() * @storage.length).floor) if @storage.length > MAX_LEN
    @storage << message if (rand() < prob) 
end
@storage=[]
概率=0.002
while(message=getnextMessage)do
@如果@storage.length>MAX_LEN,则删除((rand()*@storage.length).floor)

@存储这是假设您不知道将接收的事件总数,并且不需要子集中的最小元素数

arr = arr[MAX_SIZE] //Create a new array that will store the events. Assuming first index 1.
counter = 1 //Initialize a counter.

while(receiving event){
  random = //Generate a random number between 1 and counter
  if( counter == random ){
     if( counter <= MAX_SIZE ){
        arr[counter] = event
     }
     else{
        tmpRandom = //Generate a random number between 1 and MAX_SIZE
        arr[tmpRandom] = event
     }
  }
  counter =+ 1

}
arr=arr[MAX\u SIZE]//创建一个新数组来存储事件。假设第一个指数为1。
计数器=1//初始化计数器。
while(接收事件){
random=//在1和计数器之间生成一个随机数
如果(计数器==随机){

这是一个常见的面试问题

一种简单的方法是用概率k/n(或1,取较小值)保存第n个元素。如果需要删除元素以保存新样本,请逐出随机元素


这将为您提供n个元素的一致随机子集。如果您不知道n,则可以估计它并获得近似一致的子集。

这称为随机采样。来源:

数组R[k];//结果
整数i,j;
//填充储液罐阵列
对于每一个i,在1到k之间
R[i]:=S[i]
完成;
//以逐渐降低的概率替换元素
对于k+1中的每个i到长度do
j:=随机(1,i);//重要提示:包含范围

如果j,你有最小子集大小吗?Enrique,不确定你的意思。如果我只得到一个事件,我希望保存它。为了避免结构偏差(比如说,事件序列中有一种模式导致每n次都不能很好地代表整个事件),您可以为每个事件选择一个介于0和N-1之间的随机数,并在得到0时存储该事件。您将得到大致相同数量的事件,但您将抵制模式。如果您知道
N
,您还可以在
[0..N]中生成一个
k
整数样本)
并在索引“出现”时选择它们。谢谢!知道问题或算法的名称很重要。这个算法不需要排序,而洗牌方法需要排序,这是我喜欢的,因为我要将项目放入一个无序的集合中。链接已失效
array R[k];    // result
integer i, j;

// fill the reservoir array
for each i in 1 to k do
    R[i] := S[i]
done;

// replace elements with gradually decreasing probability
for each i in k+1 to length(S) do
    j := random(1, i);   // important: inclusive range
    if j <= k then
        R[j] := S[i]
    fi
done