Google AnalyticsとCookieを使って、アイコンのA/Bテストをしてみた

こんにちは。制作部の苅部です。

今回は最近実施したGoogle Analyticsを使ったA/Bテストについて書こうと思います。

仕組み自体はすごくシンプルですので、ツールの導入が難しい場合にも簡易的なA/Bテストが実施できると思います。

Google Analyticsを使う機会が少ないエンジニア/デザイナーの方や、普段フロントエンドの実装をされてないディレクターの方に向けて、今回の事例を簡単に共有できればと思います。

実施の経緯

運用中のサービスで採用しているアイコンについて、「どうもわかりづらい」「テキストラベルを加えた方が伝わりそう」といった意見が上がっておりデザイン変更を検討していました。

ただ変更するにあたっては「分かりやすくなった(効果があった)」という状態を数値で把握できるようにしたいので、[オリジナルデザイン]と[改善後デザイン]それぞれで、一定期間A/Bテストを実施することになりました。
[改善後デザイン]のクリック数が継続して高ければ、"UIの認知度が向上した"という判断ができると思ったのです。

普段のA/BテストはSaaSが提供している多機能なプラットフォームで実施しているのですが、今回のUIはサードパーティーとしてのJavaScriptを使い広範囲(複数サブドメイン)に展開しているため、自前で実装する流れとなりました。

要件と実装概要

今回の要件は以下のようになっています。

  • [JavaScriptファイルで展開しているUI]にてA/Bテストを実施してクリック数/CTRを計測
  • サービスを横断したUIのため、サービスを超えてもデザインパターンが変わらないようにする。
  • Google TagManager/ユニバーサルアナリティクスを利用(すでに利用していたため)

そして全体の処理の流れは次のようになります。

  1. JavaScriptが実行され、Cookieにセグメント用の乱数をセット。(一定期間保持する。)
  2. その値を使い、任意の確率で各デザインパターンを構築
  3. デザインパターンごとにdataLayer変数(カスタムディメンション)やイベントラベルをセット
  4. dataLayer変数を拾った上でgtm.jsが構築される
  5. gtm.jsからanalytics.jsが構築される
  6. analytics.jsがカスタムディメンションを送信

HTMLの構造

Google TagManagerのスニペットはbody開始タグ直後への設置が推奨されているため、HTMLとしては以下のような形になります。

<html>
<head>
  <!-- 共通UIを構築し、dataLayer変数を定義する -->
  <script src="ui_elements.js"></script>
</head>
<body>
  <!-- gtm.jsが構築される。そのあとにanalytics.jsが構築される -->
  <noscript><iframe src="//www.Google TagManager.com/ns.html?id=GTM-MP7TC7"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.Google TagManager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','profileIdが入ります');</script>
  <!--
    以降にコンテンツが入る
  -->
</body>
</html>

Google Analytics / Google TagManagerの準備

Google Analyticsのカスタムディメンションとイベントトラッキングという機能を使います。

カスタムディメンションとはユーザーに紐づく属性を追加で設定するための仕組みで、イベントトラッキングとはユーザーのインタラクションで発生するイベントを送信するための仕組みです。

今回はクリック数とCTR計測が目的ですので

  • [表示されたデザインパターン]をカスタムディメンション設定
  • [クリックされたデザインパターン]をイベント設定

として、それぞれ分母/分子としてCTRを計算しています。

※以降の画面キャプチャは2016年8月の状態のものです。

Google Analyticsの設定

カスタムディメンションを新規に作成します。
※カスタムディメンションを作成・編集するにはプロパティに対する編集権限が必要です。

[管理] > [任意のプロパティ] > [カスタム定義] > [カスタムディメンション]にて [新しいカスタムディメンション]を選択します。

わかりやすい任意の名前でカスタムディメンションを設定して[作成]を選択します。
今回はbtn-menuとしました。

※作成後に[作成したカスタム ディメンション]という画面でサンプルコードが表示されますが、今回は気にしなくて大丈夫です。

元のページに戻ると新しいディメンションが追加されたことがわかると思います。

Google TagManagerの設定

カスタムディメンションをGoogle TagManagerで利用するため、ユーザー定義変数としてデータレイヤー変数の設定をします。
※ データレイヤー変数でなくとも、"JavaScript変数"を使う事でグローバル変数を取得する事もできます。

まずは任意のコンテナの中で[変数]を選び[ユーザー定義変数]で[新規]を選択します。

変数の種類はデータレイヤー変数とします。

変数名とデータレイヤーの変数名を設定し変数を作成します。

次に、タグに対してカスタムディメンションとデータレイヤー変数を紐付けます。

任意のコンテナの中で[タグ]を選び、今回利用するタグを選択します。
(タグを発行していない場合は発行します。)

タグの設定でカスタムディメンションの設定をします。
ここではデータレイヤー変数とGAのカスタムディメンションのインデックス番号を紐付けます。

以上の内容でGoogle Analytics/Google TagManagerの準備が整いました。

Cookieでのセグメント値の設定と読み込み

デザインパターンを任意の確率でコントロールできるようにします。
4桁程度の乱数(セグメント値)をCookieに保存する仕組みと、それを取得できるような仕組みを作ります。
こんな感じの関数で使ってみます。

function initSegment() {
    var COOKIE_NAME = '_segment';
    var COOKIE_DOMAIN = 'example.com';
    var SEGMENT_LIMIT = 9999;
    var segmentCookie = $.cookie(COOKIE_NAME);
    var segmentValue = parseInt(Math.random() * SEGMENT_LIMIT, 10);
    if (segmentCookie) {
        window._segment = segmentCookie;
    } else {
        $.cookie(COOKIE_NAME, segmentValue, {expires:100, path:'/', domain: COOKIE_DOMAIN})
        window._segment = segmentValue;
    }
};

※見通しを良くするためjQueryCookieを使っている想定で書いています。

サブドメインまでセグメント値を共有するためCookieを使っていますが、 SameOriginの範囲であればLocalStorageで良いと思います。

さて、セグメント値が設定できたので以下のような形で分岐処理ができるようになります。

if(window._segment >= 5000){
  html = '<a href="#">ボタン1 : 1/2の確率で表示</a>'
}else{
  html = '<a href="#">ボタン2 : 1/2の確率で表示</a>'
}

クリックイベントも取得できるようにしたいので、AタグにGoogleのイベント用関数を設定します。
これによってボタンがクリックされた数をレポートで集計できるようになります。

if(window._segment >= 5000){
  html = '<a href="#" onclick="ga(\'send\',\'event\',\'header\',\'menu\',\'button_01\');">ボタン1 : 1/2の確率で表示</a>'
}else{
  html = '<a href="#" onclick="ga(\'send\',\'event\',\'header\',\'menu\',\'button_02\');">ボタン2 : 1/2の確率で表示</a>'
}

以上で、確率のコントロールとイベント送信ができるようになりました。

dataLayer変数の用意(JavaScript)

グローバル空間にdataLayer変数を配列で用意しておきます。
※この変数名はGoogle TagManagerのコンソールで変更可能ですが、dataLayerのままの方が明示的で誰が見ても分かりやすいと思います。

今回の場合こんな感じです。
デザインパターンごとに、配列へpushするオブジェクトを分けています。

window.dataLayer = dataLayer || []
if(_segment >= 5000){
  dataLayer.push({'btn-menu': 'button_01'})
}else{
  dataLayer.push({'btn-menu': 'button_02'})
}

Google TagManagerで用意したデータレイヤー変数btn-menubutton_NNという値を設定しています。
btn-menuはGoogle Analyticsのカスタムディメンション1番目に紐づけているので、Google Analytics APIコール時にはcd1として送信される事になります。

※Google TagManagerのスニペットの実行より手前のタイミングで宣言する必要があります。

検証方法について

フロントの実装が完了したら、ログと疎通の確認を行います。

クライアントからGoogle AnalyticsAPIへのコール内容は、以下URLへのリクエストパラメータにて確認することができます。
https://www.google-analytics.com/r/collect

WEBブラウザのDeveloperToolを使ってみると、カスタムディメンションの1番に割り当てている内容がcd1button_01として設定されている事が分かります。

コールを正しく受け取れとれているかどうかは、Google Analyticsのリアルタイムレポートのイベントタブで確認する事ができます。
直近30秒ごとのイベントが見れますので疎通確認として使えます。便利ですね。

A/Bテストの実施結果

さてさて、気になるテストの結果ですが、2箇所のUIで実施したところいずれも1週間以上継続して[改善後デザイン]でプラスの効果が確認できました。

※ 2パターンをそれぞれ1/2の確率で表示させています。
※ 実際に使用しているデザインとは異なるものの、構成としてはほぼ同じです。
※ サンプル数や結果の数値差によって誤差の範囲と言えるケースもありますので、有意差の検定も実施しています。母数としては十分な数があります。

テスト1. テキストラベルの追加

アイコンの中にテキストラベルを入れてみました。
テキスト情報を含める事で、UIパーツの役割が理解しやすくなると思います。

・UIイメージ

※ 実際のデザインとは若干異なります。

・集計結果

※ イベント数と日付を表示していませんが、Google Analytics上での実際のレポートです。

デイリーでのクリック数が20%近く向上して、CTR比較でも有意差が出ました。
ここまで明らかな違いが出ると思っていなかったので驚きです。

テスト2. テキストのサイズとコントラスト比の調整

アイコンのシンボルとテキストのサイズやコントラストを調整して視認性を向上させました。 改善パターンのコントラスト比については、WCAG 2.0およびJIS X 8341-3:2010で定められている指針の達成基準(コントラスト比4.5:1と3:1)を満たせたと思います。

最低限のコントラスト: テキスト及び画像化された文字の視覚的な表現には、少なくとも4.5:1 のコントラスト比をもたせる。
ただし、次の場合は除く: (レベルAA)
大きな文字: サイズの大きなテキスト及びサイズの大きな画像化された文字には、少なくとも 3:1 のコントラスト比がある。

達成基準 1.4.3 を理解する | WCAG 2.0解説書

・UIイメージ

※ 実際のデザインとは若干異なります。

オリジナル改善パターン
背景色#f8f8f8#ffffff
シンボルのサイズ--20%
シンボルの色#999999#888888
シンボルのコントラスト比2.7:13.5:1
テキストのサイズ-+2px
テキストの色#777777#666666
テキストのコントラスト比4.2:15.7:1

・集計結果

※ イベント数と日付を表示していませんが、Google Analytics上での実際のレポートです。

デイリーでのクリック数が15%近く向上して、CTR比較でも有意差が出ました。
テキストラベルを見やすい形で配置しコントラスト比も高めたことで、UIが認知されるようになったと思います。

以上2つのA/Bテストは1~2週間実施して、いずれもプラスの効果があったと判断できたため新しいデザインで反映する事となりました。


注意点
今回の場合A/Bテストの情報(デザイン)を非同期で取得するような形にはせず、すべてJavaScriptファイルの中で保持しています。
つまりA/Bテストの内容が反映されるのはJavaScriptファイルのキャッシュに左右されますので実際に反映されるまでの誤差も考慮する必要があります。
(キャッシュの保持はレスポンスヘッダやブラウザの仕様に則る形となります。場合によってはCDNキャッシュも考慮する必要があります)

Google Analyticsを使うことのメリット

実際にGoogle Analyticsを使ってみて、以下2点がメリットとして感じられました。

  • アクセス解析として現場で広く利用されているため導入障壁が低い
  • カスタムディメンションやイベント起点でのレポーティングが可能

導入障壁の低さ

やはりGoogle Analyticsの経験者は多く、ディレクターやフロントエンジニアとの意思疎通が楽だなと実感しています。

Google Analyticsに慣れておけば、将来的にFirebaseAnalyticsやOptimize360を使う事になったとしてもスムーズに使いこなす事ができるかもしれません。

レポーティング機能

バナーのクリエイティブ比較であればクリック数だけを追えばいいのかもしれませんが、UI変更の場合にはページ遷移後の行動把握のため、カスタムディメンションが必要になる事が多いと思います。

例えばそういったケースではカスタムレポートの目標到達プロセスが役に立ちます。

クリック数だけでなく、その後の行動とコンバージョンをセグメントごとに比較することができるため、より本質的なA/Bテストができると思います。

また、コホート分析を使えば[チュートリアルUIの掲出/非掲出]それぞれでセグメントを設定して比較する みたいな使い方もできたりします。7日間継続率をKPIとして設定している場合に活用できそうです。

コホート分析

このようにレポート機能が豊富なため、Google AnalyticsはA/Bテストとの相性がとても良いと思います。 テストパターンの切り替えとセグメント送信をA/Bテストプラットフォームで、レポーティングをGoogle Analyticsで、といった具合に使い分けるのもアリかもしれません。

まとめ

Google Analyticsの高機能さのおかげでCookieだけでも、実践的なA/Bテストが簡単に実施できることがわかりました。

今回のA/Bテストでは、"普段見落としがちな小さなUI"へのアクセシビリティ配慮の必要性が学習でき、成果にも結びつける事ができたと思います。

A/Bテスト実施によってカンや経験に頼る事なくUIを組み立てる事ができますし、レポーティング手法を学ぶことで提案の幅も広がると思います。
今後もこのような形で検証を繰り返して、KPIとUX改善の両方を追い続けていきたいと思います。

参考URL