본문 바로가기
카테고리 없음

MMORPG 어뷰징 검출 과제

by 민트초코맛꼬깔콘 2024. 1. 6.

※ 수년 전에 게임 데이터로 공부할 기회가 생겨 작성했던 자료를 일부 수정하여 기록으로 남겨놓고자 함

 

1. 개요


1.1 내용

  • 특정 게임에서 골드를 파밍하는 어뷰저를 판별해 내는 룰 혹은 머신러닝 알고리즘 구현

1.2 참고사항

  • 어뷰저란? 기획적으로 의도하지 않은 방식으로 게임 정보를 대량 획득하거나 도움을 주는 유저

1.3 데이터 설명

 

2. 탐색적 데이터 분석 (EDA)


2.1. 문제 목적

  • 골드를 파밍하는 어뷰저를 정확하게 판별하는 것으로 테스트셋 44,736건에 대하여 제재 대상은 1, 비제재 대상은 0으로 함.
  • 어뷰저라 판단할 수 있을 특성들에 대하여 아래 [표 2]과 같이 생각해 봄

 

2.2. 변수 탐색

  • [그림 1]을 보면 학습셋 104,399개 테스트셋 44,736개로 7:3의 비율로 나타남
  • 컬럼 중 logging_timestamp만 str로 구성되어 있으며 모두 int형태의 변수로 되어있음

 

2.3. 시각화 – 피어슨 상관분석(Pearson Correlation Analysis)

  • 피어슨 상관관계를 통하여 각 변수들 간의 관계를 알 수 있음.
  • 모든 데이터가 ‘continuous’ 해야 하며 logging_timestamp는 우선 제거하고 분석함
    • (-1 : 음의 상관관계 / 0 : 상관없음 / 1 : 양의 상관관계)

 

2.4 시각화 – 미래의 제재여부(blocked), 캐릭터 식별자(newID)

  • 학습용 데이터셋에는 44개의 컬럼으로 이루어져 있고, 테스트용 데이터셋은 ‘blocked’ 값을 제외한 43개의 컬럼으로 이루어져 있음.
  • [그림 2]에서 보는 것처럼 테스트셋에 대하여 제재 대상은 62,460건 비제재 대상은 41,939건으로 6:4의 비율로 나타남.
  • newID 기준
    • 학습셋: 전체 10,441개 (제재: 6,246/비제재: 4,195)
    • 테스트셋: 전체 4,475개 (제재/비제재 알 수 없음)
  • 대부분의 데이터가 하나의 newID 당 10개의 스냅샷 로그가 남아 있지만 아래 [표 3]에서의 해당 newID들은 10개 미만의 스냅샷 로그를 갖고 있음.

 

2.5. 시각화 – 직업식별자(char_jobcode)

  • 전체(게임 전체직업 개수 알 수 없음) 중 165개의 직업 종류
  • 제재 대상은 5개의 직업만 플레이하였고 비제재 대상은 165개의 직업을 플레이함
  • 21, 29, 30, 31의 경우 게임 내에서 두루 인기가 좋은 직업일 것 같으나 32번의 경우 잘 이용되지 않는 직업인데 어뷰징 용도로 이용됨

 

2.6. 시각화 – 캐릭터 레벨(char_level)

  • 모든 데이터에서의 최소 레벨은 10, 최고 레벨은 159를 나타냄 (제재: 10133/비제재: 10159)
  • 이를 보아 0~10 레벨은 튜토리얼 등을 진행하며 10부터 필드로 진출하는 방식을 것으로 예상함

  • 다음으로 char_jobcode에 따른 유저 레벨(최소/최대)을 보니 각 직업이 가질 수 있는 제한범위가 있음
  • 최소 레벨 기준 10, 30, 60, 100에서의 분포가 나타나는 것으로 보아 10, 30, 60, 100에서 직업특성화, 전직, 승급 등의 캐릭터직업의 변화가 나타나는 것으로 예상됨

⚠️ 한 가지 특이점은 10부터 최대 133까지 직업의 변화 없이 하나의 직업으로만 플레이한 유저도 상당수 존재함

  • 캐릭터의 레벨 변화를 알아보기 위해 [그림 5]와 같이 스냅샷 로그 기준으로 마지막 타임의 레벨과 첫 타임의 레벨과 차이를 비교해 보았음
  • 하지만, 이것은 잘못된 비교임. 타임스탬프 구간이 짧을 수도 있고 길 수도 있어서 정확한 비교 방법이 될 수 없음

  • 방법을 조금 바꿔서 스냅샷 로그에서 연속되는 타임스탬프(30분) 간격이 있을 경우 30분간 업한 레벨 값을 확인해 보았음
  • [그림 6]에서 볼 수 있듯이 30분 간격을 넘는 경우는 무시하고, 다시 그다음 로그와 30분 간격으로 비교해 보았음
  • 하지만 단순 수치상 변화만 보기에는 레벨 후반부로 갈수록 더 많은 경험치를 얻어야 하기에 상승폭이 줄어듦. 레벨 구간별 가중치 등을 주는 것도 방법으로 생각됨

 

2.7. 시각화 - 해당 스냅샷 로그가 찍힌 시점(logging_timestamp)

테스트셋의 스냅샷 로그 기간은 2017-06-09부터 2017-06-29까지 21간의 데이터로 구성됨

  • 캐릭터 기준 10개씩의 기록구간을 살펴보면 30분 간격으로 스냅샷 로그가 남으며, 4시간 30분 동안 연속으로 로그가 남은 캐릭터가 있는 반면 17일에 걸쳐 10개의 로그가 남은 경우도 있음
  • Blocked
    • 가장 짧은 구간: 0 days 04:30:11.320154
    • 가장 긴 구간: 2 days 19:06:20.131132
  • Unblocked
    • 가장 짧은 구간: 0 days 04:30:12.032881
    • 가장 긴 구간: 17 days 21:03:52.563561
  • 제재 유저들은 밤, 시간대에 많이 플레이하는 경향이 있음

⚠️ 주어진 데이터에서 캐릭터별 10개씩의 스냅샷 로그가 연속적인 것인지 중간에 누락된 것들이 있는 것인지 알 수 없음

  • [표 6]과 같이 캐릭터 별 로그 기록 구간을 확인할 수 있음.
  • 제재되는 경우는 대부분이 당일에 발생하는 경우가 대부분임

 

2.8. 결측치 확인 및 기타

  • Null, Na는 존재하지 않음
  • 누적 카운트가 없음 - 아래의 5개 컬럼은 누적된 데이터가 없어서 제외하여도 무방하다고 판단
    • socialBooleanB
    • accountMetaAmountA
    • charSessionAmountB
    • tradeSessionAmountC
    • tradeSessionAmountE
  • 설명이 없음 – 컬럼에는 있는 데이터지만 제공받은 ReadME.txt에서는 설명이 되어 있지 않음
  • 정체를 알 수 없는 데이터는 사용하지 않는 것이 맞으나 컬럼명으로 유추해 보아 움직임과 메타정보과 관련된 데이터라고 추정되어 그냥 사용하기로 함
    • charSessionAmountD
    • charMoveSessionAmountA

 

2.9. EDA를 통해 알아낸 것, 알아내지 못한 것

  • 데이터 종류
    • 해당 로그 데이터는 XXXXX에서 서비스 중인 XXXXX의 로그로 예상됨
    • 201X-XX-22에 XXXXX 신규 직업이 업데이트되고 XXXXX가 업데이트되기 전의 37개의 직업이 존재할 때의 로그로 예상됨
  • 레벨
    • 각각의 캐릭터마다 레벨 10, 30, 60, 100 구간마다 전직 이벤트가 있음
  • 로그
    • 로그 간격이 30분이 넘어선 31~40분 등의 경우 그 사이 재접속한 것으로 판단됨
    • 제공되는 데이터의 10개의 로그 시점이 연속적인 것인지? 중간에 누락되는 기록이 있는지?
    • 어뷰징 중이라고 판단되는 시점에만 30분 간격으로 로그 찍히는 것인지? 접속 후 매 30분마다 기록되는 것인지?
  • 제재 판단
    • 해당 로그 시점으로 어뷰징이라 판단되면 로그 앞뒤로 blocked으로 기록되는가?
    • 제공 데이터 기준으로 마지막 시점 기준으로 어뷰징이면 앞의 로그도 blocked=1으로 변하는가?
    • 제재 대상이라고 판단되는 순간부터 blocked=1으로 판단되는가?

 

3. 데이터 전처리(Data Preprocessing)


3.1. 교차 검증(Cross Validation)

  • 주어진 테스트 데이터셋에는 제재/비제재 관련 정보가 없음. 따라서, 자체적으로 모델을 평가할만한 검증시스템이 준비되어야 함. 크게 Hold-out 방식과 k-fold 방식으로 나뉨

 

3.2. 전처리 – 범주형 변수

  • 주어진 데이터들이 대부분 행동기록 관찰된 현상을 수치적으로 표현한 데이터라 one-hot encoding 등의 기법이 필요 없음
  • 스냅샷 로그 시점(logging_timestamp)의 경우 우선은 제외하고 진행

 

4. 변수 생성(Feature Engineering)


4.1. 변수의 사칙연산

  • 차원이 증가함에 따라 모델의 성능이 안 좋아지는 현상이 있음
  • 관련이 있는 변수들을 더하거나 곱하는 등의 합치는 방법이 있음
    • tradeSessionAmountA, tradeSessionAmountB, tradeSessionAmountD
      • tradeSessionAmount으로 합침
    • logging_timestamp에서 시간단위로 새로운 컬럼 추가
    • charSessionAmountC, actionSessionAmountM 제거
    • socialSessionAmountB

 

4.2. 변화량 (레벨, 스킬사용 횟수 등)

  • 통상적인 범주 내의 경험치 습득량 및 스킬 연속 사용 횟수 등에 대한 변화량을 구간으로 수치병 변수
  • 10건의 연속적인 로그일 경우 4시간 반이 소요, 4시간 반을 기준으로 레벨 변화폭 (미적용)

 

5. 모델(Model)


5.1. Random Forest Classifier

  • 다수의 decision tree를 학습하는 앙상블 기법임
  • 제재/비제재를 예측하는 Binary Classificaion 문제이므로 그중 대표적인 Random-Forest를 이용함
  • 학습데이터의 20%를 Validation Set으로 사용함

5.2. XGBoost

  • 미적용

5.3. LightGBM

  • 미적용

 

6. 결론(Conclusion)


  • 제재에 대한 recall을 높으나 precision이 낮아 신뢰하기가 힘들며, 비제재에 대한 recall은 많이 낮지만 precision은 조금 높은 편임. Accuracy는 85.25%%로 나타남