如何从非常庞大的数据集中获得无偏的随机样本?

时间:2013-04-03 21:36:32

标签: random-sample

对于我正在研究的应用程序,我需要从一个非常大的数据集中采集一小组值,从大约60万亿(并且正在增长)中获取几百个数量级。

通常我使用查看均匀随机数r(0..1)是否小于S / T的技术,其中S是我仍然需要的样本项数,T是项中的项目数。设置我还没有考虑过。

然而,有了这些新数据,我没有时间为每个值滚动模具;有太多了。相反,我想生成随机数量的条目以“跳过”,在下一个位置选择值,然后重复。这样我就可以滚动模具并访问列表S次。 (S是我想要的样本的大小。)

我希望有一种直接的方法可以做到这一点,并按照S / T测试的方式创建一个无偏见的样本。

  • 说实话,大致不偏不倚就行。

  • 这与这个人的问题有关(或多或少都是后续的):

https://math.stackexchange.com/questions/350041/simple-random-sample-without-replacement

  • 还有一个侧面问题......首先表现出来的人称之为“邮递员算法”,但我不确定他是否在拉我的腿。是吗?

2 个答案:

答案 0 :(得分:2)

这个怎么样:

  • 预先计算从0到数据集大小的随机数。
  • 订购您的号码,从低到高
  • 将连续数字之间的差异存储为跳过大小
  • 使用上面的跳过大小迭代大数据集。

...假设您收集样品的顺序无关紧要

答案 1 :(得分:1)

所以我考虑了一下,并从 http://math.stackexchange.com

获得了一些帮助

归结为:

  • 如果我一次 随机选择 n 项目,那么第一个会落在哪里?也就是说, min({r_1 ... r_n})。 math.stackexchange的一位有帮助的人将其归结为这个等式:

x = 1 - (1 - r)**(1 / n)

即, n 次幂的分布为1减去(1-r)。然后求解 x 。很简单。

  • 如果我生成一个统一的随机数并将其插入 r ,则其分布与 min({r_1 ... r_n})相同 - 与最低项目相同的方式。瞧!我只是模拟选择第一项,好像我随机选择了所有 n

  • 所以我跳过列表中的那些项目,选择那个,然后......

  • 重复直到 n 为0

这样,如果我有一个大型数据库(如Mongo),我可以跳过,find_one,skip,find_one等等。直到我拥有了我需要的所有项目。

我遇到的唯一问题是我的实现偏好列表中的第一个和最后一个元素。但我可以忍受。

在Python 2.7中,我的实现如下:

def skip(n):
    """
    Produce a random number with the same distribution as
    min({r_0, ... r_n}) to see where the next smallest one is
    """
    r = numpy.random.uniform()
    return 1.0 - (1.0 - r) ** (1.0 / n)


def sample(T, n):
    """
    Take n items from a list of size T
    """
    t = T
    i = 0
    while t > 0 and n > 0:
        s = skip(n) * (t - n + 1)
        i += s
        yield int(i) % T
        i += 1
        t -= s + 1
        n -= 1

if __name__ == '__main__':

    t = [0] * 100
    for c in xrange(10000):
        for i in sample(len(t), 10):
            t[i] += 1  # this is where we would read value i

    pprint.pprint(t)