プロセスログからグラフを作成するのは非常に簡単です。アナリストは現在、プロセスの研究を容易にするように設計された、Celonis、Disco、PM4PY、ProMなどの十分な種類の専門的な開発を自由に利用できます。グラフから偏差を見つけて、それらから正しい結論を引き出すことははるかに困難です。
自分自身を証明し、特に関心のあるいくつかの専門的な開発が何らかの理由で利用できない場合、またはグラフを操作するときに計算の自由度を高めたい場合はどうなりますか?自分でマイナーを作成し、グラフを操作するために必要な機能のいくつかを実装することはどれほど難しいですか?実際には、標準のPythonライブラリを使用してこれを行い、計算を実装し、プロセスの所有者が関心を持つ可能性のある詳細な質問に彼らの助けを借りて回答します。
この記事に記載されているソリューションは産業用の実装ではないことを、すぐに予約したいと思います。これは、明確に機能するため、簡単に適応できる単純なコードを使用して、自分でログの操作を開始する試みです。このソリューションはビッグデータには使用しないでください。これには、たとえば、ベクトル計算を使用したり、イベントに関する情報を収集および集約する方法を変更したりするなど、大幅な改善が必要です。
グラフを作成する前に、計算を実行する必要があります。グラフの実際の計算は、前述のマイナーと同じになります。計算を実行するには、イベントに関する知識(グラフの頂点とそれらの間の接続)を収集し、それらをたとえばリファレンスブックに記録する必要があります。参照は、計算計算手順(githubのコード)を使用して入力されます)。完成した参照は、グラフ描画の手順にパラメーターとして渡されます(上記のリンクのコードを参照してください)。この手順では、次のようにデータをフォーマットします。
digraph f {"Permit SUBMITTED by EMPLOYEE (6255)" -> "Permit APPROVED by ADMINISTRATION (4839)" [label=4829 color=black penwidth=4.723857205400346]
"Permit SUBMITTED by EMPLOYEE (6255)" -> "Permit REJECTED by ADMINISTRATION (83)" [label=83 color=pink2 penwidth=2.9590780923760738]
"Permit SUBMITTED by EMPLOYEE (6255)" -> "Permit REJECTED by EMPLOYEE (231)" [label=2 color=pink2 penwidth=1.3410299956639813]
…
start [color=blue shape=diamond]
end [color=blue shape=diamond]}
そしてそれをGraphvizグラフィックエンジンに渡してレンダリングします。
実装されたマイナーを使用してグラフの作成と調査を開始しましょう。以下の例のように、データの読み取りと並べ替え、グラフの計算と描画の手順を繰り返します。たとえば、イベントログは、BPIC2020コンペティションの国際宣言から取得されます。競争へのリンク。
ログからデータを読み取り、日付と時刻で並べ替えます。.xes形式は以前に.xlsxに変換されていました。
df_full = pd.read_excel('InternationalDeclarations.xlsx')
df_full = df_full[['id-trace','concept:name','time:timestamp']]
df_full.columns = ['case:concept:name', 'concept:name', 'time:timestamp']
df_full['time:timestamp'] = pd.to_datetime(df_full['time:timestamp'])
df_full = df_full.sort_values(['case:concept:name','time:timestamp'], ascending=[True,True])
df_full = df_full.reset_index(drop=True)
グラフを計算してみましょう。
dict_tuple_full = calc(df_full)
グラフを描きましょう。
draw(dict_tuple_full,'InternationalDeclarations_full')
手順を完了すると、プロセスグラフが表示されます。
結果のグラフは読み取れないため、簡略化します。
読みやすさを向上させたり、グラフを単純化したりするには、いくつかのアプローチがあります。
- 頂点またはリンクの重みによるフィルタリングを使用します。
- ノイズを取り除きます。
- 名前の類似性でイベントをグループ化します。
アプローチ3を取りましょう。
イベントを組み合わせるための辞書を作成しましょう。
_dict = {'Permit SUBMITTED by EMPLOYEE': 'Permit SUBMITTED',
'Permit APPROVED by ADMINISTRATION': 'Permit APPROVED',
'Permit APPROVED by BUDGET OWNER': 'Permit APPROVED',
'Permit APPROVED by PRE_APPROVER': 'Permit APPROVED',
'Permit APPROVED by SUPERVISOR': 'Permit APPROVED',
'Permit FINAL_APPROVED by DIRECTOR': 'Permit FINAL_APPROVED',
'Permit FINAL_APPROVED by SUPERVISOR': 'Permit FINAL_APPROVED',
'Start trip': 'Start trip',
'End trip': 'End trip',
'Permit REJECTED by ADMINISTRATION': 'Permit REJECTED',
'Permit REJECTED by BUDGET OWNER': 'Permit REJECTED',
'Permit REJECTED by DIRECTOR': 'Permit REJECTED',
'Permit REJECTED by EMPLOYEE': 'Permit REJECTED',
'Permit REJECTED by MISSING': 'Permit REJECTED',
'Permit REJECTED by PRE_APPROVER': 'Permit REJECTED',
'Permit REJECTED by SUPERVISOR': 'Permit REJECTED',
'Declaration SUBMITTED by EMPLOYEE': 'Declaration SUBMITTED',
'Declaration SAVED by EMPLOYEE': 'Declaration SAVED',
'Declaration APPROVED by ADMINISTRATION': 'Declaration APPROVED',
'Declaration APPROVED by BUDGET OWNER': 'Declaration APPROVED',
'Declaration APPROVED by PRE_APPROVER': 'Declaration APPROVED',
'Declaration APPROVED by SUPERVISOR': 'Declaration APPROVED',
'Declaration FINAL_APPROVED by DIRECTOR': 'Declaration FINAL_APPROVED',
'Declaration FINAL_APPROVED by SUPERVISOR': 'Declaration FINAL_APPROVED',
'Declaration REJECTED by ADMINISTRATION': 'Declaration REJECTED',
'Declaration REJECTED by BUDGET OWNER': 'Declaration REJECTED',
'Declaration REJECTED by DIRECTOR': 'Declaration REJECTED',
'Declaration REJECTED by EMPLOYEE': 'Declaration REJECTED',
'Declaration REJECTED by MISSING': 'Declaration REJECTED',
'Declaration REJECTED by PRE_APPROVER': 'Declaration REJECTED',
'Declaration REJECTED by SUPERVISOR': 'Declaration REJECTED',
'Request Payment': 'Request Payment',
'Payment Handled': 'Payment Handled',
'Send Reminder': 'Send Reminder'}
イベントをグループ化して、プロセスグラフをもう一度描きましょう。
df_full_gr = df_full.copy()
df_full_gr['concept:name'] = df_full_gr['concept:name'].map(_dict)
dict_tuple_full_gr = calc(df_full_gr)
draw(dict_tuple_full_gr,'InternationalDeclarations_full_gr'
名前の類似性によってイベントをグループ化した後、グラフの読みやすさが向上しました。質問への答えを見つけてみましょう。質問のリストへのリンク。たとえば、事前に承認された承認が先行していない宣言はいくつありますか?
提起された質問に答えるために、関心のあるイベントでグラフをフィルタリングし、プロセスグラフを再度描画します。
df_full_gr_f = df_full_gr[df_full_gr['concept:name'].isin(['Permit SUBMITTED',
'Permit APPROVED',
'Permit FINAL_APPROVED',
'Declaration FINAL_APPROVED',
'Declaration APPROVED'])]
df_full_gr_f = df_full_gr_f.reset_index(drop=True)
dict_tuple_full_gr_f = calc(df_full_gr_f)
draw(dict_tuple_full_gr_f,'InternationalDeclarations_full_gr_isin')
結果のグラフの助けを借りて、提起された質問に簡単に答えることができます-116と312の宣言の前に事前に承認された許可がありませんでした。
さらに、接続116および312に対して「失敗」(「ケース:概念:名前」でフィルタリング、目的の接続に参加)し、グラフのアクセス許可に関連するイベントがないことを確認できます。
通信116で「失敗」しましょう。
df_116 = df_full_gr_f[df_full_gr_f['case:concept:name'].isin(d_case_start2['Declaration FINAL_APPROVED'])]
df_116 = df_116.reset_index(drop=True)
dict_tuple_116 = calc(df_116)
draw(dict_tuple_116,'InternationalDeclarations_full_gr_isin_116')
接続312で「失敗」しましょう。
df_312 = df_full_gr_f[df_full_gr_f['case:concept:name'].isin(d_case_start2['Declaration APPROVED'])]
df_312 = df_312.reset_index(drop=True)
dict_tuple_312 = calc(df_312)
draw(dict_tuple_312,'InternationalDeclarations_full_gr_isin_312')
受信したグラフには権限に関連するイベントがないため、回答116と312の正しさが確認されます。
ご覧のとおり、マイナーを作成し、グラフを操作するために必要な機能を実装することは難しい作業ではありません。PythonとGraphvizの組み込み関数は、グラフィックエンジンとして正常に処理できます。