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

廿TT

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

Web 解析データの平均滞在時間、本当は平均になっていないのでは?

本エントリの要約

Web 解析データの平均滞在時間は、「滞在時間÷訪問数」で計算される。

でもこれは統計的な意味での「平均」(母平均の推定量)にはなっていない(気がする)。

なぜなら Web 解析データの滞在時間は、「区間打ち切り」されたデータだからだ。

それが実務上の問題につながるか、というとよくわからない。そんなに問題ない気もする。

平均滞在時間の算出方法

本エントリでは「Web 解析データの平均滞在時間、本当は平均になっていないのでは?」という問題提起をします。

この問いを理解するためにはまず、Web 解析における滞在時間がどのように計測されているのかを知る必要があります。

(滞在時間という語は正確でなく、セッション継続時間と呼ぶほうがいいのかもしれません)

例えば、代表的な Web 解析ツール Google アナリティクスでは、サイトへの滞在時間は以下のように計測されます。

f:id:abrahamcow:20141207130752j:plain
アナリティクスでのセッション数の算出方法 - アナリティクス ヘルプ より一部改変して引用)

アクセス解析ではサイト閲覧開始から閲覧終了までをストップウォッチを持って計測するような具合にはいかないので、カチッとページが読み込まれた瞬間瞬間の時刻しかわかりません。

なので、サイト滞在時間を測るには、サイト閲覧開始時刻と閲覧終了時刻の差分をとるわけです。

「ん? カチッとページが読み込まれたときの時刻しかわからないなら、閲覧終了の時刻ってどう判断すんだ?」

はい。それは適当なところで打ち切るのです。

Google アナリティクスのデフォルトでは、30分以上の間ページが読み込まれなかったら、その訪問(セッション)は終了とみなし、直前のページの閲覧時刻を「閲覧終了の時刻」とします。


※正確さよりわかりやすさを重視し、あえて大雑把に説明している部分があります。Google アナリティクスのセッション継続時間の計測方法について正確に知りたい方は、公式のヘルプを参照してください。


Google アナリティクス以外のアクセス解析ツールでも同様、訪問(セッション)の終了は適当なところで打ち切ることで判定します。

(ちゃんと調べてはいませんが、「30分放置でセッション切れ」っていうのは Web 解析のデファクトスタンダードになっていた気がします。)

生ログを直にさわって滞在時間を測るとしても、セッションはどこか適当なところで区切るしかないでしょう。

(そういえばソーシャルゲームとかの業界はデータの活用が盛んらしいけど、あれは滞在時間とかどうやってみてるのかな?)

そして平均滞在時間は「合計滞在時間÷合計訪問数」という形で計算されます。

(平均セッション継続時間 = 各セッションの継続時間の合計 ÷ 総セッション数)
Session Duration, Avg - Analytics Help

区間打ち切り

上述の通り、滞在時間のデータには打ち切りが発生します。

30分でセッションが切れるとしたら、滞在時間15分という観測値は「15分以上、45分未満サイトを閲覧していた」という情報を持つわけです。

閲覧終了というイベントが [15, 45) という区間内に起こったことだけがわかっている、このような観測を区間打ち切りされた観測と呼びます。

区間打ち切りされた観測  [L_i, R_i) , (i=1, \ldots, n) に対して尤度を構成すると、

 \displaystyle \prod_{i=1}^n \left[ \{1-F(L_i)\} - \{ 1-F(R_i) \} \right]

となります。ここで F は確率分布関数です。

尤度に 1-F が出てくるのは一見変な感じがするかもしれません。

[1.5, 2) という観測があったとしたら、それは「1.5 以上 2 未満」という意味ですので、確率密度関数 f(x)積分値、

 \displaystyle \int^{2}_{1.5} f(x) \, dx

が尤度になるということです。
f:id:abrahamcow:20141207145747p:plain

curve(dweibull(x,2), xlim=c(0,4),ylab="f(x)")
x = seq(1.5, 2, length=100)
y = dweibull(x,2)
polygon(c(x,x[length(x)],x[1]), c(y,0,0), col="cornflowerblue")

と、こんな感じで考えて、とりあえず一番かんたんな分布ということで指数分布を仮定したら、平均滞在時間の最尤推定量が求まります。

離散時間データからの指数分布パラメータの最尤推定 - 廿TT

ノンパラメトリックな方法については、不勉強なのでぜんぜんわかりません。

ケーススタディ

RGoogleAnalytics でデータを取得して平均の推定値と信頼区間を出してみます。

f:id:abrahamcow:20150927131400p:plain

Google アナリティクスの平均滞在時間と指数分布を仮定した平均滞在時間の推定値の比較プロット。

推定値どうしの順位は変わらず、値が格段に大きくなっています。

f:id:abrahamcow:20150927131545p:plain

ランディングページごとの平均滞在時間の95%信頼区間です。

指数分布を仮定した右打ち切りデータの平均の区間推定(ってこれでいいのかな?) - 廿TT

特別面白い傾向はないかな。

#データ抽出時のクエリ
myid <- GetProfiles(oauth_token)$id
query.list <- Init(start.date = "2015-08-01",
                   end.date = "2015-08-31",
                   dimensions = "ga:landingPagePath",
                   metrics = "ga:sessions,ga:sessionDuration,ga:avgSessionDuration",
                   max.results = 10000,
                   sort = "-ga:sessions",
                   table.id = sprintf("ga:%s", myid[1])
)

ga.query <- QueryBuilder(query.list)
gadf <- GetReportData(ga.query, oauth_token)

alpha = 0.5 #信頼水準
n = gadf$sessions
mu_hat = a/(log(gadf$sessionDuration+a*n)-log(gadf$sessionDuration)) #平均滞在時間
num = 2 * n * mu_hat
exp_CI <-data.frame(mu_hat, lower= num/ qchisq((1-alpha/2),df=2*n), upper= num/ qchisq(alpha/2,df=2*n))

exp_CI$landingPagePath <- gadf$landingPagePath

plot(gadf$avgSessionDuration, mu_hat,
     xlim=c(0,4000),ylim=c(0,4000),
     xlab="avgSessionDuration",ylab=expression(hat(mu)))
abline(0,1,lty=2)

library(ggplot2)
theme_set(theme_bw(base_size=15,"HiraKakuPro-W3"))
ggplot(exp_CI[1:10,], aes(x=landingPagePath,y=mu_hat))  +
  geom_bar(stat="identity", alpha=0.6)+
  labs(y=expression(hat(mu))) + 
  geom_errorbar(aes(ymin=lower,ymax=upper), colour="red3") +
  coord_flip()

参考文献と関連エントリ

生存時間解析

生存時間解析

区間打ち切りデータについてのターンブルのアルゴリズム - 廿TT

追記(12月8日)

下のようなフィードバックを頂きました。ありがとうございます。

https://twitter.com/tomotana/status/541746787497697281

あーそっか、多くの人々にとって「数学」とか「統計学」って、「数字当てクイズ」のイメージなんだろうな。

統計学的に正確な議論」=「とにかく細かいとこまでぴったしカンカン数字を当てる」という理解なんだ。

だから「ビジネスの現場ではアカデミックなことやってもしょうがない。本来の目的を忘れてはならない」みたいな、ぼくからみれば支離滅裂なものいいが出てくるしまかり通るんだ。

何度おんなじことに気づきなおすんだろう、おれは。

統計学っていうのはそういうものじゃないですよ。

  • 「データ」=「生の食材」
  • 統計学的に正確な議論」=「ていねいに料理すること」
  • 「推定量」=「完成した料理」

だと思ってください。

「完成された料理をおいしくたべること」が「ざっくりと傾向を比較すること」です。

平均の推定量という一見かんたんそうな料理も、微分積分とか使ってていねいに作られているのです。

平均を見て施策を判断したりする人は「料理を食べる」側の人なので、料理法まで詳しく理解する必要はないです。料理をざっくり食べて構わないです。

でもいまぼくは、「料理を作る」話をしているので、いろいろ工夫して計算する必要があるのです。

ざっくり作って、食べる側の人が食中毒になっちゃったら大変でしょ?

(研究者でもなんでもないぼくごときが「統計学とは〜」なんて語るのはおこがましいのですが、その点については目をつぶってください。)