やりたいこと
すごいニッチな内容。Webサイトに置いてECであれば、GoogleAnalyticsで[ページの価値]を[eコマース]設定で把握している会社も多いのではないかと思う。Criteoの自動最適化に使われているROASの概念もこれに通ずる。ただ、世の中にはECサイト型で収益をあげるものの他に、メディアとして情報を自サイトに掲載することで収益をあげるものもある。仮にこういった手法を掲載課金型モデルとして、メディア側はこの掲載課金の中にある、広告メニューの価値をどう推し量るべきか?
今回は、GoogleAnalyticsのPVをベースに、PVと広告メニュー売上を比較。どの広告メニューのPVが価値が高いのかを可視化したい。
最終的にできあがるもの
Jupyter Notebookのhtmlを最初に見た方が全体像がわかりやすいです。またGitHubにJupyter NotebookとCSVを公開しています。
全体の流れ
- GoogleTagManagerで広告メニュートラッキングを行う
- GoogleAnalytics APIにおいて対象データの取得
- 対象データの整形
- PVと広告メニュー売上を比較
- グラフ化
※社内のSQLを利用しない理由:会社にもよるが、メディア運営しているなら、各広告メニューによるPV推移はとってるだろうし、SQLで見れる。ただ、自社DBのSQL接続権限を持ってないというマーケターも多いように思う。そこでGoogleAnalyticsのAPIを使うことで、マーケターにとってデータ把握が容易になる。また、自社のPVカウントってボットを多量に含んでいるのであまり信頼の置けない数値だったりする。・・・と個人的に思っている。
必要なもの
- Jupyter Notebook
- matplotlib
- google2pandas ※これはマジでいい
- pandas
- GoogleAnalyticsアカウント
- GoogleTagManagerアカウント
- GoogleCloudPlatformのちょっとした知識
1. GoogleTagManagerで広告メニュートラッキングを行う
仮にWebサイトが下記のようなディレクトリ構造になっている場合、課金対象になっているのは色の付いているところ。いわゆる詳細ページ。色合いがそれぞれの広告メニューで金額が違う。まずやりたいことは、この各広告メニューにおいてのPVの総和をカウント。
この総PVというものが、広告メニュー毎にGoogleAnalyticsで計測できていなければいけない。GoogleTagManagerにおいて、[変数]に格納して[GAイベント]としてGoogleAnalyticsに送信する方法を考えていく。
1 2 3 4 5 6 7 8 9 10 11 |
<div class="hoge"> <img src="img1.png"> </div> <p>ほにゃらら</p> <div class="hoge"> <img src="img1.png"> </div> <p>ほにゃらら</p> <div class="hoge"> <img src="img1.png"> </div> |
例えば、ある広告メニューではclass名が”hoge”となっているものがimgを囲っているとする。そしてimgの点数が広告メニューを分けている場合。GoogleTagManagerでhogeの回数をカウントする変数を「カスタムJavascript」で作ればよい。こんな感じ。
これでGoogleTagManagerではhoge回数をカウントしてclassCount変数に格納することができるようになった。タグマネのプレビュー画面をみてもclassCountが取得できていることがわかる。
では早速GoogleAnalyticsにこの情報を送る。さらっと解説すると下記。タグマネで簡単に実装できる。[カテゴリ][アクション][ラベル]を任意の値を設定。今回はimgの枚数によって、仮想広告メニューT1〜T4まで売ってるということで[ラベル]に変数を利用した。イベント発火のトリガーはこんな感じで設定。
そしてテスト発火させてみて。GoogleAnalyticsを確認。うん、取れたみたいです。
GoogleAnalytics APIにおいて対象データの取得
GoogleAnalyticsのAPIを使いこなしている人は、Webプロダクトを作っているエンジニアの人以外ではそんなにいないのではないかと思う。というのもGAのダッシュボード自体が優秀で、使いやすい。「API叩くまでも・・・」ということ。ただ、データの[セグメント][メトリックス]を日時なんかで細かく切る場合は、ダッシュボードだと行数オーバーして対応できない。また、データの先の加工はエクセルなんかでやっている人が多いので、だったらAPIも利用できた方がよいかと思います。
先ほどはのイベントを取得してみましょう。
- Get started exploring Google Analytics data with Python Pandasでgoogle2pandasをpip
- はじめてのアナリティクス API: インストール済みアプリケーション向け Python クイック スタートのステップ1まで実行
- client_secret.jsonを保存
- 下のコードをJupyter Notebookで実行
ids、start_date、secrets等は条件に応じて変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
%matplotlib inline from google2pandas import * import pandas as pd from pandas import Series, DataFrame import matplotlib.pyplot as plt # API接続 start_index = 1 query = { 'ids' : 'YOURVIEWID', 'metrics' : 'ga:totalEvents', 'dimensions' : ['ga:eventCategory', 'ga:eventAction', 'ga:eventLabel'], 'start_date' : 'yyyy-mm-dd', 'end_date' : 'yyyy-mm-dd', 'start_index' : start_index, 'max_results' : 10000} conn = GoogleAnalyticsQuery( token_file_name='my_analytics.dat', secrets='client_secret.json') df, metadata = conn.execute_query(**query) df |
本来は上記の通りGAから値を取得するのですが。サンプルデータを代わりにCSVで用意。DataFrameで表示するとこんな感じです。
1 2 3 4 |
#本来は上記の通りGAから値を取得する・・・。サンプルデータをGAで作るのが面倒だったため。「sample_ga.csv」を用意した。 df = pd.read_csv('sample_ga.csv') df = df.rename(index=df['eventLabel']) df |
eventCategory | eventAction | eventLabel | totalEvents | |
---|---|---|---|---|
T1 | Ad_Rank | view | T1 | 45803 |
T2 | Ad_Rank | view | T2 | 972235 |
T3 | Ad_Rank | view | T3 | 798452 |
T4 | Ad_Rank | view | T4 | 734943 |
対象データの整形
また広告メニューT1〜T4はそれぞれ「価格」と「広告の数」が違います。その内容をdf2として以下作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 広告ランクと価格と広告数 ad_rank_and_price ={'T1':10000, 'T2':20000, 'T3':30000, 'T4':40000} ad_total = {'T1':3768, 'T2':3155, 'T3':2422, 'T4':1398} #値が入ってない空のデータフレーム作成 df2 = pd.DataFrame(index=['T1','T2','T3','T4'], columns=['ad_price', 'ad_total']) #広告価格と広告数を代入 for price in ad_rank_and_price.keys(): df2['ad_price'][price] = ad_rank_and_price[price] for total in ad_total.keys(): df2['ad_total'][total] = ad_total[total] df2 |
できました。
ad_price | ad_total | |
---|---|---|
T1 | 10000 | 3768 |
T2 | 20000 | 3155 |
T3 | 30000 | 2422 |
T4 | 40000 | 1398 |
dfとdf2をインデックスをキーにしてマージします。
1 2 3 |
#dfとdf2のマージ df3 = pd.merge(df, df2,left_index=True, right_index=True) df3 |
eventCategory | eventAction | eventLabel | totalEvents | ad_price | ad_total | |
---|---|---|---|---|---|---|
T1 | Ad_Rank | view | T1 | 45803 | 10000 | 3768 |
T2 | Ad_Rank | view | T2 | 972235 | 20000 | 3155 |
T3 | Ad_Rank | view | T3 | 798452 | 30000 | 2422 |
T4 | Ad_Rank | view | T4 | 734943 | 40000 | 1398 |
PVと広告メニュー売上を比較
ここからさらにT1〜T4までの広告がいくら売上をあげているのか(=’ad_earnings’)を計算して、そこから計PV(=’totalEvents’)で割り戻します(=’ad_value’)。
1 2 |
df3['ad_earnings'] = df3['ad_price'] * df3['ad_total'] df3['ad_value'] = df3['ad_earnings'] / df3['totalEvents'] |
計算できましたね。
eventCategory | eventAction | eventLabel | totalEvents | ad_price | ad_total | ad_earnings | ad_value | |
---|---|---|---|---|---|---|---|---|
T1 | Ad_Rank | view | T1 | 45803 | 10000 | 3768 | 37680000 | 822.654 |
T2 | Ad_Rank | view | T2 | 972235 | 20000 | 3155 | 63100000 | 64.902 |
T3 | Ad_Rank | view | T3 | 798452 | 30000 | 2422 | 72660000 | 91.0011 |
T4 | Ad_Rank | view | T4 | 734943 | 40000 | 1398 | 55920000 | 76.0875 |
ad_valueに関する考え方
ad_valueは「1PVあたりの売上高」を示しています。コンテンツ自体がPVを生み出すものというサイトでは、あまり馴染まない考え方かもしれません。ただ、週間で広告が入れ替わるような掲載課金型のメディアの場合は少し違います。メディアのプロモーションのアロケーションを考えるときに、限りあるパイからどの広告に追加で投資すべきか?または今後の広告の価格はどう扱うべきか考えることが重要になります。このad_valueは定点観測していくことで、その2点を考えていく指標として使えます。
グラフ化
最後にせっかくなのでグラフ化。Seriesを棒グラフのpandas.plotメソッドに渡して、showするのみ。X軸は指定しなければ、自動でインデックス渡してくれます。楽ですね。
1 2 |
df3['ad_value'].plot(kind='bar') plt.show() |
できた。
(再掲)最終的にできあがったもの
ZoomやChatworkでファイル共有している方へ
リモートワークが一般的になってきた今「誰が」「どこで」「何を」ファイル共有しているのかしっかりと把握する必要があります。easyDBを利用すればセキュリティ上で安全なファイル共有をクラウド上で行えるだけでなく、ファイルのバージョン管理等も簡単にできます。
>>>リモートワーク時代の安全なファイル共有「easyDB」はこちら