jaehyeong.net
writing
2026-05-15·baseball·9 min

xwOBA − wOBA 갭, 절반은 운이고 나머지는 발이다

EV가 1등으로 보였던 건 통계적 착시였다. 분포 변수들은 spray angle과 hit distance의 그림자고, 끝까지 살아남는 건 sprint speed. 갭의 40% 정도가 구조적, 나머지는 노이즈다.

토이프로젝트 정리 노트. 2015–2024 MLB 풀시즌(PA ≥ 500) 1,247개 시즌. 데이터는 FanGraphs + Baseball Savant. 코드는 repo.

xwOBA에서 wOBA를 뺀 값을 보고 흔히 "운이 좋았다", "운이 없었다"고 말한다. 절반 정도는 맞는 말이고, 나머지 절반은 발이다.

gap_woba = xwOBA − wOBA

양수면 기대보다 덜 받은 타자, 음수면 더 받은 타자. 양 끝에 누가 있는지 보자.

갭 상위 (기대보다 덜 받음)Seasongapsprint_speed
Cabrera, Miguel2017+0.05724.9
Howard, Ryan2015+0.05124.3
Cabrera, Miguel2016+0.05024.4
Morales, Kendrys2016+0.05024.3
Calhoun, Kole2018+0.04926.1
갭 하위 (기대보다 더 받음)Seasongapsprint_speed
Friedl, TJ2023−0.06628.3
Cozart, Zack2017−0.06226.0
Burns, Billy2015−0.05729.1
Strange-Gordon, Dee2015−0.05429.1
Arozarena, Randy2021−0.05228.7

sprint_speed 열만 봐도 갈림이 명확하다. 위쪽 24, 아래쪽 28+ ft/s. 이걸 어떻게 추적할지가 분석의 출발이었다.

EV가 1등으로 보였다

단순 OLS를 돌리면 갭을 가장 잘 설명하는 변수는 평균 타구 속도(avg_EV)였다. 표준화 계수 +0.31, p ≈ 0. 랜덤포레스트 importance도 1등. 결론은 "강하게 친 타자일수록 wOBA가 xwOBA를 못 따라간다"가 된다.

그런데 avg_EV는 xwOBA를 만드는 재료 자체다. 강하게 친 타자는 정의상 xwOBA가 높고, wOBA에는 천장이 있다. 안타는 안타고 홈런은 홈런이다. EV가 높을수록 xwOBA는 끝없이 올라가는데 wOBA가 못 따라가서 갭이 벌어진다. EV가 갭을 만든다기보다 지표 정의상 그렇게 보이는 것에 가깝다.

검증은 회귀식에 xwOBA를 같이 넣어 통제하면 된다.

변수단순 회귀 βxwOBA 통제 후 βp
avg_EV+0.308+0.1390.002
sprint_speed−0.192−0.210< 0.001
chase_pct+0.184+0.204< 0.001
bb_pct−0.137−0.225< 0.001
gb_share−0.173−0.0910.009

avg_EV의 β가 절반 잘려나가고 p도 0.002로 밀렸다. xwOBA를 통한 매개 효과지 직접 효과가 아니라는 얘기다. 후보 1번이 여기서 빠진다.

avg_EV의 표준화 계수가 xwOBA 통제 전후로 크게 줄어드는 막대 비교
xwOBA를 통제하기 전(왼쪽)과 후(오른쪽). avg_EV는 절반 이상 깎여 나가고 sprint_speed와 bb_pct가 오히려 강해진다.

단순 회귀로 끝냈으면 결론을 잘못 낼 뻔했다.

통제 후 남은 셋

sprint_speed의 β는 통제 후 오히려 커진다(−0.21). 빠른 발일수록 갭이 음수, wOBA가 xwOBA를 이기는 쪽이다. 잘 맞지 않은 내야 땅볼을 안타로 만들고, 짧게 떨어진 외야 타구를 한 베이스 더 가져간다. xwOBA 모델은 타구의 질만 보고 "아웃이어야 한다"고 판정하지만 실제 결과는 발이 뒤집는다.

sprint speed 사분위별 평균 갭 막대그래프
sprint speed 사분위로 끊어본 평균 갭. 가장 빠른 Q4는 갭이 음수(기대보다 더 받음), 가장 느린 Q1은 양수.

bb_pct와 chase_pct도 끝까지 살아남는다. 메커니즘은 sprint와 다르다. 출루 자체를 xwOBA가 직접 보상하지 않는 영역이라 wOBA에 들어간 값이 잔차로 새어나온다. 선구안 좋은 타자는 음수 쪽, 쫓아치는 타자는 양수 쪽.

fb_pct는 확장 모델에서 단일 변수 중 갭과 가장 강하게 엮인다. 띄울수록 갭이 양수, 즉 잘 맞은 정타가 외야 플라이로 잡혀나간다.

"1등 결정 요인"을 단정하기는 어렵다. final_summary는 sprint_speed, OLS 확장 모델은 fb_pct, RF는 avg_EV를 1등으로 꼽았다. 모델 스펙에 따라 1위가 바뀌는 상황이면 셋을 묶어 보는 쪽이 데이터에 더 충실하다. 손해 보는 타자의 인상은 셋을 합쳤을 때 가장 또렷하다. 느리고, 띄우고, 볼을 쫓아치는 타자. 카브레라 후기, 하워드, 푸홀스, 칼훈이 그 프로필이다.

한 층 더: spray + distance

여기서 멈출 수도 있었다. 한 가지가 걸렸다. pull_pct, oppo_pct, fb_pct, gb_pct가 정말 갭의 원인일까, 아니면 더 본질적인 변수의 그림자일까.

두 가지를 의심했다.

gap_woba 분해 가설
├─ Missing 1: spray angle (방향)
│    pull%/oppo%는 그 surrogate
├─ Missing 2: hit distance (비행 거리, hang time, 공기저항)
│    fb%/gb%/avg_LA는 그 surrogate
└─ 잔여: sprint_speed (−) + 진짜 random

spray_xwoba_v2 스크립트에서 단계별로 추가하며 β 변화를 추적했다.

변수원본 (A)+spray (B)+distance (C)shrink B→C
pull_pct−0.08+0.007−0.04spray가 흡수
oppo_pct−0.11+0.04+0.006spray가 흡수
fb_pct+0.45+0.51+0.21distance가 흡수 (−59%)
gb_pct+0.03+0.10−0.01distance가 흡수 (−109%)
avg_LA−0.30−0.21−0.12distance가 일부 흡수
sprint_speed−0.30−0.29−0.38끝까지 살아남음

pull과 oppo의 영향력은 spray angle을 직접 넣은 순간 무너진다. fb와 gb는 hit distance를 넣은 순간 절반 이하로 깎인다. 시즌별로 갭이 변해가는 흐름, 외야 수비가 좋아지면서 잘 친 공도 더 자주 잡히는 추세도 결국 이 "거리" 채널로 들어온다.

A/B/C 모델에서 변수별 표준화 계수가 단계적으로 변화하는 그림
A: 기본 통제. B: +spray. C: +distance. pull/oppo는 B에서, fb/gb/avg_LA는 C에서 흡수된다. sprint_speed만 끝까지 강해진다.

두 변수를 다 통제한 뒤에도 끝까지 남는 게 sprint_speed다. 같은 거리, 같은 방향, 같은 발사각의 타구라도 발이 빠른 타자는 갭을 줄인다.

그래서 얼마나 구조적인가

갭의 시즌 간 상관(r_yoy)이 0.375다. 비교하면:

변수r_yoy
sprint_speed0.949
avg_EV0.775
xwOBA0.675
wOBA0.529
gap_woba0.375

xwOBA와 wOBA 자체는 시즌 간에 꽤 재현되지만 갭은 절반 이하의 재현성이다. 거칠게 말해 갭의 40% 정도가 구조적, 60%가 운에 가까운 노이즈다.

모델이 보지 못한 것

R²는 14–19%다. 갭의 80% 이상은 위 변수들로 설명되지 않는다. 가장 크게 빗나간 이상치들을 보면 단서가 있다. Zack Cozart (2017), Nolan Arenado (2019), Paul Goldschmidt (2022). 셋 다 콜로라도 시기와 겹친다. 쿠어스 필드의 고지대 효과는 모델에 들어가 있지 않다.

상대 수비의 질, 타구가 떨어지는 지점의 운, 1루까지 전력질주하느냐 같은 주루 센스도 잔차에 섞여 있다. 발과 선구안과 띄움이 갭의 일부를 설명한다는 건 분명하지만, 갭은 본질적으로 노이즈가 많은 지표라는 것도 같이 받아들여야 한다.

남은 5분의 3이 무엇인지, park-adjusted 잔차나 OAA를 직접 회귀에 넣으면 어디까지 좁혀지는지가 다음 분석으로 가져갈 질문이다.


Data: FanGraphs (pybaseball.batting_stats) + Baseball Savant (statcast_sprint_speed), 2015–2024, PA ≥ 500. n = 1,247. Mediation via sequential OLS controls (xwOBA → spray → distance). YoY correlation as proxy for ICC.