2021-03-06 08:31:26

지난 번에 타율보다 OPS가 높은 팀이 승리할 가능성이 크다는 내용의 글을 작성했었습니다. 오늘은 좀 더 나아가서, 타율, 출루율, OPS(출루율 + 장타율), RC(출루율 * 장타율)이 각각 득점과 어떠한 상관관계를 갖는지를 계산한 후, 어떤 스탯이 가장 득점과 연관이 있는지에 대해서 살펴보겠습니다.  

 

이를 위해서, 저는 MLB의 1970년부터 2019년까지의 팀 기록 중, 5000 타수 이상을 기록한 경우를 분석에 사용했습니다. 시즌 타수가 5000타수보다 적었던 경우에는 타율의 편차가 비교적 크기 때문에 제외했습니다. MLB 데이터를 얻기 위해서 레먼 데이터베이스를 사용했습니다. 또한 상관관계를 평가하기 위해 피어슨 상관계수를 계산했습니다. 

 

타율과 득점 사이의 상관관계

우선 타율(AVG)과 득점 사이의 상관관계부터 살펴보겠습니다. 

 

 

보다시피, 타율과 득점 사이의 상관계수는 0.7716입니다. 

 

출루율과 득점 사이의 상관관계

이번에는 출루율과 득점 사이의 상관관계를 살펴보겠습니다. 타율과 득점 사이의 상관관계보다 더 강할까요?

 

 

출루율과 득점 사이의 상관계수는 0.8636으로 타율과 득점 사이의 상관계수 0.7716보다 약 0.1 정도 높습니다. 즉, 출루율이 타율보다 좀 더 득점력과 연관이 있다는 것입니다. 추신수 선수의 경우 이 출루율이 매우 좋았기 때문에, 거액의 연봉을 보장받고 클리블랜드에서 텍사스 레인저스로 이적했던 것입니다. 

 

OPS와 득점 사이의 상관관계

이번에는 OPS와 득점 사이의 상관관계를 살펴보겠습니다. OPS는 출루율 + 장타율입니다. 

 

 

OPS와 득점 사이의 상관계수는 0.9512로 타율, 출루율과의 상관계수보다 훨씬 높습니다. 이렇기 때문에 현대야구에서는 타율보다는 출루율을, 출루율보다는 OPS를 더 중요하게 생각하는 것입니다.

 

RC와 득점 사이의 상관관계

OPS는 출루율과 장타율을 더한 것이라고 했습니다. RC는 출루율과 장타율을 곱한 것입니다. RC와 득점 사이의 상관관계는 어떤지 확인해보겠습니다. 

 

OPS의 상관계수보다 아주 살짝 더 높습니다. 하지만, OPS가 연산에 있어서 좀 더 쉽기 때문에 RC보다 OPS가 좀 더 각광받고 있는 것 같습니다. 아무래도 덧셈이 곱셈보다 쉽죠. 

 

정리

타율, 출루율, OPS, RC 중에 어떤 것이 더 득점과 관련이 있는지 살펴봤습니다. 

 

타율 < 출루율 < OPS < RC

0.7716 < 0.8636 < 0.9512 < 0.9542

 

위 순서로 더 상관관계가 강했습니다. 하지만, OPS와 RC는 득점과의 상관관계에 있어서 큰 차이는 없었습니다. 우리는 OPS 또는 RC가 높은 선수가 팀 득점에 기여하는 바가 크다는 것을 위 내용을 통해 추론할 수 있습니다. 

 

소스코드

저는 오늘 포스팅을 작성하는 데 있어서 필요한 시각 자료들은 다음의 파이썬 코드로 만들었습니다. 필요하신 분은 참고하시기 바랍니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import sqlite3
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
 
# 한글 폰트 사용을 위해서 세팅
font_path = "C:/Windows/Fonts/ngulim.ttf"
font = font_manager.FontProperties(fname=font_path).get_name()
rc('font', family=font)
 
with sqlite3.connect("lahmansbaseballdb.sqlite"as con:
    cur = con.cursor()
    cur.execute('''
    select AB, H, R, BB, HBP, SF, "2B", "3B", HR from teams where yearID >= 1970 and AB >= 5000;
    ''')
    # AB: 타수
    # H: 안타
    # R: 득점
    # BB: 볼넷
    # HBP: 몸에 맞는 공
    # SF: 희생플라이
    # 2B: 2루타
    # 3B: 3루타
    # HR: 홈런
 
    data = cur.fetchall()
 
    AB = np.zeros((len(data)))
    H = np.zeros((len(data)))
    R = np.zeros((len(data)))
    BB = np.zeros((len(data)))
    HBP = np.zeros((len(data)))
    SF = np.zeros((len(data)))
    H2 = np.zeros((len(data)))
    H3 = np.zeros((len(data)))
    HR = np.zeros((len(data)))
 
    for i in range(len(data)):
        AB[i] = data[i][0]
        H[i] = data[i][1]
        R[i] = data[i][2]
        BB[i] = data[i][3]
        HBP[i] = data[i][4]
        SF[i] = data[i][5]
        H2[i] = data[i][6]
        H3[i] = data[i][7]
        HR[i] = data[i][8]
 
    AVG = H/AB  # 타율
    OBP = (H + BB + HBP) / (AB + BB + HBP + SF)  # 출루율
 
    H1 = H - H2 - H3 - HR  # 1루타 갯수
    SLG = (H1 + H2*2 + H3*3 + HR*4/ AB  # 장타율
    OPS = OBP + SLG  # OPS (출루율 + 장타율)
    RC = OBP * SLG  # RC (출루율 * 장타율)
    print(RC)
 
    plcc1 = round(stats.pearsonr(AVG, R)[0], 4)
    plcc2 = round(stats.pearsonr(OBP, R)[0], 4)
    plcc3 = round(stats.pearsonr(OPS, R)[0], 4)
    plcc4 = round(stats.pearsonr(RC, R)[0], 4)
 
    plt.scatter(AVG, R, c='b', s=10, alpha=0.3)
    plt.title('타율과 득점 사이의 상관관계')
    plt.xlabel('타율')
    plt.ylabel('득점')
    plt.text(0.25500"상관계수: "+str(plcc1), fontsize=20, color='red')
    plt.grid(True)
    plt.savefig('./corr_between_avg_and_r.png')
    plt.show()
 
    plt.scatter(OBP, R, c='b', s=10, alpha=0.3)
    plt.title('출루율과 득점 사이의 상관관계')
    plt.xlabel('출루율')
    plt.ylabel('득점')
    plt.text(0.32500"상관계수: "+str(plcc2), fontsize=20, color='red')
    plt.grid(True)
    plt.savefig('./corr_between_obp_and_r.png')
    plt.show()
 
    plt.scatter(OPS, R, c='b', s=10, alpha=0.3)
    plt.title('OPS와 득점 사이의 상관관계')
    plt.xlabel('OPS')
    plt.ylabel('득점')
    plt.text(0.7500"상관계수: " + str(plcc3), fontsize=20, color='red')
    plt.grid(True)
    plt.savefig('./corr_between_ops_and_r.png')
    plt.show()
 
    plt.scatter(RC, R, c='b', s=10, alpha=0.3)
    plt.title('RC와 득점 사이의 상관관계')
    plt.xlabel('RC')
    plt.ylabel('득점')
    plt.text(0.12500"상관계수: " + str(plcc4), fontsize=20, color='red')
    plt.grid(True)
    plt.savefig('./corr_between_rc_and_r.png')
    plt.show()
 
 
cs

 

bskyvision의 추천글

[세이버메트릭스] 타율이 높은 팀 vs OPS가 높은 팀, 누가 이길까?  

[세이버메트릭스] OPS를 좀 더 개선한 GPA란?  

[세이버메트릭스] 타타타자로 시작하는 말-타석, 타수, 타율  

 

참고자료

[1] 벤저민 바우머, 앤드루 짐발리스트 지음, "세이버메트릭스 레볼루션"