개발/데이터 분석

배틀그라운드 유저 데이터 분석해보기 2. 데이터 인사이트 및 추출

잠수돌침대 2023. 1. 15. 18:00

완성된 프로젝트를 보고 계십니다. 분석 결과만을 보고 싶으시다면 아래의 URL에 접속해주세요.

https://songmin9813.tistory.com/51(Steam 버전 배틀그라운드유저 분석해보기)

 

이전 내용과 이어집니다.

https://songmin9813.tistory.com/43(1. 프로세스 수립)


데이터 타입 및 추출 방법

 

PUBG 내 모든 데이터의 반환은 JSON을 통해 이루어지는 것을 확인했다. 몇 개의 예시 Execute를 통해 Request 되는 URL의 특징을 파악해 낼 수 있었고, 이를 코드에 담아 추출하는 과정을 담았다.

 

모두 공통점으로 curl 형식의 입력을 주는 것을 확인

다만 인증 여부를 떠나 curl 형식으로 작성되어있는 항목이 많기에 request url을 직접 넣는 것보다 curl 코드를 request 형식으로 변환한 후 request를 사용하여 반환하도록 코드를 작성하였다.

 

변환을 위해 Curl Converter라는 사이트를 찾아냈고, 해당 사이트에 들어가 Curl 코드를 입력하면 request 코드를 반환하는 것이 굉장히 유용했다.

 

https://curlconverter.com/(Curl Converter)

아주 야무진 사이트이다. 여러 언어로도 사용이 가능하니 적극 추천!

 

이를 통하여 결과물을 추출해내는 코드를 작성할 수 있었고, 이를 토대로 지난 14주간의 Match ID 정보를 추출해 낼 수 있었다. 

 

아래는 Curl Converter를 이용하여 추출한 ID를 토대로 Match 정보를 추출해내는 함수이다.

def get_match(match_id):
    headers = {'accept': 'application/vnd.api+json',}
    response = requests.get('https://api.pubg.com/shards/steam/matches/'+match_id, headers=headers)
    return response.json()

 


Raw Data 추출 및 데이터 인사이트

 

블라블라블라

 

추출 과정을 통해 Steam PUBG 데이터를 기준으로 2주간 약 5700개의 Match ID를 찾을 수 있었고, 이를 위 get_match 함수에 적용시켜 모든 정보를 JSON 파일로 담아 저장하는 과정을 포함했다.

 

크기 실화냐...

 

JSON 파일로 이루어진 Raw Data로만 355MB를 차지하는 것이 인상깊다. 이 파일 때문에 깃허브에 해당 파일 올리지도 못했다지. 실제로 깃허브의 한 파일의 최대 허용 크기는 100MB, 권장 허용 크기는 50MB이다.

 

그럼 어떤 내용이 필요할까?

 

위의 Raw Data를 모두 사용하는 것은 시각화에 많은 도움이 될 것 같지 않고, 어떤 데이터를 살리고 죽일 것인지에 대한 생각을 슬슬 할 필요가 있을 것 같다.  

 

해당 JSON 파일과 DOCS를 토대로 대충 필자가 어떤 내용을 시각화하면 좋을지에 대한 생각을 육하원칙에 의거하여 생각해봤고, 다음과 같은 결과물만 남기고 나머지는 Drop 하는 방향으로 가닥을 잡았다.

 

누가 언제 어디서 무엇을 어떻게
게이머 이름
게이머 or 봇 여부,
티어
한 세션 플레이 시간, 플레이 날짜 플레이 맵, Steam PUBG 기준, 국가 K/D, 아이템 획득, 파티 플레이 여부 어떤 아이템 사용, 죽은 이유, 총기  

 

상기 표에서 밑줄이 쳐진 부분은 추가는 하고 싶으나, 데이터 추출의 시간상의 한계로 추가하지 못한 내용들이 담겨있다.

 

결과적으로 쓸모없다 생각하는 데이터를 모두 제하고, 일단 살리고자 하는 데이터들은 다음과 같다.

 

 

1. 해당 Match에서 플레이된 맵
2. 솔로/듀오/스쿼드 플레이 여부
3. 총 게임 플레이 시간
4. 플레이어 각각의 플레이 정보

 

그리고 각각을 살려둔 이유는 아래의 내용과 같다.

 

1번 : 필자는 모바일 배그를 하며 에란겔이라는 맵을 가장 즐겨 했다. 그에 반해 다른 맵을 그리 선호하지 않는 편인데, 다른 사람들은 과연 다른 맵을 얼마나 많이 플레이하고 있을까가 궁금했다.

2번 : 혼자서 즐기는 사람이 많은지, 다같이 즐기고자 하는 사람이 많은지에 대한 내용도 궁금했다. 필자는 배그만큼은 같이 하는 게임이라 인식하고 있는데, 다른 사람들은 어떻게 생각하고 있을지 궁금했다.

3번 : 평균적인 플레이 시간과 더불어 평균 생존 시간 등 시간과 관련된 모든 항목에 대한 기준 지표가 될 것 같아 살려두었다.

4번 : 해당 시각화의 핵심이라 할 수 있는 정보였다. 1차적으로 유저들이 어떠한 플레이 양상을 보이고 있는지에 대한 정보가 필요했고, 이는 시간과 데이터가 많더라도 무조건적으로 가져가고 싶었던 항목 중 하나였다.     

 

상기 네 개에 대한 정보들을 각각 테이블로 만들어 관리하되 이 때 사용된 고유 Match ID는 원활한 Join을 위해 모두 Primary Key로 두기로 하였다.

 

아래는 JSON에서 상기 내용을 추출하여 초기화시키는 코드의 일부이다.

 

map_name=match_table[0]['data']['attributes']['mapName'] # 현재 맵의 이름
game_mode=match_table[0]['data']['attributes']['gameMode'] # 솔로/듀오/스쿼드
duration=match_table[0]['data']['attributes']['duration'] # 게임 진행 시간
personal_attributes=match_table[0]['included'][0]['attributes']['stats'] # 플레이어 개인 정보

 

공식 DOCS에서 제공하는 데이터이기 때문에 결측치가 없는 건 정말 좋은 것 같다. 실제로 info 함수를 작동시켜 보아도 모든 열에 대하여 깔끔하게 non-null이 나오는 부분에서 카타르시스를 느꼈다.

 

💡 초기 프로세스 수립과 더불어 해당 시리즈를 투고할 때까지 사용한 데이터는 2022/12/29~2023/01/10 사이의 데이터를 사용하였음을 사전에 명시하는 바이다.