通过使用一组样本估算多个集合的交集的大小


10

我正在研究一种算法,该算法需要计算由至少2个集合的交集生成的集合的大小。进一步来说:

z=|A0An|

相交的集合是由SQL查询生成的,为了保持运行速度,我提前获取了每个查询的计数,然后以计数最小()的集合为准,并使用这些ID作为其余的大查询,因此交集实际上变为:A0

z=|(A0A1)(A0An)|

即使这个策略也让我有一些相当大的查询要运行,因为有时可能很大。我要解决的想法是随机抽取样本,并将其与其余集合相交,然后外推回的适当估计。我的问题是:进行采样然后外推以返回到值(如果不是完全准确的话)具有可预测的误差范围的最佳方法是什么|A0|A0zz


到目前为止,这是我尝试过的(使用伪代码):

sample_threshold := 10000
factor := 1
if (len(A0) > sample_treshold) {
    factor = sample_threshold / len(A0)
}

// Take a random sample of size 10000 from A0

// Intersect all the other sets with the A0 sample, then with each other
working_set := A0
for i, a := range A {
    a = intersect(A0, a)
    working_set = intersect(working_set, a)
}

z := len(working_set) * (1 / factor)

此代码有效,但似乎始终高估了z,较小的样本量会产生较高的估计。另外,我不确定如何将两个以上的集合相交。

我希望这个问题有意义,请让我知道是否可以进一步澄清。另外,如果这个问题不在主题范围内或属于其他地方,请告诉我,我很乐意提出。


根据Bill的评论,我进行了一些快速试验,以显示样本量与误差的关系。每个样本数量存储桶运行20次,您可以看到有一个非常明显的趋势:

情节


我认为无需替换的简单随机抽样应该有效。我对你被高估感到困惑。看起来它正好映射为使用随机样本中的样本均值估算总体均值。您正在尝试估计的元素与其他 s 相交的总体概率。我已经举了一个简单的例子,它很好用。您如何确定自己始终被高估?它发生了20次中的15次还是200次中的150次?样本真的是随机的吗?A0A
条例草案

1
@Bill我添加了一个样本数量与误差的曲线图,该曲线图说明了我所看到的。大约是20的20倍。至于随机样本,它与一样随机ORDER BY RAND(),虽然并不完美,但应该适合此任务。
Jimmy Sawczuk 2014年

@JimmySawczuk将“工作集”直接与“ a”相交而不是“ intersect(A0,a)”而不是直接相交会更好吗?因为“ A0”可能会在首次运行后大于算法中当前的“工作集” ...我是否正确理解了这一点?

您能否确认您实际上是指集合而不是多集合(即,集合中没有重复项)?因为,如果有的话,很容易通过您的方法高估“交叉点”的大小。(考虑一下只是同一元素的100个副本,而您采样了其中一半的情况。)A0
Innuo

还可以问相交的大小相对于原始集合的大小是否极小?如果是这样,我认为那可以解释您的问题。我进行了一些模拟(使用较小的集合),而且得到的估计值也相当一致,尽管很小。

Answers:


3

如果您的集包含重复的元素(即,实际上是一个多集),则相交的大小将被您的过程高估,因为比例因子使用的是采样元素的数量,而不是采样的唯一“类型”的数量。您可以通过将因子计算为随机样本中唯一元素的数量与全套中唯一元素的数量之比来校正估计值。A0A0


0

正如Innuo所指出的那样,我的问题是因为采样集的重复项导致伪代码过低,这又导致最终的外推值过高,因为它是通过的逆生成的。删除重复项解决了这个问题,现在该算法根据我期望的直线生成了增量与样本大小的曲线图(这些线表示该样本大小相对于总体人口的置信水平为95%时的误差范围):A0factorzfactor

情节

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.