DBHC

Package DBHC is an implementation of a sequence clustering algorithm that uses a mixture of discrete-output hidden Markov models (HMMs), the Discrete Bayesian HMM Clustering (DBHC) algorithm. The algorithm uses heuristics based on the Bayesian Information Criterion (BIC) to search for the optimal number of hidden states in each HMM and the optimal number of clusters. The packages provides functions for finding clusters in discrete sequence data with the DBHC algorithm and for plotting heatmaps of the probability matrices that are estimated in the cluster models.

Example

Below a basic example of how to use package DBHC for obtaining sequence clusters for the Swiss Household data in package TraMineR:

library(DBHC)
library(TraMineR)

## Swiss Household Data
data("biofam", package = "TraMineR")

# Clustering algorithm
new.alphabet <- c("P", "L", "M", "LM", "C", "LC", "LMC", "D")
sequences <- seqdef(biofam[,10:25], alphabet = 0:7, states = new.alphabet)

# Code below takes long time to run
res <- hmm.clust(sequences)

# Heatmaps
cluster <- 1  # display heatmaps for cluster 1
transition.heatmap(res$partition[[cluster]]$transition_probs,
                   res$partition[[cluster]]$initial_probs)
emission.heatmap(res$partition[[cluster]]$emission_probs)

## A smaller example, which takes less time to run
subset <- sequences[sample(1:nrow(sequences), 20, replace = FALSE),]

# Clustering algorithm
res <- hmm.clust(subset, K.max = 3)

# Number of clusters
print(res$n.clusters)

# Table of cluster memberships
table(res$memberships[,"cluster"])

# BIC for each number of clusters
print(res$bic)

# Heatmaps
cluster <- 1  # display heatmaps for cluster 1
transition.heatmap(res$partition[[cluster]]$transition_probs,
                   res$partition[[cluster]]$initial_probs)
emission.heatmap(res$partition[[cluster]]$emission_probs)

Case study

The school-to-work vignette works through a larger example end to end, on the mvad data in package TraMineR: 712 young people followed month by month for 70 months, each month recorded as one of employment, further education, higher education, joblessness, school, or training.

library(DBHC)
library(TraMineR)

data("mvad", package = "TraMineR")
mvad.seq <- seqdef(mvad[, 17:86], id = mvad$id, cnames = 1:70,
                   alphabet = c("employment", "FE", "HE", "joblessness",
                                "school", "training"),
                   states = c("EM", "FE", "HE", "JL", "SC", "TR"))

set.seed(2024)
res <- hmm.clust(mvad.seq)  # about a minute for 712 sequences

The algorithm finds four routes through the six states:

Cluster Individuals Hidden states Trajectory
1 222 4 further education, then employment, which is absorbing
2 162 4 training, then employment, through spells of joblessness
3 121 6 school, then higher education
4 207 8 mixed, and least likely to have settled by the last month

None of the background variables in mvad were shown to the algorithm, so they are a fair check on the partition. The share of individuals leaving school with five or more GCSEs at grades A-C runs from 13 percent in the training route up to 65 percent in the school-to-higher-education route, and grammar school attendance separates the clusters as sharply. Religion and family composition do not, so the clusters track educational pathway rather than the demography of the sample.

vignette("school-to-work", package = "DBHC")