Gidhub BE Developer

Project [5:5]

2018-02-14
goodGid

머신러닝 - 결정 트리(Decision Tree)를 기반으로 운동 경기 결과 예측하기

  1. 지도 학습이란 ?
  2. 개발 환경 설정 : skikit-learn과 pandas
  3. 분류 문제와 결정 트리
  4. 교차 검증
  5. NBA 경기 데이터 수집 및 전처리

  • 2015 ~ 16년 NBA 경기의 데이터를 수집하자.

import os
import pandas

home_folder = os.path.expanduser(os.getcwd()) # 현재 디렉토리를 home_folder로 지정
data_folder = os.path.join(home_folder,"resources")  # [1]

'''
[1]
home_folder로 부터 타고 타고 들어간다. 
os.path.join(home_folder,"resources")  ==> home_folder/resources
os.path.join(home_folder,"resources","test")  ==> home_folder/resources/test
'''

data_files=["nba_2015_10.csv", "nba_2015_11.csv", "nba_2015_12.csv",
            "nba_2016_01.csv", "nba_2016_02.csv", "nba_2016_03.csv",
            "nba_2016_04.csv", "nba_2016_05.csv", "nba_2016_06.csv"]


cvs_objs = []
for f in data_files:
    month_data = os.path.join(data_foler, f)
    cvs_objs.append(pandas.read_csv(month_data))


season_result = pandas.concat(cvs_objs, ignore_index=True)

# 데이터 컬럼의 제목을 지정
season_result.columns = ["Date", "StartTime", "VisitorTeam", "VisitorPts",
                         "HomeTeam", "HomePts", "ScoreType", "Overtime", "Notes"]

print(season_result[-2:]) # 끝에서 2번째 부터 마지막까지 출력 





                 Date StartTime            VisitorTeam  VisitorPts  \
1309  Sun Jun 14 2015   8:00 pm    Cleveland Cavaliers          91   
1310  Tue Jun 16 2015   9:00 pm  Golden State Warriors         105   

                   HomeTeam  HomePts  ScoreType Overtime Notes  
1309  Golden State Warriors      104  Box Score      NaN   NaN  
1310    Cleveland Cavaliers       97  Box Score      NaN   NaN  

pandas의 read_csv() 메서드를 이용하면 CSV 형태의 파일로부터

2차원 테이블 형태의 데이터 프레임 객체를 얻을 수 있다.


또한 월별로 분리된 데이터 프레임 객체를 concat() 메서드를 이용해

하나의 큰 데이터 프레임 객체로 합칠 수 있다.

이 때 ignore_index의 인자를 True로 설정하면

새롭게 생성되는 데이터 프레임에서는 월별 데이터의 인덱스를 사용하는 대신에

새롭게 카운팅하게 된다.


season_result["HomeWin"] = season_result["HomePts"] > season_result["VisitorPts"]

print(season_result[-2:])

                 Date StartTime            VisitorTeam  VisitorPts  \
1309  Sun Jun 14 2015   8:00 pm    Cleveland Cavaliers          91   
1310  Tue Jun 16 2015   9:00 pm  Golden State Warriors         105   

                   HomeTeam  HomePts  ScoreType Overtime Notes  HomeWin  
1309  Golden State Warriors      104  Box Score      NaN   NaN     True  
1310    Cleveland Cavaliers       97  Box Score      NaN   NaN    False  

season_result에 ‘HomeWin’ 컬럼을 추가해

홈팀의 승패 여부를 확인해 볼 수 있다.


또한 스포츠 경기에서 상위권의 팀은

핵심 선수의 부상/은퇴/이적과 같은 특별한 이변이 없는 한

상위권을 지속해서 유지하는 경향이 있다.

2014~15 시즌의 순위 역시 결정 트리의 특성 값으로 활용할 수 있다.


standing_file = os.path.join(data_folder, "nba_2014_2015_standing.csv")

# standing_file에 0번째 줄은 불필요한 데이터이므로 skip
standing_result = pandas.read_csv(standing_file, skiprows=[0]) 


선수 개개인의 능력 또하 게임의 승패에 큰 영향을 끼친다.

농구 경기에서 분당 생산적인 활동을 얼마나 하는지 나타내는 지수로

PER(Player Efficiency Rating)이 있으며,

2015~16년 시즌 PER 수치 또한 결정 트리의 특성 값으로 활용할 수 있다.


player_file = os.path.join(data_folder, "nba_2016_player_stat.csv")
player_result = pandas.read_csv(player_file)


이제 NBA 리그의 모든 선수 데이터를 순회하면서

각 선수의 팀과 PER 값을 추출한 다음

team_per딕셔너리에 팀의 이름은 키로, 선수 개개인의 PER 값은 리스트 형태로 추가한다.

team_per = {}
for key, value in team_name.items():
    team_per[value] = []

for idx, row in player_result.iterrows():
    player = row["PLAYER"]
    per = row["PER"]
    team_list = player.split(',')[1].strip(' ').split("/")
    for team in team_list:
        team_per[team_name[team]].append(per)

이렇게 저장된 팀별 PER 지수가 정말 의미가 있는지 확인해보자.

import numpy
print("Golden State Warriors: Sum of PER: {0:.2f} / Mean of PER: {1:.2f}"
      .format(numpy.sum(team_per["Golden State Warriors"]), numpy.mean(team_per["Golden State Warriors"])))
print("Philadelphia 76ers: Sum of PER: {0:.2f} / Mean of PER: {1:.2f}"
      .format(numpy.sum(team_per["Philadelphia 76ers"]), numpy.mean(team_per["Philadelphia 76ers"])))




Golden State Warriors: Sum of PER: 192.37 / Mean of PER: 16.03
Philadelphia 76ers: Sum of PER: 165.17 / Mean of PER: 13.76



Recommend

Index