3

假设我们在数据库中有 5000 个用户。用户行有性别列、出生地点列和状态(已婚或未婚)列。

如何生成满足这些条件的随机子集(假设 100 个用户):

  • 40% 应该是男性,60% 应该是女性
  • 50%应该出生在美国,20%出生在英国,20%出生在加拿大,10%在澳大利亚
  • 70%应该结婚,30%不应该。

这些条件是独立的,也就是说我们不能这样做:

  • (0.4 * 0.5 * 0.7) * 100 = 14 位男性用户,在美国出生并已婚
  • (0.4 * 0.5 * 0.3) * 100 = 6 位男性用户,出生于美国且未婚。

这一代有算法吗?

4

5 回答 5

2

细分需要准确还是近似?通常,如果您要生成这样的样本,那么您正在做一些统计研究,因此生成一个近似样本就足够了。

以下是如何执行此操作:

有一个函数 genRandomIndividual()。

每次生成一个个体时,使用随机函数选择性别 - 男性,概率为 40%

再次使用随机函数选择出生地点(只需在 0-1 区间内生成一个实数,如果落在 0-.5,则选择 USA,如果 .5-.7,则选择 &K,如果 .7-.9 则选择 Canada,否则澳大利亚)。

使用随机函数选择已婚状态(再次生成 0-1,如果 0-.7 则已婚,否则不生成)。

一旦你有了一组特征,在数据库中搜索满足这些特征的第一个个体,将它们添加到你的样本中,并将其标记为已经添加到数据库中。继续这样做,直到你完成了你的样本量。

可能没有满足这些特征的个体。然后,只需生成一个新的随机个体。由于世代是独立的并根据所需的概率生成特征,因此最终您将拥有正确大小的样本大小,其中个体根据指定的概率随机生成。

于 2009-12-21T19:58:41.507 回答
1

你可以尝试这样的事情:

  • 选择一个随机的初始集合 100
  • 直到你有正确的分配(或放弃):
    • 选择一个不在集合中的随机记录,以及一个随机记录
    • 如果交换另一条记录使您更接近所需的集合,请交换它们。否则,不要。

我可能会使用与所需分布的距离平方和作为决定是否交换的指标。

这就是使集合保持随机性的原因。请记住,可能没有与您所追求的分布相匹配的子集。

于 2009-12-19T21:22:12.613 回答
1

请务必注意,您可能无法找到满足这些条件的子集。举个例子,假设您的数据库只包含美国男性和澳大利亚女性。显然,您无法生成任何满足您的分布约束的子集。

于 2009-12-21T20:03:45.257 回答
0

(Rewrote my post completely (actually, wrote a new one and deleted the old) because I thought of a much simpler and more efficient way to do the same thing.)

I'm assuming you actually want the exact proportions and not just to satisfy them on average. This is a pretty simple way to accomplish that, but depending on your data it might take a while to run.

First, arrange your original data so that you can access each combination of types easily, that is, group married US men in one pile, unmarried US men in another, and so on. Then, assuming that you have p conditions and you want to select k elements, make p arrays of size k each; one array will represent one condition. Make the elements of each array be the types of that condition, in the proportions that you require. So, in your example, the gender array would have 40 males and 60 females.

Now, shuffle each of the p arrays independently (actually, you can leave one array unshuffled if you like). Then, for each index i, take the type of the picked element to be the combination from the shuffled p arrays at index i, and pick one such type at random from the remaining ones in your original group, removing the picked element. If there are no elements of that type left, the algorithm has failed, so reshuffle the arrays and start again to pick elements.

To use this, you need to first make sure that the conditions are satisfiable at all because otherwise it will just loop infinitely. To be honest, I don't see a simple way to verify that the conditions are satisfiable, but if the number of elements in your original data is large compared to k and their distribution isn't too skewed, there should be solutions. Also, if there are only a few ways in which the conditions can be satisfied, it might take a long time to find one; though the method will terminate with probability 1, there is no upper bound that you can place on the running time.

于 2009-12-22T09:12:14.227 回答
0

算法这个词可能太强了,因为对我来说这意味着形式主义和出版,但是有一种方法可以选择具有精确比例的子集(假设你的百分比从样本宇宙中产生整数),而且它比其他简单得多提出的解决方案。我已经构建了一个并对其进行了测试。

顺便说一句,我很抱歉在这里反应迟钝,但是这些天我的时间有限。我相当快地编写了一个硬编码的解决方案,从那以后我一直在将它重构为一个体面的通用实现。因为一直很忙,所以还没说完,但我不想再耽误回答了。

方法:

基本上,您将分别考虑每一行,并根据您的标准是否为您提供选择每个列值的空间来决定它是否可选。

为此,您需要将每个列规则(例如,40% 的男性、60% 的女性)视为一个单独的目标(例如,给定所需的 100 子集大小,您正在寻找 40 个男性、60 个女性)。为每个人做一个计数器。

然后循环,直到您创建了子集,或者您检查了示例 Universe 中的所有行但没有找到匹配项(请参阅下面的内容)。这是伪代码中的循环:

- Randomly select a row.  
- Mark the row examined.
- For each column constraint:
    * Get the value for the relevant column from the row
    * Test for selectability:
        If there's a value target for the value, 
        and if we haven't already selected our target number of incidences of this value, 
        then the row is selectable with respect to this column
    * Else: the row fails.
- If the row didn't fail, select it: add it to the subset

这就是它的核心。它将提供一个与您的规则匹配的子集,否则它将无法这样做......这让我想到了当我们找不到匹配项时会发生什么。

不满意:

正如其他人所指出的,对于任意样本宇宙,并不总是能够满足任意一组规则。即使假设规则是有效的(每个值的百分比总和为 100),子集大小小于宇宙大小,并且宇宙确实包含足够的具有每个选定值的个体来达到目标​​,如果值实际上并不是独立分布的。

考虑样本宇宙中所有男性都是澳大利亚人的情况:在这种情况下,您只能选择尽可能多的男性,您可以选择澳大利亚人,反之亦然。因此,即使我们选择的所有澳大利亚人都是男性,也无法从这样的宇宙中满足一组约束(子集大小:100;男性:40%;澳大利亚人 10%)。

如果我们改变约束条件(子集大小:100;男性:40%;澳大利亚人 40%),现在我们可以创建一个匹配的子集,但是我们选择的所有澳大利亚人都必须是男性。如果我们再次更改约束条件(子集大小:100;男性:20%;澳大利亚人 40%),现在我们可以制作一个匹配的子集,但前提是我们不选择太多澳大利亚女性(不超过一半这个案例)。

在后一种情况下,选择顺序很重要。根据我们的随机种子,有时我们可能会成功,有时我们可能会失败。

出于这个原因,算法必须(我的实现确实)准备好重试。我认为这是一个耐心测试:问题是在我们决定约束与样本总体不兼容之前,我们愿意让它失败多少次。

适应性

该方法非常适合描述的 OP 任务:选择与给定标准匹配的随机子集。不适合回答一个稍微不同的问题:“是否有可能形成具有给定标准的子集”。

我对此的推理很简单:算法无法找到子集的情况是数据包含未知链接,或者标准允许样本宇宙中的子集数量非常有限。在这些情况下,任何子集的使用对于统计分析都是有问题的,至少在没有进一步考虑的情况下是这样。

但是为了回答是否可以形成子集的问题,这种方法是不确定的和低效的。最好使用其他人提出的更复杂的随机排序算法之一。

预验证:

发现并非所有子集都可以满足的直接想法是执行一些初始验证,并且可能分析数据以查看它是可回答的还是只能有条件回答的。

我的立场是,除了最初验证每个列规则是有效的(即列百分比总和为 100,或足够接近)并且子集大小小于全域大小之外,没有其他值得事先验证正在做。可以提出一个论点,即您可能想要检查宇宙中每个选定值是否包含足够多的个体(例如,宇宙中实际上有 40 名男性和 60 名女性),但我没有实现。

除此之外,任何识别群体中联系的分析本身都是耗时的,如果通过更多的重试来运行这个东西,你可能会得到更好的服务。也许这只是我缺乏统计背景的说法。

不完全是子集和问题

有人建议这个问题就像子集和问题。我认为这是微妙而显着的不同。我的推理如下:对于子集和问题,您必须形成并测试一个子集才能回答它是否符合规则的问题:在添加之前不可能(除非在某些边缘条件下)测试单个元素它到子集。

但是,对于OP的问题,这是可能的。正如我将解释的,我们可以随机选择行并单独测试它们,因为每行的权重为 1。

于 2010-04-16T12:52:21.620 回答