【问题标题】:R: How to get a sum of two distributions?R:如何获得两个分布的总和?
【发布时间】:2016-03-14 01:33:24
【问题描述】:

我有一个简单的问题。 我想对两个非参数分布求和。

这是一个例子。 有两个城市有 10 个房子。我们知道每个房子的能源消耗。 (已编辑)我想获得从每个城市中选择的随机房屋之和的概率分布。

A1 <- c(1,2,3,3,3,4,4,5,6,7) #10 houses' energy consumption for city A
B1 <- c(11,13,15,17,17,18,18,19,20,22) #10 houses' energy consumption for city B

我有一个 A1 和 B1 的概率分布,如何得到 A1+B1 的概率分布? 如果我只在 R 中使用A1+B1,它会给出12 15 18 20 20 22 22 24 26 29。但是,我认为这是不对的。因为房子里没有秩序。

当我改变房子的顺序时,它会给出另一个结果。

# Original
A1 <- c(1,2,3,3,3,4,4,5,6,7)
B1 <- c(11,13,15,17,17,18,18,19,20,22)
#change order 1
A2 <- c(7,6,5,4,4,3,3,3,2,1) 
B2 <- c(22,20,19,18,18,17,17,15,13,11)
#change order 2
A3 <- c(3,3,3,4,4,5,6,7,1,2) 
B3 <- c(17,17,18,18,19,13,20,11,22,15)
sum1 <- A1+B1; sum1
sum2 <- A1+B2; sum2
sum3 <- A3+B3; sum3

红线是 sum1、sum2 和 sum3。我不确定如何获得两个分布之和的分布。请给我任何想法。谢谢!

(如果这些分布是正态分布或均匀分布,我可以很容易地得到分布的总和,但这些不是正态分布,没有顺序)

【问题讨论】:

    标签: r sum distribution


    【解决方案1】:

    难道不是在添加之前对分布进行排序就可以解决这个问题吗?

    A1 <- c(1,2,3,3,3,4,4,5,6,7) #10 houses' energy consumption for city A
    B1 <- c(11,13,15,17,17,18,18,19,20,22) #10 houses' energy consumption for city B
    sort(A1)+sort(B1)
    

    【讨论】:

    • 没有。提问者要问的是来自 A 的随机元素加上来自 B 的随机元素之和的分布。正如上面的经验证明,对于小样本,这可以通过考虑所有可能的对来近似(这不适用于大样本)。您正在做的是成对添加值,这既不正确(因为您只考虑每个点一对),而且即使它是正确的,也假设样本大小相等,这通常不是正确的。
    【解决方案2】:

    理论上,两个随机变量的和分布是它们的PDF的卷积,details,为:

    PDF(Z) = PDF(Y) * PDF(X)

    所以,我认为这种情况可以通过convolution来计算。

    # your data
    A1 <- c(1,2,3,3,3,4,4,5,6,7) #10 houses' energy consumption for city A
    B1 <- c(11,13,15,17,17,18,18,19,20,22) #10 houses' energy consumption for city B
    
    # compute PDF/CDF
    PDF_A1 <- table(A1)/length(A1)
    CDF_A1 <- cumsum(PDF_A1)
    
    PDF_B1 <- table(B1)/length(B1)
    CDF_B1 <- cumsum(PDF_B1)
    
    # compute the sum distribution 
    PDF_C1 <- convolve(PDF_B1, PDF_A1, type = "open")
    
    # plotting
    plot(PDF_C1, type="l", axe=F, main="PDF of A1+B1")
    box()
    axis(2)
    # FIXME: is my understand for X correct?
    axis(1, at=seq(1:14), labels=(c(names(PDF_A1)[-1],names(PDF_B1))))
    

    注意:

    CDF:累积分布函数

    PDF:概率密度函数

    ## To make the x-values correspond to actually sums, consider
    ## compute PDF
    ## pad zeros in probability vectors to convolve
    r <- range(c(A1, B1))
    pdfA <- pdfB <- vector('numeric', diff(r)+1L)
    PDF_A1 <- table(A1)/length(A1)                        # same as what you have done
    PDF_B1 <- table(B1)/length(B1)
    pdfA[as.numeric(names(PDF_A1))] <- as.vector(PDF_A1)  # fill the values
    pdfB[as.numeric(names(PDF_B1))] <- as.vector(PDF_B1)
    
    ## compute the convolution and plot
    res <- convolve(pdfA, rev(pdfB), type = "open")
    plot(res, type="h", xlab='Sum', ylab='')
    

    ## In this simple case (with discrete distribution) you can compare
    ## to previous solution
    tst <- rowSums(expand.grid(A1, B1))
    plot(table(tst) / sum(as.vector(table(tst))), type='h')
    

    【讨论】:

    • 我不想这么说,但我以前不知道卷积。我一直在阅读,但无法完全掌握,特别是关于 R 中可用的不同 type 参数。你有指向最喜欢的解释的链接吗?我已经阅读了您的 Wikipedia 链接,以及关于卷积的 Wiki,以及其他一些搜索者。任何其他的赞赏。
    • @slickrickulicious 感谢您的编辑和解决方案。也是很好的学习资料:)
    • 感谢你们两位; @slickrickulicious 在阅读了更多内容后,我认为 convolve 可以通过使第二个参数代表“内核”来在 2D 网格上执行某种空间平滑。我不知道如何让它工作。这是对该功能的潜在适当使用吗?如果是这样,我可能会在这里提出另一个问题,显示我的尝试和期望的结果。
    • @rbatt,非常好的blog 用于卷积。
    • 非常感谢! slickrickulicious、rbatt 和 Patric。我认为这是我问题的正确答案。我能再问一件事吗?是否可以使用反卷积或其他方法获得 A1+B1 的变量?例如(12,13,14,14,...,21,21,21,21,21,....28,29)
    【解决方案3】:

    编辑:

    现在我更好地理解了这个问题,并看到了@jeremycg 的回答,我认为我有一种不同的方法,我认为它可以更好地适应样本量。

    与其依赖 A1B1 中的值作为分布中的唯一值,我们可以推断这些只是分布中的样本。为了避免对分布施加特定形式,我将使用经验“等效”:样本密度。如果我们使用density 函数,我们可以推断从任一城镇对连续范围的家庭能源使用进行采样的相对概率。我们可以从density()$x 值中随机抽取任意数量的能量(有替换),其中我们采用的sampleprob=density()$y 加权...即,密度图中的峰值位于 x-应该更频繁地重新采样的值。

    作为一种启发式,一个过于简单的陈述可能会说mean(A1) 是 3.8,mean(B1) 是 17,因此这两个城市的能源消耗总和平均应该是 ~20.8。将其用作“是否有意义测试”/启发式,我认为以下方法符合您想要的结果类型。

    sample_sum <- function(A, B, n, ...){
        qss <- function(X, n, ...){
            r_X <- range(X)
            dens_X <- density(X, ...)
            sample(dens_X$x, size=n, prob=dens_X$y, replace=TRUE)
        }
    
        sample_A <- qss(A, n=n, ...)
        sample_B <- qss(B, n=n, ...)
    
        sample_A + sample_B
    }
    
    ss <- sample_sum(A1, B1, n=100, from=0)
    
    png("~/Desktop/answer.png", width=5, height=5, units="in", res=150)
    plot(density(ss))
    dev.off()
    

    请注意,我将密度图限制在 0,因为我假设您不想推断负能量。我看到合成密度的峰值刚好在 20 以上,所以“这是有道理的”。

    这里的潜在优势是,您无需查看两个城市房屋中所有可能的能源组合,即可了解总能源使用的分布情况。如果你能定义两者的分布,你就可以定义成对和的分布。

    最后,计算时间是微不足道的,尤其是与查找所有组合的方法相比。例如,每个城市有 1000 万套房屋,如果我尝试执行 expand.grid 方法,我会收到 Error: cannot allocate vector of size 372529.0 Gb 错误,而 sample_sum 方法需要 0.12 秒。

    当然,如果答案对你没有帮助,那么速度就一文不值;)

    【讨论】:

    • 感谢您的回答。抱歉,我的问题不太清楚。我想绘制两个城市的能源总和分布,而不是仅仅梳理两个城市。
    • @user3309420 当您说“总和”时,您是指将每个城市的房屋配对,然后将它们的使用情况相加吗?从统计学上讲,这对我来说没有任何意义;至少对于我能想象的任何情况都不是。我开始怀疑这是否更像是一个统计问题。
    • 我更改了我的问题以使其更清楚。我的意图是每个城市的那对房子的总和。这是从每个城市中选择的随机房屋之和的概率分布。 (我有A和B的概率分布,怎么才能得到A+B的概率分布?)
    • 感谢您的努力!这很有帮助!
    • 简直太棒了,可扩展性。谢谢!
    【解决方案4】:

    你可能想要这样的东西:

    rowSums(expand.grid(A1, B1))
    

    使用 expand.grid 将为您提供 A1 和 B1 的所有组合的数据框,rowSums 将添加它们。

    【讨论】:

    • 谢谢!我认为这是个好主意!我只是想知道这在理论上或统计上是否正确。能否请您提供更多背景信息?
    • 这取决于你想要什么。这是从每个城市中选择的随机房屋之和的概率分布。另一个答案也是一个很好的答案,具体取决于您的具体目标。
    • "这是从每个城市中随机选择的房子之和的概率分布" 这就是我想要的! ;) 谢谢!
    • 还有一个问题,在这种情况下,每栋楼只有10栋房子。所以。我们需要 10 * 10 的组合来得出分布。但是,如果房屋数量增加,比如说 10,000,则需要 10,000 * 10,000,这可能是模拟的负担。你有减少它的想法吗?你认为我应该使用抽样方法吗?
    • @jeremycg 我根据我认为您正在做的事情以及 OP 想要的内容对我的答案进行了编辑。你认为这是相同的基本思想吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    • 2010-09-30
    • 2019-02-20
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 2014-01-15
    相关资源
    最近更新 更多