【问题标题】:Generating a random sample for a given probability distribution为给定的概率分布生成随机样本
【发布时间】:2020-01-10 10:10:39
【问题描述】:

我有一个带有 pdf f(x)=4xe^-x 的随机变量 X,其中 x>0

我如何从这个分布中抽取一个大小为 1000 的随机样本?

【问题讨论】:

  • 到目前为止你尝试过什么?你看过inverse transform sampling吗?另外,您的“初学者问题”的背景是什么?在家工作?自习?等等。
  • @maydin 您应该将其发布为答案,以便我们实际上可以否决它,因为它根本不会生成正确的分布
  • @ChrisHaug 我不明白你的意思。函数在上面,x 值也在上面。那么问题是什么?我刚刚生成了随机选择的 x 值的 y 值。也许我没有清楚地理解这个问题。
  • @maydin 我认为您误读了这个问题,因为生成的样本没有所需的分布(对于 x>0,密度 f(x) = 4xe^{-x}),那就是全部。您生成的样本以 4/e 为界,但实际上大多数样本应该比这更大。

标签: r random statistics probability


【解决方案1】:

这是Gamma distribution,shape=a=2 和 scale=1。

q <- rgamma(1000, shape = 2, scale = 1)

【讨论】:

    【解决方案2】:

    一个简单的解决方案是rejection sampling(尽管在Severin Pappadeux's answer below 上查看我的cmets)。一个通用的拒绝采样算法很容易在 R 中实现(如果它没有在 几个 包中实现,我会感到惊讶,我只是没有查找哪些包具有这样的功能):

    #' Rejection sampling
    #' 
    #' @param f A function calculating the density of interest
    #' @param g A function giving the proposal density
    #' @param rg A function providing random samples from g
    #' @param M A numeric vector of length one giving a bound on the the ratio
    #'   f(x) / g(x). M must be > 1 and greater than or equal to f(x) / g(x) over
    #'   the whole support of X.
    #' @param n An integer vector of length one giving the number of samples to
    #'   draw; the default is ten thousand.
    #' @param ... Further arguments to be passed to g and rg
    rejection_sampling <- function(f, g, rg, M, n = 10000, ...) {
        result <- numeric(n)
        for ( i in 1:n ) {
            reject <- TRUE
            while ( reject ) {
                y <- rg(n = 1, ...)
                u <- runif(1)
                if ( u < ( f(y) / (M * g(y, ...)) ) ) {
                    result[i] <- y
                    reject <- FALSE
                }
            }
        }
        return(result)
    }
    

    然后我们可以使用它从您的分布中获取样本,并将样本的密度与真实概率密度一起绘制,看看它的效果如何:

    x <- seq(0.01, 15, 0.01)
    f <- function(x) 4 * x * exp(-x)
    y <- f(x)
    set.seed(123)
    z <- rejection_sampling(f = f, g = dexp, rg = rexp, M = 10, n = 1e3, rate = 1/4)
    dens <- density(z, from = 0.01, to = 15)
    scaling_constant <- max(y) / max(dens$y)
    plot(x, y, type = "l", xlab = "x", ylab = "f(x)", lty = 2, col = "blue")
    lines(dens$x, dens$y * scaling_constant, col = "red", lty = 3)
    legend("topright", bty = "n", lty = 2:3, col = c("blue", "red"),
           legend = c("True f(x)", "(Re-scaled) density of sample"))
    

    拒绝抽样的工作原理是从提案分布中抽取样本,如果随机均匀偏差大于比率f(x) / M g(x),则拒绝它们,其中g(x) 是您的提案密度,Mf(x) / g(x) 的界限如上面 Roxygen 文档中的简要描述。

    我在上面使用了速率参数为 1/4 的指数建议分布。你可以使用其他人。

    这个 p.d.f.如Severin Pappadeux's answer 所述,与形状为 2、比例为 1 的 Gamma 分布成正比。 (也就是说,如果你将这些参数插入到 Gamma p.d.f. 中,你会发现它与你的只是一个缩放常数不同)。根据您这样做的目的,这可能是更好的方式,或者这种方式。我不确定您的目标是从任意分布中生成样本例如作为示例,或者您需要来自此分布本身的样本等。通常最好识别是否你的任意pdf实际上是一个已实现分布的示例,但如果您不在这种情况下,则需要诸如拒绝抽样之类的东西。

    【讨论】:

    • 你的评论在哪里?
    • @SeverinPappadeux 对不起,我的意思是评论。当我第一次看到你的答案时,当数学不等于完全时,我有一个短暂的失误。但是,后来我意识到它当然只是被一个缩放常数所抵消,因此是成比例的,这就是你所需要的。所以,我回答的最后一段解释说你的回答当然是正确的(因此我赞成),我只提供更通用的算法,以防 OP 遇到无法表达他们的自定义 pdf 的情况。作为(例如)伽玛分布
    猜你喜欢
    • 2015-05-18
    • 1970-01-01
    • 2014-10-06
    • 2016-01-06
    • 2020-07-02
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    相关资源
    最近更新 更多