tak's data blog

배틀그라운드 어뷰징 정의 및 탐지(kaggle 데이터 활용)(1) 본문

프로젝트/배틀그라운드 어뷰징 정의 및 분석

배틀그라운드 어뷰징 정의 및 탐지(kaggle 데이터 활용)(1)

hyuntaek 2022. 11. 29. 18:51
반응형
SMALL

실제로 게임을하면서 어뷰징으로 이탈했던 경험과 이를 해결하기 위해 내가 할 수 있는 일은 무엇일까?? 고민하며

게임 어뷰징 탐지라는 분야에 관심을 가지게 되었다. 게임데이터로 어뷰징탐지를 직접 해보면 어떨까?라는 의문을 시작으로 다음과 같은 분석을 진행하였다.

 

배틀그라운드 어뷰징 유저 탐지이다.

 

사실 아래 데이터는 kaggle 대회로 유저들의 순위를 예측하는 대회이다.

https://www.kaggle.com/competitions/pubg-finish-placement-prediction/data

 

PUBG Finish Placement Prediction (Kernels Only) | Kaggle

 

www.kaggle.com

 

0. 문제인식

 

데이터를 보는 과정에서 다음 2가지에대한 의문이 생겼다.

1) walkdistance(걷는 거리)가 0인데 winPlacePerc가 1인 경우(우승) 

-> 어떻게 걷는 거리가 0인데 우승을 할 수 있지? 어뷰징일까?

 

2) 슈팅 게임의 경우 에임핵이 존재. 유튜브를 통해 에임핵이라는 것이 존재한다는 점을 파악. 이러한 에임핵은 원활한 게임 환경에 해를 끼친다.(유저들의 이탈) --> 그렇다면 에임핵을 직접 정의하고 판단해 인사이트 도출이 가능하지 않을까?

이미지 출처: 유튜브 로자르 채널

그렇다면 위의 kaggle 데이터 안에서도 내가 어뷰징유저를 스스로 정의해서 모델링까지 이뤄낼 수 있지 않을까??라는 생각에 분석을 시작하였다.

 

어뷰징유저를 정의한 방법과 EDA 및 분석과정은 아래와 같다.

 

 

0-1 활용 데이터

 

기존 데이터

 

전처리 데이터

기존 4,446,966명의 데이터 -> 127,573명의 데이터

(아래의 조건에 맞춰 전처리한 데이터)

 

normal(일반유저) = 121,324명

abusing(어뷰징유저) = 6,249명

 

 

1. 어뷰징 정의

winPlacePerc = 1(우승)인 유저 가운데 aim_point가 이상치인 경우

이렇게 정의한 이유는 우승이라는 특정 조건이 일반유저와 어뷰징유저에서 동일하게 적용되어야 다른 조건들을 제대로 비교할 수 있을 것이라고 생각했기 때문이다.

 

그리고 aim_point는 아래와 같이 정의했다. 

# 킬수와 헤드샷 킬수가 일치한 경우 (배틀그라운드 특성상 총기의 반동 때문에 헤드샷 킬이 쉽지 않음)
train['aim_point'] = train['headshotKills']/train['kills']
train['aim_point'] = train['aim_point'].fillna(0)

headshotkills(헤드샷 킬수) / kills(실제 킬수) 로 정의했다. 그 이유는 배틀그라운드는 총의 반동이 심해서 헤드샷이 쉽지 않다. 그런데 위의 비율을 보았을 때 비정상적으로 크다면 에임핵 의심으로 판단할 수 있을 것이다.

 

그래서 winPlacePerc = 1(우승)인 유저 가운데 aim_point가 이상치인 경우를 어뷰징 유저라고 정의했다.

 

 

2. EDA 및 분석

Q1. 플레이 타입에 따라 차이가 있을까?

  • 플레이타입에 차이를 보이지는 않는다.

 

 

 

 

Q2. 어뷰징유저(에임핵)는 아이템을 많이 획득할 필요가 없을 것이다.

-> 라이플 이외에 수류탄 등의 아이템은 에임핵과의 목적이 다르기 때문에

 

 

# 중심극한정리에의해 표본평균의 분포가 정규분포를 따른다고 가정함

# 정규성을 만족할 때 등분산 검정(bartlett)
stats.levene(data[data['user_status'] == 'abusing']['weaponsAcquired'],
            data[data['user_status'] == 'normal']['weaponsAcquired'])
# 등분산성을 만족하지 않는다.
BartlettResult(statistic=24.538103476364096, pvalue=7.294767502746544e-07)

# 그렇다면 welch ttest

 

# ttest (유저에 따른 무기획득수 평균차이 검정)
from scipy.stats import ttest_ind

print(data[data['user_status'] == 'abusing']['weaponsAcquired'].mean(), 
      data[data['user_status'] == 'normal']['weaponsAcquired'].mean())

# ttest에  equal_var = False를 추가하면 welch ttest
_, p = ttest_ind(data[data['user_status'] == 'abusing']['weaponsAcquired'], 
                data[data['user_status'] == 'normal']['weaponsAcquired'],  equal_var = False)
print(f'p={p:.3f}')


5.468714994399104 5.692319738881013
p=0.000
  • 무기획득에 대한 평균 검정을 한 결과 p값이 0.05보다 작아 통계적으로 유의한 차이가 있음을 확인했다.
  • 그리고 가설대로 어뷰징유저의 평균 weaponsAcquired(무기획득수)가 적음을 확인함.

-> 결국 어뷰징유저는 무기를 종류별로 획득할 필요가 없음.

 

 

Q3. 에임핵은 광역기(수류탄 등), 후라이팬 등을 잘 사용하지 않을 것, 습득도 총위주로만

-> 그렇다면 killStreaks(짧은 시간안에 적을 동시 처치)가 적지 않을까??

# ttest (유저에 따른 평균 동시처치횟수 검정)
from scipy.stats import ttest_ind

print(data[data['user_status'] == 'abusing']['killStreaks'].mean(), 
      data[data['user_status'] == 'normal']['killStreaks'].mean())


_, p = ttest_ind(data[data['user_status'] == 'abusing']['killStreaks'], 
                data[data['user_status'] == 'normal']['killStreaks'],  equal_var = False)
print(f'p={p:.3f}')


1.0800128020483277 1.3287725429428638
p=0.000
  • 어뷰징 유저는 거의 1에 수렴
  • 검정 결과 어뷰징유저가 일반유저에비해 killStreaks가 적고 통계적으로 유의한 차이가 있음을 보임

-> 에임핵을 사용하는 유저는 다중으로 짧은 시간에 처치를 할 수 없음

 

 

  • killStreaks(다중 처치 횟수)와 weaponsAcquired(무기 획득 수)의 lmplot결과
  • 실제로 일반유저가 더 양의 선형관계를 보임

 

 

Q4. revives(팀을 살린 횟수)도 적을 것, 아이템도 덜 획득했으므로 구급상자, 붕대 등의 치료 아이템이 적으므로

 

# ttest (유저에따른 팀원을 살린 횟수 평균 검정)
from scipy.stats import ttest_ind

print(data[data['user_status'] == 'abusing']['revives'].mean(), 
      data[data['user_status'] == 'normal']['revives'].mean())


_, p = ttest_ind(data[data['user_status'] == 'abusing']['revives'], 
                data[data['user_status'] == 'normal']['revives'],  equal_var = False)
print(f'p={p:.3f}')


0.3858217314770363 0.4871583528403284
p=0.000
  • 어뷰징 유저가 살린 횟수가 더 적음을 통계적으로 확인

 

 

Q5. 에임핵, 헤드샷으로 한번에 적을 죽이니 DBNOs(기절 상태)를 유발하지 않을 것이다.

# ttest (유저에따른 기절시킨 횟수 평균 검정)
from scipy.stats import ttest_ind

print(data[data['user_status'] == 'abusing']['DBNOs'].mean(), 
      data[data['user_status'] == 'normal']['DBNOs'].mean())


_, p = ttest_ind(data[data['user_status'] == 'abusing']['DBNOs'], 
                data[data['user_status'] == 'normal']['DBNOs'],  equal_var = False)
print(f'p={p:.3f}')


1.0193630980956954 2.0850450034618047
p=0.000

 

  • 실제로 검정 결과 어뷰징유저는 기절 상태를 유발하지 않고 한번에 죽일 것이라고 판단

  • 기절상태와 다수의 적처치 횟수는 일반유저가 좀 더 양의 선형관계
  • 어뷰징유저는 에임핵으로 개개인의 유저를 죽이지만 일반유저는 수류탄과 같은 광역기로 다수의 적을 사냥함

 

위의 변수들을 기반으로 heatmap을 그려보았다.

일반유저
어뷰징유저

  • killStreaks(짧은 시간내에 다중으로 킬했을 때)와 DBNOs(기절 시킨 횟수)와의 상관계수 값이 일반유저는 0.59로 어뷰징유저 0.35보다 높음

-> 어뷰징유저는 기절보다는 한번에 헤드샷으로 상대를 보내기 때문

-> 수류탄과 같은 광역기로 다중 기절, 죽이지 않고 에임으로만 상대했을 것임

 

 

Q6. 그렇다면 어뷰징유저들은 어시스트가 적지 않을까?

-> 혼자서 해결할 수 있기 때문에

# ttest (유저에따른 어시스트 횟수 평균 검정)
from scipy.stats import ttest_ind

print(data[data['user_status'] == 'abusing']['assists'].mean(), 
      data[data['user_status'] == 'normal']['assists'].mean())


_, p = ttest_ind(data[data['user_status'] == 'abusing']['assists'], 
                data[data['user_status'] == 'normal']['assists'],  equal_var = False)
print(f'p={p:.3f}')


0.962393983037286 1.108997395404042
p=0.000
  • 어시스트 횟수가 더 적음을 확인

 

 

Q7. 그렇다면 어뷰징유저들은 팀원들을 돕는 행위가 적을것이다.

-> boosts(부스트 물약), heals(팀원을 치료하는 행위)의 사용이 적을 것이다. 

-> 그럼 weaponsAcquired(무기 획득 수) 대비 boosts + heals의 아이템 비율이 적지 않을까???

 

위의 의문을 기반으로 아래와 같은 not_weapon 피처를 생성함

data['not_weapon'] = (data['boosts'] + data['heals'])/data['weaponsAcquired']
data = data.replace([np.inf, -np.inf], np.nan)
data = data.fillna(0)
# ttest (유저에따른 아이템획득 비율 평균 검정)
from scipy.stats import ttest_ind

print(data[data['user_status'] == 'abusing']['not_weapon'].mean(), 
      data[data['user_status'] == 'normal']['not_weapon'].mean())


_, p = ttest_ind(data[data['user_status'] == 'abusing']['not_weapon'], 
                data[data['user_status'] == 'normal']['not_weapon'],  equal_var = False)
print(f'p={p:.3f}')


1.2802245955482225 1.4604191866466927
p=0.000
  • 확실히 어뷰징유저가 무기획득수가 더 높고 남을 돕거나 체력을 회복하는 아이템 횟수의 사용비율이 적음

 

 

Q8. 에임핵으로 처치 가능성이 높으므로 killPlace(처치횟수 등수)가 높은 편에 속할 것이다.

  • 어뷰징유저(빨간색), 일반유저(파란색)의 분포로 보아 어뷰징유저는 상위 등수에 포진하고 있지는 않지만 하위 등수에는 절대 포진하고 있지 않음.(기본 평타 이상의 실력)
  • 그러나 일반유저는 우승했지만 하위 등수에도 어느정도 포진(실력이 고르게 분포)

 

 

여기까지 데이터를 분석한 결과입니다. 추가적인 인사이트는 계속 데이터를 살펴보면서 확인해야겠네요.

이제 다음 단계로 어뷰징유저 탐지 모델링을 실시하는 포스팅을 올리도록 하겠습니다. 

 

 

3. 결론

- 어뷰징유저(에임핵 의심)는 무기를 덜 획득한다.

- 수류탄 등의 사용이 적어 killStreaks(짧은 시간안에 적을 동시 처치)가 낮다.

- 팀과 관련된 변수 revives(팀을 살린 횟수), heal(회복) 등이 적다.

- 어뷰징유저는 killPlace(처치횟수 등수)가 일반유저에비해 높은 편에 속한다.

 

 

 

기억해야할 점

1) 지난번에 과제로 분산분석을 제출하면서 아쉬웠던 점이 있었다. 위의 내용과도 어느정도 연관이 된다. 

분산분석시 비모수검정에서 크루스칼왈리스 중위수 검정은 사후검정을 할 수 없다. 두 집단씩 나눠서 Mann Whiteny U-test를 실시하여야 한다.(Bonferroni Correction Method: 크루스칼왈리스로 집단 간 차이가 있다고 나왔을 때, 집단별로 짝을 묶어서 Mann Whiteny U-test를 실시한다. 대신 유의수준 alpha는 집단수로 나누어 준다.)

+ 등분산성을 만족하지 않는다면 welch ttest를 실시한다.(ttest_ind에서 equal_var = False)

 

2) 데이터분석에서 도메인지식의 중요성을 다시금 느낀다. 

(그렇다면 자기장이라는 특수한 시스템이 있는 배그에서 다른 변수들을 도출해 볼 수 있지 않을까??)

반응형
LIST