지난 게시글 보기
https://songmin9813.tistory.com/70(2. PCA)
지난 게시글에서 PCA를 이용하여 35개의 변수를 약 70%의 분산으로 표현할 수 있는 14개의 변수로 압축한 것으로 게시글을 마무리했다. 이번에는 이를 이용하여 비지도 학습 중 Clustering 기법인 K-Means Clustering을 적용해 보고 어떠한 결과가 나왔는지 소개하는 시간을 가져본다.
비지도 학습이요...?
이 얘기를 함에 앞서 지도 학습과 비지도 학습에 대한 개념을 간단히 살펴보고 넘어가 보도록 하자. 이 둘과 다른 강화 학습도 존재하다만, 통상적으로 머신 러닝 기법이라 하면 이 둘을 지칭하는 것이라 해도 무방할 것이다.
결과적으로 이 둘의 가장 큰 차이는 정답(=레이블, 종속 변수 등등)이 존재하냐, 존재하지 않느냐의 차이라 볼 수 있다.
지도 학습의 종류
1. 분류(Classification)
주어진 카테고리(=라벨, 레이블, 리스트 등등)에 분류하는 문제들을 일컫는다. 단순히 맞다/아니다와 더불어 여러 객체를 인식하는 기술. 실시간 사물 인식의 정수라 할 수 있는 딥러닝의 YOLO 알고리즘도 이 Classificaiton 범주에 들어간다 해도 무방할 것이다.
아래의 예시를 통해서 어떠한 방식으로 학습이 되는지 간접적으로 이해해보자.
1. 철수와 승호는 남자라 분류했습니다. 영희와 수진은 여자라 분류했습니다. 이 넷만 보았을 때, 여러분은 어떤 부류에 속할 것 같나요? (이진 분류 문제)
2. 철수는 강아지를 키웁니다. 승호는 고양이를 키웁니다. 영희는 강아지/고양이를 모두 키우고 수진은 둘 모두 기르지 않습니다. 여러분은 어떤 부류에 속할 것 같나요? (다중 분류 문제)
2. 회귀(Regression)
수치형 데이터들을 이용하여 상관관계나 패턴을 이끌어내고, 이를 토대로 추후에 나올 데이터를 예측할 때 주로 사용되는 분석이다. 정수/실수와 같은 수치형 데이터에서 회귀 분석이 사용되며, 카테고리를 one-hot encoding을 통하여 수치화시킨 후 회귀 분석을 진행하여도 무방하다.
아래는 회귀 분석의 예시
Q. 1을 넣었는데 2라는 값이 나왔습니다. 2를 넣었는데 4라는 값이 나왔습니다. 3을 넣었을 때 어떤 값이 나올까요?
비지도 학습
정답이 존재하지 않는 데이터를 비슷한 특징으로 묶어 설명하고 싶을 때 사용하는 학습기법이다. 사회 현상을 분석하거나 어떠한 방식으로 카테고리화할지를 모를 때 등. 명확한 답이 존재하지 않을 때 사용하는 방법이며, 명확한 답이 없기에 통상적으로 지도 학습보다는 학습률이 떨어진다고도 할 수 있을 것 같다.
안경을 쓰고 카라 없는 반팔을 입고 있는 남자 '철수'
안경을 쓰지 않고 카라 있는 긴팔을 입고 있는 남자 '승호'
안경을 쓰고 카라 없는 긴팔을 입고 있는 여자 '영희'
안경을 쓰지 않고 카라 있는 반팔을 입고 있는 여자 '수진'
여러분은 이들을 두 부류로 나누어야 합니다. 어떻게 나누시겠습니까?
필자는 해당 학습 중에서 가장 대표적인 클러스터링(Clustering) 기법을 이용하여 유저들의 성향을 분류하기로 마음먹었고 그 이유는 다음과 같다.
1. 플레이어 데이터들을 이용하여 필자가 스스로 플레이어 특성을 파악하기는 불가능
2. 플레이어의 플레이 양상 및 현상을 관찰하기 위해
K-Means Clustering
Clustering의 가장 대표적인 알고리즘이며, 작동되는 방식은 아래의 Step과 같다.
Step 1. 우선 K개의 랜덤한 점(=데이터 포인트=중심점)을 찍는다.
Step 2. 각 데이터에 대하여 가장 가까운 데이터 포인트에 군집화를 진행.
Step 3. 군집화된 데이터들을 바탕으로 새로운 데이터 포인트를 선정.
Step 4. 다시 각 데이터에 대하여 새롭게 만들어진 데이터 포인트에 군집화를 진행.
Step 5. 이를 군집화가 변하지 않을 때까지(=수렴할 때까지) 반복!
알고리즘 자체가 단순해서 영상이 아닌 검색과 이론 공부를 통해서도 충분히 이해가 가능한 알고리즘이었다. 해당 알고리즘의 단점이라 하면 이상치에 민감하다는 것과 K값을 직접 설정해주어야 한다는 것 정도?
K의 값을 정성적인 방법(현재의 방법론은 Richard Bartle로 인한 4가 되시겠다) 외에도 Elbow Method(클러스터의 수를 순차적으로 늘려가며 모니터링. 결과의 차이에 심한 등락을 보이지 않는 지점이 최적의 K), Silhouetee Method(군집 데이터들 간의 비유사성을 계산하여 평균 실루엣 값이 최대가 되는 K 도출) 등 여러 방법론이 존재한다고 한다.
필자는 상기 이론을 바탕으로 K가 정성적 내용인 4일 때와, 기계적으로 도출해 냈을 때의 차이와 그 양상을 교차 확인해보고자 한다.
코딩 가보자고
이 역시 관련 라이브러리가 제공되고 있기에 쉬운 코딩이 가능하다. 내가 파이썬을 놓을 수 없는 이유가 바로 이게 아닐까?
우선 적절한 K가 선정되었는지 Elbow Method를 통해 살펴본다. 1부터 10 정도로 클러스터링을 걸어보고 최적의 K가 선정되었는지를 살펴보자.
from sklearn.cluster import KMeans
distortions = []
for i in range(1, 11):
km = KMeans(n_clusters=i, random_state=0)
km.fit(principal_df)
distortions.append(km.inertia_)
# plot
plt.plot(range(1, 11), distortions, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.show()
그나마 급격하게 완만해지는 지점은 2 임을 알 수 있다. 그렇다면 K값을 2로 놓았을 때와 4로 놓았을 때의 경과를 간단한 결과부 구현을 통해 알아보도록 하자.
richard_km = KMeans(n_clusters = 4, random_state = 0).fit_predict(principal_df)
elbow_km = KMeans(n_clusters = 2, random_state = 0).fit_predict(principal_df)
clustering_table=pd.DataFrame({'richard':richard_km, 'elbow':elbow_km}) # 이론상 4와 elbow 2가 포함된 dataframe 생성
player_df=player_df.reset_index(drop=True) # 인덱스 재정렬
result_table=pd.concat([player_df,clustering_table],axis=1)
분석 결과
CLI를 간단히 구현하여 Richard Bartle 기반 경과를 살펴본다.
for i in range(4):
print('Richard Bartle 기반 '+str(i+1)+'번째 그룹')
print('총 군집 수 : '+str(len(result_table[result_table['richard']==i]))+'/'+str(len(result_table)))
print('평균 기절시킨 횟수 :', result_table[result_table['richard']==i]['DBNOs'].mean())
print('평균 준 대미지 :', result_table[result_table['richard']==i]['damageDealt'].mean())
print('평균 킬 :', result_table[result_table['richard']==i]['kills'].mean())
print('평균 생존시간 :', result_table[result_table['richard']==i]['timeSurvived'].mean())
print('최다 사망 페이즈 :', result_table[result_table['richard']==i]['phase'].value_counts().keys()[0],'페이즈')
print('초당 평균 이동거리 :', ((result_table[result_table['richard']==i]['walkDistance'] +
result_table[result_table['richard']==i]['swimDistance'] +
result_table[result_table['richard']==i]['rideDistance']) /
result_table[result_table['richard']==i]['timeSurvived']).mean())
print()
분석 결과 - Richard Bartle 기반
첫 번째 군집 - Killers 그룹
다른 플레이어를 기절시킨 횟수와 더불어 준 대미지/킬이 가장 높은 것으로 군집화되었다. 그렇기에 다른 군집들보다 플레이어를 죽이는 것에 많은 관심을 가지고 있는 Killers 부류에 속할 것 같다. 속된 말로 여포 플레이, 공격에 많은 관심을 가지고 있는 플레이어랄까.
Richard Bartle이 말하는 Killers의 비율이 제일 낮다(평균적으로 5~10%)는 특징을 어느 정도 공유하는 것도 눈에 띈다. 약 10%의 플레이어가 플레이어를 죽이며 만족을 느낀다고도 해석이 가능할 것 같다.
두 번째 군집 - Acheivers 그룹
배틀로열의 우승 목표인 '마지막까지 살아남아라'라는 게임의 목표를 '모두 죽이는 것'이 아닌 '오랫동안 생존하는 것'으로 해석한 플레이어들이 모인 그룹으로 보인다. 이 또한 플레이어를 죽인다는 것이 아닌 게임의 목표에 충실한 것으로 보이기에(생존 시간이 비교적 높다) Killers와는 다른 방향으로 게임의 목표에 충실한 Acheivers 그룹이라 해석이 가능할 것이다.
세 번째 군집 - Explorers 그룹
사실 해당 군집을 월드와 상호작용하는 Explorers 그룹이라 단정 짓기는 어려울 것이다. Explorers의 특징으로 월드/맵 자체에 흥미가 있다기보다는 Killers, Acheivers 그룹에 의하여 빨리 킬을 당함으로 이동 기반 상대적으로 게임 자체에 많은 기여를 하지 못한 케이스가 더 많을 것이기 때문이다.
하지만 다른 군집에 비해 Explorers 특징을 가지고 있는 플레이어가 있을 확률이 높다는 점, 그리고 월드의 이동 거리와 킬 수를 상대적으로 고려했을 때 다른 플레이어 그룹에 비해 Explorers 그룹의 특징을 띤다고는 할 수 있을 것이다.
네 번째 군집 - Socialisers 그룹
이는 거의 땅에 닿자마자 이동도 해보지 못하고 죽어 바로 다음 게임을 준비해야 하는 경우가 이에 속할 것 같다. 모든 지표가 다른 군집에 비해 낮은 양상을 보여 해당 군집에 오래 머무르고 있는 플레이어는 게임의 내적 요소로 재미를 얻기보다는 외적 요소(친구와 같이 떠들면서 하기 등)로 재미를 찾고 있다는 것이 올바른 해석일 것이다.
아래는 Elbow Method 기반 결과이다.
for i in range(2):
print('Elbow Method 기반 '+str(i+1)+'번째 그룹')
print('총 군집 수 : '+str(len(result_table[result_table['elbow']==i]))+'/'+str(len(result_table)))
print('평균 기절시킨 횟수 :', result_table[result_table['elbow']==i]['DBNOs'].mean())
print('평균 준 대미지 :', result_table[result_table['elbow']==i]['damageDealt'].mean())
print('평균 킬 :', result_table[result_table['elbow']==i]['kills'].mean())
print('평균 생존시간 :', result_table[result_table['elbow']==i]['timeSurvived'].mean())
print('최다 사망 페이즈 :', result_table[result_table['elbow']==i]['phase'].value_counts().keys()[0],'페이즈')
print('초당 평균 이동거리 :', ((result_table[result_table['elbow']==i]['walkDistance'] +
result_table[result_table['elbow']==i]['swimDistance'] +
result_table[result_table['elbow']==i]['rideDistance']) /
result_table[result_table['elbow']==i]['timeSurvived']).mean())
print()
Richard Bartle 기반 군집 결과에서 1,2번째 군집/3,4번째 군집이 비슷한 양상을 보이고 있는 것으로 확인되었고, 실제로 각각이 합쳐져 2개의 군집이 만들어진 것을 확인할 수 있었다.
마치며
데이터를 이용한 가공과 군집화를 진행하고, 이를 간단히 CLI로 구현함으로 빠르게 결과만을 살펴보았다. 게임의 장르 특성상 반드시 사망자가 나와야 게임이 진행되는 구조이기 때문에 4가지의 특성을 가진 플레이어를 해당 지표만을 이용해서 판단하는 것은 꽤나 어려울 것으로 보인다.
하지만 다른 군집에 비해 각각의 군집들이 꽤나 뚜렷하면서도 재밌는 결과가 도출되었기 때문에, 해당 이론은 어느 정도 통용되는 이론이라는 생각도 들었다. 이론으로만 알고 있던 게임 지식을 데이터적으로 접근해 보고, 직접 군집화시켜 보면서 그 차이와 경과를 보는 것이 신선하면서도 흥미로운 경험으로 다가온 것 같다.
다음에는 시간이 된다면 플랫폼별로 플레이를 나눈 결과도 살펴보고, 제대로 된 시각화 자료도 가져와 소개하는 시간을 가져보도록 하겠다.
기본적인 데이터 가공 및 검증 프로젝트는 일단 마무리!
'개발 > 데이터 분석' 카테고리의 다른 글
4종류의 게이머가 존재한다고? - 2. PCA (0) | 2023.02.14 |
---|---|
4종류의 게이머가 존재한다고? - 1. 인사이트 및 전처리 (0) | 2023.02.12 |
우리가 분석을 하며 놓치고 있는 것들 - 회귀분석 (0) | 2023.02.04 |
Kakao 버전 배틀그라운드 유저 데이터 분석해보기[통합] (2) | 2023.01.25 |
[Python/Analytic] 배틀그라운드 유저 데이터 분석 코드 공유 (8) | 2023.01.23 |