트랙 CC2180분

발견과 적합성 심화

실습 24에서 알파 알고리즘, 휴리스틱 마이너, 귀납적 마이너는 같은 로그에서 서로 다른 모델을 냈고, 적합도와 정밀도도 달랐다. 알고리즘이 더 있다면 무엇을 기준으로 고르는가. 정밀도 값 0.969와 0.999가 같은 모델에서 나온다면 어느 쪽을 믿는가. 그리고 2단계에서는 6월 1일에 규칙이 바뀐 것을 미리 알고 기간을 나눴다. 날짜를 모르는 팀의 로그에서 프로세스가 언제 바뀌었는지는 어떻게 찾는가. 이 모듈은 발견 알고리즘 여섯 개와 손으로 고친 모델을 같은 표에서 비교하고, 선언적 제약을 발견해 팀 규칙 파일과 맞대고, 기간 창을 통계 검정으로 비교해 변화가 생긴 곳을 찾는다.

진행
설명 55분, 실습 105분, 정리 20분
결과
모델 비교 보고(pm-lab/model-compare.md), 규칙 파일 개정안(pm-lab/rules-revision.md), 표류 점검 보고(pm-lab/drift.md)
명령
model-compare.py, declare-rules.py, drift-check.py
cd ~/gh-pm-lab

이 모듈은 실습 22의 pm-lab/orbit-event-log-clean.csv와 실습 26에서 QA 업무에 범위를 정한 pm-lab/process-rules.tsv를 쓴다. 규칙 파일이 없으면 실습 26의 3단계를 먼저 한다.

1발견 알고리즘의 계보

로그에서 모델을 만드는 방법은 크게 세 갈래로 발전했다. 로그에서 순서 관계를 뽑아 모델을 짜 맞추는 방법, 로그를 재현할 수 있는 모든 모델 가운데 가장 좁은 것을 수식으로 구하는 방법, 로그를 나눠 가며 블록 구조를 만드는 방법이다.

알고리즘발표방법결과 모델PM4Py 2.7.23.8
알파 알고리즘2004직접 이어짐 관계에서 인과, 병행, 선택 관계를 정해 장소를 만든다페트리넷. 짧은 반복과 건너뛰기를 표현하지 못한다discover_petri_net_alpha
휴리스틱 마이너2006관계의 빈도로 의존도를 계산하고 기준 아래를 버린다휴리스틱 넷. 건전성을 보장하지 않는다discover_petri_net_heuristics
퍼지 마이너 (Fuzzy Miner)2007활동과 연결의 중요도로 덜 중요한 것을 묶거나 지운다(귄터와 판 데르 알스트, BPM 2007)실행 의미가 없는 지도. 적합도를 잴 수 없다없다 (ProM, Disco 같은 도구에 있다)
ILP 마이너 (영역 이론)2009, 2018로그의 모든 접두사를 재현하는 장소를 정수 선형 계획으로 찾는다(판 데르 베르프 등 2009, 판 젤스트 등 2018)페트리넷. 로그를 모두 재현한다discover_petri_net_ilp
귀납적 마이너 IM, IMf2013로그를 순서, 선택, 병행, 반복으로 나눌 수 있는지 차례로 시험한다. IMf는 드문 행동을 잡음으로 버린다(리만스 등)프로세스 트리. 언제나 건전하다discover_petri_net_inductive
귀납적 마이너 IMd2015, 2018로그 대신 직접 이어짐 그래프만으로 나눈다. 로그를 한 번만 읽어 큰 로그에 쓴다(리만스 등, Software & Systems Modeling 2018)프로세스 트리귀납적 마이너의 Variants.IMd
분할 마이너 (Split Miner)2019직접 이어짐 그래프를 거른 뒤 분기 게이트웨이의 조합을 찾는다(아우구스투 등, Knowledge and Information Systems 2019)BPMN. 교착이 없도록 만들지만 블록 구조로 제한하지 않는다discover_bpmn_split_miner

2같은 로그, 일곱 모델

실습 26의 팀 절차 모델(프로세스 트리)을 파일로 저장하고, 발견 알고리즘 여섯 개와 함께 비교한다. model-compare.py는 모델마다 크기, 건전성, 토큰 재생과 정렬로 잰 적합도와 정밀도, 일반화, 단순성을 계산한다.

귀납적 마이너(잡음 0.2)와 휴리스틱 마이너의 값은 실습 24의 표와 같다. 새로 더한 모델을 읽는다.

모델숫자읽는 법
IMd적합도 1.000, 정밀도 0.251직접 이어짐 그래프만으로는 개발 구간을 더 나누지 못해, 작업 시작과 막힘 갈래 뒤에 활동 8개를 아무 순서로나 몇 번이든 허용하는 고리를 두었다. 무엇이든 허용하는 꽃 모양(flower) 모델과 같은 구조다
ILP 마이너적합도 1.000, 정밀도 0.829, 전이 13개가장 작으면서 모든 사례를 재현한다. 대신 로그에 없는 순서도 꽤 허용한다
분할 마이너그대로 재현 91.1%, 정밀도 0.988IMf(86.0%, 0.993)보다 사례를 더 재현하고 정밀도는 비슷하다. 다시 열린 업무를 반복으로 담았고, PR 없는 QA 업무 23건만 모델 이동으로 남았다
팀절차그대로 재현 70.8%, 정밀도 0.969와 0.999실습 26의 182/257과 같다. 같은 모델의 정밀도가 측정 방법에 따라 다르다(아래 “정밀도를 재는 방법”)

모델을 고르는 기준은 질문이다. 팀과 절차를 합의할 때는 정밀도가 높고 작은 모델(IMf, 분할 마이너)을, 모든 사례를 다음 분석(정렬, 시뮬레이션)에 넣어야 할 때는 적합도가 1이고 건전한 모델(ILP, 잡음 0의 귀납적 마이너)을 쓴다. 적합도와 정밀도가 모두 높아도 건전하지 않은 모델(휴리스틱 마이너)은 정렬의 입력으로 쓰지 못한다.

3정렬의 비용과 계산량

정렬(alignment)은 사례의 사건열과 모델이 허용하는 실행 하나를 짝지으며 어긋남의 비용이 가장 작은 짝을 찾는다(아드리안샤 등 2011). PM4Py의 표준 비용은 로그 이동과 보이는 전이의 모델 이동에 10000, tau 이동에 1, 동기 이동에 0이다. tau에 작은 비용을 주는 것은 비용이 같은 정렬 가운데 tau를 덜 쓰는 쪽을 고르기 위해서다. 사례의 적합도는 1 − 어긋남 수 ÷ (사건 수 + 모델의 가장 짧은 실행 길이)로 계산한다.

최적 정렬은 사례의 사건열로 만든 추적 넷(trace net)과 모델을 곱한 동기 곱(synchronous product) 위에서 A* 탐색으로 찾는다. 탐색 공간은 사건열의 위치 수와 모델이 가질 수 있는 상태(마킹) 수의 곱만큼 커지고, 모델에 병행이 많으면 마킹 수가 지수적으로 늘어난다. 위 출력의 마지막 표는 가장 긴 변형(사건 17개)에 대한 동기 곱의 크기다. 잡음 0의 귀납적 마이너는 업무 완료를 병행 갈래에 두었기 때문에 도달할 수 있는 상태가 504개로 가장 많다. Orbit은 병행이 거의 없어 상태가 수백 개에 그치지만, 병행하는 활동이 많은 모델에서는 상태 수가 지수적으로 늘어 사례 하나의 정렬에도 오래 걸린다. PM4Py가 정렬을 변형마다 한 번만 계산하는 것도 이 때문이다.

4정밀도를 재는 방법

방법계산팀절차 모델 값
ETC, 토큰 재생 기반 (무뇨스가마와 카르모나 2010)로그의 접두사마다 모델이 허용하는 다음 활동 가운데 로그에서 실제로 나온 비율. 접두사를 토큰 재생으로 따라간다0.969
정렬 기반 ETC (아드리안샤 등 2015)같은 계산을 정렬한 결과 위에서 한다. 로그에 있지만 모델에 없는 사건은 정렬이 먼저 걸러 낸다0.999
엔트로피 기반 (폴리뱌니 등 2020)로그와 모델이 허용하는 행동 집합의 크기를 엔트로피로 재어 비율을 구한다. 모델을 더 넓히면 정밀도가 줄어드는 단조성(monotonicity)을 증명했다PM4Py에 없다. 명령행 도구 Entropia로 잰다

팀절차 모델에서 두 ETC가 다른 이유는 모델에 없는 활동(결정 기록, 막힘)이다. 토큰 재생 기반 ETC는 모델에 맞지 않는 접두사도 토큰을 보충하며 따라가 그 상태의 허용 활동을 세고, 정렬 기반 ETC는 어긋난 사건을 정렬로 먼저 걸러 낸 뒤 모델이 실제로 갈 수 있는 상태에서만 센다. 폴리뱌니(A. Polyvyanyy) 등은 2020년 ACM TOSEM 논문에서 ETC 계열이 모델을 넓혀도 정밀도가 오를 수 있음(단조성 위반)을 보였다. 숫자 하나로 모델을 비교할 때는 같은 측정 방법으로 잰 값끼리만 비교하고, 보고서에 측정 방법을 적는다.

5모델 수리: 어긋난 곳만 고치기

팀절차 모델이 사례의 70.8%만 재현한다면 모델을 새로 발견하는 대신 어긋난 곳만 고칠 수 있다. 파흘란트(D. Fahland)와 판 데르 알스트는 2015년 Information Systems 논문 “Model repair”에서 정렬로 어긋난 부분 사건열을 모아, 그 위치에 반복이나 하위 프로세스를 더해 원래 모델과 가장 비슷하게 남기는 방법을 제안했다. 같은 생각으로 손으로 고쳐 본다. 정렬의 로그 이동이 결정 기록 43, 막힘과 막힘 해소 36, 다시 열림과 둘째 PR의 활동 13이었으므로(실습 26), 세 곳에 갈래를 더한다.

  • 작업 시작 뒤에 “막힘 → 막힘 해소”를 넣을 수 있는 선택 갈래
  • 첫 커밋과 PR 생성 사이에 결정 기록을 넣을 수 있는 선택 갈래
  • “첫 커밋 … PR 병합” 갈래(PR이 없는 업무는 tau로 건너뛴다)와 업무 완료를 한 묶음으로 두고, 다시 열림으로 그 묶음을 반복하는 고리

고친 모델은 257건을 모두 재현하고(토큰 재생과 정렬 적합도 모두 1.000), 정밀도는 0.985다. 전이는 10개에서 18개로 늘었다. 업무 완료는 고리 안에 한 번만 두었다. 같은 이름의 전이가 둘 있으면 토큰 재생은 그중 하나를 어림으로 골라 실행하는데, 업무 완료를 두 곳에 둔 모델로 같은 명령을 두 번 실행하면 토큰 재생 적합도가 0.994와 1.000으로 다르게 나온 일이 있다. 정렬은 가능한 짝을 모두 탐색하므로 실행마다 같다. 이름이 같은 전이가 있는 모델은 정렬로 잰 값을 쓴다.

고친 모델을 팀 절차로 받아들일지는 따로 정한다

모델 수리는 “기록이 이렇게 흘렀다”를 모델에 넣는 일이다. 결정 기록 갈래를 넣으면 “개발 중에 정책이 바뀌어도 된다”는 절차가 되고, 실습 28의 개선안 B(착수 전 결정 확인)와 반대가 된다. 고친 모델은 분석과 시뮬레이션의 기준 모델로 쓰고, 팀의 절차 문서는 회의에서 갈래마다 받아들일지 정한 뒤 고친다.

6선언적 제약 발견과 규칙 파일

절차 모델은 허용하는 순서를 모두 그린다. 선언적(declarative) 모델은 지켜야 할 제약만 적고, 제약을 어기지 않는 순서는 모두 허용한다. 페시치(M. Pesic)와 판 데르 알스트가 2006년 BPM 워크숍에서 제안한 Declare가 대표적이고, 디 치초(C. Di Ciccio)와 메첼라(M. Mecella)의 MINERful(ACM TMIS 2015)은 로그 통계로 제약을 빠르게 발견한다. 실습 21의 process-rules.tsv는 Declare의 템플릿 셋(absence, response, precedence)에 기한 있는 규칙(within)을 더한 것이다.

PM4Py 2.7.23.8의 discover_declare는 템플릿마다 활성 사례(제약이 적용되는 사례)와 지킨 사례를 센다. declare-rules.py는 그 결과를 규칙 파일과 맞대고, 규칙 후보와 기간 사이에 신뢰도가 바뀐 제약을 적는다.

위에서부터 읽는다.

  1. 자동 기준이 고른 486개: PM4Py는 기준을 주지 않으면 가장 좋은 제약의 활성 비율과 신뢰도에 0.8을 곱한 값을 기준으로 쓴다. 그 결과에는 absence(결정 기록)처럼 257건 중 214건이 지킨 제약도 들어 있다. 이 제약을 규칙으로 쓰면 “결정 기록을 남기지 않는다”가 되어, 실습 26에서 경계한 대로 기록을 줄이는 쪽으로 행동을 바꾼다. 신뢰도가 100%가 아닌 제약은 “대개 그렇다”는 서술로 읽는다.
  2. 규칙 파일과 비교: response(막힘, 막힘 해소)는 36건 모두 지켰지만 자동 기준에서는 빠졌다. 활성 사례가 257건 중 36건(14%)이라 활성 비율 기준에 못 미쳤기 때문이다. 드문 활동에 관한 규칙은 활성 비율 기준을 낮춘 엄격 기준(10% 이상, 신뢰도 100%)에서만 보인다. within 규칙은 Declare 기본 템플릿에 시간 조건이 없어 비교하지 못했다.
  3. 규칙 후보 14개: 이어지는 쌍과 겹치는 템플릿을 줄인 결과다. chainsuccession(리뷰 승인, PR 병합)은 “승인 바로 다음은 병합, 병합 바로 앞은 승인”으로, 규칙 파일의 precedence보다 강하다. chainprecedence(첫 커밋, 결정 기록)은 결정 기록 43건이 모두 첫 커밋 바로 다음에 나왔다는 서술이다. 개발이 시작된 뒤에 정책이 바뀐다는 실습 25의 발견을 제약 하나로 적은 것이다.
  4. 기간 비교: response(결정 기록, 변경 요청)의 신뢰도가 78%(14/18)에서 32%(8/25)로 떨어졌다. 결정 기록이 있는 업무가 6월 이후에는 변경 요청으로 덜 이어진다는 뜻이다. 비교한 제약이 418개라서 p = 0.005 하나만으로 변화라고 판정하지 않는다. 6월 1일에 리뷰 당번과 함께 시작한 정책 변경 업무의 완료 조건 갱신 규칙(실습 27)이 겨냥한 관계라는 사전 가설이 있을 때 의미가 있다.

규칙 파일 개정안을 pm-lab/rules-revision.md에 적는다. 키트의 process-map.sh가 읽는 유형(absence, response, precedence, within)으로 적을 수 있는 것과 없는 것을 나눈다.

# 규칙 파일 개정안 (근거: declare-rules.py, 2026-03~09 Orbit 257건)

| 규칙 | 제안 | 근거 |
| - | - | - |
| precedence 리뷰 승인 / PR 병합 | 유지 | 234/234. chainsuccession도 234/234지만 process-map.sh에 "바로 다음" 유형이 없다 |
| precedence PR 병합 / 업무 완료 (area!=qa) | 유지 | 범위를 정한 뒤 234/234 |
| response 막힘 / 막힘 해소 | 유지 | 36/36. 자동 기준에서는 활성 비율 때문에 빠진다 |
| absence 다시 열림 | 유지 (감시용) | 244/257. 위반 건수를 목표로 삼지 않는다 |
| within PR 생성 / 첫 리뷰 / 1작업일 | 유지 | Declare 기본 템플릿으로 적을 수 없다 |
| response 변경 요청 / 리뷰 승인 | 추가 | 63/63. 변경 요청을 받고 승인 없이 닫힌 PR을 찾는다 |
| 결정 기록은 작업 시작 전에 | 지금 유형으로 적을 수 없다 | not-succession(작업 시작, 결정 기록)이 필요하다. 지금은 43/43이 어긴다. 개선안 B를 적용하면 감시 규칙으로 쓴다 |

7개념 표류 찾기

보스(R. P. J. C. Bose) 등은 2014년 IEEE Transactions on Neural Networks and Learning Systems 논문에서 프로세스가 분석 기간 중에 바뀌는 것을 개념 표류(concept drift)라고 부르고, 세 과제로 나눴다. 바뀐 시점 찾기, 바뀐 부분 찾기, 바뀐 모양 설명하기다. 바뀌는 모양은 한 번에 바뀌는 급변(sudden), 옛 방식과 새 방식이 한동안 섞이는 점진(gradual), 계절처럼 되풀이되는 반복(recurring) 등으로 나뉜다. 방법의 뼈대는 사례를 시간 순서로 창에 나누고, 창마다 특징을 뽑아 이웃한 창의 특징이 같은 분포에서 나왔는지 검정하는 것이다.

drift-check.py는 사례를 작업 시작 신호의 달로 나누고 두 종류를 검정한다. 흐름은 사례마다 직접 이어짐 관계가 있는지(0/1)를 모아 두 창의 비율 차이 합(흐름 거리)을 순열 검정(999회, 씨앗값 1)으로, 시간은 첫 리뷰 대기와 처리 시간을 맨-휘트니 U 검정으로 비교한다. 이웃한 창 비교가 다섯 번이므로 검정마다 p값을 홈(Holm) 방식으로 보정한다.

달별 중앙값 두 개를 위아래로 그린 선 그래프. 위는 첫 리뷰 대기로 3월 8.6h, 4월 5.3h, 5월 5.8h에서 6월 1.8h로 떨어지고 7월 1.8h, 8월 1.5h다. 아래는 처리 시간으로 42.6h, 35.5h, 35.0h, 30.4h, 27.7h, 26.2h로 꾸준히 줄었다. 5월과 6월 사이에 세로 점선이 있다.
작업 시작 달별 중앙값(업무 시간). drift-check.py의 창별 요약 표를 그렸다. 점선은 첫 리뷰 대기에서 보정한 p값이 0.05보다 작았던 5월 → 6월 경계다.

보정한 p값이 0.05보다 작은 비교는 5월 → 6월의 첫 리뷰 대기 하나다(5.8h → 1.8h). 날짜를 모르고 로그만 받았어도 6월에 리뷰 대기가 바뀌었다는 것을 찾는다. 나머지 결과도 읽는다.

  • 흐름 거리는 어느 비교에서도 유의하지 않다: 6월의 변화는 활동의 순서보다 기다리는 시간에서 컸다. 직접 이어짐 관계만 특징으로 쓰는 방법(PM4Py의 pm4py.algo.concept_drift에 있는 보스 등의 2011년 방식도 관계 빈도를 쓴다)은 시간만 바뀐 변화를 대상으로 삼지 않는다. 흐름과 시간을 따로 검정하는 이유다.
  • 7월 → 8월의 흐름 거리가 가장 크다: 8월에는 변경 요청이 있었던 PR 업무가 8%로 줄었다. 그러나 관계 전체로 본 순열 검정은 보정 뒤 p = 0.505다. 관계 하나만 골라 검정하면 우연히 나온 차이도 작은 p값을 낸다. 9월 자료가 쌓인 뒤 다시 본다.
  • 처리 시간은 이웃한 달끼리는 차이가 없지만 꾸준히 줄었다: 42.6h에서 26.2h까지 달마다 조금씩 줄어 이웃한 창 비교로는 어느 경계에서도 유의하지 않다. 점진적인 변화는 기준 창과 비교해야 보인다.

3월과 비교하면 처리 시간은 7월부터 보정한 p값이 0.001보다 작다. 4주 창에서는 “4월 27일~ → 5월 25일~” 비교에서 첫 리뷰 대기가 바뀌었다고 나온다. 5월 25일에 시작한 창에 5월 마지막 주와 6월의 사례가 섞였기 때문이다. 창의 경계가 변화 시점과 맞지 않으면 변화가 그 창 전체로 번져 보인다. 창을 짧게 하면 시점은 정확해지지만 창마다 사례가 적어 검정력이 떨어진다. Orbit의 달 단위 창에는 사례가 40~49건씩 들어 있다.

표류 점검을 주간 보고에 넣을 때

창을 날마다 새로 계산하고 검정을 반복하면, 실제로 아무것도 바뀌지 않아도 언젠가 유의한 결과가 나온다(여러 번 들여다보기의 문제). 표류 점검은 달마다 한 번, 정해 둔 지표 몇 개로 하고, 유의한 결과는 원인을 확인할 사례 목록으로 쓰고, 확인을 마친 뒤에 결론을 적는다.

막히면
증상확인과 해결
오류: 프로세스 트리를 읽지 못했다따옴표가 짝을 이루는지, 연산자 뒤에 괄호가 바로 오는지(->(, X(, *(, +() 확인한다. 활동 이름은 작은따옴표로 감싼다
정렬 열이 모두 -다모델이 건전하지 않다. 건전성 열을 본다. 손으로 쓴 트리는 언제나 건전하므로, 발견한 모델이 문제라면 다른 알고리즘을 쓴다
ILP 마이너에서 solution from scipy may be unstable 경고가 나온다PM4Py가 선형 계획을 SciPy로 풀 때 내는 경고다. 이 교안의 결과는 이 경고가 난 상태로 계산했다. PuLP를 설치하면 PM4Py가 그쪽을 쓴다
규칙 비교에서 범위를 정한 규칙이 “전체”로 나온다규칙 파일의 여섯째 열이 탭으로 구분되었는지 확인한다(cat -et pm-lab/process-rules.tsv)
오류: 비교할 창이 두 개보다 적다로그 기간이 짧다. --window 4w로 창을 줄이거나 --min-cases를 낮춘다. 사례가 20건보다 적은 창의 검정은 믿기 어렵다
  • 발견 알고리즘 여섯 개와 팀절차 모델을 같은 표로 비교하고, 질문에 맞는 모델을 고른 이유를 적었다.
  • 같은 모델의 두 정밀도(ETC 0.969, 정렬 기반 0.999)가 다른 이유를 설명할 수 있다.
  • 정렬의 로그 이동을 근거로 팀절차 모델을 고쳐 적합도와 정밀도를 다시 쟀다.
  • 선언적 제약 발견 결과를 규칙 파일과 맞대고 pm-lab/rules-revision.md를 썼다.
  • drift-check.py로 5월 → 6월의 변화를 찾고, 흐름 거리가 유의하지 않은 이유를 설명할 수 있다.

마치며...

같은 로그에서 알고리즘마다 크기, 적합도, 정밀도가 다른 모델이 나왔고, 측정 방법에 따라 같은 모델의 정밀도도 달랐다. 모델은 질문으로 고르고, 숫자는 같은 방법으로 잰 것끼리 비교한다. 선언적 제약 발견은 규칙 후보와 함께 “대개 그렇다”는 서술을 내놓았고, 기간 창의 통계 검정은 날짜를 모르는 상태에서 6월의 리뷰 대기 변화를 찾았다. 다음 모듈에서는 그 리뷰 대기를 대기열로 보고, 시뮬레이션으로 배정 정책을 비교한다.