聰明不如鈍筆
총명불여둔필
assignment KindeR

R로 4할 타자 출현 확률 알아보기(feat. dbinom(), pbinom())

메이저리그 '마지막 4할 타자' 테드 윌리엄스. 동아일보DB


제발 누군가 빨리 좀 타율 4할을 넘겼으면 좋겠다. 그래야 사람들이 마지막 4할 타자에 대한 질문을 그에게 쏟아내느라 나를 가만히 내버려 둘 테니 말이다.


테드 윌리엄스(1918~2002)는 1986년 펴낸 책 '타격의 과학(The Science of Hitting)'에 이렇게 썼습니다.


그러나 윌리엄스는 끝내 또 다른 4할 타자를 보지 못한 채 숨을 거뒀습니다. 그 뒤로 메이저리그는 18시즌을 더 치렀지만 여전히 4할 타자는 나오지 않았습니다.


현재까지도 메이저리그에서 마지막으로 타율 4할을 넘긴 건 1941년 윌리엄스입니다. 윌리엄스는 그해 타율 .406(456타수 185안타)을 기록했습니다.


윌리엄스 이전까지만 해도 타자 스무 명이 총 스물 여덟 번 4할을 넘겼습니다.



그런데 윌리엄스를 마지막으로 4할 타자가 자취를 감춘 이유는 뭘까요? 


미국 진화생물학자 스티븐 제이 굴드(1941~2002) 전 뉴욕대 교수는 저서 '풀하우스'(1996년 출간)를 통해 이렇게 주장했습니다.


시간이 지날수록 시스템이 안정화되면서 최고 타율 선수와 최저 타율 선수 사이 차이가 줄어들어 튀는 선수가 사라졌기 때문이다.


진화생물학적 관점에서 보면 4할 타자가 '돌연변이'라고 할 수 있는 셈입니다.


이런 주장을 통계학적으로 풀어내면 정규분포를 통해 설명할 수 있습니다.



정규분포에서는 평균에서 멀어질수록 사례가 점점 줄어들게 됩니다.


그러니 최고 타율 선수와 최저 타율 선수 사이 차이가 줄어들면 = 편차가 줄어들면 그만큼 특정 편차 바깥에 존재하는 사례가 줄어들 수밖에 없습니다.


실제로 한 경기 평균 3타수 이상을 기록한 선수들 타율을 가지고 표준편차를 계산해 그래프를 그려 보면 갈수록 차이가 줄어든다는 사실을 알 수 있습니다.


 

그러니 굴드 교수 이야기처럼 메이저리그에서 4할 타자라는 돌연변이가 나타날 확률도 점점 줄어들 수밖에 없는 겁니다.

 

(사실, 이건 한국 프로야구도 마찬가지입니다.)


롭 만프레드 메이저리그 커미셔너 동아일보DB


그런 점에서 올해는 여느 때보다 메이저리그에서 4할 타자를 볼 확률이 높은 해라고 할 수 있습니다.


신종 코로나 바이러스 감염증(코로나19) 때문에 정규리그 경기를 팀당 60경기씩만 치르기 때문입니다.


1962년부터 지난해까지는 한 팀이 162경기를 소화해야 한 시즌을 마칠 수 있었습니다.


이렇게 경기 숫자가 줄어들면 4할 타자가 출현할 확률이 올라가게 됩니다.


과연 이 확률이 얼마나 올라가는 걸까요? 그리고 이런 건 어떻게 알 수 있을까요?


R로 간단히 알아보도록 하겠습니다.



타자가 안타를 칠 확률은 이항분포(二項分布)를 통해 설명할 수 있습니다.


이항분포를 활용해 시뮬레이션을 진행하는 건 기본적으로 동전을 던져서 앞면이 나올 때와 뒷면이 나올 때 결과를 달리하는 반복하는 작업이라고 할 수 있습니다.  


단, 동전을 던졌을 때는 앞면과 뒷면이 나올 확률이 모두 $\frac{1}{2}$이지만 이항분포에서는 성공 확률을 따로 설정할 수 있습니다.


예, 그렇습니다. 이번 실험에서 우리는 타율을 성공 확률로 삼을 겁니다.


타율 .300인 타자가 다섯 번 타석에 들어서 안타를 두 번 칠 확률 그러니까 타율 .400을 기록할 확률[각주:1]은 아래처럼 계산할 수 있습니다.


$$\begin{align}\ _5 C_2 (0.3)^2(1-0.3)^3 = 0.3087\end{align}$$


실제 계산에는 이렇게 조합(combination)을 써야 하지만 우리는 R를 쓸 것이기 때문에 복잡한 수학 공식은 필요가 없습니다.


설혹 이항분포에 대해 조금 더 알고 싶으신 분은 "롯데 '가을야구' 진출 확률, 이항분포로 알아보자!" 포스트가 도움이 될 수 있습니다.


자, 그럼 바로 R를 가지고 이항분포 세계로 뛰어 들어 보겠습니다.


R에서 이항분포 확률 계산을 도와주는 함수는 dbimon()입니다.


먼저 위에서 우리가 알아본 확률은 R 코드로는 그냥 아래처럼 치면 끝입니다.

dbinom(2, 5, .300)
[1] 0.3087


이 확률은 다섯 타석에서 안타를 딱 두 개 칠 확률입니다.


그러면 두 개 이상 칠 확률은 어떻게 계산할 수 있을까요?


가장 간단한 방법은 현재 확률에 안타를 3~5개 칠 확률을 더하는 겁니다.

dbinom(3, 5, .300)
[1] 0.1323
dbinom(4, 5, .300)
[1] 0.02835
dbinom(5, 5, .300)
[1] 0.00243


이를 모두 더하면 .16308 ≒ 16.3%가 나옵니다.


따라서 원래 실력이 타율 .300인 선수가 다섯 타석에서 타율 4할 이상을 기록할 확률은 16.3%라고 할 수 있습니다.


누적확률값을 보여주는 pbinom() 함수를 쓰면 이렇게 일일이 계산하지 않아도 이 확률을 알 수 있습니다.

pbinom(2, 5, .300)
[1] 0.83692


이 숫자는 타율 .300인 타자가 다섯 타석에서 안타를 두 개 미만으로 기록할 확률을 나타냅니다.


우리가 알고 싶은 건 안타를 두 개 이상 기록할 확률이니까 그냥 1(=100%)에서 이 숫자를 빼면 됩니다.

1 - pbinom(2, 5, .300)
[1] 0.16308


그러면 우리가 알고 싶어했던 바로 그 숫자가 나왔습니다.


이제 실제 데이터를 가지고 타석과 안타 숫자를 조정해 보도록 하겠습니다.


최근 10년(2010~2019년) 동안 메이저리그에서 규정타석(503타석) 이상 들어서 타격왕 자격을 갖춘 선수는 평균 605타석, 541타수를 기록했습니다.


타자가 문자 그대로 타석에 한 번씩 들어설 때마다 타석 기록이 하나씩 올라가게 되며 이때 볼넷이나 몸에 맞는 공, 희생번트 또는 희생플라이 등으로 타석이 끝나게 되면 타수 계산에서는 빠지게 됩니다.


2010년 아메리칸리그 챔피언 결정전 당시 조시 해밀턴(오른쪽). 동아일보DB 


그리고 이 기간 제일 높은 타율을 남긴 건 2010년 당시 텍사스에서 뛰던 조시 해밀턴(39)이었습니다. 


해밀턴은 이해 타율 .359(518타수 186안타)를 기록했습니다.


최근 10년 메이저리그 평균인 541타수를 기록하면서 타율 .400 이상을 기록하려면 안타를 최소 217개 쳐야 합니다.


따라서 2010년 해밀턴이 타율 4할 이상을 기록할 확률을 이런 코드로 계산할 수 있습니다.

1 - pbinom(217, 541, .359)
[1] 0.01904947


해밀턴처럼 뛰어난 타율 관리 능력을 선보인 선수도 기록을 4할 이상으로 끌어 올릴 확률은 1.9% 정도밖에 되지 않았다는 사실을 확인할 수 있습니다.


162경기가 60경기로 줄어들면 우리가 기준으로 삼고 있는 541타수도 200타수로 줄어들게 됩니다. 


200타수에서 타율 .400 이상을 기록하려면 안타를 적어도 80개는 쳐야 합니다.


이 확률도 간단한 코드로 알아볼 수 있습니다.

1 - pbinom(80, 200, .359)
[1] 0.1005437


경기 숫자가 37% 정도로 줄어드니까 4할 이상을 기록할 확률이 10.1%로 다섯 배 이상 뛰었습니다.


개념 설명을 드리느라 차근차근 돌다리를 두드리면서 왔지만 사실 결과만 필요할 때는 딱 코드 한 줄이면 되는 셈입니다.


경기 숫자가 차이가 날 때 타율 4할 이상을 기록할 확률이 얼마나 차이가 나는지 그래프로도 확인할 수 있습니다.


위에서 본 것처럼 dbinom() 함수를 쓰면 타수별로 타율이 .000(안타가 0개)일 때부터 타율 1.000(타수만큼 안타를 칠) 때까지 나올 확률을 전부 계산할 수 있습니다.


이렇게 구한 결과를 가지고 그냥 그림을 그리면 그만입니다.


이 작업을 진행하기에 앞서 늘 그랬던 것처럼 먼저 tidyverse 패키지를 (설치하고) 불러오는 것부터 진행합니다.

#install.packages('tidyverse')
library('tidyverse')
## -- Attaching packages ---------------------------------------------------------------------------------- tidyverse 1.3.0 --
## √ ggplot2 3.3.0     √ purrr   0.3.4
## √ tibble  3.0.1     √ dplyr   0.8.5
## √ tidyr   1.1.0     √ stringr 1.4.0
## √ readr   1.3.1     √ forcats 0.5.0
## -- Conflicts ------------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()


이어서 안타 0~200개를 뜻하는 x열을 만든 다음 각 행만큼 안타가 나올 확률을 계산해 더해보겠습니다.

tibble(hit=0:200) %>%
  mutate(p=dbinom(hit, 200, .359)) 
# A tibble: 201 x 2
     hit        p
   <int>    <dbl>
 1     0 2.35e-39
 2     1 2.64e-37
 3     2 1.47e-35
 4     3 5.43e-34
 5     4 1.50e-32
 6     5 3.29e-31
 7     6 5.98e-30
 8     7 9.29e-29
 9     8 1.25e-27
10     9 1.50e-26
# ... with 191 more rows

여기서 mutate() 함수를 활용하는 작업이 잘 이해가 가지 않는다 싶으신 분은 '최대한 친절하게 쓴 R로 데이터 뽑아내기(feat. dplyr)' 패키지가 도움이 될 수 있습니다.


이렇게 계산을 마쳤으면 그냥 그래프를 그리면 됩니다.


200타수일 때는 안타 80개가 타율 4할을 결정하는 기준이니까 이 영역은 따로 표시하도록 하겠습니다.

tibble(hit=0:200) %>%
  mutate(p=dbinom(hit, 200, .359)) %>%
  ggplot(aes(x=hit, y=p)) +
  geom_area(fill='gray') +
  geom_area(data=.%>%filter(hit>=80), fill='black') +
  geom_vline(xintercept=80) 


이번에도 그래프를 그리는 부분이 이해가 가지 않는다는 분이 계시면 '최대한 친절하게 쓴 R로 그래프 그리기(feat. ggplot2)' 포스트를 읽어 보시면 좋습니다.


일단 이 그래프를 p1이라는 변수에 넣어놓고 계속해 162 경기를 기준으로도 같은 그래프를 그린 다음 p2에 저장하겠습니다.

tibble(hit=0:200) %>%
  mutate(p=dbinom(hit, 200, .359)) %>%
  ggplot(aes(x=hit, y=p)) +
  geom_area(fill='gray') +
  geom_area(data=.%>%filter(hit>=80), fill='black') +
  geom_vline(xintercept=80) -> p1
tibble(hit=0:541) %>%
  mutate(p=dbinom(hit, 541, .359)) %>%
  ggplot(aes(x=hit, y=p)) +
  geom_area(fill='gray') +
  geom_area(data=.%>%filter(hit>=217), fill='black') +
  geom_vline(xintercept=217) -> p2


그다음 patchwork 패키지를 활용하면 이 두 그래프를 쉽게 붙여 그릴 수 있습니다.

#install.packages('patchwork')
library('patchwork')


그래프 두 개를 위 아래로 배치하고 싶을 때는 그냥 '/' 기호만 쓰면 됩니다.

p1/p2

이 그래프를 통해 아래 있는 162경기 때 안타 개수별 확률 편차가 더 적다는 사실을 확인할 수 있습니다.


그러니 굴드 전 교수 이야기처럼 경기 숫자가 많으면 4할 타자가 나올 확률도 그만큼 내려간다고 할 수 있습니다.


학창시절 수학 시간에 '도대체 이걸 배워서 어디에 써먹나' 싶었던 이항분포는 사실 이렇게 쓸모가 있던 확률분포였던 셈입니다.


우리는 계속 이 기간 최고 타율(.359)을 기준으로 계산했는데 현실에 맞게 계산을 해보면 162경기 체제에서 4할 타자가 나올 확률은 0.002%, 60경기 체제에서는 3.4% 정도입니다.


그럼 모두들 Happy Charting, Happy Tidyversing!


  1. 사실 타율은 '안타 숫자 ÷ 타수'입니다. 뒤에서 살펴보겠지만 타석과 타수는 살짝 다른 개념입니다. [본문으로]

댓글, 2

account_circle
vpn_key
web

security

mode_edit
KindeR | 카테고리 다른 글 더 보기