야구 분석/Python

메이저리그 선수들의 WAR 예측하기 1

sam_j_s 2024. 6. 30. 09:43
728x90
반응형

주제

메이저리그 선수들의 과거 데이터를 바탕으로 향후 선수 데이터를 예측하는 방법을 알아보겠습니다. 이 선수가 팀 승리에 얼마나 공헌하였는지를 종합하여 표현하는 스탯인 WAR을 이용하여 해 보겠습니다.
 

선수 데이터 가져오기

import os
import pandas as pd
import numpy as np
from pybaseball import batting_stats

START = 2003
END = 2023

 
다양한 웹사이트에서 야구 데이터를 다운로드할 수 있는 pybaseball을 이용해서 2003년부터 2023년 사이의 선수들의 데이터를 가져오겠습니다.

batting = batting_stats(START, END, qual=200)
batting.to_csv("batting.csv")

 
2003년부터 2023년까지의 선수들의 데이터 중 타석이 200타석 이상인 선수들의 데이터만 가져오도록 해주었습니다.

batting = batting.groupby("IDfg", group_keys=False).filter(lambda x: x.shape[0] > 1)
batting

다음 시즌의 선수들의 WAR을 예측하고 싶은데 선수가 단일 시즌에 대한 데이터만 가지고 있으면 예측을 할 수 없어 단일 시즌인 선수는 제외해 주었습니다.
 6775개의 행을 볼 수 있습니다. 이들은 2003년부터 2023년까지 200번의 타석에 오른 타자들이면 최소한 두 시즌의 데이터를 가지고 있습니다. 베리 본즈나 무키 베츠 등등 유명한 선수들이 있는 것을 알 수 있습니다.
 

데이터 전처리

def next_season(player):
    player = player.sort_values("Season")
    player["Next_WAR"] = player["WAR"].shift(-1)
    return player

batting = batting.groupby("IDfg", group_keys=False).apply(next_season)

 
다음 시즌의 WAR을 예측하는 것이므로 데이터를 선수별로 분할한 다음 각 선수에 대해 다음 해의 WAR 값을 가져오는 함수를 만들었습니다.

batting[["Name", "Season", "WAR", "Next_WAR"]]

선수의 이름, 시즌, WAR, 다음 시즌 WAR을 불러와 보았습니다. Alfredo Amezaga의 경우 2006년에는 1.1의 WAR을 기록하고 2007년에는 2.0, 2008년에는 1.2, 2009년은 해당하는 데이터가 없으므로 NaN이 나온 것을 알 수 있습니다.

null_count = batting.isnull().sum()
null_count

batting 데이터를 가져온 것을 보면 많은 데이터가 비어있는 것을 알 수 있습니다. 옛날에는 측정하지 않은 데이터가 생긴 것도 있고 야구장별로 측정하는 것이 다르기 때문에 해당하는 지워주도록 하겠습니다.

complete_cols = list(batting.columns[null_count == 0])
batting = batting[complete_cols + ["Next_WAR"]].copy()
batting

NaN값이 있는 데이터는 제거해야 되지만 Next_WAR은 몇 가지 누락된 값이 있지만 예측하려는 목표이므로 데이터 프레임에 유지해야 됩니다.
Next_WAR를 제외한 다른 데이터에서는 NaN값이 안 나오는 것을 알 수 있습니다.

batting.dtypes

이제 열의 데이터 유형을 확인하여 일부 열이 object로 되어 있는데 이를 처리해주어야 합니다.

batting.dtypes[batting.dtypes == "object"]

이름, 팀, 달러, 연령대가 있는 것을 알 수 있습니다.

batting["Dol"]

달러열은 팬그래프가 통계에 따라 선수의 가치를 제공하는 것이므로 지워주겠습니다.

batting["Age Rng"]

연령대는 시즌 중의 선수의 나이에 대해서 나오는 것입니다. 시즌 중에 생일이 지나면 나이가 바뀌는 것이지만 필요가 없으므로 지워주겠습니다.

batting["Team"].astype("category")

 
35개의 팀이 나오는 것을 알 수 있습니다. 이것을 팀별로 숫자로 바꿔주겠습니다.

batting["Team"].astype("category").cat.codes

플로리다는 12로 애너하임은 1로 변한 것을 알 수 있습니다. 이것을 team_code로 넣어주겠습니다.

batting_full = batting.copy()
batting = batting.dropna()

마지막으로 타격 데이터의 복사본을 만들어 주었습니다. 그렇게 하는 이유는 실제로 타격 데이터를 제외할 것이기 때문입니다.

728x90
반응형

'야구 분석/Python'의 다른글

  • 현재글 메이저리그 선수들의 WAR 예측하기 1

관련글