Skip to contents

Synthetic navigation sequences

paths <- list(
  s1 = c("home", "search", "product", "checkout"),
  s2 = c("home", "search", "product", "home"),
  s3 = c("home", "category", "product", "checkout"),
  s4 = c("home", "category", "home", "search")
)
sequence_data <- do.call(rbind, lapply(seq_along(paths), function(i) {
  data.frame(sequence_id = names(paths)[i],
             sequence_order = seq_along(paths[[i]]),
             state = paths[[i]], stringsAsFactors = FALSE)
}))

First-order transition network

network <- create_transition_network(
  sequence_data,
  normalise = "from",
  include_self = TRUE
)
network
#>   group_key  context from_state to_state count sequence_count
#> 1   __all__ category   category     home     1              1
#> 2   __all__ category   category  product     1              1
#> 3   __all__     home       home category     2              2
#> 4   __all__     home       home   search     3              3
#> 5   __all__  product    product checkout     2              2
#> 6   __all__  product    product     home     1              1
#> 7   __all__   search     search  product     2              2
#>   sequence_prevalence    weight
#> 1                0.25 0.5000000
#> 2                0.25 0.5000000
#> 3                0.50 0.4000000
#> 4                0.75 0.6000000
#> 5                0.50 0.6666667
#> 6                0.25 0.3333333
#> 7                0.50 1.0000000
summarise_transition_centrality(network)
#>      state out_degree in_degree total_degree out_strength in_strength
#> 1 category          2         1            3            1   0.4000000
#> 2 checkout          0         1            1            0   0.6666667
#> 3     home          2         2            4            1   0.8333333
#> 4  product          2         2            4            1   1.5000000
#> 5   search          1         1            2            1   0.6000000
#>   total_strength closeness betweenness  pagerank
#> 1      1.4000000 0.3582090           1 0.1362227
#> 2      0.6666667 0.0000000           0 0.2207604
#> 3      1.8333333 0.3636364           4 0.2020395
#> 4      2.5000000 0.2727273           5 0.2704079
#> 5      1.6000000 0.2857143           1 0.1705694
detect_transition_communities(network)
#>      state community
#> 1 category         1
#> 2 checkout         1
#> 3     home         1
#> 4  product         1
#> 5   search         1

Centrality values are graph-structural descriptors. They do not independently measure attention, importance, intent, or influence.

Higher-order transition model

model <- fit_higher_order_transition_model(
  sequence_data,
  order = 2L,
  smoothing = 0.5,
  backoff = TRUE
)
predict_next_state(model, c("home", "search"))
#>   order       context next_state count probability used_order  used_context
#> 1     2 home > search    product     2   0.5555556          2 home > search
#> 2     2 home > search   category     0   0.1111111          2 home > search
#> 3     2 home > search   checkout     0   0.1111111          2 home > search
#> 4     2 home > search       home     0   0.1111111          2 home > search
#> 5     2 home > search     search     0   0.1111111          2 home > search
predict_next_state(model, c("unseen"))
#>   order  context next_state count probability used_order used_context
#> 1     0 <unseen>   category     0         0.2          0     <unseen>
#> 2     0 <unseen>   checkout     0         0.2          0     <unseen>
#> 3     0 <unseen>       home     0         0.2          0     <unseen>
#> 4     0 <unseen>    product     0         0.2          0     <unseen>
#> 5     0 <unseen>     search     0         0.2          0     <unseen>

Whole-sequence bootstrap

boot <- bootstrap_transition_network(
  sequence_data,
  n_boot = 20L,
  level = 0.95,
  seed = 8L
)
head(boot)
#>   group_key  context from_state to_state count sequence_count
#> 1   __all__ category   category     home     1              1
#> 2   __all__ category   category  product     1              1
#> 3   __all__     home       home category     2              2
#> 4   __all__     home       home   search     3              3
#> 5   __all__  product    product checkout     2              2
#> 6   __all__  product    product     home     1              1
#>   sequence_prevalence    weight bootstrap_mean bootstrap_sd  conf_low conf_high
#> 1                0.25 0.5000000      0.5166667    0.3932917 0.0000000 1.0000000
#> 2                0.25 0.5000000      0.4833333    0.3932917 0.0000000 1.0000000
#> 3                0.50 0.4000000      0.4064286    0.1762160 0.2000000 0.6787500
#> 4                0.75 0.6000000      0.5935714    0.1762160 0.3212500 0.8000000
#> 5                0.50 0.6666667      0.6083333    0.2164641 0.3333333 1.0000000
#> 6                0.25 0.3333333      0.3916667    0.2164641 0.0000000 0.6666667
#>   n_boot confidence_level
#> 1     20             0.95
#> 2     20             0.95
#> 3     20             0.95
#> 4     20             0.95
#> 5     20             0.95
#> 6     20             0.95

Bootstrap samples are drawn at the sequence level, preserving within-sequence transition dependence.