Nothing
## EM-like algorithm for a nonparametric mixture model with
## independent repeated measures - some ID, some not
npEMindrep <- # npEMindrep is an alias (only for backward compatibility)
npEM <- function(x, mu0, blockid = 1:ncol(x),
bw=bw.nrd0(as.vector(as.matrix(x))), samebw = TRUE,
h=bw, eps=1e-8,
maxiter=500, stochastic = FALSE, verb = TRUE){
bw <- h # h is alternative bandwidth argument, for backward compatibility
x <- as.matrix(x)
n <- nrow(x) # number of subjects
r <- ncol(x) # number of measurements in each subject
u <- match(blockid, unique(blockid))
if (is.matrix(mu0))
m <- dim(mu0)[1] # mu0=centers
else
m <- mu0 # mu0=number of clusters
if(!samebw && !is.matrix(bw)) {
bw <- matrix(bw, nrow=max(u), ncol=m)
}
z.hat <- matrix(0, nrow = n, ncol = m)
tt0 <- proc.time() # for total time
## Initial Values
if(m == 1) z.hat <- matrix(1, nrow = n, ncol = m)
else{
kmeans <- kmeans(x, mu0)
for(j in 1:m)
z.hat[kmeans$cluster==j, j] <- 1
}
iter <- 0
if (stochastic) {
sumpost <- matrix(0, n, m)
}
finished <- FALSE
lambda <- matrix(0, nrow = maxiter, ncol = m)
loglik <- NULL
orderx <- xx <- list()
for(k in 1:max(u)) {
xx[[k]] <- as.vector(x[, u==k])
if (!samebw) {
orderx[[k]] = order(xx[[k]]) # only needed for IQR calculation for bw
}
}
### Cfunction <- ifelse(samebw, "KDErepeated", "KDErepeatedbw")
while (!finished) {
iter <- iter + 1
bw.old <- bw
t0 <- proc.time()
## Note: Enter loop assuming E-step is done -- i.e., z.hat in place
## M-Step
lambda[iter, ] <- colMeans(z.hat)
## density estimation step
if (stochastic) {
z <- t(apply(z.hat, 1, function(prob) rmultinom(1, 1, prob)))
cs <- colSums(z)
z.tmp <- sweep(z, 2, cs, "/")
z.tmp[, cs==0] <- 1/NROW(z.tmp) # Just in case
}
else {
cs <- colSums(z.hat)
z.tmp <- sweep(z.hat, 2, cs, "/")
z.tmp[, cs==0] <- 1/NROW(z.tmp) # Just in case
}
fkernel <- matrix(1, n, m)
h <- bw # This is for samebw == TRUE
for (k in 1:max(u)) {
r2 <- sum(u == k) # block size
if (!samebw) {
wts <- apply(z.tmp, 2, function(z) rep(z/r2, r2))
variances <- colSums(wts * outer(xx[[k]], colSums(wts * xx[[k]]), '-')^2)
iqr <- apply(as.matrix(wts[orderx[[k]],]), 2, wIQR, xx[[k]][orderx[[k]]],
already.sorted=TRUE, already.normalized=TRUE)
h <- bw[k, ] <- 0.9 * pmin(sqrt(variances), iqr/1.34) *
pmax(1,r2*n*lambda[iter, ])^(-1/5)
# Note: Doesn't allow "sample size" < 1.
# browser()
}
if(samebw){
ans <- .C(C_KDErepeated, n = as.integer(n), m = as.integer(m),
r = as.integer(r2), x = as.double(x[,u==k]),
h = as.double(h), z = as.double(z.tmp), f = double(n*m),
PACKAGE="mixtools")
} else{
ans <- .C(C_KDErepeatedbw, n = as.integer(n), m = as.integer(m),
r = as.integer(r2), x = as.double(x[,u==k]),
h = as.double(h), z = as.double(z.tmp), f = double(n*m),
PACKAGE="mixtools")
}
fkernel <- fkernel * matrix(ans$f, ncol = m)
}
lambda.f <- sweep(fkernel, 2, lambda[iter, ], "*")
## E-step (for next iteration)
z.hat <- lambda.f/rowSums(lambda.f)
loglik <- c(loglik,sum(log(rowSums(lambda.f)))) # log-likelihood
finished <- iter >= maxiter
if (stochastic) {
sumpost <- sumpost + z.hat
}
else if (iter > 1) { # This convergence criterion may be too simplistic:
maxchange <- max(abs(lambda[iter,] - lambda[iter-1,]))
if (!samebw)
maxchange <- max(maxchange, max(abs(bw.old - bw)))
finished <- finished | (maxchange < eps)
}
if (verb) {
t1 <- proc.time()
cat("iteration", iter, " lambda ", round(lambda[iter, ], 4))
cat(" time", (t1 - t0)[3], "\n")
}
}
if (!samebw) {
rownames(bw) <- paste("block", 1:max(u))
colnames(bw) <- paste("component", 1:m)
}
if (verb) {
tt1 <- proc.time()
cat("lambda ", round(lambda[iter, ], 4))
cat(", total time", (tt1 - tt0)[3], "s\n")
}
if (stochastic) {
return(structure(list(data = x, posteriors = sumpost/iter,
lambda = lambda, bandwidth = bw,
blockid = u, lambdahat = colMeans(lambda),
loglik = loglik),
class="npEM"))
}
else {
return(structure(list(data = x, posteriors = z.hat,
lambda = lambda[1:iter,], bandwidth = bw,
blockid = u, lambdahat = lambda[iter,],
loglik = loglik),
class="npEM"))
}
}
# Not sure whether the following function is really necessary:
npEMindrepbw <- function (x, mu0, blockid = 1:ncol(x), bw =
bw.nrd0(as.vector(as.matrix(x))), eps = 1e-08,
maxiter = 500, stochastic = FALSE, verb = TRUE){
npEM(x=x, mu0=mu0, blockid=blockid, bw=bw, samebw=FALSE, eps=eps,
maxiter=maxiter, stochastic=stochastic, verb=verb)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.