Welcome to ClientVPS Mirrors

Getting started with simOutrank

Getting started with simOutrank

simOutrank clusters the traces of an event log by an outranking model of similarity. Instead of collapsing every perspective into a single distance, it scores each pair of traces on several problem-specific criteria – activities, transitions, duration, case attributes – and aggregates them with ELECTRE-III-style concordance and discordance. The result is a credibility matrix S that a spectral or hierarchical algorithm then partitions.

This vignette walks through the whole pipeline on the bundled illustrative_log, a 25-case customer-service log from Delias et al. (2023).

library(simOutrank)
head(illustrative_log)
#>   case_id activity           timestamp status satisfaction
#> 1       1        B 2021-01-01 00:01:00   GOLD         High
#> 2       1        E 2021-01-01 00:02:00   GOLD         High
#> 3       2        B 2021-01-01 00:01:00   GOLD         High
#> 4       2        E 2021-01-01 00:02:00   GOLD         High
#> 5       3        B 2021-01-01 00:01:00   GOLD         High
#> 6       3        E 2021-01-01 00:02:00   GOLD         High

1. Traces

as_traces() turns an event log into a traces object: the time-ordered, integer-encoded activity sequence of every case, plus the case-level attribute table.

traces <- as_traces(illustrative_log,
                    case_id = "case_id", activity = "activity",
                    timestamp = "timestamp")
traces
#> <traces>: 25 cases, 5 distinct activities
#>   trace length: min 2, median 5, max 7
#>   case attributes: status, satisfaction
summary(traces)[1:5, ]
#>   case_id n_events n_distinct
#> 1       1        2          2
#> 2       2        2          2
#> 3       3        2          2
#> 4       4        2          2
#> 5       5        2          2

2. Criteria

Criteria are built with the crit_* helpers. Each carries a direction (similarity or dissimilarity), a weight, and ELECTRE-III thresholds (indifference, similarity, and an optional veto). Here we mirror the four criteria of the source paper: what activities occur, in what order, and two case attributes.

criteria <- list(
  crit_activity_profile(weight = 0.2, indifference = 0.7, similarity = 0.8,
                        veto = 0.4),
  crit_edit_distance(weight = 0.2, similarity = 2, indifference = 3, veto = 6),
  crit_nominal("status", weight = 0.3),
  crit_nominal("satisfaction", weight = 0.3)
)
criteria[[1]]
#> <criterion 'activity_profile'>: direction = similarity, weight = 0.2
#>   indifference = 0.7, similarity = 0.8, veto = 0.4

Thresholds may be fixed numbers or quantiles of the criterion’s own value distribution via as_quantile(); the parameter-tuning vignette explores that choice.

3. Similarity

outrank_similarity() resolves any quantile thresholds, normalises the weights, and aggregates the per-criterion indices into S.

sim <- outrank_similarity(traces, criteria)
sim
#> <outrank_sim>: 25 cases, 4 criteria
#>   S in [0.000, 1.000], symmetric = TRUE
round(sim$S[1:5, 1:5], 2)
#>   1 2 3 4 5
#> 1 1 1 1 1 1
#> 2 1 1 1 1 1
#> 3 1 1 1 1 1
#> 4 1 1 1 1 1
#> 5 1 1 1 1 1

4. How many clusters?

eigengap() plots the smallest eigenvalues of the normalized Laplacian; a gap after the k-th value suggests k groups.

eigengap(sim, k_max = 8)

5. Cluster

The paper targets four natural groups (tier x satisfaction). Spectral clustering uses a seed for reproducible k-means.

clust <- cluster_traces(sim, k = 4, seed = 42)
clust
#> <outrank_clust>: 25 cases in 4 clusters (spectral)
#>   cluster sizes: 1=6, 2=8, 3=5, 4=6
split(names(clust$memberships), clust$memberships)
#> $`1`
#> [1] "11" "12" "13" "14" "15" "24"
#> 
#> $`2`
#> [1] "16" "17" "18" "19" "20" "21" "22" "23"
#> 
#> $`3`
#> [1] "6"  "7"  "8"  "9"  "10"
#> 
#> $`4`
#> [1] "1"  "2"  "3"  "4"  "5"  "25"

6. Use the result

Join memberships back onto the event log, inspect a cluster’s attribute profile, and compute validity indices.

augmented <- augment_log(clust, illustrative_log)
#> Joining on case-id column 'case_id'.
head(augmented)
#>   case_id activity           timestamp status satisfaction .cluster
#> 1       1        B 2021-01-01 00:01:00   GOLD         High        4
#> 2       1        E 2021-01-01 00:02:00   GOLD         High        4
#> 3       2        B 2021-01-01 00:01:00   GOLD         High        4
#> 4       2        E 2021-01-01 00:02:00   GOLD         High        4
#> 5       3        B 2021-01-01 00:01:00   GOLD         High        4
#> 6       3        E 2021-01-01 00:02:00   GOLD         High        4

plot(clust, type = "profile", attribute = "status")


if (requireNamespace("clValid", quietly = TRUE)) {
  validate_clusters(clust)
}
#> connectivity         dunn 
#>    20.276190     0.489198

Where next

Reference

Delias, P., Doumpos, M., Grigoroudis, E. and Matsatsinis, N. (2023). Improving the non-compensatory trace-clustering decision process. International Transactions in Operational Research, 30(3), 1387–1406. doi:10.1111/itor.13062 ```

Need a high-speed mirror for your open-source project?
Contact our mirror admin team at info@clientvps.com.

This archive is provided as a free public service to the community.
Proudly supported by infrastructure from VPSPulse , RxServers , BuyNumber , UnitVPS , OffshoreName and secure payment technology by ArionPay.