각종 스포츠/KBO

스탯티즈) 타자 스탯 중 상관 관계가 높은 스탯들은?

강청색 2024. 3. 7. 01:07

스탯티즈를 분석해서 글을 써보고자 한다.

import pandas as pd

url = "http://www.statiz.co.kr/stat.php?mid=stat&re=0&ys=1982&ye=2023&se=0&te=&tm=&ty=0&qu=auto&po=0&as=&ae=&hi=&un=&pl=&da=1&o1=WAR_ALL_ADJ&o2=TPA&de=1&tr=&cv=&ml=1&sn=30&pa=0&si=&cn=&lr=1"
tables = pd.read_html(url)
print(len(tables),"개의 테이블이 있습니다")
df_list = pd.read_html(url)
df = df_list[0]
df

이런 식의 정렬되지 않은 데이터 프레임이 나타난다.

# 두 번째 레벨의 컬럼명만 선택하여 사용
df.columns = df.columns.get_level_values(2)
#선택 행 이후 행 다 삭제
index_of_column_29 = 29
df = df.iloc[:, :index_of_column_29 + 1]  
df

정렬을 진행하면  411 rows × 30 columns의 항목이 뜨게 된다

# df 이름 항목에서 이름이 있는 행 제거
df = df[~df['이름'].str.contains('이름')]
#다음 해당하는 컬럼 삭제
columns_to_drop = ['순', '타석', '타수','WAR*']
df = df.drop(columns=columns_to_drop)
df.info()

해당된 행들을 지우고 컬럼을 지웠더니 343 *24의 데이터가 나타났다.

다만 속성이 전부 object이기 때문에 변환이 필요하다.

# 팀 이름을 제외한 나머지 열은 int로 변환
int_columns = df.columns.difference(['이름','타율', '출루', '장타', 'OPS', 'wRC+','wOBA'])
df[int_columns] = df[int_columns].astype(int)
# '타율', '출루', '장타', 'OPS', 'wRC+' 열을 float로 변환
float_columns = ['타율', '출루', '장타', 'OPS', 'wRC+','wOBA']
df[float_columns] = df[float_columns].astype(float)

다음과 같이 속성이 변경 되었다.

우선적으로 득점과 상관이 있는 스탯들은 무엇이 있는지 궁금해서 시각화를 진행하게 되었다.

 

# 2번쨰 컬럼부터 진행(object 제거)
df = df.iloc[:,1:]

2번째 열부터 진행해야 Object항목인 이름이 없어 오류가 발생하지 않는다.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 폰트 설정
plt.rc('font', family='Malgun Gothic')

# 선택한 항목들
selected_columns = ['타율', '출루', '장타', 'OPS', '안타', '2타', '홈런', '루타', '타점', '3타', '도루', '볼넷', '삼진', '병살', '희타', '희비']

# 색상 설정
colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'brown', 'pink', 'gray', 'cyan', 'magenta', 'lime', 'teal', 'lavender', 'coral', 'lightblue']

# 4행 4열의 그리드 생성
fig, axs = plt.subplots(nrows=4, ncols=4, figsize=(20, 20))

# 각 항목을 그리드에 순서대로 표시
for i, column in enumerate(selected_columns):
    row = i // 4  # 현재 항목의 행 인덱스
    col = i % 4   # 현재 항목의 열 인덱스
    sns.scatterplot(x='득점', y=column, data=df, color=colors[i], ax=axs[row, col])
    axs[row, col].set_xlabel('득점')
    axs[row, col].set_ylabel(column)
    axs[row, col].grid(True)

# 그리드 간의 간격 조절
plt.tight_layout()
plt.show()

 

일단 타점과 루타의 상관관계가 높은 것으로 나타냈다.

좀 더 보기 편하게하려고 히트맵을 활용해 진행하였다.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 득점과 다른 열 간의 상관관계만 추출
corr_with_score = df.corr()['득점'].drop('득점')

# 상관관계 크기를 기준으로 내림차순 정렬
sorted_corr = corr_with_score.sort_values(ascending=False)

# 폰트 설정
plt.rc('font', family='Malgun Gothic')

# 히트맵 생성
plt.figure(figsize=(4, 7))
sns.heatmap(pd.DataFrame(sorted_corr), annot=True, cmap='coolwarm', fmt=".2f", cbar=False)
plt.title('Correlation Heatmap with 득점')
plt.show()

가장 높은 스탯은 타점, 루타, 안타, 2타(2루타)로 나타났으며, 상관이 없는 스탯은 팀(연도), 도실(도루실패), 희타(희생타), 도루, 3타(3루타), 고4(고의사구)로 나타났다.

3루타도 장타이긴 한데 가장 낮다니 의외긴하고 고의사구를 하는 이유가 뭔지 알 거 같다.

득점만 하긴 그래서 OPS, 타율, 홈런, 타점을 뽑아서 진행했다.

OPS - 상위권 : 장타, wOBA, 출루, 타율, 득점 / 하위권 : 팀, 도실, 희타, 3타, 도루

타율 - 상위권 : OPS, wOBA, 출루, 장타, 득점 / 하위권 : 팀, 희타, 도실, 고4, 도루

홈런 - 상위권 : 장타, 루타, OPS, 타점, 득점 / 하위권 : 팀, 도실, 희타, 3타, 도루

타점 - 상위권 : 득점, 루타, 안타, 2타, OPS / 하위권 : 팀, 도실, 희타, 도루, 3타

로 나타났으며, 득점이 공통적으로 들어가 있었으며, 장타가 타점을 제외하고 공통적으로 속해있었다.

하위권에서는 팀은 연도를 나타내는 거라 제외하자면 도실, 희타, 도루, 3루타 및 고의사구가 낮게 연관되어 있었다.

홈런과 OPS가 높은 야구를 빅볼 야구라고 하는데 장타가 필수인 것을 알 수 있었다.

 

투수편으로 돌아옵니다.