Finite Mixture Model (FMM)

Finite Mixture Model (FMM) merupakan pengelompokan (clustering) berdasarkan sebaran (distribusi) dari data. Penentuan banyaknya kelompok yang terbentuk harus memenuhi suatu kriteria tertentu. Disini akan dijelaskan bagaimana cara melakukan pengelompokan dengan FMM dengan kriteria DIC (Deviance Information Criterion) dan menggunakan pendekatan Bayesian untuk mengestimasi parameternya Info lebih lanjut dapat kunjungi https://www.linkedin.com/in/dwimantara/. Untuk sitasi materi silahkan kunjungi https://iopscience.iop.org/article/10.1088/1742-6596/1494/1/012012

library(boot)
library(coda)
## Warning: package 'coda' was built under R version 4.0.2
library(R2WinBUGS)
## Warning: package 'R2WinBUGS' was built under R version 4.0.2

Import Data

Disini digunakan data Iris. perhatikan baik- baik karena FMM merupakan Unsupervised learning, maka tidak memperhatikan target sehingga target dapat dihilangkan lalu disini Untuk MODEL FMM diperlukan beberapa fitur tambahan seperti T, ALPHA, dan N

#DATA
dataset1 <- datasets::iris

# Tambahkan Fitur T
a<-c(1)
b<-data.frame(rep(c('NA'), each=148))
c<-c(2)
d<-c(3)
e<-c(4)

f<-rbind(a,b,c)
names(f)<-'T2'

g<-rbind(a,b,d)
names(g)<-'T3'

h<-rbind(a,b,e)
names(h)<-'T4'

data<-cbind(dataset1,f,g,h)
head(data)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species T2 T3 T4
## 1          5.1         3.5          1.4         0.2  setosa  1  1  1
## 2          4.9         3.0          1.4         0.2  setosa NA NA NA
## 3          4.7         3.2          1.3         0.2  setosa NA NA NA
## 4          4.6         3.1          1.5         0.2  setosa NA NA NA
## 5          5.0         3.6          1.4         0.2  setosa NA NA NA
## 6          5.4         3.9          1.7         0.4  setosa NA NA NA

Hilangkan fitur target

Jangan lupa daftarkan Masing-masing fiturnya

var1 <- data[,1:4]

N <- nrow(dataset1) 

Sepal.Length<-var1$Sepal.Length
Sepal.Width<-var1$Sepal.Width
Petal.Length<-var1$Petal.Length
Petal.Width<-var1$Petal.Width

FMM 2 Cluster

Berikut ini fitur T, nilai alpha, Inisialisasi awal untuk Bayesian FMM, serta Model FMM untuk 2 Cluster

T <- data$T2
alpha <- c(1,1)
df<-list("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","N","alpha","T")

#INIT
inits = function() {
  lambda1 = mean(var1$Sepal.Length[1:100]) +rnorm(1,0,.01)
  theta = 50
  sigma2 = var(var1$Sepal.Length[1:100])
  return(list(lambda = c(lambda1, NA),
              theta1 = theta,
              tau = 1/sigma2,
              P = c(100, 100-60)/60))
}

#MODEL
mixmodel=function() {
  for( i in 1 : N ) {
    Sepal.Length[i] ~ dnorm(mu1[i], tau)
    Sepal.Width[i] ~ dnorm(mu2[i], tau)
    Petal.Length[i] ~ dnorm(mu3[i], tau)
    Petal.Width[i] ~ dnorm(mu4[i], tau)
    mu1[i] <- lambda[T[i]]
    mu2[i] <- lambda[T[i]]
    mu3[i] <- lambda[T[i]]
    mu4[i] <- lambda[T[i]]
    T[i] ~ dcat(P[]) }
  P[1:2] ~ ddirch(alpha[])
  theta1 ~ dnorm(0.0, 1.0E-6)%_%I(0.0, )
  lambda[1] ~ dnorm(0.0, 1.0E-6)
  lambda[2] <- lambda[1] + theta1
  tau ~ dgamma(0.001,0.001)
  sigma <- 1 / sqrt(tau)
}

parameters <- c("lambda","sigma","P")

FMM.fit<-jags(df, inits=inits, parameters, n.chains=1, n.burnin=100000, 
              n.iter=200000, model.file=mixmodel, DIC=TRUE)
## module glm loaded
## Warning in jags.model(model.file, data = data, inits = init.values, n.chains =
## n.chains, : NAs introduced by coercion
## Compiling model graph
##    Resolving undeclared variables
##    Allocating nodes
## Graph information:
##    Observed stochastic nodes: 602
##    Unobserved stochastic nodes: 152
##    Total graph size: 913
## 
## Initializing model
# Jika ada notif merah setelah melakukan fitting jangan khawatir langsung PRINT saja koding print(FMM.fit)
print(FMM.fit)
## Inference for Bugs model at "C:/Users/NALEND~1/AppData/Local/Temp/RtmpWQkOVO/model3eb448231282.txt", fit using jags,
##  1 chains, each with 2e+05 iterations (first 1e+05 discarded), n.thin = 100
##  n.sims = 1000 iterations saved
##            mu.vect sd.vect     2.5%      25%      50%      75%    97.5%
## P[1]         0.497   0.258    0.049    0.293    0.484    0.708    0.942
## P[2]         0.503   0.258    0.058    0.292    0.516    0.707    0.951
## lambda[1]    3.320   0.187    2.843    3.262    3.359    3.433    3.553
## lambda[2]    3.605   0.189    3.367    3.489    3.567    3.670    4.106
## sigma        1.979   0.056    1.870    1.944    1.980    2.016    2.091
## deviance  2523.303   3.585 2515.706 2521.508 2523.109 2525.127 2530.910
## 
## DIC info (using the rule, pD = var(deviance)/2)
## pD = 6.4 and DIC = 2529.7
## DIC is an estimate of expected predictive error (lower deviance is better).

Dari sini dapat dilihat bahwa FMM dengan 2 Cluster memiliki nilai DIC seperti diatas. Selanjutnya lakukan pengelompokan menggunakan FMM dengan 3 Cluster

FMM 3 Cluster

Berikut ini fitur T, nilai alpha, Inisialisasi awal untuk Bayesian FMM, serta Model FMM untuk 3 Cluster

T <- data$T3
alpha <- c(1,1,1)
df<-list("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","N","alpha","T")

#INIT
inits2 = function() {
  lambda1 = mean(var1$Sepal.Length[1:100]) +rnorm(1,0,.01)
  theta = mean(var1$Sepal.Length[101:150])-lambda1
  theta2 = 60
  sigma2 = var(var1$Sepal.Length[1:100])
  return(list(lambda = c(lambda1, NA, NA),
              theta1 = theta,
              theta2 = theta2,
              tau = 1/sigma2,
              P = c(100, 100-60, 50)/60))
}

#MODEL
mixmodel2=function() {
  for( i in 1 : N ) {
    Sepal.Length[i] ~ dnorm(mu1[i], tau)
    Sepal.Width[i] ~ dnorm(mu2[i], tau)
    Petal.Length[i] ~ dnorm(mu3[i], tau)
    Petal.Width[i] ~ dnorm(mu4[i], tau)
    mu1[i] <- lambda[T[i]]
    mu2[i] <- lambda[T[i]]
    mu3[i] <- lambda[T[i]]
    mu4[i] <- lambda[T[i]]
    T[i] ~ dcat(P[]) }
  P[1:3] ~ ddirch(alpha[])
  theta1 ~ dnorm(0.0, 1.0E-6)%_%I(0.0, )
  theta2 ~ dnorm(0.0, 1.0E-6)%_%I(0.0, )
  lambda[1] ~ dnorm(0.0, 1.0E-6)
  lambda[2] <- lambda[1] + theta1
  lambda[3] <- lambda[2] + theta2
  tau ~ dgamma(0.001,0.001)
  sigma <- 1 / sqrt(tau)
}

parameters <- c("lambda","sigma","P")

FMM.fit<-jags(df, inits=inits2, parameters, n.chains=1, n.burnin=100000, 
              n.iter=200000, model.file=mixmodel2, DIC=TRUE)
## Warning in jags.model(model.file, data = data, inits = init.values, n.chains =
## n.chains, : NAs introduced by coercion
## Compiling model graph
##    Resolving undeclared variables
##    Allocating nodes
## Graph information:
##    Observed stochastic nodes: 602
##    Unobserved stochastic nodes: 153
##    Total graph size: 916
## 
## Initializing model
# Jika ada notif merah setelah melakukan fitting jangan khawatir langsung PRINT saja koding print(FMM.fit)
print(FMM.fit)
## Inference for Bugs model at "C:/Users/NALEND~1/AppData/Local/Temp/RtmpWQkOVO/model3eb423a23ad6.txt", fit using jags,
##  1 chains, each with 2e+05 iterations (first 1e+05 discarded), n.thin = 100
##  n.sims = 1000 iterations saved
##            mu.vect sd.vect     2.5%      25%      50%      75%    97.5%
## P[1]         0.386   0.233    0.042    0.186    0.363    0.567    0.846
## P[2]         0.228   0.186    0.010    0.079    0.180    0.330    0.696
## P[3]         0.386   0.231    0.036    0.188    0.363    0.566    0.867
## lambda[1]    3.202   0.279    2.430    3.133    3.267    3.365    3.516
## lambda[2]    3.461   0.165    3.149    3.373    3.465    3.556    3.772
## lambda[3]    3.704   0.227    3.417    3.556    3.656    3.785    4.332
## sigma        1.975   0.057    1.861    1.939    1.974    2.011    2.093
## deviance  2524.051   4.676 2515.053 2521.390 2523.947 2526.750 2533.671
## 
## DIC info (using the rule, pD = var(deviance)/2)
## pD = 10.9 and DIC = 2535.0
## DIC is an estimate of expected predictive error (lower deviance is better).

Dari sini dapat dilihat bahwa FMM dengan 3 Cluster memiliki nilai DIC seperti diatas. Selanjutnya lakukan pengelompokan menggunakan FMM dengan 4 Cluster

FMM 4 Cluster

Berikut ini fitur T, nilai alpha, Inisialisasi awal untuk Bayesian FMM, serta Model FMM untuk 4 Cluster

T <- data$T4
alpha <- c(1,1,1,1)
df<-list("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","N","alpha","T")

#INIT
inits3 = function() {
  lambda1 = mean(var1$Sepal.Length[1:100]) +rnorm(1,0,.01)
  theta = mean(var1$Sepal.Length[101:150])-lambda1
  theta2 = 60
  theta3 = 40
  sigma2 = var(var1$Sepal.Length[1:100])
  return(list(lambda = c(lambda1, NA, NA, NA),
              theta1 = theta,
              theta2 = theta2,
              theta3 = theta3,
              tau = 1/sigma2,
              P = c(100, 100-60, 50, 60)/60))
}

#MODEL
mixmodel3=function() {
  for( i in 1 : N ) {
    Sepal.Length[i] ~ dnorm(mu1[i], tau)
    Sepal.Width[i] ~ dnorm(mu2[i], tau)
    Petal.Length[i] ~ dnorm(mu3[i], tau)
    Petal.Width[i] ~ dnorm(mu4[i], tau)
    mu1[i] <- lambda[T[i]]
    mu2[i] <- lambda[T[i]]
    mu3[i] <- lambda[T[i]]
    mu4[i] <- lambda[T[i]]
    T[i] ~ dcat(P[]) }
  P[1:4] ~ ddirch(alpha[])
  theta1 ~ dnorm(0.0, 1.0E-6)%_%I(0.0, )
  theta2 ~ dnorm(0.0, 1.0E-6)%_%I(0.0, )
  theta3 ~ dnorm(0.0, 1.0E-6)%_%I(0.0, )
  lambda[1] ~ dnorm(0.0, 1.0E-6)
  lambda[2] <- lambda[1] + theta1
  lambda[3] <- lambda[2] + theta2
  lambda[4] <- lambda[3] + theta3
  tau ~ dgamma(0.001,0.001)
  sigma <- 1 / sqrt(tau)
}

parameters <- c("lambda","sigma","P")

FMM.fit<-jags(df, inits=inits3, parameters, n.chains=1, n.burnin=100000, 
              n.iter=200000, model.file=mixmodel3, DIC=TRUE)
## Warning in jags.model(model.file, data = data, inits = init.values, n.chains =
## n.chains, : NAs introduced by coercion
## Compiling model graph
##    Resolving undeclared variables
##    Allocating nodes
## Graph information:
##    Observed stochastic nodes: 602
##    Unobserved stochastic nodes: 154
##    Total graph size: 919
## 
## Initializing model
# Jika ada notif merah setelah melakukan fitting jangan khawatir langsung PRINT saja koding print(FMM.fit)
print(FMM.fit)
## Inference for Bugs model at "C:/Users/NALEND~1/AppData/Local/Temp/RtmpWQkOVO/model3eb448607ead.txt", fit using jags,
##  1 chains, each with 2e+05 iterations (first 1e+05 discarded), n.thin = 100
##  n.sims = 1000 iterations saved
##            mu.vect sd.vect     2.5%      25%      50%      75%    97.5%
## P[1]         0.276   0.203    0.019    0.114    0.225    0.397    0.755
## P[2]         0.200   0.171    0.004    0.058    0.159    0.300    0.613
## P[3]         0.208   0.174    0.006    0.071    0.159    0.304    0.647
## P[4]         0.316   0.216    0.024    0.137    0.268    0.461    0.785
## lambda[1]    3.103   0.309    2.291    2.976    3.173    3.306    3.476
## lambda[2]    3.354   0.206    2.860    3.256    3.377    3.483    3.688
## lambda[3]    3.544   0.175    3.241    3.443    3.527    3.629    3.950
## lambda[4]    3.780   0.254    3.458    3.609    3.729    3.893    4.445
## sigma        1.974   0.057    1.872    1.934    1.971    2.010    2.099
## deviance  2524.745   5.722 2513.669 2521.401 2524.783 2528.009 2535.449
## 
## DIC info (using the rule, pD = var(deviance)/2)
## pD = 16.4 and DIC = 2541.1
## DIC is an estimate of expected predictive error (lower deviance is better).

Dari sini dapat dilihat bahwa FMM dengan 3 Cluster memiliki nilai DIC seperti diatas. Dari sini terlihat bahwa Nilai DIC dari pengelompokan menggunakan FMM 2 Cluster < 3 Cluster < 4 Cluster. Sehingga banyak Cluster yang dipilih adalah Cluster dengan nilai DIC terendah, Maka dipilihlah pengelompokan menggunakan FMM 2 Cluster untuk Data IRIS ini.

Sekian Dari Saya Semoga Bermanfaat

Info lebih lanjut dapat kunjungi https://www.linkedin.com/in/dwimantara/. Untuk sitasi materi silahkan kunjungi https://iopscience.iop.org/article/10.1088/1742-6596/1494/1/012012