Create a project
cargo new my-analysis
cd my-analysis
cargo add process_mining@=0.6.2This needs a Rust toolchain. The default features cover XES, OCEL 2.0 XML and JSON, discovery and conformance. SQLite, DuckDB and a few other formats are optional feature flags. The crate is still in active development, so pin the version you build against.
Get the sample data
The quickstart uses the Road Traffic Fine Management log: 150,370 fines, 561,470 events, 11 activities. Put the data folder in the project root, next to Cargo.toml.
The program
Replace src/main.rs with:
use process_mining::conformance::case_centric::alignments::{
align_variants, compute_fitness, AlignmentOptions,
};
use process_mining::core::event_data::case_centric::utils::activity_projection::EventLogActivityProjection;
use process_mining::discovery::case_centric::alphappp::full::{
alphappp_discover_petri_net, AlphaPPPConfig,
};
use process_mining::discovery::case_centric::dfg::discover_dfg;
use process_mining::{EventLog, Exportable, Importable};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// The file extension (.xes.gz) selects the format.
let log = EventLog::import_from_path("data/road-traffic-fines.xes.gz")?;
println!("{} traces", log.traces.len());
// Directly-follows graph: which activity follows which, and how often.
let dfg = discover_dfg(&log);
println!("{} activities", dfg.activities.len());
// Alpha+++ works on the activity projection: every trace variant once, with its count.
let projection = EventLogActivityProjection::from(&log);
println!("{} variants", projection.traces.len());
let config = AlphaPPPConfig {
balance_thresh: 0.1,
fitness_thresh: 0.8,
replay_thresh: 0.0,
log_repair_skip_df_thresh_rel: 4.0,
log_repair_loop_df_thresh_rel: 4.0,
absolute_df_clean_thresh: 1,
relative_df_clean_thresh: 0.01,
};
let net = alphappp_discover_petri_net(&projection, config);
println!(
"{} places, {} transitions",
net.places.len(),
net.transitions.len()
);
// How well does the model explain the log? Align every variant, then aggregate.
let options = AlignmentOptions::default();
let alignments = align_variants(&net, &projection, &options);
let fitness = compute_fitness(&alignments, &net, &options)?;
println!("log fitness {:.3}", fitness.log_fitness);
net.export_to_path("model.pnml")?;
Ok(())
}Run it in release mode, since discovery and alignments are much faster with optimizations:
cargo run --release150370 traces
11 activities
231 variants
10 places, 16 transitions
log fitness 0.886Alpha+++ also prints about 20 lines of progress information while it runs, which the output above leaves out.
The program step by step
Import and export
EventLog, OCEL, PetriNet and the other data types implement the Importable and Exportable traits. import_from_path and export_to_path pick the format from the file extension (.xes, .xes.gz, .json, .pnml, ...). For files without a telling extension, import_from_reader and export_to_writer take the format explicitly. The file formats page lists every supported format per type.
Discover a directly-follows graph
discover_dfg counts how often each activity directly follows another. The result has activities, edges with frequencies, and start and end activities.
Discover a Petri net with Alpha+++
Alpha+++ works on an EventLogActivityProjection, a compact form of the log that keeps every trace variant once with its count. The road traffic log has 231 variants, so everything after this step is fast even though the log has 150,370 traces.
The AlphaPPPConfig thresholds filter rare behavior before and during discovery. The discovery how-to explains each of them.
Check conformance
align_variants computes an optimal alignment between the model and each variant (in parallel). compute_fitness combines them, weighted by how often each variant occurs, and returns log_fitness, average_fitness, perfectly_fitting_frac and total_costs. A log fitness of 0.886 means the model explains most of the observed behavior but not all of it.
Next steps
- Event data types:
EventLog,OCELand the linked OCEL types, and when to use which. - Discover a model and check conformance in more depth.
- Object-centric analysis with the Order Management OCEL.
- The full Rust API, including everything not covered here: docs.rs/process_mining.