초안 !

야구 분석.ipynb

노시환

김영웅

양의지

나성범

고승민

박해민

김도영

최종 코드 수합 파일

최최종 더이상의 변화는 없다

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)