SynBPS
SynBPS (Synthetic Business Process Simulation) generates event logs from business processes that exist only as a set of parameters. Instead of calibrating a simulation model to an existing log, you specify the data-generating process directly: how cases arrive, which activity follows which (with or without memory, and with how much randomness), how long activities take, and when work waits for a resource or for business hours. Every component is a well-known parametric distribution, and every parameter can be varied as a factor in an experimental design.
This makes SynBPS a tool for controlled experiments in predictive process monitoring. Rather than evaluating a method on a handful of public logs alone, you can extend the evaluation across hundreds of processes whose characteristics you chose, replicate each setting with new seeds, and attribute differences in performance to the process instead of the log. Because the process is fully known, the transition tables and duration parameters behind every log can be inspected, which also makes it possible to compute the best achievable performance on that log and measure a model against it.
What SynBPS is not. It does not learn a simulation model from an existing event log (see Simod or Prosimos for this). The method is described in Riess (2024), SIMULATION, https://doi.org/10.1177/00375497241233326 [pdf]
Getting Started
You can install SynBPS using pip:
pip install SynBPS
Installing a specific version from GitHub
A release can also be installed directly from GitHub, for example when a new release is not yet available on PyPI:
pip install git+https://github.com/Mikeriess/SynBPS.git@v1.2.1
Replace v1.2.1 with the tag of the release you need (see the releases page). This requires git to be installed on your machine. Each release also carries the built wheel file (.whl) as an asset, which can be installed with pip install <path or URL of the wheel file> without git.
Once installed, you can:
- Run a simulation experiment with your own models using the End-to-end example notebook for a short demo of SynBPS.
- Or simply generate a single event-log using the example code in the Event-log example notebook. This code example also lets you integrate the power of SynBPS into your own custom code pipeline (for advanced users).
- For the memoryless process, you can also specify the parameters of the distributions manually as shown in the Custom distribution Event-log example notebook.
Documentation
See the official documentation here. The dataprep page describes prefix_data, which turns an event-log into a prefix-log with features and targets for a model, and split_cases, which assigns the cases to the train and test set by time.
Settings
All settings of generate_eventlog and of a design table, with the name used in the paper, the unit and an example value. Time is measured in days. The last column says which process type or entropy level uses the setting.
| Setting | In the paper | Meaning | Unit | Example | Used by |
|---|---|---|---|---|---|
number_of_traces |
n | Number of traces (cases) in the event-log | count | 1000 | both |
process_type |
process without / with memory | memoryless: first-order Markov chain (alg. 6). memory: higher-order Markov chain (alg. 7) |
"memory" |
both | |
process_entropy |
entropy level | min_entropy: one deterministic trace. med_entropy: med_ent_n_transitions possible transitions from each state, with random weights. max_entropy: every transition equally likely from every state (alg. 4), the uniform extreme. custom: distributions from files, see custom_distributions. See the ladder of the levels below |
"med_entropy" |
both | |
process_memory |
k | Order of the higher-order Markov chain: the number of previous activities the next activity depends on | count, 1 or more | 2 | memory |
statespace_size |
d_size | Number of activity types. The activities are named with the letters a, b, c, ... (up to version 1.1.9: b, c, d, ...) | count, 2 to 29 | 5 | both |
med_ent_n_transitions |
n_transitions | Number of possible transitions from each state (context), drawn from the activities and the absorption state. Between 2 and statespace_size, plus 1 for the process with memory |
count | 3 | med_entropy |
med_ent_kappa |
kappa (alg. 5) | Minimum of the total probability of ending the trace, summed over all states, where the absorption state contributes 1. States get random transitions to the absorption state until the sum is reached, so a higher value gives shorter traces. Values up to 1 add nothing, and the search becomes very slow above the upper limit. That every trace ends is guaranteed separately, by a check that the absorption state can be reached from every state | probability mass, 0 to 1 + statespace_size/2 |
2 | memoryless, med_entropy |
p_abs_min |
not in the paper (added in 1.1.8) | Minimum probability of ending the trace from any context, which guarantees that every trace ends. 0 removes the guarantee | probability, 0 to 1 (1 excluded) | 0.05 | memory, med_entropy and max_entropy |
max_len |
not in the paper (added in 1.1.8) | Maximum number of events in a trace, after which an exception is raised | count | 10000 | both |
inter_arrival_time |
1/λ in alg. 1 | Mean time between the arrivals of two traces. The time between arrivals is exponential with this mean | days | 1.5 | both |
process_stability_scale |
1/λ in eq. 19 | Mean of the exponential noise added before each event. 0 means no noise | days | 0.1 | both |
resource_availability_p |
p (alg. 8) | Probability that an agent is available at a request | probability, above 0 and at most 1 | 0.5 | both |
resource_availability_n |
n (alg. 8) | Number of agents | count, 1 or more | 3 | both |
resource_availability_m |
m (alg. 8) | Time per request until an agent is available. The number of requests is geometric with success probability 1 - (1 - p)^n. Which requests take the time is set by resource_availability_mode. Note that 0.041 days is about one hour, and 15 minutes is 0.0104 days |
days | 0.041 | both |
resource_availability_mode |
alg. 8 with failed_requests |
all_requests: every request takes resource_availability_m, also the successful one, so the offset is at least m. failed_requests: only the requests at which no agent was available take the time, so the offset is 0 when an agent is available at the first request. The two modes use the same random draws, so a log differs only in h_t |
"all_requests" |
both | |
activity_duration_lambda_range |
ξ in section 4.5 | Upper limit of the uniform distribution (from 0.0001) the mean activity durations Λ(d, t) are drawn from, one per activity and position in the trace. The duration of an event is exponential with that mean, so Λ(d, t) is 1/λ in eq. 18 | days | 1 | both |
Deterministic_offset_W |
deterministic offset (alg. 9) | Business hours. weekdays: open 06:00 to 18:00, Monday to Friday. all-week: open 06:00 to 18:00 every day. none: always open. An event which is due during closed hours starts when the process opens again; its duration then runs uninterrupted |
"weekdays" |
both | |
Deterministic_offset_u |
eta (eq. 21) | Length of a week in the time unit used: 7 when the time unit is days. The business hours above assume 7 | time units per week | 7 | both |
datetime_offset |
not in the paper | Years added to 1970 for the timestamps. The simulation starts (t = 0) on the first Sunday of that year at 18:00, so the business hours fall on Monday to Friday for every offset | years | 54 | both |
seed_value |
seed | Seed of all random streams. The same settings and seed give the same event-log, and the first traces of a log do not change when number_of_traces grows |
integer, 0 to 2^32 - 1 | 1337 | both |
custom_distributions |
not in the paper | Files with the initial probabilities p0, the transition matrix p and the duration parameters Lambda, for process_entropy custom. See the custom distribution example notebook |
{"p0": "data/p0.csv", "p": "data/p.csv", "Lambda": "data/lambda.csv"} |
memoryless, custom |
Some properties of the simulation which are useful to know when building on SynBPS:
- Traces are independent of each other: the resource offset is drawn per event (alg. 8), and there is no shared queue.
- The mean duration
Lambda(d, t)depends on the activity and on its position in the trace, so the same activity has a different mean duration at position 2 and position 5. - All parameters of exponential distributions are means, in days:
inter_arrival_time,process_stability_scaleand the mean activity durationsLambda(d, t)drawn up toactivity_duration_lambda_range. This is the scale parameter of numpy. The paper writes the exponential distribution with a rate λ in eq. 7, eq. 18 and alg. 1, and the rate is 1 divided by the setting. The expected throughput time of a trace (eq. 25) is therefore the sum of the mean durations and offsets of its events. - The process behind a log (initial probabilities, transition tables and mean activity durations) can be recovered from the settings with
recover_dgp(SynBPS.simulation.simulate_eventlog), independent ofnumber_of_traces, or returned together with the log withgenerate_eventlog(settings, return_dgp=True). A prefix shorter thanprocess_memoryuses the table of its own length. number_of_tracesis not the number of events: the trace length depends on the entropy level,statespace_size,med_ent_n_transitions,p_abs_minandprocess_memory.- The entropy levels form a ladder:
min_entropy(one deterministic trace), thenmed_entropywithmed_ent_n_transitionsfrom 2 up to every transition (statespace_size+ 1 for the process with memory,statespace_sizefor the memoryless process), thenmax_entropy.max_entropyis the uniform extreme: the next activity does not depend on the previous ones, soprocess_memoryhas no effect there, andcheck_settingswarns when it is above 1. The highest level where every transition is possible and the memory order matters ismed_entropywithmed_ent_n_transitions=statespace_size+ 1. run_experimentspasses the settings of the run to every user function which declares asettingskeyword argument, as the row of the design table. A training function which needs the data-generating process recovers it from them withrecover_dgp. See the documentation of the example.
Citation
If you use SynBPS, please cite the corresponding paper. The paper can be cited as:
@article{riess2024synbps,
title={SynBPS: a parametric simulation framework for the generation of event-log data},
author={Riess, Mike},
journal={SIMULATION},
pages={00375497241233326},
year={2024},
publisher={SAGE Publications Sage UK: London, England}
}
Contributing
If you would like to contribute to SynBPS, you are welcome to submit your suggestions, bug reports, or pull requests. Follow the guidelines to ensure smooth collaboration.
Thanks
Jacob Schreiber and Pomegranate team. Joachim Scholderer and Kristoffer Lien.
Metadata
Release files for SynBPS 1.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| synbps-1.2.1.tar.gz | 64.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| synbps-1.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 115.3 kB
Release files / synbps-1.2.1.tar.gz
| Download URL | synbps-1.2.1.tar.gz |
|---|---|
| Size | 64.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c2b29cea0ec4e95920f6b62ec2c2305a502e0db4c273fd4d0ec85eefb97b30a
|
|
BLAKE2b-256 checksum How to use checksums |
1b999614b26807610c93c29fea353b41fdc03c8369fd2a743173f0616898d38b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / synbps-1.2.1-py3-none-any.whl
| Download URL | synbps-1.2.1-py3-none-any.whl |
|---|---|
| Size | 50.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0606ffbbc1cbf12145a1f42cd32db942f13bd709f9dde4e1b4370bba2de9a4db
|
|
BLAKE2b-256 checksum How to use checksums |
2192281605fe460011d576963abddff2793089118cd7908b1378af607150db0b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|