본문 바로가기
아이디어월드/스포츠 AI 베팅

5) 5일만에 스포츠 AI 베팅 만들기 : 머신러닝 본격적용 DAY 2

by khalidpark 2022. 2. 8.

가공된 최종 데이터

데이터 분석을 통해 홈 또는 어웨이 배당률이 1.01 또는 1.02가 되어야 확률이 높음을 확인했다

머신러닝은 내가 알지못한 또다른 통찰력을 가지고 오지 않을까 하는 기대로

다른 작업없이 그냥 배당률 수치만을 놓고 결과를 비교해봤다

 

1차시도 : 랜덤포레스트

사용한 데이터 : HOME BET, AWAY BET, RESULT

정확도 : 64%

 

import pandas as pd

target = 'RESULT'
train = pd.read_csv('/content/NBA DATA.csv')

train = train[['HOME BET', 'AWAY BET','RESULT']]

train.head()

from sklearn.model_selection import train_test_split
train, test = train_test_split(train, train_size=0.80, test_size=0.20, 
                              stratify=train[target], random_state=2)

train, val = train_test_split(train, train_size=0.80, test_size=0.20, 
                              stratify=train[target], random_state=2)

train.shape, val.shape, test.shape


features = train.drop(columns=[target]).columns

X_train = train[features]
y_train = train[target]
X_val = val[features]
y_val = val[target]
X_test = test[features]

from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer 
from sklearn.pipeline import make_pipeline

pipe = make_pipeline(
    RandomForestClassifier(n_jobs=-1, random_state=10, oob_score=True)
)

pipe.fit(X_train, y_train)
print('검증 정확도: ', pipe.score(X_val, y_val))

 

(한동안 안보다가 보려니까 개념을 다 까먹어서 빠르게 복습하느라 시간이 꽤 걸렸다)

 


2차시도 : 랜덤포레스트에 하이퍼파라미터 튜닝

사용한 데이터 : HOME BET, AWAY BET, RESULT

정확도 MAE : 0.41

 

#랜덤포레스트에 하이퍼파라미터 튜닝

from sklearn.ensemble import RandomForestRegressor
from scipy.stats import randint, uniform
from sklearn.model_selection import RandomizedSearchCV

pipe = make_pipeline(
    RandomForestRegressor(random_state=2)
)

dists = {
    'randomforestregressor__n_estimators': randint(50, 500), 
    'randomforestregressor__max_depth': [5, 10, 15, 20, None], 
    'randomforestregressor__max_features': uniform(0, 1) # max_features
}

clf = RandomizedSearchCV(
    pipe, 
    param_distributions=dists, 
    n_iter=50, 
    cv=3, 
    scoring='neg_mean_absolute_error',  
    verbose=1,
    n_jobs=-1
)

clf.fit(X_train, y_train);
# Fitting 3 folds for each of 50 candidates, totalling 150 fits


print('최적 하이퍼파라미터: ', clf.best_params_)
print('MAE: ', -clf.best_score_)
Fitting 3 folds for each of 50 candidates, totalling 150 fits
최적 하이퍼파라미터:  {'randomforestregressor__max_depth': 5, 'randomforestregressor__max_features': 0.2658193705824027, 'randomforestregressor__n_estimators': 492}
MAE:  0.4111623069059827

1차 결론 : 어김없이 쓰레기를 넣으면 쓰레기가 나온다


3차시도 : XGBOOST 사용 및 각 팀명을 데이터값으로 함께 활용 (Encoder)

사용한 데이터 : HOME TEAM, AWAY TEAM, HOME BET, AWAY BET, RESULT

정확도 : 62%

target = 'RESULT'
train = pd.read_csv('/content/NBA DATA.csv')

train = train[['HOME TEAM','AWAY TEAM','HOME BET', 'AWAY BET','RESULT']]

train.head()

train.dtypes

from sklearn.model_selection import train_test_split
train, test = train_test_split(train, train_size=0.85, test_size=0.15, 
                              stratify=train[target], random_state=2)

train.shape, test.shape

features = train.drop(columns=[target]).columns

X_train = train[features]
y_train = train[target]
X_test = test[features]
y_test = test[target]

#XGBoost 사용

from xgboost import XGBClassifier
from sklearn.preprocessing import OrdinalEncoder
from sklearn.impute import SimpleImputer

pipe = make_pipeline(
    OrdinalEncoder(),
    XGBClassifier(n_estimators=200
                  , random_state=2
                  , n_jobs=-1
                  , max_depth=7
                  , learning_rate=0.2
                 )
)

pipe.fit(X_train, y_train);

pipe

from sklearn.metrics import classification_report
# train 학습, 검증셋 정확도
print('검증 정확도', pipe.score(X_test, y_test))

print(classification_report(y_test, pipe.predict(X_test)))


모든 경기를 다 맞추고자 함은 욕심이다. 

배당률 갭이 큰, 즉 상대적으로 경기결과가 예상되는 경기만 추려서 진행하자

4차시도 : 배당률갭이 3이상인 경기들만 추려서 머신러닝 진행

정확도 : 87.5%

target = 'RESULT'
train = pd.read_csv('/content/NBA DATA 2.csv')

train = train[['HOME TEAM','AWAY TEAM','HOME BET', 'AWAY BET','RESULT','BET GAP']]

train.head()

OVER_3 = train['BET GAP'] >= 3

train[OVER_3]

train = train[OVER_3]

train = train[['HOME TEAM','AWAY TEAM','HOME BET', 'AWAY BET','RESULT']]

train.head()

train.dtypes

from sklearn.model_selection import train_test_split
train, test = train_test_split(train, train_size=0.85, test_size=0.15, 
                              stratify=train[target], random_state=2)

train.shape, test.shape

features = train.drop(columns=[target]).columns

X_train = train[features]
y_train = train[target]
X_test = test[features]
y_test = test[target]

#XGBoost 사용

from xgboost import XGBClassifier
from sklearn.preprocessing import OrdinalEncoder
from sklearn.impute import SimpleImputer

pipe = make_pipeline(
    OrdinalEncoder(),
    XGBClassifier(n_estimators=200
                  , random_state=2
                  , n_jobs=-1
                  , max_depth=7
                  , learning_rate=0.2
                 )
)

pipe.fit(X_train, y_train);

pipe

from sklearn.metrics import classification_report
# train 학습, 검증셋 정확도
print('검증 정확도', pipe.score(X_test, y_test))

 

함정에 빠지지 말아야할 점이

기본통계 확률자체랑 머신러닝의 결과값이 과연 의미있는 차이가 있는지도 중요하다

 

배당률갭이 3이상인 경기수 1229개중 역배당경기결과수 148개

즉 약 87% 확률로 예상밖의 경기결과가 나온다는 걸 알수있다

 

꼭 머신러닝을 통하지 않더라도 비슷한 결과가 나오는걸로 보아

개선사항이 필요하다

728x90

댓글