초안 !
최최종 더이상의 변화는 없다
baseball batter prediction (1).ipynb
import pandas as pd
import numpy as np
import re
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
# 모델
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
# 데이터 불러오기
data = pd.read_csv('baseball_data.csv')
data.head()
################## 전처리 ########
import pandas as pd
import re
# 아웃 카운트
def determine_outcount(x):
if '무사' in x:
return 0
elif '1사' in x:
return 1
elif '2사' in x:
return 2
else:
return None # 만약 '무사', '1사', '2사'가 아닌 다른 값이 있다면 None을 할당
data['out_count'] = data['Prev'].apply(lambda x: determine_outcount(x))
# 'BC' 컬럼에 NaN 값이 있는 경우, 타격 외의 상황이므로 제외 (도루, 견제 등)
data = data.dropna(subset=['BC'])
# 타순
data['bat_order'] = data['Batter'].str.split().str[0]
# 홈/원정 경기를 표시하는 컬럼을 추가합니다. (0:원정, 1:홈)
data['home_away'] = data['Inning'].apply(lambda x: '말' in x).astype(int)
# 이닝
data['Inning'] = data['Inning'].str.extract('(\\d+)').astype(int)
# WPe에서 %를 떼고 숫자형으로 변환
data['WPe'] = data['WPe'].str.rstrip('%').astype(float)
# 볼 카운트
data[['ball', 'strike']] = data['BC'].str.extract(r'\\((\\d+)-(\\d+)\\)')
# 주자 위치
def extract_runners(prev_str):
runner_positions = {'base_1': 0, 'base_2': 0, 'base_3': 0}
if '1루' in prev_str:
runner_positions['base_1'] = 1
if '2루' in prev_str:
runner_positions['base_2'] = 1
if '3루' in prev_str:
runner_positions['base_3'] = 1
# 복수 주자 상황 처리 (예: '1,2루')
matches = re.findall(r'(\\d)루', prev_str)
for match in matches:
runner_positions[f'base_{match}'] = 1
return pd.Series(runner_positions)
# 'Prev' 컬럼을 사용하여 주자 위치를 표시하는 컬럼을 추가합니다.
data[['base_1', 'base_2', 'base_3']] = data['Prev'].apply(extract_runners)
# 'Result' 컬럼을 사용하여 타자의 결과 (0: 아웃 혹은 삼진, 1: 그 외)
data['result'] = data['Result'].apply(lambda x: 0 if '삼진' in x or '아웃' in x else 1)
# 안쓰는 데이터 아웃
data = data.drop(['Date', 'Pitcher', 'BC', 'Result', 'Prev', 'Next', 'REa', 'WPa', 'Batter'], axis=1)
# 데이터 확인
data.head()
############ 스케일링 ############
# 숫자형 칼럼과 카테고리형 칼럼 분리
numeric_features = ['WPe', 'REs', 'LEV', 'ball', 'strike', 'out_count']
categorical_features = ['Team', 'bat_order', 'Inning', 'home_away', 'base_1', 'base_2', 'base_3']
# 숫자형 데이터 스케일링
scaler = StandardScaler()
numeric_data = data[numeric_features]
numeric_data_scaled = scaler.fit_transform(numeric_data)
numeric_data_scaled_df = pd.DataFrame(numeric_data_scaled, columns=numeric_features)
# 스케일링된 숫자형 데이터를 원래 데이터셋에 대체
for feature in numeric_features:
data[feature] = numeric_data_scaled_df[feature]
# 원-핫 인코딩
one_hot_encoded_columns = pd.get_dummies(data[categorical_features], drop_first=True)
data = data.drop(categorical_features, axis=1)
data = pd.concat([data, one_hot_encoded_columns], axis=1)