メインコンテンツに移動
デベロッパーのためのクラウド活用方法
AWS for Games logo featuring a white game controller icon and the text 'AWS FOR GAMES'.

実践 ! 機械学習でゲームの休眠ユーザーを予測してみよう

2023-07-03 | Author : Sheng Hsia Leng, 保里 善太

はじめに

ゲームをこよなく愛する皆さん、こんにちは ! Game Solutions Architect の Leng (@msian.in.japan) と Partner Solutions Architect の Zen (@HoriZenta) です。

前々回前回 とゲーム分野に AI/ML を活用するための概要をお話ししました。特に 前回 は AI/ML の活用ステップを理解していたくだために「ユーザー離脱予測」をベースに「何を準備して」「どのように作っていくのか」を 3 つのステップでお伝えしました。今回は前回の記事をもとに実際に機械学習モデルを作ってユーザー離脱予測を実践してみましょう。また、ユーザー離脱予測モデルから、ユーザー離脱の要因分析をする方法にも触れます。


X ポスト » | Facebook シェア » | はてブ »

builders.flash メールメンバー登録

毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。 
今すぐ特典を受け取る »

AWS for Games

AWS for Games はより早い開発、よりスマートな運営、そしてより楽しいゲームへの成長という BuildRunGrow の 3 つの柱に沿ってサポートします。本日は Grow の柱、中でもゲームの運営に重要なゲーム分析と AI/ML に焦点を当てています。

ゲーム運営上、ユーザーのゲーム継続率を維持するために、ユーザーの休眠や離脱を事前に予測しそれに対して効果的な対策を行うことは重要です。例えば、事前に予測したゲームをやめそうなユーザーに対してはアイテムを付与したり特定のイベントに招待する通知を送り離脱を阻止する対策が考えられます。

また、後ほど述べるようにユーザー離脱の要因分析を行うことで、ユーザーが継続しやすいゲームシナリオへ改善する対策も取ることができます。

A diagram showing the stages of game development using AWS: Build (クラウドゲーム開発), Run (ゲームサーバー, ゲームセキュリティ, ゲーム向けデータベース), and Grow (LiveOps, ゲーム分析, AI & ML), with Japanese text and relevant icons.

どうやるのか ?

ここでは、潜在的な休眠ユーザーの予測に Amazon SageMaker Studio と AutoGluon という機械学習ライブラリを利用します。AutoGluon は Amazon が提供する AutoML ライブラリであり、ここでは表形式のデータを推論するための AutoGluon-Tabular を利用します。Amazon SageMaker Studio の環境セットアップについては こちらのブログ を参考にしてください。 

また、機械学習にはデータが必要です。今回は、とあるゲームデータをサンプルとして利用します。それぞれのデータはデータベースに保存されているものを CSV ファイルとして出力してあります。

ここでは一般的なゲームプロダクトの運営でよく取得されている時系列ベースのユーザー行動を記録したゲームログ (プレイログ) とユーザーのサマリー情報を持つ二種類のデータを用います。ゲームログは目的に応じて、gameplay テーブルと sales テーブルと login テーブルに分かれています。ユーザーのサマリー情報は、user テーブルに保存されています。

データの詳細は、「今回用いたデータの説明」を参照してください。

前提条件を決める

今回は一定期間プレイヤーの行動を監視して、そのユーザーが継続してゲームをプレイし続けるか否かを推定します。ユーザー行動の分析には、通常ゲームサーバーに保存されるゲームログ (プレイログ) を利用します。

今回は 1 ヶ月間の行動ログを元に 3 ヶ月後 (ここでは便宜上 90 日後) の月のアクティブユーザーと休眠ユーザーを予測することにします。

A Japanese-language visual diagram showing the process for forecasting active and dormant game users over three months. The diagram uses illustrated calendars and AWS for Games branding to depict the monitoring of player actions and subsequent prediction of user behavior in games.

行動ログについて

行動ログはデータベースに保存されており、それぞれ gameplay テーブルと sales テーブルと login テーブルに分かれています。これらは時系列のデータとして保存されているので、ユーザー毎に集計した後、テーブルを Join して一つの行動ログとして準備します。学習に用いるユーザー行動ログの期間は 2021/9/1 - 2021/9/30 の 30 日間とします。
An example illustration showing how gameplay, sales, and login tables in game data are joined into a single table with unified user metrics. The diagram includes labeled tables with user statistics and demonstrates data integration for game analytics. AWS for Games branding appears in the lower right corner.

ユーザー離脱予測

ユーザー行動を監視してから 90 日後、つまりこの場合 2021/11/30 以降にユーザーがアクティブかどうかを分析してラベル付けを行い教師データとします。

アクティブなユーザーについてはサマリー情報を持つ user テーブルを使って分析します。user テーブルには通常 lastLoginTime のようなユーザーの最終ログイン日時が記録されたカラムが存在するからです。

これを用いて、 2021/11/30 以降でもログインしているユーザーを継続ユーザー (churn = False) と定義し、ログインしていないユーザーを離脱ユーザー (churn = True) と定義してフラグを追加します。そして上で用意した行動ログのユーザー ID と突き合わせ、各ユーザーの行動データに対して churn フラグ列をマージすることでラベル付けを行い、教師データを完成させます。

ここで完成した教師データの最後の列、churn フラグ列の True / False を予測することが今回の機械学習モデルの目的です。

なお、今回は休眠ユーザーの予測の大まかなプロセスを理解していただくことが目的ですので、予測の精度をチューニングして深く追い込んでいくようなことはしません。

A data table showing game user metrics for churn prediction, including playTime, progress, enemy counts, purchases, userId, and the churn prediction column, with Japanese annotation and AWS for Games branding.

セットアップ

さて、それでは Amazon SageMaker Studio を開いて、実際に手を動かしてユーザー離脱予測モデルを構築してみましょう。

こちらのチュートリアルでは、SageMaker Studio のインスタンスタイプとして ml.m5.xlarge を利用することをお勧めします。事前に ml.m5.xlarge が選択されているかご確認ください。

AutoGluon をインストールします。SageMaker Studio ノートブックで Python 3 (MXNet 1.8 Python 3.7 CPU Optimized) のカーネルが選択されていれば、以下のコマンドだけでインストールが可能です。インストールの詳細については こちら をご参照ください。Jupyter 環境では、冒頭に ! を付けることでコマンドを実行できます。

AutoGluon をインストール

コマンド

bash
!pip install autogluon

ライブラリをインポート

このノートブックで使用するライブラリをインポートします。

python
# AutoGluonをインポートする。
from autogluon.tabular import TabularDataset, TabularPredictor

# その他のライブラリをインポートする。
import pprint
import os
from IPython.display import display
from IPython.display import HTML
import pandas as pd
import numpy as np
import datetime

データのダウンロード

今回こちらのチュートリアルで使用するゲームのデータをダウンロードします。

bash
!wget https://gametech-cfn-templates-public.s3.amazonaws.com/dataset/game_data_sample.zip

zip を解凍

データは zip で圧縮されているので解凍します。

bash
!unzip -qq -o "game_data_sample.zip"

ベースディレクトリとして設定

解凍後に game_data_sample というディレクトリが作成され、その中に諸々の CSV データが保存されています。ファイルパスのベースディレクトリとして設定しておきます。

python
# ゲームデータ保存先のディレクトリ
basedir = 'game_data_sample'

前処理・データの準備

行動ログの分析と前処理

学習と予測に用いるプレイヤーの行動ログを用意します。先ほども述べたように学習と予測に用いるユーザー行動ログの期間は 2021/9/1 - 2021/9/30 の 30 日間ですので、データサンプリング期間 (Time Window) を下記のように設定します。

python
# 今回の行動ログのサンプリング期間
window_start = '20210901'
window_end = '20210930'

ユーザー毎の集計

行動ログは時系列のログとして login テーブル、gameplay テーブル、そして sales テーブルに分かれてデータベースに保存されていますので、まずはそれぞれのテーブルに対してユーザー毎の集計を行います。

データサンプリング期間をユーザー単位でグルーピングした後、各ユーザーのログイン回数やシナリオの進捗状況、アイテム課金額などを集計します。最後に集計した 3 つのテーブルを Join (結合) して一つの行動ログを作ります。

ログインデータの処理

次の処理は login テーブルを CSV ファイルから読み込んで、データサンプリング期間内での各ユーザー毎のログイン回数を集計しています。

A Japanese instructional graphic for the .head() function, featuring a cartoon witch character holding a book, a lightbulb icon, and the AWS for Games logo. The text explains how to extract the first 5 data entries.

ログインデータ集計のためのコード

コード

python
login_data = pd.read_csv(os.path.join(basedir, 'login.csv'))
login_data['loginTime'] = pd.to_datetime(login_data['loginTime'], format='%Y/%m/%d %H:%M:%S')
login_data = login_data[(pd.to_datetime(window_start, format='%Y/%m/%d', utc=True) <= login_data['loginTime']) & (pd.to_datetime(window_end, format='%Y/%m/%d', utc=True) >= login_data['loginTime'])]
login_data = login_data.groupby('userId').count()
login_data = login_data.rename(columns={'loginTime':'loginCount'})
login_data.head()

ゲームプレイ結果を集計

次の処理では gameplay テーブルを CSV ファイルから読み込んで、データサンプリング期間内での各ユーザー毎のゲームプレイ結果を集計しています。集計前に id カラムやアイテム名など休眠ユーザーの予測に寄与しないカラムは予め削除しています。

A data table showing statistics for dormant game users, including user ID, playTime, progress, enemies defeated in stages, and experience gained.

ゲームプレイ結果集計のためのコード

コード

python
gameplay_data = pd.read_csv(os.path.join(basedir, 'gameplay.csv'))
gameplay_data['startTime'] = pd.to_datetime(gameplay_data['startTime'], format='%Y/%m/%d %H:%M:%S')
gameplay_data = gameplay_data[(pd.to_datetime(window_start, format='%Y/%m/%d', utc=True) <= gameplay_data['startTime']) & (pd.to_datetime(window_end, format='%Y/%m/%d', utc=True) >= gameplay_data['startTime'])]
gameplay_data = gameplay_data.drop(['id', 'startTime', 'dungeonId', 'result', 'friendId', 'userCharacterId', 'userCharacterName', 'userWeaponId', 'userWeaponName', 'userSkinId', 'userSkinName'], axis=1)
gameplay_data = gameplay_data.groupby('userId').agg({'playTime': np.sum, 'progress': np.mean, 'enemies1': np.sum, 'enemies2': np.sum, 'enemies3': np.sum, 'enemies4': np.sum, 'enemies5': np.sum, 'gainExp': np.sum})
gameplay_data.head()

売上データの処理

次の処理では sales テーブルを CSV ファイルから読み込んで、データサンプリング期間内での各ユーザーのアイテム購入数や課金額を集計しています。こちらも集計前に id カラムやアイテム名など休眠ユーザーの予測に寄与しないカラムは予め削除しています。

A table showing dormant game user purchase data, including user IDs, item prices, number of purchases, and total price per user.

売上データ集計のためのコード

コード

bash
sales_data = pd.read_csv(os.path.join(basedir, 'sales.csv'))
sales_data['purchasedTime'] = pd.to_datetime(sales_data['purchasedTime'], format='%Y/%m/%d %H:%M:%S')
sales_data = sales_data[(pd.to_datetime(window_start, format='%Y/%m/%d', utc=True) <= sales_data['purchasedTime']) & (pd.to_datetime(window_end, format='%Y/%m/%d', utc=True) >= sales_data['purchasedTime'])]
sales_data = sales_data.drop(['id', 'purchasedTime', 'store', 'itemId', 'itemName'], axis=1)
sales_data = sales_data.groupby('userId').agg({'price': np.sum, 'purchaseNum': np.sum, 'totalPrice': np.sum})
sales_data.head()

データの結合

最後に集計した gameplay テーブルと login テーブルと sales テーブルを結合して一つのデータとしてまとめます。

Illustration of a wizard character holding a book with Japanese text explaining the .fillna() function for handling missing data values, and the AWS for Games logo in the corner.

データ結合のためのコード

コード

bash
data = pd.merge(gameplay_data, sales_data, on='userId', how='left')
data = pd.merge(data, login_data, on='userId', how='left')
data = data.fillna(0)
data.head()

ユーザー行動ベースログの作成が完了

これでデータサンプリング期間内におけるユーザーの行動ベースのログを作成することができました。このデータを学習させてモデルを作ります。

ただ、この時点では、各ユーザーの行動結果に対してそれが離脱につながるのか、継続につながるのかを判別する正解ラベルが付与されていません。そこで次に、教師あり学習の学習用データを作成するために、得られた行動ログに正解ラベルをラベリングしていきます。

行動ログにラベル付を行い教師データの完成

ここでは先ほど得られた行動ログに対して、実際に 90 日後にログインしているユーザーとそうでないユーザーに対して正解のラベル付けを行います。

ここで休眠ユーザー予測の目的をもう一度確認しておきましょう。今回の目的は 1 ヶ月間の行動ログを元に3ヶ月後 (便宜上 90 日後) の月のアクティブユーザーと休眠ユーザーを予測することでした。

ユーザーがアクティブか非アクティブかはユーザーのログイン履歴から確認します。各ユーザーの最終ログイン履歴を確認するには user テーブルを見ると分かります。user テーブルを俯瞰してみましょう。

ユーザーのログイン履歴から確認

スクリプト

python
user_data = pd.read_csv(os.path.join(basedir, 'user.csv'))
user_data.head()

churn 列を追加

最後の列に lastLoginTime というカラムがあり、これが各ユーザーの最終ログイン日時を表しています。先頭の id カラムがユーザーIDを表しています。このテーブルにユーザー離脱の有無を表す churn 列を追加します。

A screenshot of a data table displaying user statistics for a game, including userName, totalTime, releasedDungeonId, level, clearTotalNum, coin, totalExp, friendsNum, startTime, and lastLoginTime. The table is used to help forecast dormant or inactive users in the game.

churn フラグの設定

ユーザー休眠の定義に基づいて 2021/11/30 以降のログインが確認できないユーザーを休眠ユーザー (離脱ユーザー) として churn フラグを True に設定します。それ以外のユーザーは 2021/11/30 以降のログインが確認できるのでアクティブユーザーとして churn フラグを False に設定しています。

python
# 行動ログの観測から90日後にActive/Inactiveユーザーをチェック
activity_check_interval = 90

# timestampをdatetime型に変換
user_data['startTime'] = pd.to_datetime(user_data['startTime'], format='%Y/%m/%d %H:%M:%S')
user_data['lastLoginTime'] = pd.to_datetime(user_data['lastLoginTime'], format='%Y/%m/%d %H:%M:%S')

# 90日以降にアクティブでないユーザーのChurnフラグをTrueとする
user_data.loc[pd.to_datetime(window_start, format='%Y/%m/%d', utc=True) + datetime.timedelta(days=activity_check_interval) > user_data['lastLoginTime'], 'churn'] = True

# それ以外のユーザーは1ヶ月後でもアクティブにログインしているのでChurnはFalse
user_data['churn'] = user_data['churn'].fillna(False)
user_data.head()

churn カラムの追加完了

実行すると先ほどの user テーブル に対して churn カラムが追加され、ユーザーの最終ログイン日時に応じて True/False フラグが追加されています。

A table displaying game user activity data including user IDs, usernames, total play time, released dungeon IDs, levels, cleared dungeons, coins, total experience, friend count, start time, last login time, and churn status.

churn フラグのラベリング

ここままで 2021/9/1 - 2021/9/30 の 30 日間のユーザーの行動データの集計結果 (data) と各ユーザーが 2021/11/30 以降に休眠しているかアクティブなのかのデータ (user_data) が出揃いました。これらは別々のテーブルに存在しているので、最後にユーザー ID を突き合わせて各ユーザーの行動データに対して churn フラグを正解データとしてラベリングします。

python
data = pd.merge(data, user_data[['id', 'churn']], left_on='userId', right_on='id', how='left')
data = data.rename(columns={'id':'userId'})
data.head()

行動ログが完成

ユーザーの行動ログに対して、一番右側に churn カラムが追加され、正解ラベルつきの行動ログが完成したことがわかります。

なお、右から二番目にある userId カラムは単なるユーザー ID であり、特徴量としては休眠ユーザーの予測に寄与しませんが、どのユーザーが離脱するかを予測した結果を分析する際にユーザー ID があった方が運用上便利ですのでデータの中に残してあります。

Table image showing a dataset with columns for play time, progress, enemies, experience gained, purchase history, login count, user ID, and churn status for game users.

学習用データと検証用データの用意

正解ラベルつきの行動ログを学習用データと学習後のモデルの精度を検証するための検証用データに分割します。ここでは、学習用データ:検証用データを 7 : 3 の割合で分割しています。

python
# 学習とテストデータに分割する。
train_data = data.sample(frac=0.7, random_state=42)
test_data = data.drop(train_data.index)

# テストデータの入力と出力を分割する。
label_column = "churn"
y_test = test_data[label_column]
X_test = test_data.drop(columns=[label_column])

コードの解説

An illustration featuring a cartoon wizard character with a book and a lightbulb, explaining the use of the .sample() function in Japanese. The text describes extracting an element at random, and the image includes 'AWS FOR GAMES' branding.

.sample()

An illustrated guide in Japanese showing the use of the Python .drop() function to specify and remove rows or columns, featuring a cartoon character in a green wizard costume holding a book with a lightbulb above their head, and an 'AWS for Games' logo. The Japanese text reads: '.drop() 行・列を指定して削減する' which means '.drop() Specify and delete rows or columns.'

.drop()

カラムの頻度を確認

今回予測するターゲットは、潜在的な休眠ユーザーで行動ログの一番右列の churn カラムです。このカラムの頻度を確認しておきましょう。

python
print("ターゲット変数の値と頻度: \n", train_data[label_column].value_counts().to_string())

churn カラムの頻度を確認

 churn カラムの頻度が True : False = 5750 : 5129 となっており、どちらかの値に偏っていたり数が少なすぎるわけでもなく、学習に適しているデータであることがわかります。

Screenshot of Python code and output in Japanese showing value counts for a target variable. The code uses train_data[label_column].value_counts().to_string() to display the frequency of True and False labels (True: 5750, False: 5129) in Japanese.

AutoGluonを使って学習を開始

さて、いよいよ学習プロセスになります。ここで初めてAutoMLである AutoGluon-Tabular の威力が発揮されます。

料理で言えば実際に火を通して調理するプロセスになります。それまではいわばデータの下拵えでした。

Cartoon illustration of two robots chopping vegetables and a girl in a green wizard costume stirring a cauldron, with an AWS for Games logo. Represents forecasting dormant users in games.

学習を開始

データと予測したいカラム名、モデルを保存するパスを指定して fit() メソッドを実行すると学習を開始します。

python
# 学習したモデルを保存するディレクトリを指定する。
dir_base_name = "churnModels"
dir_best = f"{dir_base_name}_best"

精度を優先してモデル構築

デフォルトでは精度とコスト (メモリ使用量、推論速度、ディスク容量等) においてバランスが取られた設定となっていますが、今回は精度を優先してモデル構築をしたいので、 fit() メソッドの引数で presets='best_quality' を指定します。

python
%%time
predictor = TabularPredictor(label=label_column, path=dir_best).fit(train_data=train_data, presets='best_quality')

学習の出力

実行を開始すると学習状態が色々と表示されます。その中で

AutoGluon infers your prediction problem is: 'binary' (because only two unique label-values observed).

というような記述があり AutoGluon が自動で今回のタスクは True/False の二値分類問題であると推論したことがわかります。私の環境では 32 秒ほどで学習が終了しました。

Screenshot showing the terminal output of an AutoGluon churn model training process, including environment details, dataset info, and feature generator steps.

モデルの性能評価

晴れて学習が終わりモデルが作成されました。ここでは先ほど作成した検証用データを用いて、このモデルの精度を確認してみましょう。

先ほどの fit() メソッドの実行結果とモデルを predictor という変数に格納しました。これは AutoGluon の TabularPredictor オブジェクトになっていて、predict() というメソッドで予測をしたり、evaluate_predictions() というメソッドで性能を確認することができます。

モデルの精度を確認

コード

python
y_pred = predictor.predict(X_test)
perf = predictor.evaluate_predictions(y_true=y_test, y_pred=y_pred, auxiliary_metrics=True)
print("Predictions:\n", y_pred)

評価の出力

実行するとモデルの精度と検証データに対して実際に True/False を予測した結果が表示されます。
A screenshot displaying model evaluation metrics and churn prediction results. The image includes test data accuracy, metrics such as accuracy, balanced accuracy, MCC, F1, precision, recall, and a list of predicted churn outcomes for a dataset.

混同行列で表示

機械学習ライブラリの scikit-learn を使って、検証データの予測結果を混同行列 (confusion matrix) で表示してみましょう。

A confusion matrix displaying prediction results for forecasting dormant users in a game, showing counts for true positives, false positives, true negatives, and false negatives.

混同行列で表示するためのコード

コード

python
from sklearn.metrics import confusion_matrix
# ラベルの順序を指定
labels = [1, 0]
# 混同行列の取得&ラベル順序指定
cm = confusion_matrix(y_test, y_pred, labels=labels)
# 出力を整形
columns_labels = ["pred_" + str(l) for l in labels]
index_labels = ["act_" + str(l) for l in labels]
cm = pd.DataFrame(cm, columns=columns_labels, index=index_labels)
print(cm.to_markdown())

混同行列とモデルの精度の意味

混同行列とモデルの精度の意味は、下の図をご覧ください。 これによると予測の精度としては、65 % の Accuracy (正解率) であることがわかります。ここの数値は学習の過程で場合によって微妙に変わってくると思いますが、65 % から大きく外れた数値になることはないと思います。65 % の正解率が要件に合わない場合さらにチューニングすることもできますが、これ以上の精度を求めるには追加の特徴量が必要になってくるでしょう。また Precision (適合率) が 70 % 近くと比較的高いので False Positive は抑えられていると考えられます。

学習過程の確認

モデルの学習中に何が起きていたのかを確認してみましょう。
fit_summary() メソッドを実行すると、学習の過程においてどのような探索を行ったのか確認できます。

fit_summary() メソッドを実行

コード

bash
results = predictor.fit_summary()

学習サマリーの出力

学習したそれぞれのモデルについて検証データにおける性能、学習にかかった時間などが表示されています。7 種類のモデル名が表示されており、AutoGluon が様々なモデルを学習したことが分かります。

Types of models trained というところを確認すると、StackerEnsembleModel_KNN など複数のベースとなるモデルと、それらをアンサンブルしたモデルになっています。

Screenshot of an AutoGluon fit_summary output showing the estimated performance of various machine learning models predicting dormant users in a game. The table details model scores, prediction and fit times, stack levels, and model types, with additional metadata about data features and a plot summary file reference.

モデル予測の要因分析

ここまででユーザー休眠予測モデルを作ることができました。このモデルを使えば、季節性を無視した場合、年間のどの月でも 30 日間の行動ログを元に 90 日後 (約 3 ヶ月後) のアクティブユーザーと休眠ユーザーを予測することができます。

では、実際に休眠する可能性のあるユーザーを予測した場合、どのようなアクションが取れるでしょうか?

一つは、モデルの予測に寄与した特徴量を分析することで、どのような要因でユーザーが離脱に至っているのかを推測することができます。離脱の要因になっているパラメータを調整することでゲーム離脱を阻止するゲームシナリオへと改善できるかもしれません。

下記のメソッドで計算される特徴量の重要度スコアは、スコアが高いほどその特徴量がモデルの性能に重要であると考えられます。スコアがマイナスの場合、その特徴量がモデルの性能にとってマイナスである可能性があります。詳しくは こちら をご確認ください。

Illustration for AWS for Games in Japanese, featuring a cartoon character in a wizard hat reading a book with a light bulb above their head, and explanatory text about feature importance in machine learning models.

特徴量の重要度スコアを計算

コード

python
feature_importances = predictor.feature_importance(test_data)
print("特徴量の重要度:")
display(feature_importances)

数値の特徴

importance の数値を見ると、 gainExp という特徴量が一番モデルの性能に寄与していることがわかります。gainExp は獲得経験値を表すパラメータです。獲得経験値が高ければ高いほど、ゲームへ没頭し依存していることが窺えるので、ユーザーの継続性の予測に寄与していることがなんとなく理解できますね。

次に数値が高いのが、 progress というパラメータです。progress はプレイ進捗状況 (100 % 中どこまでクリアできたか) を表すので、この数値が高いユーザーの継続率が高くなることもなんとなく予想ができます。

面白い特徴としては、enemies4、enemies5、enemies1 などの数値が特徴量重要度の上位に来ている点です。enemies4 は 4 という名前が付けられた種類の敵をプレイヤーが倒した数を表します。

Screenshot of a Python data science notebook showing feature importance analysis for predicting dormant users in a game. The table lists features such as gainExp, progress, enemies, loginCount, playTime, and purchaseNum with their calculated importance scores and statistics. The output includes code, a runtime estimation bar, and all text is in Japanese and English.

ユーザー継続率に関する考察

さらなる分析が必要ですが、例えば enemies4 を多く倒したユーザーが継続しているのに対して、 enemies4 を倒せていないユーザーが多く離脱してしまっているのだとすると、enemies4 の攻略がゲームバランス的に難しいのかもしれません。enemies4 の難易度を下げることによってユーザーの継続率が高まるかは試してみる価値はありそうです。

また、もう一つ面白い特徴としては、totalPrice や purchaseNum のスコアがマイナスになっている点です。totalPrice や purchaseNum はユーザーのゲーム内アイテムの課金額と購入数を表していますが、モデルの性能に寄与していないどころかマイナス要因になっていることがわかります。

ゲームの継続性を予測する際にアイテムの課金額と購入数が意外にも関連していないことも見えてきます。課金しているユーザーだからといってゲームの継続性を予測できないのだとすると、もしかしたらアイテムを購入してもゲームの継続に結びつかないゲームシナリオになっているのかもしれません。

A Japanese language infographic titled 'AWS FOR GAMES' presenting insights into user retention in games. It highlights that the difficulty of 'enemies4' impacts user retention rate, while the amount spent on in-app purchases does not. Includes illustrations of a red demon face and a treasure chest with gems.

まとめ

ここまで、とあるゲームログを参考にして、将来の休眠ユーザーとアクティブユーザーを予測する方法を紹介しました。ここに書いた内容はほんの入り口に過ぎませんが、少しでもユーザー離脱予測の敷居が下がれば、本記事が皆様のお役に立てたかと思います。

なお、ここで使った SageMaker Studio は停止しない限り課金が発生してしまうので、作業が終わりましたら、こちら を参考に Studio ノートブックを停止しておきましょう。

(補足) 今回用いたデータの説明

ユーザーのゲームログ

データベースには時系列ベースのユーザー行動履歴が保存されており、それぞれ記録の目的に応じて gameplay テーブルと sales テーブルと login テーブルに分かれて保存されています。

gameplay : ダンジョンでのゲームのプレイ履歴情報

カラム名

説明

id

ゲームごとの一意の UUID

startTime

開始日時

dungeonId

ダンジョン ID

userId

ユーザー ID

result

プレイ結果 (Clear or Fail)

playTime

プレイ時間 (分)

progress

プレイ進捗状況 (100 % 中どこまでクリアできたか)

friendId

フレンドのユーザー ID

userCharacterID

ユーザーの利用キャラクター ID

userCharacterName

ユーザーの利用キャラクター名

userWeaponId

ユーザーの利用武器 ID

userWeaponName

ユーザーの利用武器名

userSkinId

ユーザーの利用スキン ID

userSkinName

ユーザーの利用スキン名

enemies1

倒した敵 1 の数

enemies2

倒した敵 2 の数

enemies3

倒した敵 3 の数

enemies4

倒した敵 4 の数

enemies5

倒した敵 5 の数

gainExp

獲得経験値

sales : ユーザーが購入したアイテムの売上履歴情報

カラム名

説明

id

売上 ID

purchasedTime

購入日時

store

購入ストア

userId

ユーザー ID

itemId

アイテム ID

itemName

購入アイテム名

price

商品単価

purchaseNum

購入個数

totalPrice

合計金額

login : ゲームユーザーのログイン履歴情報

カラム名

説明

userId

ユーザー ID

loginTime

ログイン日時

ユーザーのサマリー情報

各ユーザーの最新のサマリーデータがデータベース内の user テーブルに保存されています。

user : ゲームユーザーの情報

カラム名

説明

id

ユーザー ID

userName

ユーザー名

totalTime

総プレイ時間 (分)

releasedDungeonId

開放済みダンジョン ID

level

レベル

clearTotalNum

ダンジョンクリア回数

coin

所持コイン (ゲーム内通貨)

totalExp

総獲得経験値

friendsNum

フレンド数

startTime

ゲーム開始日時

lastLoginTime

最終ログイン日時

筆者プロフィール

Anime-style illustration of a girl with big eyes, brown hair, and a pink shirt, set against a green background.

Sheng Hsia Leng

アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト

ゲーム業界に特化したソリューションアーキテクトとしてお客様を支援しております。
RPG とドット絵ゲームが好きです。オフモードの時はインスタでバイリンガル漫画を投稿しています。

A person wearing a helmet is riding a horse in a forest clearing with bare trees in the background.

保里 善太

保里 善太
アマゾン ウェブ サービス ジャパン合同会社
シニアソリューションアーキテクト

半導体関連精密機器の組み込み制御エンジニアとして研究開発のキャリアをスタートさせ、モバイルゲーム業界での開発経験、FinTech 業界でのエンジニア経験、スタートアップでの CTO 経験を生かして日々技術支援を必要としている AWS ユーザー様をサポートしています。
技術的関心はもっぱらマルチエージェントシミュレーションと機械学習とクラウドセキュリティ。0 歳の息子の子育てを楽しみながら、各地を旅行するのが現在の楽しみ。