Pandas で、Google Analytics のデータをセグメント分けしてみます。
以下実施したことを記載します。
前提
以下、前提事項を記載します。
-
clientId を予めカスタムディメンションとして送付しておく
データセットは、Google Analytics で取得したデータです。
Google Analytics は デフォルト設定では、どのユーザーのアクセスなのかを識別することができません。
このため、Google Analytics の cookie を クライアントID として、 カスタムディメンションとして 送信しています。
Google Analytics の cookie をカスタムディメンションとして送付する方法は、以下の記事が参考になりました。
2016年の新定番!ユーザーエクスプローラーをもっと活用するための簡単な方法 | 株式会社プリンシプル -
Google Analytics Spreadsheet Add-on で、データを取得する
google analytics spreadsheet add-on を使って、Google Analytics からデータを取得します。
上記の使用方法は、Googleアナリティクスの分析はスプレッドシートのアドオンで全自動化しよう が参考になりました。
レコメンドに使用するデータセットとして、以下の Metrics、Dimensions を指定しています。
また、データの取得件数ですが、デフォルトは1000件までです。10000件までは引き上げられるので、10000件を設定しています。- Metrics
- ga:pageviews
- Dimensions
- ga:date
- ga:dimension8 (clientId) を設定しているdimensionになります。ここはそれぞれ変わります。
- ga:pagePath
- Metrics
-
Google Analytics Spreadsheet Add-on のデータ取得イメージ
以下のようなデータになります。
-
どんな観点でセグメントをつけるか
ユーザーあたりのpageviewで、セグメント分けをします。
1、2-4、5以上という雰囲気で分けます。
セグメント分けの手順
以下、手順でセグメント分けをしていきます。
- スプレッドシートからpython へのデータ取り込み
データの取り込みを実施します。 - データの分布を確認する
セグメント分けの前に、どのくらいの割り合いで分けるか決定するため、データ分布を確認します。 - セグメント分け
実際にデータをセグメント分けします。
スプレッドシートからpython へのデータ取り込み
python へのデータの取り込み、形式変換を実施します。
google スプレッドシートからのデータの取り込みには、gspread
を使います。
事前準備
必要なライブラリをインストールします。
python3 -m pip install gspread --user
python3 -m pip install oauth2client --user
python3 -m pip install df2gspread --user
python3 -m pip install pandas --user
python3 -m pip install sklearn --user
python3 -m pip install matplotlib --user
python3 -m pip install plotly --user
スプレッドシートのデータを取得する
以下のコードで、スプレッドシートのデータを取得してデータセットとして使用します。
API にアクセスするための JSON Key の発行が事前に必要になります。
APIの発行方法、gspread
の使い方は以下の記事が参考になりました。
[Python] Google SpreadSheetをAPI経由で読み書きする - YoheiM .NET
データ取得、pandas のdataframe に変換するプログラム
以下に記載します。
from oauth2client.service_account import ServiceAccountCredentials
def download_as_df(sheet_id, wks_name):
from df2gspread import gspread2df as g2d
# key_file 以下の指定方法だと、notebook と同じディレクトリにあるキーファイルを取得しています。
key_file = "spreadsheet_api_key.json"
scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name(key_file, scope)
df = g2d.download(sheet_id, wks_name=wks_name, col_names=True, row_names=False, credentials=credentials, start_cell = 'A15')
df = df.sort_values(by='ga:date')
return df
# 201710月-201712月のデータを取得する
df_201710 = download_as_df("1brCpWvk2uofc3MEt-ASb2cuZ-u8Zmx-ICxSTltlbVBQ","ユーザーの行動レポート 201710")
df_201711 = download_as_df("1brCpWvk2uofc3MEt-ASb2cuZ-u8Zmx-ICxSTltlbVBQ","ユーザーの行動レポート 201711")
df_201712 = download_as_df("1brCpWvk2uofc3MEt-ASb2cuZ-u8Zmx-ICxSTltlbVBQ","ユーザーの行動レポート 201712")
# dataframeのマージ
import pandas as pd
df = pd.concat([df_201710, df_201711, df_201712])
データの分布を確認する
以下、参考にしながら進めました。
Pandasでデータ集計をする際に最低限覚えておきたいメソッド - Qiita
ユーザのPageView の分布を計算する
# clientID 単位にページVIEWを集計
df_groupby = df.groupby("ga:dimension8",as_index=True)
# groupby した結果の ga:pageviews をカウント カウント結果をソートする
df_count_page_views = df_groupby.agg({"ga:pageviews": "count"}).sort_values("ga:pageviews",ascending=False)
# データの分布をvalue_counts()で出力、結果をソートする
series_counts = df_count_page_views["ga:pageviews"].value_counts().sort_index(0)
series_counts
1 10286
2 1082
3 301
4 127
5 67
6 29
7 27
8 10
9 8
10 7
11 7
12 4
13 5
14 4
15 2
16 1
17 2
18 3
20 4
21 1
23 1
24 1
25 1
28 1
33 1
43 1
74 1
177 1
Name: ga:pageviews, dtype: int64
plotlyで折れ線グラフを表示
# plotlyで折れ線グラフを表示
import plotly
plotly.offline.init_notebook_mode(connected=False)
plotly.offline.iplot([{
'x': series_counts.index,
'y': series_counts.values,
'name': "ga:pageviews"
}], filename='データ分布', show_link=False, config={"displaylogo":False, "modeBarButtonsToRemove":["sendDataToCloud"]})
plotly で円グラフ表示
# ploty で円グラフ表示
import plotly
import plotly.graph_objs
labels = series_counts.index
values = series_counts.values
trace = plotly.graph_objs.Pie(labels=labels, values=values)
plotly.offline.init_notebook_mode(connected=False)
plotly.offline.iplot([trace], filename='basic_pie_chart')
セグメント分けをする
ほとんど、1ページを見に来て帰る人が多いことがわかります。
エルボー法でクラスタ数をいくつにすればよいのか確認してみます。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display, HTML # Jupyter notebook用
from sklearn.cluster import KMeans
%matplotlib inline
def plot_elbow(array):
distortions = []
for i in range(1,11): # 1~10クラスタまで一気に計算
km = KMeans(n_clusters=i,
init='k-means++', # k-means++法によりクラスタ中心を選択
n_init=10,
max_iter=300,
random_state=0)
km.fit(array) # クラスタリングの計算を実行
distortions.append(km.inertia_) # km.fitするとkm.inertia_が得られる
plt.plot(range(1,11),distortions,marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.show()
array = np.array([series_counts.index,
series_counts.values,
], np.int32)
array = array.T
plot_elbow(array)
クラスタ数は2つに分けるのが、よさそうです。
クラスタ数2でクラスタリングします。
pred = KMeans(n_clusters=2).fit_predict(array)
pred
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0], dtype=int32)
2回以上アクセスしているグループを更にクラスタリングします。
del series_counts[1]
array = np.array([series_counts.index,
series_counts.values,
], np.int32)
array = array.T
plot_elbow(array)
pred = KMeans(n_clusters=2).fit_predict(array)
pred
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0], dtype=int32)
2回と、3回以上にわかれました。
3回以上を更にクラスタリングします。
del series_counts[2]
array = np.array([series_counts.index,
series_counts.values,
], np.int32)
array = array.T
plot_elbow(array)
pred = KMeans(n_clusters=4).fit_predict(array)
pred
array([1, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 2], dtype=int32)
3回のクラスタリングとデータ削除で以下のセグメントを得ました。
- pageviewが1のグループ
- pageviewが2のグループ
- pageviewが3-4のグループ
- pageviewが5-74 (5以上99以下) のグループ
- pageviewが74以上(100以上)のグループ
Google Analytics から、セグメントの設定が可能なので、上記をセグメントして設定してみようと思います。
その他考慮したほうが良さそうな観点
ユーザーあたりのpageviewでセグメントを設定してみました。
以下、実施しながら考慮したほうがいいかもしれないと思った観点を記載します。
- pageview ではなく、セッション数を使う。
- 日をまたいだアクセス 初回アクセス後に別の日に同じページを訪れているか。
以上です。
コメント