테니스 빅3(페더러,나달,조코비치)의 그랜드 슬램 우승 횟수 확인하기

Michael-Oh·2021년 7월 22일
0

오늘 정리할 개념

데이터 사이언스를 공부하기 위한 기초 개념들 정리해본다.

  • CSV
  • pandas
  • EDA
  • 특성 공학(Feature Engineering)
  • 데이터 조작(Data manipulation)
  • 시각화란?

질문과 => 검색키워드 정리

  • 어떻게 하면 폴더 안에 파일을 한꺼번에 가져올 수 있을까? ⇒ os.listdir
  • 어떻게 하면 csv 파일만 가져올 수 있을까? ⇒file.endswith
  • 어떻게하면 하나의 데이터 프레임으로 만들 수 있을까? ⇒ concat, list comprehesion
  • 인덱스 정리 ⇒ reset_index
  • 소수점 자리수 정리 ⇒ round
  • 데이터를 어떻게 합칠까? ⇒ concat
  • 어떻게 시각화 할 수 있을까? ⇒matplotlib
  • 어떻게하면 둥그런 형태로 차트를 그릴 수 있을까?⇒ pie chart
  • 어떻게하면 각 연도별 횟수를 시각화할 수 있을까? ⇒ bar plot

페더러 경기 데이터를 가져오기

테니스 데이터를 바탕으로 내가 배워나간 개념들을 하나씩 정리해 나간다.

우선, 테니스 데이터를 가져온다. 테니스 데이터를 구하기 위해 여러가지 검색을 하였는데, 테니스 데이터를 오픈 소스로 제공하는 분의 githube를 찾았다(자원봉사 형태로 자료를 모으고, CSV 형태로 자료를 제공한다). 그 자료를 바탕으로 테니스 데이터를 분석하였다.

판다스로 페더러 데뷔년도부터 데이터 가져오기

# 경로설정
path = './페더러데뷔년도'
# 경로에 있는 모든 파일을 가져옴
file_list = os.listdir(path)
# 경로에 있는 csv 파일만 가져옴
file_list_py = [file for file in file_list if file.endswith('.csv')]

위와 같이 csv파일만을 가져오는 list를 만든다.

# 데이터 프레임을 만들기
df_tennis = pd.DataFrame()

# file_list의 csv파일을 반복적으로 concat 시켜서 하나의 데이터 프레임으로 합친다.
for i in file_list:
	data = pd.read_csv(i) ## csv 파일을 불러온다.
	df_tennis = pd.concat([df_tennis, data]) ## 불러온 csv 파일을 하나로 합친다.

<질문 ⇒ 검색키워드, velog에 구현방법 있음>

  • 어떻게 하면 폴더 안에 파일을 한꺼번에 가져올 수 있을까? ⇒ os.listdir
  • 어떻게 하면 csv 파일만 가져올 수 있을까? ⇒file.endswith
  • 어떻게하면 하나의 데이터 프레임으로 만들 수 있을까? ⇒ concat, list comprehesion

페더러의 기본 정보 확인하기

EDA(Exploratory Data Analysis)란?

탐색적 분석, “복잡한 모델링이나 수식을 쓰지 않고, 데이터를 탐색하는 것 “이다. 데이터를 탐색하는 것이 주 목적이다.

ATP 테니스 데이터

오픈 소스 파일에 간단한 데이터 사전(data dictionary)를 제공하고 있었다.

# 필요한 특성들
##tourney_id : 투어 종류
##tourney_level : 그랜드슬램급 - G, 마스터즈급- M, 등등
##tourney_date : 경기 날짜
##winner_name : 이긴 선수 이름
##loser_name : 진 선수 이름 등

내가 원하는 정보를 찾기 위해서 어떤 특성들을 알아야 하는지 살펴 보았다.

그 선수의 경기를 찾기 위해서는 상대방이 있는 단식게임이기 때문에, ‘winner_name’과 ‘loser-name’에 특정 선수 이름을 넣고 검색하면 그 선수의 경기 정보를 찾을 수 있다. 그리고 참가한 대회의 종류가 있어서, ‘tourney_level’ 특성에서 원하는 대회를 선택하여 정보를 찾을 수 있다.

# 1998년부터 2021년까지 가장 많은 승리를 가진 선수
df_tennis['winner_name'].value_counts()
## 실행하면!
Roger Federer         1251
Rafael Nadal          1030
Novak Djokovic         962
David Ferrer           740
Andy Murray            686
# 페더러 기록만 가져오기
## 페더러가 이긴 경기
df_federer_win = df_tennis[df_tennis['winner_name'] == 'Roger Federer']
...

## 페더러가 진 경기
df_federer_lose = df_tennis[df_tennis['loser_name'] == 'Roger Federer']
...

위와 같이, 데이터의 특성과 정보를 어떤 모델링을 쓰거나 수학적인 공식을 쓰지 않고 데이터 자체를 탐색하는 것을 EDA, 탐색적 분석이라고 부른다.

페더러의 승리, 패배 알아보기

특성 공학(Feature Engineering)이란?

“해당 분야에 대한 지식이나 창의성을 활용하여 데이터 셋 안에 항목들을 재조합, 새로운 데이터 만드는 것”이다. 예를 들어 전체의 경기 수, 테니스에서는 승리한 경기 수, 패배한 경기 수, ATP 경기 중 승률 등을 구하는 것이 해당한다.

페더러의 기본 경기 정보

페더러의 정보(전체 경기수/승리/패배/승률 등)를 확인해본다.


#승리한 경기수
df_federer_win = df_tennis[df_tennis['winner_name'] == 'Roger Federer']
df_federer_win= df_federer.reset_index(drop=True) ## index 정리
#진 경기수
df_federer_lose = df_tennis[df_tennis['loser_name'] == 'Roger Federer']
df_federer_lose = df_federer_lose.reset_index(drop=True)## index 정리
 
#전체 경기수 
## 이긴 경기와 진 경기를 합쳐서 전체 경기수를 구한다.
df_federer_total = pd.concat(['df_federer_lose, df_federer_win'])

# 전체 경기수 / 승리수/ 패배 수/ 승률
total_num = len(df_federer_total)
win_num = len(df_federer_win) 
lose_num = len(df_federer_lose)
승률 :win_rate= win_num /total_num * 100
패배율 : lose_rate= lose_num /total_num * 100

## 전체경기/승리/패배
print('전체 경기 : ',len(df_federer_total))
print('승리 :',len(df_federer_win))
print('패배 :',len(df_federer_lose))

## 소수자리수 정리
print('페더러 승률:', round(win_rate,2),'%')
print('페더러 패배율:', round(lose_rate,2),'%')
전체 경기 :  1528
승리 : 1251
패배 : 277
페더러 승률: 81.87 %
페더러 패배율: 18.13 %

페더러의 기본 정보들을 가지고, 전체 경기수/승리/패배/승률 등을 만들어 낼 수 있다. 기존의 승리한 경기, 패배한 경기 데이터를 바탕으로 두 데이터를 조합하여 전체 경기의 데이터(df_federer_total)를 구하고, 그에 따라 승리수 or 패배수/전체 경기수를 구하여 승률과 패배율을 구하였다. 이와 같은 방식으로 기존의 데이터로 도메인지식이나 창의성을 활용하여 항목들을 재조합하여 새로운 데이터를 만들것을 '특성공학', 'Feature Engineering'이라고 한다.

<질문 & 키워드>

  • 인덱스 정리 ⇒ reset_index
  • 소수점 자리수 정리 ⇒ round
  • 데이터를 어떻게 합칠까? ⇒ concat

페더러는 ATP 그랜드 슬램 대회에서 20회 우승한 것이 맞을까?

Data manipulation?

‘여러 개로 쪼개진 데이터를 하나의 데이터로 만들기도 하고 하나의 데이터셋에서 필요한 feature를 뽑아서 조합하는 것’을 의미한다.

여기서 전체 경기의 데이터를 만드는 과정에서 concat를 사용하여 데이터를 만들었는데, Data manipulation의 일종이라고 이야기 할 수 있다.

그랜드 슬램 정보 가져오기

로저 페더러가 그랜드 슬램에 참여한 경기를 확인하고, 그곳에서 얼마나 우승하였는지 확인해 본다.

# 페더러 전 경기 중, 그랜드 슬램 경기 뽑아내기
df_federer_grandslam = df_federer_total[df_federer_total['tourney_level'] == 'G'] ## 'tourney_level'에서 'G' 는 그랜드 슬램을 의미한다.

## 경기수
len(df_federer_grandslam) : 425

## 그랜드 슬램 라운드 확인
df_federer_grandslam['round'].value_counts()

## 그랜드 슬램 결승전 진출 확인
df_federer_grandslam_final = df_federer_grandslam[df_federer_grandslam['round'] == 'F'] ## ['round'] == 'F'] 결승진출을 이야기

## 그랜드 슬램 결승 진출 우승 확인
df_federer_grandslam_final_win = df_federer_grandslam_final[df_federer_grandslam_final['winner_name'] == 'Roger Federer' ] ## 결승 진출 후 우승하였는지 체크

### 각 그랜드 슬램별 횟수
print('그랜드 슬램 우승횟수:', len(df_federer_grandslam_final_win))
그랜드 슬램 우승횟수: 20

### 결승진출 시 승률 계산 & 소수점 2번째 자리까지!
print("페더러 결승 진출시 우승확률:", round(len(df_federer_grandslam_final_win)/len(df_federer_grandslam_final),2),'%')

페더러 결승 진출시 우승확률: 0.65 %

# 각 그랜드 슬램 우승 횟수
# 호주 오픈 우승횟수
print('호주 오픈 우승횟수 : ',len(df_federer_australian_open_win))

# 프랑스 오픈 우승횟수

print('롤랑가로스 우승횟수 : ',len(df_federer_roland_garros_win))

# 윔블던 우승횟수

print('윔블던 우승횟수 : ',len(df_federer_wimbledon_win))

# U.S오픈 우승횟수
print('U.S오픈' 우승횟수 : ',len(df_federer_U.Sopen_win))

호주 오픈 우승횟수 :  6
롤랑가로스 우승횟수 :  1
윔블던 우승횟수 :  8
U.S오픈 우승횟수 :  5

논리적으로 순차적으로 필요한 정보를 뽑아내 봤다.

  1. 페더러의 전체 데이터 중에 그랜드 슬램에 경기 데이터를 뽑아낸다.
  2. 페더러가 그랜드 슬램 중 결승전에 진출한 경기를 뽑아낸다.
  3. 페더러가 결승전에서 이긴 경기를 뽑아낸다.
  4. 페더러의 그랜드 슬램 결승전 승률을 구하기 위해 결승전 이긴 수/결승전 진출 수를 구한다.
  5. 각 그랜드 슬램 별 우승 횟수를 확인한다.

어떻게 하면 각 연도별 그랜드 슬램 우승 횟수를 보여줄 수 있을까?

그랜드 슬램 우승횟수를 확인하고, 더 궁금한 점이 있었다. 각 연도별 몇 번 우승했는지 궁금했다. 그래서 어떻게 자료를 만들어야 할지 고민했다.

우선 각 연도별로 나누기로 했다.

날짜 데이터 다루기!

df_federer_grandslam_final_win['tourney_date'] = pd.to_datetime(df_federer_grandslam_final_win['tourney_date'], format='%Y%m%d')
## 년도별로 정리
df_federer_grandslam_final_win['tourney_date'] = df_federer_grandslam_final_win['tourney_date'].dt.year
df_federer_grandslam_final_win

pandas에서 datetime을 다룰 수 있다. 그래서 년/월/일로 나누어서 이용할 수 있도록 바꾸고, 년도별로 구분하여 진행했다.

## 각각의 연도 자동으로 횟수 정리/ 데이터 프레임으로 만들기
df_federer_grandslam_count = pd.DataFrame(df_federer_grandslam_final_win['tourney_date'].value_counts())
df_federer_grandslam_count
     tourney_date
2004	3
2006	3
2007	3
2017	2
2005	2
2009	2
2018	1
2003	1
2008	1
2010	1
2012

새롭게 데이터 프레임을 만들어서 각 연도별 횟수를 확인했다.

잘 눈에 안들어오는 정보 어떻게 쉽게 보여줄까?

함께 테니스를 치는 지인에게 이런 정보들을 찾을 수 있다고 이야기 했다. 그런데 눈에 안들어온다고 하였다. 한 눈에 들어올 방법이 없을까 고민했다.

시각화란?

“데이터를 한 눈에 알아볼 수 있도록 변경하는 것” 의미한다.

페더러의 구했던 정보 시각화(파이차트)

## 전체 게임 수 중에
fig = plt.figure(figsize=(5,5))
plt.title('No. Roger Federer wins and losses throughout his careers')
plt.pie([df_federer_win.count()[0], df_federer_lose.count()[0]], labels=[f'{df_federer_win.count()[0]} matches win', f'{df_federer_lose.count()[0]} matches lose'], textprops={'fontsize':20})

https://cdn-images-1.medium.com/max/720/1*dzWV6A4a02xCFolKTOzK6Q.png

## 승률
fig = plt.figure(figsize=(5,5))
plt.title('Rate. Roger Federer wins and losses throughout his careers')
plt.pie([win_rate, lose_rate], labels=[f'{win_rate}% win_rate', f'{lose_rate} % lose_rate'], textprops={'fontsize':20})

https://cdn-images-1.medium.com/max/720/1*6OFrsvKyyraWceog1T7TtA.png

페더러는 연도별로 몇 번 그랜드 슬램을 우승하였나?

## 우승횟수 정리
plt.title('No. Grandslam Championships')
plt.yticks([1,2,3,4])
plt.bar(df_federer_grandslam_count.index, df_federer_grandslam_count['tourney_date'])

https://cdn-images-1.medium.com/max/720/1*MlF_d4TkotENrlXmtrno7A.png

<질문 & 키워드>

  • 어떻게 시각화 할 수 있을까? ⇒matplotlib
  • 어떻게하면 둥그런 형태로 차트를 그릴 수 있을까?⇒ pie chart
  • 어떻게하면 각 연도별 횟수를 시각화할 수 있을까? ⇒ bar plot

앞으로 더 살펴볼 수 있는 것들

  • 마스터즈 급 우승
  • 투어급 우승
  • 연속 주간 세계랭킹 1위 지속기간
  • 각 선수별 통계자료 확인, 함수, 클래스화
  • 이형택, 권순우 국내 선수들 기록 확인

데이터 사이언스로서 앞으로 진행해 나갈 것

“로저 페더러는 정말 그랜드 슬램을 20회 우승했을까?”라는 질문으로 실제 테니스 데이터를 다뤄보았다. 이를 통해 데이터 분석에서 필요한 4가지 개념을 정리했다. EDA, Feature Engineering, Data Mainpulation, 시각화를 개념정리하고 실제 어떤 것들인지 살펴보았다. 9개월간 데이터 사이언스를 배운 시점에서 하루하루 배웠던 개념들을, 내가 가장 익숙하고 관심있는 데이터들을 활용하여 하나씩 정리해 나갈 것이다. 그 첫번째 시작이다.

마치며.

로저 페더러를 고트(GOAT, Greatest Of All Time : 역대 최고의 선수)라고 부르는지 그 이유의 첫번째 근거인 그랜드 슬램 20회 우승을 실제로 그런지 알아보았다. 방송국 혹은 위키피디아에서 제공하는 데이터를 확인하는 것이 아니라 실제 ‘날 것 데이터’(low data)에서 확인해보는 과정을 거쳤다. 이렇게 실제 내가 알고 있는 것들에 대해서 로우 레벨에 데이터에서 실제 시각화까지 하는 과정을 하나씩 정리해 나갈 것이다. 그 과정에서 내가 배우고 알고 있는 데이터 사이언스의 개념들을 차근차근 정리해 나갈 것이다.

에러노트

에러 발생

df_federer_grandslam_final_win['tourney_date'] = df_federer_grandslam_final_win['tourney_id'].dt.year
에러 메세지 : AttributeError: Can only use .dt accessor with datetimelike values

에러가 발생했다. 그런데 처음에 이해가 되지 않았다. datatime 에러는 처음 보는 것이었다.

그래서 차근차근 문제를 접근해봤다.

  1. dtype으로 확인했다. 그런데 dtype이 object였다.
  2. 다른 데이터를 확인해보니 dtype이 datatime이었다.
  3. 코드에 문제가 있는 것으로 확인하여 다시 보았다.
df_federer_grandslam_final_win['tourney_id'].dt.year
=> df_federer_grandslam_final_win['tourney_date'].dt.year
## 착각하여 tourney_id로 잘못입력한 것

코드를 확인하고 다시 진행해보니, 제대로 작동하였다.

profile
초보 개발자의 테니스 과학적 분석 Dev-Log

0개의 댓글

관련 채용 정보