중앙값과 MAD로 만드는 잡음에 강한 자동 보정
센서 값, 사용자 입력, 응답 시간처럼 계속 들어오는 측정값을 보고 어떤 값을 조금씩 맞춰 가야 할 때가 있다(리듬게임 자동 싱크가 그 예). 이때 필요한 건 두 가지다. 대표값을 잡음에 휘둘리지 않게 구하는 것, 그리고 그 값을 향해 출렁이지 않게 움직이는 것.
평균 대신 중앙값
평균은 값 하나만 크게 튀어도 끌려간다. [10, 12, 11, 9, 300]의 평균은 68이지만 중앙값은 11이다. 이렇게 '몇 개가 망가져도 답이 안 망가지는 정도'를 붕괴점(breakdown point)이라고 하는데, 평균은 0%(하나만 망가져도 끝), 중앙값은 50%(절반 가까이 망가져도 버팀)다.
흩어짐도 강건하게: MAD
표준편차도 평균처럼 이상치에 약하다. 대신 MAD(Median Absolute Deviation)를 쓴다. 중앙값에서 각 값이 얼마나 떨어졌는지 구하고, 그 거리들의 중앙값을 다시 구한다.
정규분포라면 표준편차 ≈ 1.4826 × MAD다. 이 비율을 이용해 'MAD의 3배 넘게 떨어진 값은 이상치'처럼 쓰기도 하고, 반대로 MAD가 크면 '지금은 데이터가 들쭉날쭉해서 판단하지 않는다'는 게이트로도 쓴다.
조금씩 따라가기: 비례 제어
대표값 e(목표와의 오차)를 구했으면 매번 e 전부가 아니라 g·e만큼(0 < g < 1) 움직인다. 오차가 그대로라면 n번 뒤 남는 오차는 e·(1−g)n로 기하급수적으로 준다. g = 0.7이면 세 번에 97%를 따라간다.
- g가 1에 가까우면 빨리 따라가지만 측정 잡음도 그대로 따라가서 값이 출렁인다.
- g가 작으면 안정적이지만 느리다.
- 한 번에 움직이는 양에 상한(clamp)을 두면, 처음 오차가 아주 클 때도 한 번에 크게 튀지 않는다. 대신 일정 속도로 따라간다.
- 아주 작은 오차(데드존)는 무시하면 목표 근처에서 쓸데없이 떨리는 걸 줄인다.
움직인 뒤엔 과거 기록도 옮긴다
보정값을 s만큼 옮겼으면, 지금까지 모은 샘플은 옛 기준으로 잰 값이다. 그대로 두면 다음 판단에서 이미 고친 오차를 또 고친다(과보정). 모아 둔 샘플에서도 s를 빼 주면 다음 판단은 '남은 오차'만 본다. 아니면 창을 비우고 새로 모아도 되지만, 그만큼 반응이 느려진다.
정리
- 대표값은 중앙값, 흩어짐은 MAD. 둘 다 정렬 한 번이면 구한다(창이 작으면 충분히 싸다).
- 흩어짐이 크면 판단 자체를 미루는 게이트를 둔다.
- 따라갈 땐 비율(g)·상한·데드존 세 가지로 속도와 안정성을 조절한다.
- 보정 후에는 과거 샘플의 기준도 같이 옮긴다.