Skip to main content
Rust4PM

Flatten logs and explore variants

Turn an OCEL into a classic event log for one object type, and list the most frequent trace variants of a log.

Flatten an OCEL on an object type

Classic techniques such as Alpha+++ and alignments need one case per trace. flatten_ocel_on(ocel, object_type) picks an object type and creates one trace per object of that type, with every event related to the object, ordered by time. Events that relate to several objects of the type appear in several traces.

import r4pm

ocel = r4pm.import_item("SlimLinkedOCEL", "data/order-management.xml.gz")

# Every order becomes a trace with all events related to it, ordered by time.
orders = r4pm.bindings.flatten_ocel_on(ocel, "orders")
projection = r4pm.bindings.log_to_activity_projection(orders)
print(r4pm.bindings.get_num_cases(projection), "orders,", r4pm.bindings.get_num_variants(projection), "variants")

r4pm.export_item(orders, "orders.xes.gz")
2000 orders, 5 variants

The result is an ordinary EventLog, so everything in discover a model and check conformance works on it. The snippet also writes it to orders.xes.gz for other tools. Flattening on items or products gives very different logs from the same data, because each object type sees a different part of the process. Reference: flatten_ocel_on.

Trace variants

A variant is a distinct sequence of activities. Many logs are dominated by a few variants, and looking at them first is often the fastest way to understand a process.

import r4pm

log = r4pm.import_item("EventLog", "data/road-traffic-fines.xes.gz")
projection = r4pm.bindings.log_to_activity_projection(log)

for variant in r4pm.bindings.get_top_n_variants(projection, 5):
    print(f"{variant['percentage']:5.1f}%  {' > '.join(variant['activities'])}")
output
 37.6%  Create Fine > Send Fine > Insert Fine Notification > Add penalty > Send for Credit Collection
 30.8%  Create Fine > Payment
 13.6%  Create Fine > Send Fine
  6.3%  Create Fine > Send Fine > Insert Fine Notification > Add penalty > Payment
  2.5%  Create Fine > Send Fine > Insert Fine Notification > Add penalty > Payment > Payment

The five most frequent of the 231 variants cover over 90% of all fines. Variants come from the activity projection, which stores each variant once with its count. In Python, get_top_n_variants(projection, n) returns the most frequent ones directly and get_variants returns all of them. References: get_top_n_variants, get_variants.