데이터분석/데이콘

[Dacon] Basic 축구선수의 유망 여부 예측 AI 경진대회 1, python

still..epochs 2022. 11. 23. 15:19

대회 출처 링크 : https://dacon.io/competitions/official/236031/overview/description

 

데이콘 Basic 축구선수의 유망 여부 예측 AI 경진대회 - DACON

분석시각화 대회 코드 공유 게시물은 내용 확인 후 좋아요(투표) 가능합니다.

dacon.io

밑바닥부터 시작하는 딥러닝.. 머신러닝 교과서를 공부 중인데, 하루에 한 두시간이라도 뭔가 해보면 좋을 것 같아서 하게 되었다. 예전에 캐글에서 타이타닉 데이터를 분석해보았을 때와 같이 이 데이터도 Classification 문제로 비슷하게 해볼 수 있을거 같아서 시도해보았다.

 

[배경] 

안녕하세요 데이커 여러분! 데이콘 Basic 축구선수의 유망 여부 예측 AI 경진대회에 오신 것을 환영합니다!

축구 선수 데이터를 이용해 선수가 유망한 선수인지를 판단하는 스카우터 역할의 AI 모델을 만들어 보세요!

다른 사람들과 인사이트를 겨뤄보며 알고리즘 대회의 즐거움을 느껴보세요.

 

[주제]

16세부터 21세의 축구 선수들의 유망 여부를 예측하는 AI 알고리즘 개발

 

[설명]

16세부터 21세의 축구 선수의 정보로부터 유망 여부를 이진 분류

 

[참가 대상]

  • 일반인, 학생 등 누구나

 

[주최 / 주관]

  • 주최: 데이콘
  • 주관: 데이콘
# 먼저 필요한 라이브러리를 import 한다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno
import warnings
warnings.filterwarnings('ignore')


# 사용할 데이터를 저장한다.
df_train = pd.read_csv('train.csv')
df_test = pd.read_csv('test.csv')

df_train.shape
>> (3019, 66)

데이터를 불러와서 확인해보면 행과 열이 (3019, 66) 형태이다.

컬럼이 66개로 굉장히 많은 편인데, 데이터 타입을 확인해 보면 ID, Position, PreferredFoot, AttackingWorkRate, DefensiveWorkRate 를 제외하고는 전부 수치형 데이터 임을 확인할 수 있다.

그렇다면 데이터 타입이 object인 컬럼들을 수치화 해주어야 하는데, 나는 일단 하드코딩으로 직접 하나하나 지정해주었다.

# Position
df_train['Position'] = df_train['Position'].map({'CB' : 0, 'ST': 1, 'RB': 2, 'LB' : 3, 'GK': 4, 'CDM': 5, 'CAM': 6, 'CM' : 7, 'RM' : 8, 'LM' : 9,
       'RWB' : 10, 'LWB' : 11, 'RW' : 12, 'CF' : 13, 'LW' : 14})
df_test['Position'] = df_test['Position'].map({'CB' : 0, 'ST': 1, 'RB': 2, 'LB' : 3, 'GK': 4, 'CDM': 5, 'CAM': 6, 'CM' : 7, 'RM' : 8, 'LM' : 9,
       'RWB' : 10, 'LWB' : 11, 'RW' : 12, 'CF' : 13, 'LW' : 14})

# PreferredFoot
df_train['PreferredFoot'] = df_train['PreferredFoot'].map({'Right' : 0, 'Left' : 1})
df_test['PreferredFoot'] = df_test['PreferredFoot'].map({'Right' : 0, 'Left' : 1})


# AttackingWorkRate
df_train['AttackingWorkRate'] = df_train['AttackingWorkRate'].map({'Medium' : 0, 'High' : 1, 'Low' : 2})
df_test['AttackingWorkRate'] = df_test['AttackingWorkRate'].map({'Medium' : 0, 'High' : 1, 'Low' : 2})


# DefensiveWorkRate
df_train['DefensiveWorkRate'] = df_train['DefensiveWorkRate'].map({'Medium' : 0, 'High' : 1, 'Low' : 2})
df_test['DefensiveWorkRate'] = df_test['DefensiveWorkRate'].map({'Medium' : 0, 'High' : 1, 'Low' : 2})

이 후 다시 데이터를 확인해 보면,

데이터의 형태가 ID를 제외하고는 전부 수치형으로 바뀌었음을 확인할 수 있다. 이제 사용하지 않을 컬럼인 ID 컬럼을 삭제해준다.

df_train.drop(['ID'], axis=1, inplace=True)
df_test.drop(['ID'], axis=1, inplace=True)

 

이제 데이터를 분석해 보아야 하는데, 모델은 RandomForestClassifier 사용하고 데이터 전처리 관련해서는 4가지 방법을 시도했다.

  1. 데이터 스케일링 하지 않을 경우
  2. 데이터 스케일링 할 경우
  3. 원 핫 인코딩 한 경우
  4. 데이터 스케일링 + 원 핫 인코딩 한 경우

각각 방법을 모두 시도해 보았는데 4번이 가장 나은 결과를 보여줘서, 4번으로 진행하였다.

# 원핫인코딩
df_train = pd.get_dummies(df_train, columns = ['Position', 'PreferredFoot', 'AttackingWorkRate', 'DefensiveWorkRate'])
df_test = pd.get_dummies(df_test, columns = ['Position', 'PreferredFoot', 'AttackingWorkRate', 'DefensiveWorkRate'])

# binary-classification
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 예측할 Prospect 컬럼을 드롭
X_train = df_train.drop('Prospect', axis = 1).values
X_test = df_test.values
target_label = df_train['Prospect'].values

# 스케일링
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
X_scaled_test = scaler.fit_transform(X_test)

# 데이터를 train 과 test로 나눈다.
X_tr, X_vid, y_tr, y_vid = train_test_split(X_scaled, target_label, test_size=0.2, random_state=2)
model = RandomForestClassifier()
model.fit(X_tr, y_tr)
prediction = model.predict(X_vid)

# 정확도 측정
print('총 {}명 중 {:.2f}% 정확도로 유망 맞춤'.format(y_vid.shape[0], 100 * metrics.accuracy_score(prediction, y_vid)))
'정확도 {:.2f}'.format((prediction == y_vid).sum() / prediction.shape[0])

정확도를 측정하면 약 78%의 정확도를 보여주고 있다.

이제 테스트 데이터를 예측해보자.

prediction = model.predict(X_scaled_test)

# 제출할 파일에 예측 결과를 덮어씌운다
submission['Prospect'] = prediction
submission

# csv파일 다운로드
submission.to_csv('submission.csv', index=False)

 

정확도는 약 73%가 나왔고....48등... 다른 모델들도 시도해보아야 할 것 같다. 그래도 직접 데이터 전처리를 시도해보고 예측해봄으로써 내 실력이 답이 없다는 것을 알게되었다. 열공..