Google Analytics で未登録と既登録のセッションを見分ける話

***本記事は [LAPRAS Advent Calendar](https://qiita.com/advent-calendar/2020/lapras) の16日目の記事です***

# はじめに

Webサービスのユーザー行動を分析するとき、Google Analytics は大変便利です。
しかしながら、GA上で少し特殊なデータ収集・分析を行うためには、多少トリッキーなテクニックが必要になることがあります。

サービスへの広告流入や登録導線におけるユーザー行動を分析するとき、既登録ユーザーと未登録ユーザーを見分けたいことがあります。
例えば、キャンペーンを開催したり新しい広告を配信したとき、本当に新規ユーザーにリーチできているのかを確認するためには、既登録ユーザーの訪問は除外して調べなければなりません。また、ユーザー登録導線の改善を行うためにデータ分析を行うとき、分母から既登録ユーザーを除外しなければ正しくCVRを測ることができません。

初訪問のユーザーでも、そのデバイスでの訪問が初めてなだけであって実は既登録の場合もあります。もっと悪いことには、そのことが判明するのはランディングページに訪問したタイミングではなくログインが完了したタイミングであるということです。
このように、サイトへの訪問ユーザーの既登録と未登録を Google Analytics で見分けることは意外と難しいです。

本記事では、Google Analytics で未登録と既登録のセッションを見分けるために工夫した点などをまとめます。
本記事で使用する Google Analytics のバージョンは 4 で GoogleTagManager と共に使用することを想定します。

# 状況と問題点

[LAPRAS](https://lapras.com) のサイト構成は概ね次のようになっています。

![スクリーンショット 2020-12-16 22.26.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309088/c65db746-400a-5983-44fc-2914dccd60b3.png)

未登録ユーザーの多くは、トップページに着地した後、その一部が離脱しつつ登録導線をStep1, Step2 と遷移して登録完了に至ります。一方、検索エンジンなどからトップページに再訪した既登録ユーザーはログインページを経てログイン済みページに遷移します。
その他にも、ログイン状態の既登録ユーザーが直接ログイン済みページを訪問する場合もあります。

また、LAPRAS では OAuth を使った認証を行っているため、登録・ログイン導線は共に外部サイトを経由します。このとき、既登録ユーザーが間違って登録導線に流入した場合や、新規登録ユーザーがログインしようとした場合、未登録・既登録の状態に応じて正しいページに遷移させるようにしています(図の破線矢印)。

このように、訪問するユーザーの種類も未登録・既登録(未ログイン)・既登録(ログイン済)の3通りがあり、さらに各ユーザーがサイト内を遷移する方法も様々です。

このような状況で、「何人の未登録ユーザーがトップページに着地し、そのうち何人が登録完了し、残りはどこで離脱したか」を調べたいとします。
何も考えずに、全セッションを母数とし、導線中の各ページを閲覧したか否かで計測した場合、

* `トップページ` → `ログイン` と遷移した既登録ユーザーが「トップページで離脱したユーザー」と判定されてしまう
* `登録Step1` → `OAuth` → `ポートフォリオ` と遷移した既登録ユーザーが「Step1で離脱したユーザー」と判定されてしまう

というように、既登録ユーザーが 「登録動線からの離脱ユーザー」 としてカウントされてしまいます。

これを防ぐためには、登録導線のユーザー行動を分析する際に既登録ユーザーを除外しなければなりません。
しかしながら、既登録ユーザーがトップページにアクセスした時点では、そのユーザーが既登録なのか未登録なのかはわかりません。
このためには、セッション単位で未登録なのか既登録なのかを判定し、既登録ユーザーを除外する必要があります。

# どうすればよいか

既登録セッションを見分けるためには、一見、「そのセッション内でログインしているか」を検出すれば良いように思えます。しかしながら、その場合「新規登録を完了したセッション」も既登録セッションとして判定されてしまいます。

そこで、既登録セッションを **「そのセッション内で新規登録を完了していないのに、ログインしているセッション」** と定義すれば良さそうです[^1]。

問題は、この複雑な条件を Google Analytics のフィルタとして設定することができるかということです。
これを実現するために、次のような2つのカスタムディメンジョンを使います。

| 名前 | スコープ | 説明 |
| --- | --- | --- |
| Is Signed-in Session | セッション | セッション内でユーザー登録を完了しているか |
| Is Logged-in Session | セッション | セッション内でログインしているか |

これらのディメンジョンを使用して既登録セッションを除外するには、 「`Is Logged-in Session`が偽 または `Is Signed-in Session`が真」 となるセッションだけを抽出すれば良いことがわかります。
このような設定を行う上で、いくつか注意すべき点がありますので、以下では順に説明していきます。

1. カスタムディメンジョンの設定の仕方
2. フィルターの設定の仕方

## 1. カスタムディメンジョンの設定

GA4 のセッションスコープのカスタムディメンジョンは1つのセッションごとに1つの値を保持します。
これは、1つのセッションの中でもPVやイベントなどが発生するたびに値をセットすることができますが、1つのセッションの中で異なる値をセットした場合、**最後にセットした値で上書きされます**。[^2]

「セッションの中で(一度でも)ユーザー登録を完了しているか」「セッションの中で(一度でも)ログインしているか」といったセッション中にあるイベントが発生しているか否かを判定する場合には注意が必要です。

例えば `Is Signed-in Session` を計測するために、セッション中で1回以上登録完了ページを閲覧しているかを計測する場合には、登録完了ページを閲覧しているときには `true` を送信し、それ以外のページを閲覧しているときには **何も値を送信しないこと** が必要です。
Google Tag Manager でこれを設定するためには、カスタム javascript 変数を用いて、次のように設定します。

```javascript
function(){
    // 登録完了ページなら true そうでないなら undefined を返す。
    return {{Page Path}}.match(/^\/sign_in\/completed/) ? true : void null;
}
```
GTMでカスタムディメンジョンに undefined を設定した場合、カスタムディメンジョンはそもそも送信されない扱いになります。
これにより、セッション中で一度でも `/sign_in/completed` を閲覧している場合は `Is Signed-in Session` が `true` に、一度も閲覧していない場合は **何も設定されていない状態** になります。

同様に、 `Is Logged-in Session` は「ログイン済ページを一度以上閲覧しているか」 を設定するようにします。


## 2. フィルターの設定

既登録ユーザーを除外したビューを作成するために、フィルターを設定します。
しかし、普通のGAのフィルターは、条件を AND で絞っていくので、
「`Is Logged-in Session`が偽 または `Is Signed-in Session`が真」 のような、 OR 条件を設定することができません。

また、上で「`Is Logged-in Session`が偽」という条件を書きましたが、前節で述べたとおり、セッション中でログインしていない場合には `Is Logged-in Session` の値は `false` ではなく **値なし** になっています。
フィルタの仕様上、値が存在しない場合には、 **フィルタ条件が存在しないものとして扱われる** ため[^3]、このような「`Is Logged-in Session`が偽」という条件がそもそも設定できない問題があります。

そこで、次のようにカスタムフィルタの詳細条件を使うことで、このような複雑な条件が指定できるようにします。

> #### フィルタ1: 「詳細」フィルタ
> 
> | 設定項目 | ディメンジョン | パターン |
> | --- | --- | --- |
> | フィールドA -> 引用A | `Is Signed-in Session` | `(.*)` |
> | フィールドB -> 引用B | `Is Logged-in Session` | `(.*)` |
> | 出力先 -> 構成 | `ユーザー定義` | `$A1,$B1` |
>
> フィールドAとフィールドBの必須のチェックは外す。
>
> #### フィルタ2: 「除外」フィルタ
> フィルタフィールド: `ユーザー定義`
> フィルタパターン: `^,1$`
> 



フィルタ1では、`ユーザー定義` フィールドに `{Is Signed-in Session},{Is Logged-in Session}` という文字列が格納します。このとき、真値の変数が文字列に変換される際には `1` 、値が設定されていない場合は空文字列となるため、 「サインインは完了していないがログインしている」という既登録セッションの場合には `ユーザー定義` フィールドの値は `,1` となります。
このとき、フィールドAとフィールドBの必須のチェックをどちらも外すことを忘れないでください。

フィルタ2では、 `ユーザー定義` フィールドの値が `,1` のセッションを既登録セッションとして除外しています。

# まとめ

今回は、少しトリッキーな方法を用いて Google Analytics で既登録セッションを除外する方法を書きました。

Google Analytics は簡単な計測をするためには非常に便利なツールですが、少し複雑なことをやろうとするとかなりトリッキーなテクニックを要求される印象です。GAで複雑なことをやるくらいなら、よりカスタマイズが用意なサービスを使ったり、自前で計測基盤を用意する方が良いのかもしれません。
しかしながら、GA はマーケティングの世界ではデファクトスタンダードとも呼べる存在で、マーケターやデータサイエンティストなど様々な人がデータ分析に使うことができる点においては、GAにデータを集約するメリットがあります。システムの規模や事業のフェーズに応じてGAとうまく付き合って行くことが大事かと思います。


[^1]: 未ログインの既登録ユーザーがログイン動線の途中で離脱してしまった場合は新規登録ユーザーと判定されてしまいますが、どうしようもない部分もあるのでここでは無視しています。

[^2]: 詳しくは[公式ヘルプ](https://support.google.com/analytics/answer/2709828?hl=ja#scope) をご覧ください。

[^3]: https://support.google.com/analytics/answer/1033162?hl=ja#limits