【问题标题】:point of intersection 2 normal curves交点 2 条法线曲线
【发布时间】:2013-06-07 10:40:22
【问题描述】:

虽然我认为这是一个基本问题,但我似乎无法找出如何在 R 中计算:

两个或多个正态分布(拟合直方图)的交点(我需要 x 值),例如具有以下参数:

d=data.frame(mod=c(1,2),mean=c(14,16),sd=c(0.9,0.6),prop=c(0.6,0.4))

用我的2条曲线的均值和标准差,并支持每个模型对分布的贡献比例。

【问题讨论】:

    标签: r normal-distribution


    【解决方案1】:

    你可以使用uniroot:

    f <- function(x) dnorm(x, m=14, sd=0.9) * .6 - dnorm(x, m=16, sd=0.6) * .4
    
    uniroot(f, interval=c(12, 16))
    
    $root
    [1] 15.19999
    
    $f.root
    [1] 2.557858e-06
    
    $iter
    [1] 5
    
    $estim.prec
    [1] 6.103516e-05
    


    ETA一些博览会:

    uniroot 是一个单变量求根器,即给定一个变量x 的函数f,它找到解方程f(x) = 0x 的值。

    要使用它,您需要提供函数f,以及假定解值所在的区间。在这种情况下,f 只是两个密度之间的差异;它们相交的点将是f 为零的位置。在这个例子中,我通过绘制一个图并看到它们在 x=15 周围相交,得到了区间 (12, 16)。

    【讨论】:

    • +1,但是你能添加一些解释这是什么/它是如何工作的吗?谢谢
    • 感谢您的文字。这太棒了!
    【解决方案2】:

    抱歉,接受的答案不好。另见:intersection of two curves in matlab

    您可以使用如下函数获取两个根:

    intersect <- function(m1, s1, m2, s2, prop1, prop2){
    
    B <- (m1/s1^2 - m2/s2^2)
    A <- 0.5*(1/s2^2 - 1/s1^2)
    C <- 0.5*(m2^2/s2^2 - m1^2/s1^2) - log((s1/s2)*(prop2/prop1))
    
    (-B + c(1,-1)*sqrt(B^2 - 4*A*C))/(2*A)
    }
    

    在你的情况下:

    > intersect(14,0.9,16,0.6,0.6,0.4)
    [1] 20.0 15.2
    

    【讨论】:

      【解决方案3】:

      我同意@Flounderer 的观点,即您应该计算两个根,但提供的函数不完整。当 s1 = s2 时,A 变为零,产生 Inf 和 NaN。

      稍作修改即可完成功能:

      intersect <- function(m1, sd1, m2, sd2, p1, p2){
      
        B <- (m1/sd1^2 - m2/sd2^2)
        A <- 0.5*(1/sd2^2 - 1/sd1^2)
        C <- 0.5*(m2^2/sd2^2 - m1^2/sd1^2) - log((sd1/sd2)*(p2/p1))
      
        if (A!=0){
          (-B + c(1,-1)*sqrt(B^2 - 4*A*C))/(2*A)
        } else {-C/B}
      } 
      m1=0; sd1=2; m2=2.5; sd2=2; p1=.8; p2=.2
      (is=intersect(m1,sd1,m2,sd2,p1,p2))
      
      xs = seq(-6, 6, by=.01)
      plot(xs, p1*dnorm(xs, m1, sd1), type= 'l')
      lines(xs, .2*dnorm(xs, m2,sd2))
      abline(v=is)
      

      使用 uniroot.all 也可以找到通用解决方案:

      library(rootSolve)
      f <- function(x, m1, sd1, m2, sd2, p1, p2){
        dnorm(x, m1, sd1) * p1 - dnorm(x, m2, sd2) * p2 }
      uniroot.all(f, lower=-6, upper=6, m1=m1, sd1=sd1, m2=m2, sd2=sd2, p1=p1, p2=p2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-11
        • 1970-01-01
        相关资源
        最近更新 更多