본문 바로가기
AI/AI 부트캠프

[AI 부트캠프] DAY 33 - EDA 프로젝트 4

by HOHHOH 2023. 9. 1.

[오늘의 일지]

EDA 프로젝트 - 자료 수집 마무리, 데이터 분석 시작

[상세 내용]

EDA 프로젝트

자료 수집 수정 마무리

- 어제 작업을 마무리한 줄 알았지만 오늘 새롭게 크롤링해 왔던 연봉정보에 대한 자료가 조금 선수들 이름에서 차이가 있어서 마지막으로 정보를 수정했습니다. 수정을 마치고 다른 자료들과 오차율을 구해봤는데 3프로 때의 매우 적은 수치를 보였습니다. 다행이라고 생각합니다.

import pandas as pd

def convert_csv_values(input_file, output_file, column_name, value_mapping):
    # Load the CSV file
    df = pd.read_csv(input_file)
    
    # 칼럼에 딕셔너리 key를 value로 변경하는 과정
    df[column_name] = df[column_name].replace(value_mapping)
    
    # 새로운 CSV file로 저장
    df.to_csv(output_file, index=False, encoding='utf-8-sig')

detail_list =  {'Ahmed Elmohamady': 'Ahmed El Mohamady',
    'Alex Oxlade-Chamberlain': 'Alex Oxlade Chamberlain',
    'Alex Song': 'Alexandre Song',
    'Robbie Brady': 'Robert Brady',
    'Cheik Tiote': 'Cheick Tiote',
    'Andrew Robertson': 'Andy Robertson',
    "Joey O'Brien": "Joseph O'Brien",
    'Rob Green': 'Robert Green',
    'Papiss Demba Cisse': 'Papiss Cisse',
    'Falcao': 'Radamel Falcao',
    'Matthew Upson': 'Matt Upson',
    'Jonathan Williams': 'Jonny Williams',
    'John Mikel Obi': 'John Obi Mikel',
    'Rob Elliot': 'Robert Elliot',
    'Will Buckley': 'William Buckley',
    'Brad Jones': 'Bradley Jones',
    'Tyias Browning': 'Jiang Guangtai',
    'Danny Lafferty': 'Daniel Lafferty',
    'Jose Pozo': 'Jose Angel Pozo',
    'Izzy Brown': 'Isaiah Brown',
    'Zeki Fryers': 'Ezekiel Fryers',
    'Alexander Sorloth': 'Alexander Soerloth',
    'Alisson': 'Alisson Becker',
    'Allan Nyom': 'Allan-Romeo Nyom',
    'Andre Zambo Anguissa': 'Andre-Frank Zambo Anguissa',
    'Bobby Reid': 'Bobby De Cordova-Reid',
    'Kell Watts': 'Kelland Watts',
    'Charly Musonda Jr': 'Charly Musonda',
    'Christian Norgaard': 'Christian Noergaard',
    'Daniel Bentley': 'Dan Bentley',
    'Dan Agyei': 'Daniel Agyei',
    "Dan N'Lundulu": 'Daniel Nlundulu',
    'Dimitrios Giannoulis': 'Dimitris Giannoulis',
    'Eric Maxim Choupo-Moting': 'Eric Choupo-Moting',
    'Fin Stevens': 'Finley Stevens',
    "Georges-Kevin N'Koudou": "Georges-Kevin Nkoudou",
    'Hamed Junior Traore': 'Hamed Traore',
    'Vicente Iborra': 'Iborra',
    'Ilya Zabarnyi': 'Illia Zabarnyi',
    'Jacob Lungi Sorensen': 'Jacob Soerensen',
    'Joao Carlos Teixeira': 'Joao Teixeira',
    'Johann Berg Gudmundsson': 'Johann Gudmundsson',
    'Jon Gorenc-Stankovic': 'Jon Gorenc Stankovic',
    'Jonathan Howson': 'Jonny Howson',
    'Joe Dodoo': 'Joseph Dodoo',
    'Jota Peleteiro': 'Jota',
    'Camilo Zuniga': 'Juan Camilo Zuniga',
    'Kepa Arrizabalaga': 'Kepa',
    'Konstantinos Tsimikas': 'Kostas Tsimikas',
    'Lasse Sorensen': 'Lasse Soerensen',
    'Leo Fuhr Hjelde': 'Leo Hjelde',
    'Mads Bech Sorensen': 'Mads Bech',
    'Mads Roerslev Rasmussen': 'Mads Roerslev',
    'Martin Odegaard': 'Martin Oedegaard',
    'Matt Worthington': 'Matthew Worthington',
    'Matthew Longstaff': 'Matty Longstaff',
    'Max Gradel': 'Max-Alain Gradel',
    'Max Kilman': 'Maximilian Kilman',
    "Nicolas N'Koulou": 'Nicolas Nkoulou',
    'Orjan Nyland': 'Oerjan Nyland',
    'Pape Sarr': 'Pape Matar Sarr',
    'Oghenekaro Etebo': 'Peter Etebo',
    'Pierre-Emile Hojbjerg': 'Pierre-Emile Hoejbjerg',
    'Stefan Ortega Moreno': 'Stefan Ortega',
    'Khanya Leshabela': 'Thakgalo Leshabela',
    'Thiago': 'Thiago Alcantara',
    'Tom Edwards': 'Thomas Edwards',
    'Tommy Robson': 'Thomas Robson',
    'Vitaliy Mykolenko': 'Vitalii Mykolenko',
    'Bojan Krkic':'Bojan'}
    # input and output 파일 경로
input_file_path = "C:/Users/LEGION/Downloads/capology_all.csv"
output_file_path = "C:/Users/LEGION/Downloads/capology_all0.csv"

convert_csv_values(input_file_path, output_file_path, "Name", detail_list)

 

본격적으로 데이터 분석을 위한 자료 통합

- 이제 데이터 분석을 하기 위해서 자료들을 통합해야 하는 상황이 있었습니다. 다행히 저희 조에서 백엔드 개발자 출신 분이 한 명 있었는데 코딩을 잘하셔서 정말 든든했습니다. 다 같이 분석할 자료를 통합 매뉴얼을 정리해서 공유해 주셨습니다. 그렇게 자료가 완성이 되었고 이제 세부적으로 어떻게 분석할 것인가에 대해서 생각하면 될 거 같습니다. 공유해 주신 자료를 통합하는 과정은 아래와 같습니다. 중간에 null값이 존재하는 것은 과감하게 버려줬습니다. 그렇게 최종적을 분석할 수 있는 값의 수가 4588개의 행이 되었습니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# plyaer data load 및 정리(프로필)
player_df = pd.read_csv('./players_all.csv')
player_df = player_df.rename(columns={'Unnamed: 0':'Id'}).drop(['No.', 'Id'], axis=1)

# 1xbet data load 및 정리(스탯)
xbet_df = pd.read_csv('./1xbet_all.csv')
xbet_df = xbet_df.drop(['Team','Age','Position'], axis=1).rename(columns={'Drb_x':'Drb_Off', 'Drb_y':'Drb_Def'})

# understat data load 및 정리(스탯)
understat_df = pd.read_csv('./understat_all0.csv')
understat_df = understat_df.drop(['No','Team'], axis=1)

# capology load(연봉)
capology_df = pd.read_csv('./capology_all0.csv')

# 프로필 + 연봉
eda_df = player_df.merge(capology_df[['Weekly Salary','Base Salary','ADJ Salary','Name', 'year']], how='left', left_on=['Name', 'year'], right_on=['Name', 'year'])
eda_df = eda_df[~eda_df.duplicated(['year', 'Name'], keep='first')] # 중복 제거

# 프로필 + 연봉 + 스탯(understat)
eda_df = eda_df.merge(understat_df, how='left', left_on=['Name', 'year'], right_on=['Name', 'year'])

# 프로필 + 연봉 + 스탯(understat) + 스탯(1xbet)
eda_df = eda_df.merge(
    xbet_df[[
        'Name', 'year', 'SpG', 'KeyP', 'Drb_Off', 'Fouled', 'Off',
        'Disp', 'UnsTch', 'Rating', 'Tackles', 'Inter','Fouls',
        'Offsides', 'Clear', 'Drb_Def', 'Blocks', 'AvgP', 'PS%']],
    how='left',
    left_on=['Name', 'year'],
    right_on=['Name', 'year']
)
eda_df = eda_df.dropna()
eda_df.info()
>>>
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4588 entries, 0 to 4754
Data columns (total 43 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   year           4588 non-null   int64  
 1   Name           4588 non-null   object 
 2   Age            4588 non-null   int64  
 3   Team           4588 non-null   object 
 4   Position       4588 non-null   object 
 5   Weekly Salary  4588 non-null   float64
 6   Base Salary    4588 non-null   float64
 7   ADJ Salary     4588 non-null   float64
 8   Apps           4588 non-null   float64
 9   Min            4588 non-null   float64
 10  G              4588 non-null   float64
 11  NPG            4588 non-null   float64
 12  A              4588 non-null   float64
 13  xG             4588 non-null   float64
 14  NPxG           4588 non-null   float64
 15  xA             4588 non-null   float64
 16  xGChain        4588 non-null   float64
 17  xGBuildup      4588 non-null   float64
 18  xG90           4588 non-null   float64
 19  NPxG90         4588 non-null   float64
 20  xA90           4588 non-null   float64
 21  xG90+xA90      4588 non-null   float64
 22  NPxG90+xA90    4588 non-null   float64
 23  xGChain90      4588 non-null   float64
 24  xGBuildup90    4588 non-null   float64
 25  SpG            4588 non-null   float64
 26  KeyP           4588 non-null   float64
 27  Drb_Off        4588 non-null   float64
 28  Fouled         4588 non-null   float64
 29  Off            4588 non-null   float64
 30  Disp           4588 non-null   float64
 31  UnsTch         4588 non-null   float64
 32  Rating         4588 non-null   float64
 33  Tackles        4588 non-null   float64
 34  Inter          4588 non-null   float64
 35  Fouls          4588 non-null   float64
 36  Offsides       4588 non-null   float64
 37  Clear          4588 non-null   float64
 38  Drb_Def        4588 non-null   float64
 39  Blocks         4588 non-null   float64
 40  AvgP           4588 non-null   float64
 41  PS%            4588 non-null   float64
 42  Age Lev        4588 non-null   object 
dtypes: float64(37), int64(2), object(4)
memory usage: 1.5+ MB

 

간단하게 지표들 확인해 보기

- 우선적으로 나이에 대한 확률 밀도 그래프를 볼 수 있는 kdeplot을 해보고 분포가 잘 되어 있는지 확인해 봤는데 정규분포 형태의 그래프가 잘 나온 거 같습니다.

sns.kdeplot(data=eda_df, x='Age')

나이에 대한 활률밀도 그래프

 

- 그렇다면 나이와 출전 횟수 간의 확률 밀도 그래프는 어떨지 나타내 보겠습니다. 확실히 어린선수들은 출전 횟수가 적은 곳에서 밀집되어 있고 25세~30세쯤 되는 선수들이 거의 많은 경기를 소화한다고 밀집되어 있는 걸로 봐서는  일반적으로 그 나이 때가 전성기에 가까운 나이 때라고 생각했습니다.

sns.kdeplot(data=eda_df, x='Age' , y='Apps' )

나이와 출전 시간 간의 확률 밀도 그래프

- 마지막으로 나이와 연봉 간의 확률 밀도 그래프를 만들어 보고 생각해 봤습니다. 확실히 전성기 때라고 생각한 25~30세 사이에 연봉의 고점이 높게 형성되어 있다는 걸 알게 되었고 생각보다 전성기 나이 때에서도 상대적으로 저연봉 선수들이 훨씬 많이 밀집되어 있어 편차가 심하다는 것도 알게 되었습니다.

sns.kdeplot(data=eda_df, x='Age' , y='ADJ Salary' )
plt.axis([12,40,0,15000000])

나이와 연봉 간의 확률 밀도 그래프

 

[마무리]

 오늘은 수집한 모든 자료의 수정을 마치고 앞으로 분석자료로서 모두 하나로 통합하는 것까지 매뉴얼을 완성해서 간단한 그래프를 그려보는 것까지 했습니다. 특히 확률 밀도 그래프를 통해서 특정 칼럼이 어디 구간에 나이별로 밀집이 되어있지를 확인해서 대략저인 전성기 나이 때를 알아볼 수 있었습니다. 내일부터는 처음 저희 조가 분석 목표로 잡았던 연봉과 선수의 성적 간의 관계에 대해서 세부적으로 설정하여 분석하는 과정을 해야 될 거 같습니다.

반응형

댓글