주제
메이저리그 선수들의 과거 데이터를 바탕으로 향후 선수 데이터를 예측하는 방법을 알아보겠습니다. 이 선수가 팀 승리에 얼마나 공헌하였는지를 종합하여 표현하는 스탯인 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()
마지막으로 타격 데이터의 복사본을 만들어 주었습니다. 그렇게 하는 이유는 실제로 타격 데이터를 제외할 것이기 때문입니다.
'야구 분석 > Python' 카테고리의 다른 글
메이저리그 선수들의 WAR 예측하기 3 (0) | 2024.07.07 |
---|---|
메이저리그 선수들의 WAR 예측하기 2 (1) | 2024.07.03 |
삼성 라이온즈 성적 크롤링하기 (1) | 2024.06.09 |
삼성 라이온즈 관중 수 시각화 (1) | 2024.06.05 |
삼성 라이온즈 관중 수 크롤링 (0) | 2024.06.01 |