오늘은 2주간 배웠던 데이터 수집 및 시각화를 활용하여 팀 프로젝트를 진행하였다.
많은 회의 끝에 우리 팀의 주제는 KBO 최상위 관중수 팀과 최하위 관중수 팀을 분석하여 최하위 팀의 관중수가 낮은 이유를 분석하고자 하였다.
분석 데이터를 수집하기 위해 KBO 공식 홈페이지에서 제공하는 데이터들을 사용하였다.
KBO 홈페이지
KBO, 한국야구위원회, 프로야구, KBO 리그, 퓨처스리그, 프로야구순위, 프로야구 일정
www.koreabaseball.com
조 안에서 데이터 크롤링 및 전처리 과정과 시각화 과정 두 파트로 나누어 분담했고, 나는 크롤링 및 전처리 과정에 참여하였다.
데이터 CSV 파일
KBO 공식 홈페이지에서 크롤링을 통해 데이터들을 CSV로 저장하였다.
파일을 불러오기 위해서는 파일들을 실행 전 다운로드 해야한다.
소스코드에 맞는 파일을 다운받아, 파일 경로에 수정하도록 하자.
관객수로 보는 흥행분석
바로 우리의 발표 제목은 관객수로 보는 흥행분석이다.
발표에서는 서론부터 결론까지의 과정을 담아 발표했지만, 블로그에서는 설명이 아닌 과정을 작성하겠다.
발표 자료는 아래의 첨부파일에서 다운받을 수 있다.
총 관중수 데이터 살펴보기
우리는 가장 총 관중수가 많았던 팀과 적었던 팀 두개를 추려야 한다.
그렇기에 KBO 가장 마지막 창단 구단인 KT가 KBO 합류한 년도인 2015년부터 2023년까지의 데이터를 수집하여 년도별 구단 총 관객수를 수집하였다.
df = pd.read_csv('/content/drive/MyDrive/ABC/audience_df.csv', encoding='utf-8')
df
위 CSV 파일에서는 어느 구단이 총 관객수가 가장 많은지 알 수 없다.
그렇기에 전처리 과정을 반드시 거쳐 데이터를 가공해야 한다.
teams = ['삼성', 'KIA', '롯데', 'LG', '두산', '한화', 'SSG', '키움', 'NC', 'KT']
average = []
for i in teams:
average.append((df[i]).mean().astype(int))
average_team = pd.DataFrame({'팀': teams, '평균': average}).sort_values('평균', ascending=False)
average_team.index = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
average_team
# 1등 LG, 꼴지 NC
전처리 후 데이터프레임을 확인해보면 1위는 LG, 꼴찌는 NC임을 확인할 수 있다.
이제 해당 데이터 프레임을 시각화 해보았다.
이제 보기 쉽게 1등팀과 꼴지팀을 한눈에 파악할 수 있다.
1등(LG)와 꼴찌(NC)의 관중 수 비교
이제 1등팀과 꼴찌팀을 본격적으로 비교해보자.
audience_win_rate_df = df[['LG', 'NC']]
audience_win_rate_df.index = [2023, 2022, 2021, 2020, 2019, 2018, 2017, 2016, 2015]
audience_win_rate_df['LG 승률'] = team_win_rate['LG']
audience_win_rate_df['NC 승률'] = team_win_rate['NC']
audience_win_rate_df
위 데이터를 보면 년도별로 두 팀의 관중 차이를 확인할 수 있다.
데이터 프레임에서 각 팀의 승률데이터는 중간의 전처리 과정이 존재한다.
밑에서 전처리 과정을 설명할 예정이니, 지금은 해당 데이터프레임만 일단 보도록 하자.
이제 년도별 최대 관중수를 시각화 해보았다.
그래프만 보더라도 코로나 시기였던 20-21년도를 제외한 모든 년도에서 LG가 압도적으로 NC를 뛰어넘음을 확인할 수 있다.
그러나 여기서 생각해야 할 점은 홈 구단의 수용가능 관중 수를 생각해야 한다.
수용가능 관중수가 적다면 당연하게도 총 관객수가 적어질 수 밖에 없다.
실제로 NC의 홈구장은 LG에 비해 수용가능 인원이 약 3000명 가량 적다고 한다.
그러면 년도별 최대 관중 수를 홈구장별 수용가능 인원으로 나눠 비율을 확인해보기로 했다.
audience_win_rate_df['LG최대관중률'] = audience_win_rate_df['LG'] / 23750
audience_win_rate_df['NC최대관중률'] = audience_win_rate_df['NC'] / 17861
audience_win_rate_df
우선 열 데이터에 구단에 따라 구장 수용가능 인원으로 나눠 추가하였다.
또한 각 구단의 시즌별 순위를 알아보기 위해 데이터를 전처리 해보았다.
temp1_df = pd.read_csv('/content/drive/MyDrive/CSV파일/NC_LG_팀순위_20240712.csv', encoding='utf-8')
temp1_df
해당 CSV에 저장된 데이터들이다.
위와 같은 데이터셋에서 LG와 NC의 순위만을 보기 위해 전처리 과정을 수행하였다.
years = range(2015, 2024)
rank_lg = []
rank_nc = []
for year in years:
index_value = temp1_df[temp1_df[str(year)] == 'LG'].index[0] + 1
rank_lg.append(index_value)
for year in years:
index_value = temp1_df[temp1_df[str(year)] == 'NC'].index[0] + 1
rank_nc.append(index_value)
team_rank = pd.DataFrame({'LG': rank_lg, 'NC': rank_nc}, index=years)
team_rank
두 데이터들을 시각화 하였다.
해당 그래프를 분석하면 가치있는 분석 결과를 얻을 수 있다.
y축의 50이 매진이라고 봤을 때 LG는 코로나 이전인 15년부터 19년까지 가을야구에 단 2번밖에 진출하지 못했다.
그러나 NC의 경우에는 코로나 이전까지 18년도를 제외한 모든 시즌에 가을야구에 진출하였음에도 비율이 낮다는 결과가 나왔다.
이를 통해 LG는 탄탄한 팬층으로 순위와 상관없이 높은 관중률이 나타났고 NC는 그렇지 않은 결과가 나왔다.
비록 19년도에는 급상승하긴 했지만 전 시즌 꼴찌에서 다시 가을야구로 복귀한 여파로 상승한걸로 보인다.
그리고 코로나 이후 22 23년도 데이터를 확인해보자.
코로나 이후 관중률을 회복하는 속도에 차이가 발생했다.
LG는 22년부터 코로나 이전의 관중률과 비슷하게 바로 회복하였지만, NC는 2년에 걸쳐 느리게 수치를 회복하였다.
이 결과도 부족한 팬층으로 발생한 결과라고 분석하였다.
팬이 부족한 NC 원인은 무엇일까 - 승률
응원하는 팀이 많이 이긴다면 응원하는 팬은 기쁘다.
그러면 NC는 계속 지니까 팬층이 없는걸까?
# 2015 - 2023년도 승률
temp2_df = pd.read_csv('/content/drive/MyDrive/CSV파일/LG_NC_팀승률_20240712.csv', encoding='utf-8')
temp2_df.index = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
temp2_df
위 데이터에서 승률을 확인해보자.
좌 데이터프레임에서는 어느 구단이 어떤 승률을 가졌는지 확인하지 못한다.
데이터를 크롤링 할 때 긁어오는 방식에 문제가 있었던 것 같다.
우 데이터는 temp_df에 저장된 구단의 승률이다.
전처리 과정을 통해 LG와 NC의 승률만 뽑아내고 싶었지만, 왼쪽의 데이터를 보고 도저히 두 구단만 전처리 하는 방식이 떠오르지 않아, 직접 수작업으로 데이터를 골라내었다.
years = range(2015, 2024)
rate_lg = [temp2_df.loc[9]['2015'], temp2_df.loc[4]['2016'], temp2_df.loc[6]['2017'], temp2_df.loc[8]['2018'],
temp2_df.loc[4]['2019'], temp2_df.loc[4]['2020'], temp2_df.loc[4]['2021'], temp2_df.loc[3]['2022'], temp2_df.loc[1]['2023']]
rate_nc = [temp2_df.loc[3]['2015'], temp2_df.loc[2]['2016'], temp2_df.loc[4]['2017'], temp2_df.loc[10]['2018'],
temp2_df.loc[5]['2019'], temp2_df.loc[1]['2020'], temp2_df.loc[7]['2021'], temp2_df.loc[6]['2022'], temp2_df.loc[4]['2023']]
team_win_rate = pd.DataFrame({'LG': rate_lg, 'NC': rate_nc}, index=years)
team_win_rate
효율적이지 못한 방법임을 알지만, 스스로 최선을 다해 생각해낸 방법이였다.
이제 위 승률 데이터를 시각화하여 비교해보자.
최고 승률만을 보았을 땐 LG가 NC보다 우세하다.
그러나 NC는 퐁당퐁당 승률을 보이고 있으며, LG는 꾸준히 우상향 중이다.
위 데이터만을 보면 승률과 관객수의 관계를 보기 쉽지 않다.
각 구단별로 승률과 관객수의 변화를 그래프로 시각화 해보았다.
LG의 경우에는 승률과 관중수의 눈에 띄는 차이는 보이지 않는 것 같다.
이제 NC를 확인해보자.
NC의 승률과 관객수 그래프를 보면 2018년도 낮은 승률을 보였음에도 관중 수의 차이는 크게 변화하지 않았다.
비록 2020년에 우승하여 승률이 높았으나, 코로나로 인해 관중 수는 낮게 집게되었다.
위의 자료들을 통해 승률과 관중 수의 차이는 연관이 없다고 결론지었다.
팬이 부족한 NC 원인은 무엇일까 - 홈런 수
직관의 재미를 올려주는 요소는 바로 홈런 수이다.
홈런을 많이 치면 경기가 재밌어지므로 관중 수가 올라가지 않을까 생각해보았다.
temp3_df = pd.read_csv('/content/drive/MyDrive/CSV파일/LG_NC_팀홈런수_20240712.csv', encoding='utf-8')
temp3_df.index = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
temp3_df
시즌 별 홈런 수를 크롤링 하는 과정도 순탄하지 않았다.
마찬가지로 위 데이터 프레임을 전처리 할 수단이 생각나지 않았다.
마찬가지로 정말 비효율적이지만 내가 할 수 있는 유일한 방법으로 데이터를 전처리 해보았다.
years = range(2015, 2024)
hr_lg = [int(temp3_df.loc[9]['2015'].split(',')[1]), int(temp3_df.loc[6]['2016'].split(',')[1]), int(temp3_df.loc[7]['2017'].split(',')[1]),
int(temp3_df.loc[3]['2018'].split(',')[1]), int(temp3_df.loc[5]['2019'].split(',')[1]), int(temp3_df.loc[4]['2020'].split(',')[1]),
int(temp3_df.loc[8]['2021'].split(',')[1]), int(temp3_df.loc[3]['2022'].split(',')[1]), int(temp3_df.loc[1]['2023'].split(',')[1])]
hr_nc = [int(temp3_df.loc[4]['2015'].split(',')[1]), int(temp3_df.loc[5]['2016'].split(',')[1]), int(temp3_df.loc[3]['2017'].split(',')[1]),
int(temp3_df.loc[10]['2018'].split(',')[1]), int(temp3_df.loc[2]['2019'].split(',')[1]), int(temp3_df.loc[2]['2020'].split(',')[1]),
int(temp3_df.loc[6]['2021'].split(',')[1]), int(temp3_df.loc[5]['2022'].split(',')[1]), int(temp3_df.loc[3]['2023'].split(',')[1])]
hr_rate = pd.DataFrame({'LG': hr_lg, 'NC': hr_nc}, index=years)
hr_rate
위 같은 험난한 과정을 거쳐 두 구단의 홈런 수를 전처리 하였다.
마찬가지로 시각화 해보았다.
홈런 수는 NC가 LG보다 높은 결과가 나왔다.
그러나 관중수는 반대였다.
그러면 홈런 수도 관중 수에 영향을 미치지 않음을 알 수 있다.
결론
NC의 비인기 원인으로 승률과 홈런 수는 영향을 주지 않음을 확인했다.
관중 수 최상위 팀과 최하위 팀의 차이가 나는 이유를 세가지 측면으로 나누어 결론을 지었다.
원인 1. 구단의 짧은 역사
NC의 연고지는 경상남도 창원이다.
그러나 경상권에 속하는 야구팀인 롯데와 삼성의 경우 역사가 깊어 팬층이 두껍기에 신생팀인 NC로 팬층이 유입되는데 한계가 있을 수 있다.
원인 2. 홈 구장의 위치
NC의 홈구장인 창원을 제외한 타 구장들은 서울, 수도권, 광역시에 위치하기에 인구수 차이가 나고 접근성이 비교적 떨어진다.
그렇기에 서울이 홈구장인 엘지는 다른 팀 팬들이 관중을 가득 채울 수 있지만, NC의 경우 지방에 위치해 타 팀 방문율이 낮을 수 있다.
원인 3. 높은 티켓 가격
NC구장의 경우 다른 9개 구단보다 홈 구장 티켓 가격이 높게 형성되어 있다.
따라서 연고지 팬들을 확보하기 위해서는 티켓 가격을 낮추고 여러 이벤트를 진행하며 홈구장 유입을 늘려야 한다고 생각한다.
해결방안
당연하게 우선적으로는 충성 고객을 늘리는데 마케팅 방향을 설정해야 한다.
충성 고객은 어릴 때부터 좋아했던 팬들에 해당되는 경우가 많다.
또한, 어린 아이가 야구 팬이 되어준다면 아이에서 친구로, 아이가 성장해서는 다시 자식에게로 야구에 대한 팬심이 전달되게 된다.
그 만큼 어린 아이를 팬층으로 만드는게 중요하다.
따라서 연령대가 낮은 어린이 팬들을 많이 확보하여 시간이 지나면서 팬층 확장을 할 수 있는 기반을 마련해야 한다.
야구 예매 시 패밀리 멤버쉽을 만들어 패밀리 시즌권을 만들고 가족 단위의 방문을 늘려, 1인 가격으로 가족 단위 관중을 받아 관중을 채움과 동시에 팬층을 두텁게 하는 전략이 필요하다고 분석하였다.
발표 후 정말 아쉬운 점이 많았다.
데이터 분석에만 초점을 맞추다 보니 전체 구성에 대한 생각이 부족했던 것 같다.
조장으로서 당연시 해야하는 것을 신경쓰지 못했고, 많은 것을 놓쳐왔던 것 같다.
그래서인지 준비하면서 높은 순위를 기대했지만 비록 순위 안에는 들지 못했다.
그러나 프로젝트를 위해 열심히 준비했고, 조원들도 많은 정성을 쏟아부어 프로젝트를 완수할 수 있었다.
비록 순위 안에는 못들었지만 스스로 조장으로서 많이 부족했던 점을 반성할 수 있었고, 최종 프로젝트에서는 어떻게 구상을 해야하는지 생각해볼 수 있는 계기가 되었던 것 같다.
'Python > 데이터분석(ABC 부트캠프)' 카테고리의 다른 글
[18일차] ABC 부트캠프 / Numpy 기초 및 머신러닝 (1) | 2024.07.21 |
---|---|
[17일차] ABC 부트캠프 / 빅데이터 분석 및 기초 통계, 딥러닝 기초 (0) | 2024.07.21 |
[15일차] ABC 부트캠프 / 건양대학교 견학 (0) | 2024.07.14 |
[14일차] ABC 부트캠프 / 셀리니움을 활용한 이미지 수집하기 (0) | 2024.07.14 |
[13일차] ABC 부트캠프 / 음악 정보 수집 및 시각화 (0) | 2024.07.14 |