Время прочтения: 3 мин.

Предположим, что имеется лог-файл process_log.csv некоторого процесса. При этом в процессе возможны шесть этапов, условно обозначенных A, B, C, D, E, F, а правильной является последовательность этапов B — C — D.

Для того, чтобы проверить правильность реализации процесса, необходимо пройти три шага.

Предварительно импортируем все необходимые библиотеки.

import pandas as pd
from pm4py.algo.discovery.dfg import algorithm as dfg_discovery
from pm4py.visualization.dfg import visualizer as dfg_visualization
import seaborn as sns
%matplotlib inline

На первом шаге в переменной correct_path задаем правильную последовательность этапов процесса, читаем лог-файл процесса process_log.csv и приводим наименования столбцов в лог-файле в соответствие с обозначениями, принятыми в библиотеке pmp4y.

correct_path = 'B-C-D'
log = pd.read_csv('process_log.csv', parse_dates=['timestamp'])
cols = {'timestamp': 'time:timestamp', 'stage': 'concept:name', 'case': 'case:concept:name'}
log.rename(columns=cols, inplace=True)

В результате этих действий столбец case:concept:name будет содержать  идентификатор реализации процесса, а столбец concept:name — наименование этапа процесса. Фрагмент полученной таблицы log приведен ниже.

indexcase:concept:nameconcept:nametime:timestamp
1001000C2018-01-29 20:56:10
101550B2018-01-30 14:27:45
102752D2018-01-30 22:24:30
103358B2018-01-31 17:48:08
104919C2018-01-31 17:51:06

Визуализируем граф процесса с помощью средств библиотеки pm4py.

dfg = dfg_discovery.apply(log)
gviz = dfg_visualization.apply(dfg, log=log, variant=dfg_visualization.Variants.FREQUENCY)
dfg_visualization.view(gviz)

На ребрах построенного графа будет отображено количество переходов между этапами процесса.

На втором шаге выполняем проверку соответствия реального процесса стандарту. Для этого создаем списки этапов процесса stages и уникальных реализаций процесса cases, составляем словарь paths, ключами в котором являются все встречающиеся последовательности этапов, а значениями — их количества, затем проверяем корректность всех последовательностей.

stages = log['concept:name'].unique().tolist()
cases = log['case:concept:name'].unique().tolist()

paths = {}
for case in cases:
    log_single = log[log['case:concept:name'] == case].sort_values(by='time:timestamp')
    path = '-'.join(log_single['concept:name'])
    paths[path] = paths.get(path, 0) + 1
    
data = [(k, v) for k, v in paths.items()]
results = pd.DataFrame(data, columns=['Путь', 'Количество'])
results['Соответствует'] = results['Путь'].apply(lambda path: 'Да' if path == correct_path else 'Нет')

В итоге получаем таблицу results, содержащую данные о всех возможных последовательностях этапов процесса, их количестве и соответствии стандарту.

ПутьКоличествоСоответствует
B-C-D600Да
A-E-D-C-C1Нет
C-F-B1Нет
D-B-B1Нет
E-E-D1Нет

На третьем шаге выполняем анализ полученных результатов. Строим диаграмму количества корректных и некорректных реализаций процесса.

conformance = results.groupby('Соответствует')['Количество'].sum().reset_index()
sns.barplot(data=conformance, x='Количество', y='Соответствует')

Из диаграммы следует, что исследуемый процесс корректно реализовался приблизительно в 60% случаев (600 из 1000).

Также визуализируем пять наиболее частых некорректных реализаций процесса.

incorrect_all = results[results['Соответствует'] == 'Нет']
incorrect_top5 = incorrect_all.groupby('Путь').sum().sort_values(by='Количество', ascending=False).head(5).reset_index()
sns.barplot(data=incorrect_top5, x='Количество', y='Путь')

Из диаграммы видно, что из некорректных реализаций процесса наиболее часто встречается последовательность этапов D — F — D.

Таким образом, выполнив несколько несложных действий, можно получить значительно более точное представление о свойствах изучаемого процесса.

Исходный код Python-ноутбука приведен в репозитории github.com/mporuchikov/process_conformance_checking.