|
| 1 | +# install.packages("MCMCpack") |
| 2 | +# install.packages("mvtnorm") |
| 3 | +library(MCMCpack) |
| 4 | +library(mvtnorm) |
| 5 | + |
| 6 | +# Preprocessing |
| 7 | +Y <- iris[, 1:4]; Y <- as.matrix(Y) |
| 8 | +Z <- matrix(rep(0, 450), 150, 3) |
| 9 | +cj <- factor(iris[, 5], labels = 1:3) |
| 10 | +colnames(Z) <- c("setosa", "versicolor", "virginica") |
| 11 | + |
| 12 | +# Preparing label matrix Z |
| 13 | +# This part is optional to view real class labels |
| 14 | +for(i in 1:150) { |
| 15 | + j <- cj[i] |
| 16 | + Z[i, j] <- 1 |
| 17 | +} |
| 18 | + |
| 19 | +# Initialization of parameters |
| 20 | +w <- matrix(rep(1/3, 450), 150, 3) |
| 21 | +mu <- list(m_1 = as.matrix(colMeans(Y) + rnorm(4, 0, 1), 4, 1), |
| 22 | + m_2 = as.matrix(colMeans(Y) + rnorm(4, 0, 1), 4, 1), |
| 23 | + m_3 = as.matrix(colMeans(Y) + rnorm(4, 0, 1), 4, 1)) |
| 24 | +mu_0 <- list(m_1 = as.matrix(colMeans(Y), 4, 1), |
| 25 | + m_2 = as.matrix(colMeans(Y), 4, 1), |
| 26 | + m_3 = as.matrix(colMeans(Y), 4, 1)) |
| 27 | +sigma <- list(s_1 = cov(Y)/3, s_2 = cov(Y)/3, s_3 = cov(Y)/3) |
| 28 | +sigma_0 <- list(s_1 = cov(Y)/3, s_2 = cov(Y)/3, s_3 = cov(Y)/3) |
| 29 | + |
| 30 | +maxiter <- 2000 # Maximum number of iterations |
| 31 | + |
| 32 | +w.result <- matrix(rep(1/3, 450), 150, 3) |
| 33 | +mu.result <- list(m_1 = as.matrix(colMeans(Y) + rnorm(4, 0, 1), 4, 1), |
| 34 | + m_2 = as.matrix(colMeans(Y) + rnorm(4, 0, 1), 4, 1), |
| 35 | + m_3 = as.matrix(colMeans(Y) + rnorm(4, 0, 1), 4, 1)) |
| 36 | +sigma.result <- list(s_1 = cov(Y)/3, s_2 = cov(Y)/3, s_3 = cov(Y)/3) |
| 37 | + |
| 38 | +# Gibbs sampling main algorithm |
| 39 | +for(t in 1:maxiter) { |
| 40 | + # Assigning cluster membership probabilities |
| 41 | + # By using Mahalanobis distance between a data point and cluster means |
| 42 | + d <- matrix(rep(0, 450), 150, 3) |
| 43 | + for(i in 1:3) { |
| 44 | + d[, i] <- sqrt(mahalanobis(x = Y, center = mu[[i]], cov = sigma[[i]])) |
| 45 | + } |
| 46 | + for(i in 1:150) { |
| 47 | + d[i, ] <- prod(d[i, ]) / d[i, ] |
| 48 | + } |
| 49 | + d <- d / rowSums(d) |
| 50 | + w <- w * d; w <- w / rowSums(w) |
| 51 | + I <- matrix(rep(0, 450), 150, 3) |
| 52 | + # Updating cluster probabilities by using Dirichlet-Categorical model |
| 53 | + for(i in 1:150) { |
| 54 | + theta <- rdirichlet(1, w[i, ]*150) |
| 55 | + I[i, ] <- as.numeric(theta == max(theta)) |
| 56 | + } |
| 57 | + Cj <- colSums(I) |
| 58 | + # Updating the parameters of Gaussians |
| 59 | + sigma_hat <- list(s_1 = 0, s_2 = 0, s_3 = 0) |
| 60 | + mu_hat <- list(s_1 = 0, s_2 = 0, s_3 = 0) |
| 61 | + for(i in 1:3) { |
| 62 | + y <- Y - matrix(rep(1, 150), 150, 1) %*% t(mu[[i]]) |
| 63 | + lambda <- 0 |
| 64 | + for(j in 1:150) { |
| 65 | + lambda <- lambda + y[j, ] %*% t(y[j, ]) |
| 66 | + } |
| 67 | + sigma[[i]] <- riwish(4 + Cj[i]*4, lambda) |
| 68 | + sigma_hat[[i]] <- solve((solve(sigma_0[[i]]) + Cj[i]*solve(sigma[[i]]))) |
| 69 | + mu_hat[[i]] <- sigma_hat[[i]] %*% (t(t(mu_0[[i]]) %*% solve(sigma_0[[i]])) + solve(sigma[[i]]) %*% t(t(I[, i]) %*% Y)) |
| 70 | + mu[[i]] <- t(rmvnorm(1, mu_hat[[i]], sigma_hat[[i]])) |
| 71 | + } |
| 72 | + # Accumulating the parameters |
| 73 | + # To be divided by number of iterations later on |
| 74 | + # In order to take their average |
| 75 | + if(t > 1) { |
| 76 | + w.result <- w.result + w |
| 77 | + for(i in 1:3) { |
| 78 | + mu.result[[i]] <- mu.result[[i]] + mu[[i]] |
| 79 | + sigma.result[[i]] <- sigma.result[[i]] + sigma[[i]] |
| 80 | + } |
| 81 | + } |
| 82 | +} |
| 83 | + |
| 84 | +# Dividing the sum of parameters along the path by number of iterations |
| 85 | +# In order to obtain their estimate (average) |
| 86 | +w.result <- w.result / maxiter |
| 87 | +for(i in 1:3) { |
| 88 | + mu.result[[i]] <- mu.result[[i]] / maxiter |
| 89 | + sigma.result[[i]] <- sigma.result[[i]] / maxiter |
| 90 | +} |
| 91 | + |
| 92 | +# Test of results |
| 93 | +# With respect to cluster probabilities in the last iteration |
| 94 | +colSums(w[1:50,]) |
| 95 | +colSums(w[51:100,]) |
| 96 | +colSums(w[101:150,]) |
0 commit comments