【问题标题】:Sampling from a discrete distribution in Julia从 Julia 的离散分布中采样
【发布时间】:2021-03-04 01:42:22
【问题描述】:

我想从discrete distribution 中反复采样以获得一个数字。

以下是一些实现我正在寻找的代码:

const probabilities = [0.3, 0.3, 0.2, 0.15, 0.05]
const cummulative_probabilities = cumsum(probabilities)

function pickone(cummulative_probabilities)
    n = length(cummulative_probabilities)
    i = 1
    r = rand()
    while r >= cummulative_probabilities[i] && i<n 
        i+=1
    end
    return i
end 

for i in 1:20
    println(pickone(cummulative_probabilities))
end

使用Distributions 的建议替代方案并没有削减它,因为我能得到的最接近的是以下代码:

using Random
using Distributions

const probabilities = [0.3, 0.3, 0.2, 0.15, 0.05]
mnd = Multinomial(1, probabilities)

for i in 1:20
    println(rand(mnd))
end

唉,在这种情况下,rand 返回一个带有单个 1 的整个向量,其余的都是零。

【问题讨论】:

  • 二项分布计算当试验独立且成功概率固定时,n 次试验中发生的“成功”次数。没有成功是一种可能性。由于您的算法从不生成零,因此它不会生成二项分布。
  • @pjs 我的意思是多项式抽签。有人公正地纠正了标题。

标签: julia distribution multinomial


【解决方案1】:

您似乎正在寻找加权采样,这是由 StatsBase.jl 中的sample 实现的:

julia> using StatsBase

julia> using FreqTables

julia> 

julia> proptable([pickone(cummulative_probabilities) for _ in 1:10^7])
5-element Named Array{Float64,1}
Dim1  │ 
──────┼──────────
1     │  0.300094
2     │       0.3
3     │  0.199871
4     │  0.150075
5     │ 0.0499595

julia> proptable([sample(Weights(probabilities)) for _ in 1:10^7])
5-element Named Array{Float64,1}
Dim1  │ 
──────┼──────────
1     │   0.29987
2     │  0.300086
3     │  0.199956
4     │  0.150184
5     │ 0.0499035

【讨论】:

  • 我想通了。但是非常感谢您教我有关 proptable 的知识!
【解决方案2】:

解决方案是使用加权概率抽样。

如果尚未添加,请添加 StatsBase 包

Pkg.add("StatsBase")

绘制样本:

using StatsBase
const probabilities = [0.3, 0.3, 0.2, 0.15, 0.05]
items = [i for i in 1:length(probabilities)]
weights = Weights(probabilities)

for i in 1:20
    println(sample(items, weights))
end

【讨论】:

    猜你喜欢
    • 2012-04-14
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 2017-03-01
    • 2016-04-22
    • 2011-09-02
    • 1970-01-01
    • 2019-02-04
    相关资源
    最近更新 更多