如何对自然数进行采样,使总和等于常数?

机器算法验证 分布 聚类 采样 马尔科夫过程
2022-03-25 18:29:48

假设我有个已分区/集群的项目,我想随机重新分区这些项目,以便集群大小的分布与我已经拥有的那些“相似”。我正在查看这个(也许没有帮助),试图对个自然数进行采样,例如可能是数千个,并且当前集群大小的分布会非常倾斜,有少量大集群和大量小集群。Nkxi1i=1kxi=NN

我看过超几何、二项式、几何分布,但这些似乎都不太适合我正在寻找的东西——我猜它比简单的分布更复杂,并且需要某种类型的类似马尔可夫的过程. 有人有什么想法吗?

3个回答

我相信您正在寻找的是类似于Dirichlet Process [DP] 的东西,它是分布上的分布。这不是一个容易理解的概念,但您将使用的基本度量是您开始使用的集群大小的离散分布。参数控制新分布与原始分布的“接近”程度。由于来自 DP 的样本是概率分布(在您的情况下是离散的),因此您可以将其乘以以获得集群大小。结果不会是整数,但仅将数字四舍五入不应影响您以有意义的方式尝试执行的操作。αN

编辑:不知何故,我比Dirichlet Distribution更熟悉 Dirichlet Process ,这正是您真正想要的。DP 是 DD 的无限维推广。

为了在算法上更精确,请参阅讨论随机数生成的小节。您的参数将基于您希望随机集群看起来像的集群大小。换句话说: 其中是称为浓度参数,它控制 Dirichlet 分布平均与原始簇大小分布的接近程度。更高的值意味着生成的 DD 将给出越来越接近您开始时样本量的精确分布的值。{nj}j=0k

α=(α1,...,αk)=(βn1N,...,βnkN)
βbeta

因此,算法将是:(如果您有权访问可以生成 Dirichlet 分布样本的函数,请忽略步骤 1 和 2。)

  1. 中为每个绘制独立样本yj=Gamma(αj,1)j=1..k
  2. 计算每个xj=yj/j=1kyjj
  3. 然后你有样本Dirichlet(α1,...,αk)=(x1,...,xk)
  4. 将样本乘以以获得近似的新集群大小。NN(x1,...,xk)
  5. 将结果四舍五入到最接近的自然数。(确保由于四舍五入N
  6. 填充元素随机排列的新簇。

与之前讨论的仅置换元素的选项相比,这具有的优势是集群大小分布并不总是相同的。来允许与原始集群大小相同或很小的变化在模拟中,这可能会导致更稳健的计算。β

实现目标的一种简单方法是排列标签。假设您有 10 个对象,其成员资格定义为你采取随机排列,然后你的新集群是 ,{1,2,3,4,5,6}{7,8}{9}{10}σ=(3,7,2,5,1,8,10,9,6,4){σ(1),σ(2),σ(3),σ(4),σ(5),σ(6)}={1,2,3,5,7,8}{σ(7),σ(8)}={9,10}{σ(9)}={6}{σ(10)}={4}

如果您想在集群大小中引入一些可变性,也可以这样做——例如,通过绘制大小为 Poi(6)、Poi(2)、Poi(1) 和 Poi(1) 的集群,拒绝样本加起来不等于 10。(Poi( ) 是一个 Poisson 随机变量,具有速率/预期值。)λλ

(我在阅读@whuber 的评论之前写了这篇文章。哎呀)

更新,基于有价值的@DanielJohnson 的评论:对于较大的总计值,该过程变得不切实际,因为它将拒绝大多数样本。那么,您想要做的是以对象总数为条件,然后泊松分布变为具有概率的多项式,其中Nλ1/L,,λk/L,L=λ1++λk+. 所以你的样本只是多项式的。但是,一些大小为 1 或 2 的集群可能会丢失,如果您不喜欢这样,那么您可以再次以所有集群都存在为条件。这将有效地引入较大集群大小的可变性,而较小的集群将保持其原始大小。同样,如果您发现自己经常拒绝样本,您可以使用以下组合: (1) 维护大小为 1 或 2 的集群;(2) 模拟较大规模的泊松或多项分布集群。

你能把这想象成球分布在个瓮中吗?这似乎符合您对集群的描述(您有个集群和数字)。如果每个瓮中至少需要一个球,则先在每个瓮中放 1 个球,然后为剩余的个球随机选择一个瓮。这是 R 中一种可能的实现:nkknnk

> nkballs <- function(n,k) {
+ tmp <- sample(k, n-k, replace=TRUE)
+ as.numeric( table(tmp) ) + 1
+ }
> 
> nkballs(1000, 25)
 [1] 36 47 40 52 40 28 34 43 37 35 38 33 45 37 45 45 37 34 38 46 42 34 56 46 32
> sum(.Last.value)
[1] 1000