読者です 読者をやめる 読者になる 読者になる

廿TT

譬如水怙牛過窓櫺 頭角四蹄都過了 因甚麼尾巴過不得

RGoogleAnalytics で RFM 指標のヒストグラム

RFM 分析とは

マーケティングの分野ではしばしば、

  • R(recency;リセンシー)直近の購買からの経過時間
  • F(frequency;フリクエンシー)観測期間中の購買回数
  • M(monetary;マネタリー)累計または平均購買金額

の 3 指標を見て優良顧客を識別することがある。

これを Google アナリティクスの指標で行うことを考える。
本ブログは残念ながら一銭も儲かっていないので、

  • ユーザー最終訪問日からの経過日数(何日間空けてアクセスしてきたか)を R(リセンシー)
  • ユーザーのセッション回数を F(frequency;フリクエンシー)

と見て、ヒストグラムで表示する。

ヒストグラムとは、ここからここまでの範囲に該当するものが何件ありますよ、というのを棒グラフで示したもののこと。

データの取得

library("RGoogleAnalytics")
query <- QueryBuilder()
access_token <- query$authorize()

#アクセストークンをコピペ

ga <- RGoogleAnalytics()
ga.profiles <- ga$GetProfileData(access_token)


#ga:daysSinceLastVisit # 最終訪問日からの日数
query$Init(start.date = "2014-06-01",
           end.date = "2014-06-30",
           dimensions = "ga:daysSinceLastVisit,ga:userType",  
#セカンダリでユーザータイプを入れておく
           metrics = "ga:visitors",
           table.id = paste("ga:",ga.profiles$id[1],sep="",collapse=","),
           access_token=access_token)

dslv <- ga$GetReportData(query)


#ga:visitCount # セッション数
query$Init(start.date = "2014-06-01",
           end.date = "2014-06-30",
           dimensions = "ga:visitCount,ga:userType",  
#セカンダリでユーザータイプを入れておく
           metrics = "ga:visitors",
           table.id = paste("ga:",ga.profiles$id[1],sep="",collapse=","),
           access_token=access_token)

vc<- ga$GetReportData(query)


データの取得方法については下記のページを参照:
Google Code Archive - Long-term storage for Google Code Project Hosting.
GoogleアナリティクスAPIでアドバンスセグメントには整数も使える
Google Analytics Data Export API リファレンス日本語訳
Query Explorer — Google Analytics Demos & Tools
RGoogleAnalytics をいじっている - 廿TT

ヒストグラム

library(ggplot2)
theme_set(theme_bw())

#ヒストグラム用にデータ整形
daysSinceLastVisit <- with(dslv,rep(daysSinceLastVisit,visitors)) 
daysSinceLastVisit <- as.numeric(daysSinceLastVisit)

qplot(daysSinceLastVisit)

上記のように単純にヒストグラムをかくと 0 の頻度が極端に多い。

f:id:abrahamcow:20140727204743p:plain

New Visitor(新規ユーザー)が多いページなのでこうなるのは当たり前であまりおもしろくない。

> head(dslv)
  daysSinceLastVisit          userType visitors
1                  0       New Visitor     3270
2                  0 Returning Visitor      179
3                  1 Returning Visitor       41
4                 10 Returning Visitor        4
5                101 Returning Visitor        3
6                104 Returning Visitor        2

そこで、ユーザータイプを Returning Visitor(再訪ユーザー)にしぼってグラフをかいてみる。

daysSinceLastVisit <- with(subset(dslv,userType=="Returning Visitor"),rep(daysSinceLastVisit,visitors)) 
daysSinceLastVisit <- as.numeric(daysSinceLastVisit)

qplot(daysSinceLastVisit) 

0〜100 くらいに大きい山、100〜200くらいに小さい山、200〜300くらいに小さい山と山が 3 つ見える。
f:id:abrahamcow:20140727205325p:plain

ヒストグラムの棒のことをビンという。
このビンの数の決め方は意外と難しい問題である。

ggplot2 のヒストグラムでは、デフォルトでビンの数を31にしているようだ。
これは特に根拠のない数字である。


また、一般に RFM 分析では、R、F、M、それぞれを5~7段階に分けることが多いらしい。
情報システム用語事典:RFM分析(あーるえふえむぶんせき) - ITmedia エンタープライズ
これもおそらくは特に根拠のない数字だが、無意識的に正規分布(左右対称な分布)を仮定したものと考えられる。

R 標準の hist 関数では、下記の三種類の方法でビンの数を決めることができる。

#スタージェスの公式
> nclass.Sturges(daysSinceLastVisit)
[1] 10

#スコットの選択
> nclass.scott(daysSinceLastVisit)
[1] 13

#フリードマン=ダイアコニスの選択
> nclass.FD(daysSinceLastVisit)
[1] 58

ヒストグラム - Wikipedia

スタージェスの公式はよく使われるが、デコボコを滑らかにしすぎる傾向があり、データが正規分布 (正確には二項分布を仮定して作られたらしいが)から離れると当てはまりが悪くなる。
61. データの分布とヒストグラム・密度推定

そこで今回はスコットの選択を採用することにする。

qplot(daysSinceLastVisit) +
  stat_bin(binwidth =(diff(range(daysSinceLastVisit))/nclass.scott(daysSinceLastVisit)))

f:id:abrahamcow:20140727213239p:plain

ユーザー層がおおむね 3 つくらいにわけられそうな感じが見て取れる。
f:id:abrahamcow:20140727213837p:plain


同様にユーザーのセッション回数も図示してみる。

visitCount <- with(subset(vc,userType=="Returning Visitor"),rep(visitCount,visitors))
visitCount <- as.numeric(visitCount)
qplot(visitCount) +
  stat_bin(binwidth =(diff(range(visitCount))/nclass.scott(visitCount)))

f:id:abrahamcow:20140727214300p:plain

こんな感じだ。

f:id:abrahamcow:20140727214637p:plain

ライトユーザー、ヘビーユーザー、超ヘビーユーザーとあだ名づけしてみた。

一般には、リセンシーが小さくてフリクエンシーが大きい顧客はいい顧客だが、今回、

  • daysSinceLastVisit (何日間空けてアクセスしてきたか)を R(リセンシー)
  • visitCount(ユーザーのセッション回数)を F(frequency;フリクエンシー)

とした。

daysSinceLastVisit は直近のアクセスからの経過時間ではなく、「観測期間中にアクセスがあったユーザーの、前回のアクセスが何日前だったか」なので注意が必要である。

ヒストグラムで表すのに適した指標

他に Google アナリティクスの提供する指標のうち、ヒストグラムで表すのに適したものとして「滞在中のページビュー」、「滞在時間」などがある。

これらはユーザー単位の指標ではなく、セッション(一回の訪問)単位の指標である。

#ga:pageDepth # 滞在中のページビュー
query$Init(start.date = "2014-06-01",
           end.date = "2014-06-30",
           dimensions = "ga:pageDepth",  
           metrics = "ga:visits", # metrics を visits に。
           table.id = paste("ga:",ga.profiles$id[1],sep="",collapse=","),
           access_token=access_token)

pd <- ga$GetReportData(query)


#ga:visitLength # 滞在時間
query$Init(start.date = "2014-06-01",
           end.date = "2014-06-30",
           dimensions = "ga:visitLength",  
           metrics = "ga:visits",
           table.id = paste("ga:",ga.profiles$id[1],sep="",collapse=","),
           access_token=access_token)

vl <- ga$GetReportData(query)

Google アナリティクスは、次のページが読み込まれるごとに滞在時間を計測していくので、1ページしか閲覧しなかった場合、滞在時間が 0 になる。

> head(pd)
  pageDepth visits
1         1   3309
2        11      1
3        12      2
4        13      1
5        15      2
6        16      1

> head(vl)
  visitLength visits
1           0   3309
2           1      1
3          10      4
4        1005      1
5        1008      1
6        1011      1

#pageDepth が 1 の visits の数と、
#visitLength が 0 の visits の数が、
#どちらも 3309 で一致している
#滞在中のページビュー
pageDepth <- with(subset(pd,pageDepth != 1),rep(pageDepth,visits))
pageDepth <- as.numeric(pageDepth)
qplot(pageDepth)+
  stat_bin(binwidth =(diff(range(pageDepth))/nclass.scott(pageDepth)))

#滞在時間
visitLength <- with(subset(vl, visitLength !=0),rep(visitLength,visits))
visitLength <- as.numeric(visitLength)

qplot(visitLength)+
  stat_bin(binwidth =(diff(range(visitLength))/nclass.scott(visitLength)))

f:id:abrahamcow:20140727224127p:plain

f:id:abrahamcow:20140727224136p:plain
(滞在時間の単位は秒)


ページ閲覧数が多く、滞在時間が長いほど、サイトへの関心度合いが高いと解釈できるので、これらの指標は Web 解析の分野で「ロイヤリティ」とか「エンゲージメント」とか呼ばれることがある。

これはなんの役に立つか

例えば、購買に結びつきやすい顧客を狙って広告を出したいときに、手始めにヒストグラムをかいてみて、ユーザー層がどのように分布しているか眺めるといった使いかたが考えられる。

Rgoogleanalytics 使ってGDN*1のリマケリスト*2作るの結構楽しい。— shota yasui (@housecat442)

https://twitter.com/housecat442/statuses/485573930195755008


また、こういうのを出しとくとちょっとプロっぽく見えるというメリットがあり得る。


より深掘りしたい方は下記の論文を読んでみてもいいかも。

RFM指標と顧客生涯価値(pdf)

*1:グーグルディスプレイネットワークの略。グーグル社の広告配信ネットワーク

*2:マーケティングのリスト。サイトに訪れたユーザーを改めてターゲティングして広告を見せるための設定