Algorithm 基于规则的子集生成

Algorithm 基于规则的子集生成,algorithm,sample,subset,Algorithm,Sample,Subset,假设数据库中有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名在美国出生且未结婚的男性用户 这一代有算法吗?您可以尝试以下方法:

假设数据库中有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名在美国出生且未结婚的男性用户

这一代有算法吗?

您可以尝试以下方法:

  • 选择一个100的随机初始集
  • 直到您获得正确的分配(或放弃):
    • 选择一个不在集合中的随机记录,以及一个在集合中的随机记录
    • 如果在另一个记录中交换使您更接近所需的集合,请交换它们。否则,不要
我会使用距离期望分布的平方和作为决定是否交换的度量


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

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

以下是如何做到这一点:

拥有一个函数genRandomIndividual()

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

再次使用随机函数选择出生地点(只需在间隔0-1内生成一个实数,如果它下降0-.5,则选择美国,如果为.5-.7,则选择&K,如果为.7-.9,则选择加拿大,否则选择澳大利亚)

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

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


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

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

(完全重写我的文章(实际上,写了一篇新文章,删除了旧文章),因为我想到了一种更简单、更有效的方法来做同样的事情。)

我假设你真的想要精确的比例,而不仅仅是满足平均水平。这是一种非常简单的实现方法,但根据您的数据,可能需要一段时间才能运行

首先,整理原始数据,以便轻松访问每种类型的组合,也就是说,将已婚美国男性分为一组,未婚美国男性分为另一组,依此类推。然后,假设您有p个条件,并且您想要选择k个元素,则创建大小为k的p个数组;一个数组将表示一个条件。使每个数组的元素按所需的比例成为该条件的类型。因此,在您的示例中,性别数组将有40名男性和60名女性

现在,独立地洗牌每个p数组(实际上,如果您愿意,可以让一个数组不被洗牌)。然后,对于每个索引i,将拾取的元素的类型作为索引i处的混洗p数组的组合,并从原始组中的其余类型中随机拾取一个这样的类型,移除拾取的元素。如果没有该类型的元素,则算法失败,因此重新排列数组并重新开始拾取元素


要使用它,首先需要确保条件是可满足的,否则它将无限循环。老实说,我看不到一种简单的方法来验证条件是否可满足,但是如果原始数据中的元素数量比k大,并且它们的分布不是太偏斜,那么应该有解决方案。此外,如果只有几种方法可以满足条件,那么可能需要很长时间才能找到一种方法;虽然该方法的终止概率为1,但您无法确定运行时间的上限。

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

顺便说一句,我很抱歉在这里反应迟钝,但我的时间最近很紧张。我很快就写了一个硬编码的解决方案,从那以后我一直在将它重构成一个像样的通用实现。因为我一直很忙,这还没有完成,但我不想再拖延回答了

方法:

基本上,您将分别考虑每一行,并根据您的标准是否为您选择每个列值提供选择的空间。 为了做到这一点,你会考虑每一个列规则(例如,40%名男性,60%名女性)作为一个索引。

- 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