데이터 소개¶
- 이번 주제는 European Soccer Database 데이터셋을 사용합니다.
- 다음 1개의 sqlite 데이터베이스를 사용합니다.
database.sqlite
- 데이터 베이스 내 총 7개의 Table을 사용합니다.
Country: 국가 정보
League: 리그 정보
Match: 경기 정보 (주 데이터셋)
Player: 플레이어 정보
Player_Attributes: 플레이어의 특성
Team: 팀 정보
Team_Attributes: 팀의 특성
Step 0. 데이터베이스와 SQL¶
SQL과 Query¶
Step 1. 데이터셋 준비하기¶
In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
문제 3. sqlite3와 Pandas로 sqlite 데이터베이스 읽어들이기¶
In [3]:
import sqlite3
In [4]:
# sqlite3.connect()와 pd.read_sql_query()로 csv파일 읽어들이기
conn = sqlite3.connect('database.sqlite')
In [90]:
df_country = pd.read_sql_query('SELECT * from Country', conn)
df_league = pd.read_sql_query('SELECT * from League', conn)
df_match = pd.read_sql_query('SELECT * from Match', conn)
df_player = pd.read_sql_query('SELECT * from Player', conn)
df_player_att = pd.read_sql_query('SELECT * from Player_Attributes', conn)
df_team = pd.read_sql_query('SELECT * from Team', conn)
df_team_att = pd.read_sql_query('SELECT * from Team_Attributes', conn)
Step 2. EDA 및 데이터 기초 통계 분석¶
문제 4. 각 데이터프레임의 구조 파악하기¶
In [91]:
# DataFrame에서 제공하는 메소드를 이용하여 각 데이터프레임의 구조 분석하기 (head(), info(), describe())
df_country.head()
Out[91]:
In [92]:
df_country.info()
In [93]:
df_league.head()
Out[93]:
In [94]:
df_league.info()
In [95]:
df_league['id'].unique()
Out[95]:
In [96]:
df_league['country_id'].unique()
Out[96]:
In [97]:
df_match.head()
Out[97]:
원하는 리그만 뽑아서 보기¶
In [98]:
df_match.loc[df_match['league_id']==1729]
Out[98]:
In [99]:
df_match['season'].unique()
Out[99]:
In [100]:
for c in df_match.columns:
print(c)
In [101]:
for c,num in zip(df_match.columns,df_match.isna().sum()):
print(c,num)
In [102]:
df_match.drop(df_match.columns[-38:],axis=1,inplace=True)
In [103]:
df_match.head()
Out[103]:
In [104]:
df_player_att.head()
Out[104]:
문제 5. 데이터프레임간의 관계 파악하기¶
In [105]:
# 데이터프레임 간 중복되는 Column이 있는지 확인하고 유용한 Column 식별하기
# Hint) unique()로 값을 비교하거나, map() 등을 활용하여 Column 관계를 확인
df_player_att['player_api_id'].value_counts()
Out[105]:
att에 중복되는 컬럼(선수)이 많으므로 선수들의 평균치를 내기¶
In [106]:
df_match
Out[106]:
In [107]:
df_match['home_player_1'].dropna().apply(int).map(df_player_att.groupby('player_api_id').mean()['overall_rating']).isna().sum()
Out[107]:
1개에서 6개라 그룹바이로 중복 없애기¶
In [108]:
df_team_att['team_api_id'].value_counts()
Out[108]:
nan 을 다 날리고 float 을 int로바꿈¶
In [109]:
df_match['away_team_api_id'].map(df_team_att.groupby('team_api_id').mean()['buildUpPlaySpeed']).isna().sum()
Out[109]:
In [ ]:
문제 6. 선수 특ፑ#49457; 사이의 상관성 파악하기¶
In [110]:
df_player_att['overall_rating']
Out[110]:
In [111]:
fig=plt.figure(figsize=(5,15))
sns.heatmap(df_player_att.drop(['id', 'player_fifa_api_id', 'player_api_id'], axis=1).corr()[['overall_rating']], annot=True)
Out[111]:
문제 7. 매치 데이터프레임에 팀 특성 데이터프레임 통합하기¶
In [112]:
# DataFrame의 map() 메소드를 활용하여 데이터프레임 통합하기
df_team_att.columns
Out[112]:
In [113]:
df_team_att.drop('buildUpPlayDribbling', axis=1, inplace=True)
In [114]:
df_team_att.columns
Out[114]:
In [118]:
def most(x):
return x.value_counts().index[0]
In [119]:
df_team_att['buildUpPlayPassingClass'].value_counts().index[0]
Out[119]:
In [121]:
team_map=df_team_att.groupby
In [122]:
team_map = df_team_att.groupby('team_api_id').aggregate(
{
'buildUpPlaySpeed': 'mean',
'buildUpPlaySpeedClass': most,
'buildUpPlayDribblingClass': most,
'buildUpPlayPassing': 'mean',
'buildUpPlayPassingClass': most,
'buildUpPlayPositioningClass': most,
'chanceCreationPassing': 'mean',
'chanceCreationPassingClass': most,
'chanceCreationCrossing': 'mean',
'chanceCreationCrossingClass': most,
'chanceCreationShooting': 'mean',
'chanceCreationShootingClass': most,
'chanceCreationPositioningClass': most,
'defencePressure': 'mean',
'defencePressureClass': most,
'defenceAggression': 'mean',
'defenceAggressionClass': most,
'defenceTeamWidth': 'mean',
'defenceTeamWidthClass': most,
'defenceDefenderLineClass': most
}
)
In [ ]:
In [123]:
team_map
Out[123]:
새로운 df 만들고 팀 정보 추가하기¶
In [124]:
df = df_match[['home_team_goal', 'away_team_goal']].copy()
In [125]:
for team in ['home_', 'away_']:
team_map.index.name = team + 'team_api_id'
for col in team_map.columns:
df[team + col] = df_match[team_map.index.name].map(team_map[col])
In [126]:
df
Out[126]:
In [127]:
df.dropna(inplace=True)
In [128]:
df.head()
Out[128]:
문제 8. 홈과 어웨이의 골 수를 승-무-패 범주로 변환하기¶
In [129]:
# 홈과 어웨이의 골 수를 범주형 데이터로 변환하기 (0: 홈팀 승, 1: 무승부, 2: 어웨이팀 승)
df['matchResult'] = df[['home_team_goal', 'away_team_goal']].aggregate(lambda x: 0 if x[0] > x[1] else 1 if x[0] == x[1] else 2, axis=1)
In [130]:
df.drop(['home_team_goal','away_team_goal'],axis=1,inplace=True)
In [131]:
df['matchResult']
Out[131]:
Step 3. 모델 학습을 위한 데이터 전처리¶
문제 9. get_dummies를 이용하여 범주형 데이터 전처리하기¶
In [132]:
col_cats=list(filter(lambda s: s.find('Class')>=0,df.columns))
col_cats
Out[132]:
In [133]:
df_cats = pd.get_dummies(df[col_cats], drop_first=True)
In [134]:
df_cats
Out[134]:
문제 10. StandardScaler를 이용해 수치형 데이터 표준화하기¶
In [135]:
from sklearn.preprocessing import StandardScaler
In [136]:
# StandardScaler를 이용해 수치형 데이터를 표준화하기
# Hint) Multicollinearity를 피하기 위해 불필요한 컬럼은 drop한다.
X_num = df.drop(['matchResult'] + col_cats, axis=1)
scaler = StandardScaler()
scaler.fit(X_num)
X_scaled = scaler.transform(X_num)
X_scaled = pd.DataFrame(data=X_scaled, index=X_num.index, columns=X_num.columns)
X_cat = df_cats
X = pd.concat([X_scaled, X_cat], axis=1)
y = df['matchResult']
In [137]:
df['matchResult'].value_counts()
Out[137]:
문제 11. 학습데이터와 테스트데이터 분리하기¶
In [138]:
from sklearn.model_selection import train_test_split
In [139]:
# train_test_split() 함수로 학습 데이터와 테스트 데이터 분리하기
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)
Step 4. Classification 모델 학습하기¶
문제 12. Logistic Regression 모델 생성/학습하기¶
In [140]:
from sklearn.linear_model import LogisticRegression
In [141]:
# LogisticRegression 모델 생성/학습
model_lr = LogisticRegression(max_iter=10000)
model_lr.fit(X_train,y_train)
Out[141]:
문제 13. 모델 학습 결과 평가하기¶
In [142]:
from sklearn.metrics import classification_report
In [143]:
# Predict를 수행하고 classification_report() 결과 출력하기
pred = model_lr.predict(X_test)
print(classification_report(y_test, pred))
전체중의 값을 보면 어떤 지표가 가장 비슷한 결과를 보였는지 알 수 있음 -> f1score¶
In [144]:
print(sum((y_test == 0)) / len(y_test))
print(sum((y_test == 1)) / len(y_test))
print(sum((y_test == 2)) / len(y_test))
문제 14. XGBoost 모델 생성/학습하기¶
나름대로 절반 넘게 맞춤 -> 51 % 로 logistic 보다 향상¶
In [145]:
from xgboost import XGBClassifier
In [146]:
# XGBClassifier 모델 생성/학습
model_xgb = XGBClassifier()
model_xgb.fit(X_train, y_train)
Out[146]:
문제 15. 모델 학습 결과 평가하기¶
In [148]:
# Predict를 수행하고 classification_report() 결과 출력하기
pred = model_xgb.predict(X_test)
print(classification_report(y_test, pred))
Step5 모델 학습 결과 심화 분석하기¶
문제 16. Logistic Regression 모델 계수로 상관성 파악하기¶
away가 강하게 수비하면 홈팀이 이길가능성 up -> 공격이 최고의 수비..¶
In [149]:
# Logistic Regression 모델의 coef_ 속성을 plot하기
fig = plt.figure(figsize=(15, 5))
plt.plot(X.columns, model_lr.coef_[0])
plt.xticks(rotation=90)
plt.title('What makes Home Team Win?')
plt.grid()
plt.show()
문제 17. XGBoost 모델로 특징의 중요도 확인하기¶
In [150]:
# XGBoost 모델의 feature_importances_ 속성을 plot하기
fig = plt.figure(figsize=(15, 6))
plt.bar(X.columns, model_xgb.feature_importances_)
plt.xticks(rotation=90)
plt.show()
반응형
'Project & Kaggle' 카테고리의 다른 글
불량 타이어 검출을 위한 CNN 모델 개발 및 PYQT(EXE 실행 프로그램) 배포 프로젝트 (2) | 2021.06.21 |
---|---|
철판 제조 공정 데이터를 활용한 분류모형 생성 및 성능 비교 (0) | 2021.04.07 |
데이터로 알아보는 리그 오브 레전드의 승리 예측 및 인사이트 (0) | 2021.02.09 |
학생들의 수업 시간 행동 분석을 통한 성적 예측 (0) | 2021.02.02 |
심부전증 환자 데이터를 통한 사망 여부 Classification (0) | 2021.02.01 |