5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS & GameAdvent Calendar 2020

Day 10

Amazon SageMaker Autopilot を利用したゲームログのチート検出

Last updated at Posted at 2020-12-10

AWS & Game Advent Calendar 2020 の10日目の記事です。

はじめに

ゲームにおけるチート行為は大変厄介なものです。チート行為を野放しにすることは、他のゲームユーザーの体験を著しく損なう上に、ゲームの運営自体にも損害を与えかねません。

しかし、これらのチート行為の検出は、従来、ゲーム運営を熟知したエンジニアが統計処理などを駆使して人力で検知を行う、非常に属人的で効率の悪いものでした。また、不正検知の自動化といっても、特定の閾値を定めただけの単純なスクリプトを流す程度の対策が取られてきました。
それなら、近年、半ば魔法の言葉となりつつある、機械学習を用いてある程度チート検出が自動化できたらどんなに効率的なことでしょう。

しかし、機械学習といっても、これまた、機械学習や統計処理を熟知したエンジニアやデータサイエンティストが必要になってきます。そのようなスキルを持ったエンジニアは、どこの会社にもいるわけではありません。

そこで、本記事では、近年注目を集めている AutoML 1 を用いた異常検知技術を使って、ゲームログからチートユーザーの検出をしてみることにします。

前提条件

利用サービス

今回利用するデータ

全てこちらの github リポジトリから参照できます。

手順の大まかな流れ

  • 擬似的なゲームログを用意してあるので、最初にそれをダウンロードします
    • ゲームログは学習用データと検証用データのデータセットに分かれています
  • 学習用のデータセットを用いて、AWSのAutoMLサービスであるAmazon SageMaker Autopilotにてログからチートを検出する機械学習モデルを作成します
  • 最適なモデルをデプロイしたあと、検証用のデータセットを用いてモデルの精度を確認します
  • 検証用のデータを運用中の新規のゲームログと見立てて、Amazon Athenaを使って作成した機械学習モデルを呼び出し、ゲームログに不正が含まれていないかを推論します

今回利用するゲームログ

今回、チート検出に利用するゲームログの内容を下記に示します。
こちらのログは、実際のゲームのログではなく、あるプログラムにより機械的に作成されたログであり、一定(全体の26%程度)のチートによる不正データを含むログとなっています。一般的なRPGやパズルゲーム、音ゲーなどのスコアや得点を伴う時系列のログを想定しています。ゲームログの内容を下記に簡単に示します。

  • player_id : プレイヤーごとに付与されている一意のユーザーID。
  • levelscore: ゲーム内でのユーザーのレベルやスキルを示す。
  • goldpotions: ユーザーの所有するゲーム内のアイテム数を示すカラム。
  • cheat_label: あらかじめゲームのイベントログが不正(チート)なのか、正常なのかラベリングしたカラム。fraudは不正を表し、チートのレコードであることを示す。 legitは正常なレコードであることを示す。
  • timestamp: 各ユーザーのアクションやイベントの発生日時。
    スクリーンショット 2020-12-10 19.21.26.png

ここで重要なのは、cheat_labelカラムに示されるように、学習用のデータセットにはあらかじめ各レコードの情報が不正なのか(fraud)、正常なのか(legit)という正解のラベリングがされていることです。これからモデルを作成する際に利用するAutoMLであるSageMaker Autopilotは教師あり学習により機械学習モデルを作成するサービスであるため、学習用データセットへの事前のラベルづけは必須になってきます。

AutoMLによる推論モデル作成手順

Amazon SageMaker Studio のセットアップ

こちらの詳細手順は割愛します。詳しくは、こちらを参照してください。

ゲームログのデータセットをダウンロード

SageMaker Studio上からnotebookを開いて下記のコードを貼り付けて実行します。今回のチート検出に使う学習用のデータセットをダウンロードします。

sh
%%sh
wget https://raw.githubusercontent.com/zentahori/sagemaker-autopilot-cheat-detection-sample/main/dataset/sample_playerlog_for_training.csv

続いて、同じように下記のコードを貼り付けて実行します。こちらは、モデル検証用のデータセットのダウンロードになります。

sh
%%sh
wget https://raw.githubusercontent.com/zentahori/sagemaker-autopilot-cheat-detection-sample/main/dataset/sample_playerlog_for_validation.csv

次に下記のコードをnotebook上で実行して、ダウンロードしたデータセットの中身を確認しておきましょう。

python
import pandas as pd
cheat = pd.read_csv('sample_playerlog_for_training.csv')
cheat[:10]
python
validation_data = pd.read_csv('sample_playerlog_for_validation.csv')
validation_data[:10]

学習用のデータセットをS3にアップロード

次に、SageMaker Autopilotでデータセットを読み込んでモデルを作成するために、一旦学習のデータセットをS3にアップロードします。下記のコードをnotebook上で実行します。

python
import sagemaker

prefix = 'sagemaker/cheat-detection/input'
sess   = sagemaker.Session()

uri = sess.upload_data(path="./sample_playerlog_for_training.csv", key_prefix=prefix)
print(uri)

こちらを実行するとアップロード先のS3バケットのURLが表示されるので、控えておきます。
あとでこちらの バケットのURLは使用します。今回使用しているS3バケットは、デフォルトのS3バケットであることに注意してください。

s3://sagemaker-us-west-2-ACCOUNT_NUMBER/sagemaker/cheat-detection/input/sample_playerlog_for_training.csv

SageMaker Autopilotによるチート検出モデルの自動作成

注意: 詳細については、こちらを参考にしてください。

SageMaker StudioのLauncherから「Build models automatically」をクリックします。
スクリーンショット 2020-12-09 23.51.53.png
AUTOPILOT EXPERIMENT SETTINGS が開くので、下記の設定値をそれぞれ入力します。

  • Experiment Name: cheat-detection-sample
  • CONNECT YOUR DATA
    • 入力の S3 bucket address: 先ほど上記の手順で表示した S3 URL
      • (例 s3://sagemaker-us-east-2-[ACCOUNT-NUMBER]/sagemaker/cheat-detection/input/sample_playerlog_for_training.csv)
    • Target: cheat_label
  • Output data location (S3 bucket)
    • 出力先のS3 bucket address: s3://sagemaker-us-east-2-[ACCOUNT-NUMBER]/sagemaker/cheat-detection/output

そのほかの値は全てデフォルトのままで、最後に Create Experimentをクリックして実験を開始します。

スクリーンショット 2020-12-10 0.26.32.png
スクリーンショット 2020-12-10 0.26.51.png

実験が開始されると、下記のようにAutopilotが自動でデータを解析して、必要な前処理や特徴量エンジニアリングやハイパーパラメータの最適化までを全て自動で実行します。
処理時間はデータ量にも依存しますが、今回のデータ量では終了までにおよそ3時間ほどかかりました。
スクリーンショット 2020-12-10 1.05.59.png

最適なモデルをデプロイする

実験完了後、 Trials タブを開くと、Experimentが様々なアルゴリズムや条件を適用して複数の異なるチューニングのモデルを作成したモデル一覧が見られます。その中で、上部に☆印付きで Best と書かれた精度の高い最適なチューニングをされたモデルがあるので、選択状態にして Deploy model をクリックします。

スクリーンショット 2020-12-10 11.12.38.png

そのまま Deploy model というタブが開くので、エンドポイントに名前を付け (cheat-detection-sampleなど)、すべての設定をデフォルトのままにします。Deploy model をクリックします。モデルが、Amazon SageMaker によって管理される HTTPS エンドポイントにデプロイされます。
スクリーンショット 2020-12-10 11.25.22.png

モデルの精度を検証する

モデルのデプロイが完了したら、検証用のデータセットを用いてモデルの精度を検証してみます。検証用のデータセットは、学習用のデータセットとは別でモデルに対しては未知のデータのはずです。
ここでは boto3 SDK の invoke_endpoint API を使用して、機械学習モデルの精度を表す重要なメトリクスである正確性、適合率、再現率、F1 スコアを計算します。

SageMaker StudioでNotebookを開き、以下のコードをコピーして貼り付け、実行します。

python
import boto3, sys

ep_name = 'cheat-detection-sample'
sm_rt = boto3.Session().client('runtime.sagemaker')

tn=tp=fn=fp=count=0

with open('sample_playerlog_for_validation.csv') as f:
    lines = f.readlines()
    # length = len(lines)
    for l in lines[1:2000]:  # Skip header
        l = l.split(',')      # Split CSV line into features
        label = l[8]          # Store 'yes'/'no' label
        del l[8]              # Remove label
        l = ','.join(l)       # Rebuild CSV line without label
                
        response = sm_rt.invoke_endpoint(EndpointName=ep_name, 
                                         ContentType='text/csv',       
                                         Accept='text/csv', Body=l)

        response = response['Body'].read().decode("utf-8")
        #print ("label %s response %s" %(label,response))

        if 'fraud' in label:
            # Sample is positive
            if 'fraud' in response:
                # True positive
                tp=tp+1
            else:
                # False negative
                fn=fn+1
        else:
            # Sample is negative
            if 'legit' in response:
                # True negative
                tn=tn+1
            else:
                # False positive
                fp=fp+1
        count = count+1
        if (count % 100 == 0):   
            sys.stdout.write(str(count)+' ')
            
print ("Done")

accuracy  = (tp+tn)/(tp+tn+fp+fn)
precision = tp/(tp+fp)
recall    = tp/(tp+fn)
f1        = (2*precision*recall)/(precision+recall)

print ("%.4f %.4f %.4f %.4f" % (accuracy, precision, recall, f1))
print ("tp:%d fn:%d tn:%d fp:%d" % (tp, fn, tn, fp))

データ2000ポイントの集計が終わると、以下のような出力が表示されます。

100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 Done
0.9995 0.9981 1.0000 0.9990
tp:525 fn:0 tn:1473 fp:1

これを表にまとめると下記のようになります。

メトリクス 数値 説明
Accuracy (正解率) 0.9995 チートあり、なしと予測したデータのうち、実際に正解したものの割合: accuracy = (tp+tn)/(tp+tn+fp+fn)
Precision (適合率) 0.9981 チートと予測したデータのうち実際にチートであるものの割合: precision = tp/(tp+fp)
Recall (再現性) 1.0000 実際にチートであるデータのうち、チートと予測されたものの割合: recall = tp/(tp+fn)
F1 スコア 0.9990 適合率と再現率の調和平均: f1 = (2precisionrecall)/(precision+recall)

スクリーンショット 2020-12-10 13.42.39.png

この表から分かるように、Recall (再現性) は100%であり、全て取りこぼしなく不正データ(チートであるとラベルされたデータ)は不正である、とこのモデルは正しく推論できていることを示しています。

Athenaを使ってゲームログからチート予測をする

Machine Learning (ML) with Amazon Athena を利用すれば、直接Athenaのクエリからチート予測の推論モデルを呼び出し、S3に保存されているログをスキャンして、チートの予測をすることが可能です。
ここでは、検証用のデータセットをS3に保存して、Athenaを用いてチート検出する手順を見て行きます。

分析データとデータソースの準備

Notebookへ下記のコードをコピーして検証用のデータセットをS3へアップロードしておきます。この際に出力された、S3のURLをメモしておきます。

python
prefix = 'sagemaker/cheat-detection/sample-data'
sess   = sagemaker.Session()

uri = sess.upload_data(path="./sample_playerlog_for_validation.csv", key_prefix=prefix)
print(uri)

Management consoleのAmazon Athenaの画面に移動して、AWS Glue Crawlerを用いて新規テーブルを作成します。 Glue Crawlerを用いたテーブルの作成詳細についてはこちらを参照してください。
スクリーンショット 2020-12-10 16.06.11.png

Glue Crawlerに cheat-detection-sample などと名前をつけて次に進みます。
スクリーンショット 2020-12-10 16.09.22.png

Add a data store のステップでは下記のように Include Pathに先ほどメモした検証用のデータのアップロード先のパスを指定します。
スクリーンショット 2020-12-10 16.52.26.png

最後にクローラーの出力先のデータベースを設定します。新規にデータベースを作成して、データベース名をcheat-detection-sampleとします。
スクリーンショット 2020-12-10 16.14.45.png

Crawlerの設定が完了したら、最後に Run crawler を実行してデータソースからテーブルを作成します。クーロールが完了するとcheat-detection-sampleという名前のデータベースとその中に sample_data というテーブルが出来上がっているはずです。
スクリーンショット 2020-12-10 16.53.04.png

モデルを使用してAthenaでチート分析を行う

さて、データソースが準備できたところで、Athenaの画面に戻りましょう。
下記のクエリをコピーして、Athenaのクエリエディタに貼り付け、クエリを実行してみます。

SQL
USING FUNCTION predict_cheating_log(player_id BIGINT, level BIGINT, score BIGINT, units BIGINT, gold BIGINT, potions BIGINT, friends BIGINT, inv_items BIGINT, timestamp VARCHAR) 
    RETURNS VARCHAR TYPE 
    SAGEMAKER_INVOKE_ENDPOINT WITH (sagemaker_endpoint = 'cheat-detection-sample') 
SELECT *, predict_cheating_log(player_id, level, score, units, gold, potions, friends, inv_items, timestamp) AS cheat
     FROM "cheat-detection-sample"."sample_data" 
     WHERE predict_cheating_log(player_id, level, score, units, gold, potions, friends, inv_items, timestamp) = 'fraud' limit 100;

実行すると、作成たモデルがチートと判断したユーザーのレコードの最初の100件を取ってきて表示します。
cheat列に記載されているのが推論によりチートと判断されたレコードです。fraud ならチート、legitなら正常です。
推論によるcheat列の結果と事前にラベルづけされた正解データを示すcheat_labelの情報が一致しいていることが確認できると思います。
スクリーンショット 2020-12-10 17.51.21.png

結果の一番最初に表示されいてるplayer_id15316のユーザーが怪しいと思えば、下記のクエリを実行して、このユーザーの行動ログを全て表示してみます。
そうすると、他の時間帯においても、常にチート行為をしていることがわかります。

SQL
USING FUNCTION predict_cheating_log(player_id BIGINT, level BIGINT, score BIGINT, units BIGINT, gold BIGINT, potions BIGINT, friends BIGINT, inv_items BIGINT, timestamp VARCHAR) 
    RETURNS VARCHAR TYPE 
    SAGEMAKER_INVOKE_ENDPOINT WITH (sagemaker_endpoint = 'cheat-detection-sample') 
SELECT *, predict_cheating_log(player_id, level, score, units, gold, potions, friends, inv_items, timestamp) AS cheat
     FROM "cheat-detection-sample"."sample_data" 
     WHERE player_id = 15316;

スクリーンショット 2020-12-10 18.03.13.png

お片づけ

最後に、今回利用したリソースを削除しておきます。SageMaker Studioのnotebook上へ下記のコードをコピーしてリソースを削除します。

python
sess.delete_endpoint(endpoint_name=ep_name)
%%sh
aws s3 rm --recursive s3://sagemaker-us-east-2-ACCOUNT_NUMBER/sagemaker/cheat-detection/
  1. AutoML (Automated Machine Learning) は、自動化された機械学習のことであり、機械学習や深層学習への深い知識がなくても強力な機械学習モデルの構築を可能にするフレームワークやサービスのこと。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?