拆分双峰分布

时间:2013-12-04 22:51:02

标签: r

在简历中有一篇关于此事的帖子(see here),下面(或原始链接)中的Adrian在R中有回复。但是,我对R大师的问题是我不确定这个函数的uniroot部分是做什么的。因为,我有时会收到此错误

Error in uniroot(f = f, lower = -10, upper = 10) : 
  f() values at end points not of opposite sign

因此我将lower更改为-1,对于某些数据集,我将其修复了,但其他人仍然出错。不确定是否可以根据输入向量动态设置(即x)。 指教?

library(mixtools)

simulate <- function(lambda=0.3, mu=c(0, 4), sd=c(1, 1), n.obs=10^5) {
    x1 <- rnorm(n.obs, mu[1], sd[1])
    x2 <- rnorm(n.obs, mu[2], sd[2])    
    return(ifelse(runif(n.obs) < lambda, x1, x2))
}

x <- simulate()

model <- normalmixEM(x=x, k=2)
index.lower <- which.min(model$mu)  # Index of component with lower mean

find.cutoff <- function(proba=0.5, i=index.lower) {
    ## Cutoff such that Pr[drawn from bad component] == proba
    f <- function(x) {
        proba - (model$lambda[i]*dnorm(x, model$mu[i], model$sigma[i]) /
                     (model$lambda[1]*dnorm(x, model$mu[1], model$sigma[1]) + model$lambda[2]*dnorm(x, model$mu[2], model$sigma[2])))
        }
        return(uniroot(f=f, lower=-10, upper=10)$root)  # Careful with division by zero if changing lower and upper
}

cutoffs <- c(find.cutoff(proba=0.5), find.cutoff(proba=0.75))  # Around c(1.8, 1.5)

hist(x)
abline(v=cutoffs, col=c("red", "blue"), lty=2)

1 个答案:

答案 0 :(得分:1)

uniroot是一维的根查找算法。在你打电话之前,你需要将根包括在内;为了确保这种情况,uniroot检查间隔的端点是否有相反的符号(我确信你可以看到这意味着根部已经被括起来了。)没有它,有一个)不保证在输入间隔中甚至存在根,并且b)除了幸运之外,没有办法像二分法这样的算法可以找到根。

您确定要dnorm功能中的find.cutoff而不是pnorm(累积密度)吗?例如,如果您设置标准偏差= 10,则概率密度函数的值将不会>输入proba为0.5,因此根本不会有根。