RのWeb制作

Webサービス制作のための技術情報を。データ分析(Python、機械学習コンペ他)や自作野球ゲームMeisyoのこと中心。

データサイエンス 監督たちの甲子園 データ分析

監督たちの甲子園(v1.3.5) 新規ユーザー分析

投稿日:2025年3月30日 更新日:

私は運営するゲームの分析を日常的に行い、機能の改善を行っています。
元々ゲーム運営のアナリスト(コンサルタント)をしていたので、ゲームの分析はチョットワカルかもしれません。

今回は、ゲームの状況をかんたんに確認するために、新規ユーザーの継続率を分析していきます。

前提

・Unity Analyticsで分析した結果です。
Unity Analytics > SQL データエクスプローラーを利用しています。
SQLの種類はPostgreSQLベースに見えます。

・全ユーザーは含んでいないログです。
(上手く取れないユーザーがかなりいる模様…)

・SQLコードを公開します。
自身のゲームの分析などにご自由にお使いください。

分析したゲームはこちら

監督たちの甲子園 世紀の逆転劇

新規ユーザーの分析

まず、分析するにあたって対象ユーザーと指標を確認しましょう。

対象ユーザー

新規ユーザーとは、ゲームを開始してすぐのユーザーのことです。
※対して、既存ユーザーはゲームを開始して何日か経過して継続しているユーザーのことを言います。

指標:継続率

継続率は、対象となるユーザーが、対象となる経過日(24時間以内)にログインしている割合を確認します。

継続とは、
DAY1であれば、新規登録後24~48時間にログインしている人をいいます。
DAY3であれば、新規登録24*3~24*(1+3)時間にログインしている人、
DAY7であれば、新規登録24*7~24*(1+7)時間にログインしている人、
DAY14であれば、新規登録24*28~24*(1+14)時間にログインしている人、
DAY28であれば、新規登録24*28~24*(1+28)時間にログインしている人です。
※DAY1, 3, 7, 14, 28の日の区切りはゲームや会社によって変わります。

この指標は「毎日ログインすることが当たり前のゲーム」で採用されやすいです。
毎日プレイすることが必須ではない場合、以下の継続率(Week版)のような指標を入れてみることがあります。

指標:継続率(Week版)

継続率(Wide版)は、継続の判定幅を広くした継続率のことです。

継続(Week版)とは、
DAY1であれば、新規登録後24~24*(1+7)時間にログインしている人をいいます。
つまり、1日後から1週間以内にログインしている人を示します。

この指標は「毎日ログインすることが当たり前ではないゲーム」で採用されます。
「1週間に1回は触ってもらえるよね」ってことです。
これは分析の都合上、「ユーザーがゲームから離脱したかどうか」を厳密に判定できないため、かなり幅を持たせて分析をしています。
分析するサービスによって変わるので、調整して使ってみてください。

分析:バージョン別継続率

それでは、ゲームの分析を行ってみます。

ゲームはバージョンアップにより内容が様変わりするため、「継続率を取るにはバージョン別が良いだろう」ということでバージョン別に分析を行います。
加えて、特定のプラットフォーム(iOS/Android/PCなど)に異常がないことを確認するために、プラットフォーム別にも分析します。「プラットフォームの継続率が大きく違う」ことは、異常があると判断できます。

分析からわかること1

では、継続率を見ていきましょう。
初期バージョン(v1.0、v1.1、v1.2)はそれほど指標が変わりません。

テコ入れしたv1.3_1は指標が大きく改善しています。これは良いアップデートだったと言えるでしょう。
ただ、さらにテコ入れしたv1.3_2は初期バージョンより下がっています。これはよろしくないので、元に戻しましょう。

という、数字からゲーム内に何が起こっているかを想像しながら見ていく必要があります。

分析からわかること2

では、プラットフォーム別に見ていきましょう。

・iOSが良さげかも?
・Androidは要改善
・PCは人がいない
※加えて、完全オフラインではログが取れない仕組みなので実態が不明なユーザーもいます。

こちらの数値と外部データを見比べてみると面白いことがわかります。
・App Store(iOS)とGoogle Play(Android)の登録数から、ログが取れないユーザーがいそう。
・App Storeのアプリ保持数は200超だが、Google Playは100いくかどうか。
Google Playユーザーのほうがアプリを消す傾向にあると言えるでしょう。このゲームは400MB近く容量ありますからね…。

分析からわかること3

1日後継続しない人は、1週間にわたって観察してもほぼ継続しないことが読み取れます。DAY1とDAY1(WEEK版)の数値がほぼ同じですし。

ただ、3日後以降はユーザーは思い思いにログインしているようです。なぜなら、DAY3の1日間だけログイン割合より、DAY3~10の間のログイン割合が大きく伸びているからです。
つまり、平均的なユーザーはこのゲームに対してどのような接し方をしているか推察できます。

このデータから追加で、深掘りとして「毎日ログインしているひと」「たまにログインしているひと」の人数を確認して、それぞれに合わせた施策を打つ等を考えていけますね。

分析コード

当ゲームはバージョンの記載方法にCLIENT_VERSION=「X.X.X」を採用しているため、複数バージョンをVERSION_GROUPにまとめています。
ある程度ユーザー数がいないと分析できないので、複数バージョンをまとめるようにしてください。

-- ユーザーIDごとのゲーム開始時間
WITH user_first_start AS (
  SELECT 
    USER_ID
    ,time_start
    ,PLATFORM
    -- バージョンごとに切り分け
    ,CASE
        WHEN CLIENT_VERSION LIKE '1.0.%' THEN 'v1.0.X'
        WHEN CLIENT_VERSION LIKE '1.1.%' THEN 'v1.1.X'
        WHEN CLIENT_VERSION LIKE '1.2.%' THEN 'v1.2.X'
        WHEN CLIENT_VERSION LIKE '1.3.%' THEN 
            CASE
                WHEN CLIENT_VERSION <= '1.3.3' THEN 'v1.3_1'
                WHEN CLIENT_VERSION <= '1.3.5' THEN 'v1.3_2'
                ELSE 'v3_3'
                END
        ELSE 'others'
    END AS VERSION_GROUP
  FROM
    (
        SELECT 
            USER_ID
            ,EVENT_TIMESTAMP AS time_start
            ,PLATFORM
            ,CLIENT_VERSION
            ,ROW_NUMBER() OVER (PARTITION BY USER_ID ORDER BY EVENT_TIMESTAMP ASC) AS rn
        FROM
            EVENTS
    ) AS t
  WHERE
    rn = 1

)
-- 継続率
, user_retention AS (
  SELECT
    fs.USER_ID
    ,fs.time_start
    ,fs.PLATFORM
    ,fs.VERSION_GROUP
    -- 通常判定版(1day内)
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 1, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (1 + 1), fs.time_start)
         THEN 1 ELSE 0 END) AS day1
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 3, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (1 + 3), fs.time_start)
         THEN 1 ELSE 0 END) AS day3
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 7, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (1 + 7), fs.time_start)
         THEN 1 ELSE 0 END) AS day7
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 14, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (1 + 14), fs.time_start)
         THEN 1 ELSE 0 END) AS day14
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 28, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (1 + 28), fs.time_start)
         THEN 1 ELSE 0 END) AS day28
    -- 判定広め版(1week内)
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 1, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (7 + 1), fs.time_start)
         THEN 1 ELSE 0 END) AS day1_w
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 3, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (7 + 3), fs.time_start)
         THEN 1 ELSE 0 END) AS day3_w
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 7, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (7 + 7), fs.time_start)
         THEN 1 ELSE 0 END) AS day7_w
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 14, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (7 + 14), fs.time_start)
         THEN 1 ELSE 0 END) AS day14_w
    ,MAX(CASE WHEN
          e.EVENT_TIMESTAMP > TIMESTAMPADD(HOUR, 24 * 28, fs.time_start)
          AND e.EVENT_TIMESTAMP <= TIMESTAMPADD(HOUR, 24 * (7 + 28), fs.time_start)
         THEN 1 ELSE 0 END) AS day28_w
  FROM
    user_first_start AS fs
  INNER JOIN
    EVENTS AS e
  ON
    fs.USER_ID = e.USER_ID
  GROUP BY
    1, 2, 3, 4
)

-- 日別分析
SELECT
  VERSION_GROUP
  ,PLATFORM
  ,DATE(MIN(time_start)) AS date_min
  ,DATE(MAX(time_start)) AS date_max
  ,COUNT(*) AS count_uu
  ,SUM(day1) / COUNT(*) AS rate_day1
  ,SUM(day3) / COUNT(*) AS rate_day3
  ,SUM(day7) / COUNT(*) AS rate_day7
  ,SUM(day14) / COUNT(*) AS rate_day14
  ,SUM(day28) / COUNT(*) AS rate_day28
  ,SUM(day1_w) / COUNT(*) AS rate_day1_w
  ,SUM(day3_w) / COUNT(*) AS rate_day3_w
  ,SUM(day7_w) / COUNT(*) AS rate_day7_w
  ,SUM(day14_w) / COUNT(*) AS rate_day14_w
  ,SUM(day28_w) / COUNT(*) AS rate_day28_w
FROM
  user_retention
GROUP BY
  1, 2
ORDER BY
  1, 2;

さいごに

今日はかんたんに、新規ユーザーの継続率からゲームの現状を分析しました。
「もっと知りたい」「○○ってどう分析すればいいの?」というコメントをいただければ、記事を書いていきたいと思います。
ぜひコメントくださいませ。( ^^)/

-データサイエンス, 監督たちの甲子園, データ分析

執筆者:


  1. […] DL数の伸びが落ちてきたため分析をしたら、、いまいちな結果(監督たちの甲子園(v1.3.5) 新規ユーザー分析)に。想定ユーザーの背景情報&ユーザーコメントを踏まえて、アップデートを行 […]

comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

【教材紹介】入門統計的因果推論

因果を推定することはビジネスにとってもインパクトがあります。 今回は、UCLAで教えられている因果推論の講義をまとめた、因果推論を使うための前知識として非常に重要な1冊を紹介します。 名称 入門統計的 …

決定木分析(Python CHAID)を解釈する

意思決定のために使用される決定木分析 Scikit-learnでの決定木にはCART(指標:giniまたはentropy)他が採用されています。 CARTは下記の2点を含め、さまざまな理由から使われて …

分析スキルも大事だけど、思考法の方が大事だよっていう話

データサイエンス関連の仕事をしていて思うのは、 分析スキルも大事だけど、思考法の方が大事だよっていう話です。 最近、会社で教育・OJT関連の業務をしていて切に思うので、つらつらと書いていきます。 まず …

【教材紹介】数理モデル入門

本当にそのモデルでいいんですか? データ分析を活用する数理モデルにはいろいろな種類があります。ただ、問題設定に合わないモデルが設定されていることがままあります。今回紹介する書籍では、体系的に数理モデル …

【教材紹介】データ解析の実務プロセス入門

「データ分析を会社で初めて行いたい」「データ分析を任されたがどうすればいいかよく分からない」というときはこちらの書籍がおすすめ。良いデータ分析を構成する分析プロセスからデータの収集方法、探索的データ解 …