R で擬似アクセスログを作ってみた

アクセスログっぽいものに対する単純な分析の練習用のデータがほしくて、擬似アクセスログを生成するコードを書いてみました。
https://gist.github.com/abicky/dfdeaec9efded25b733a#file-access_logs-r

擬似アクセスログの仮定

  • ユーザの状態(新規ユーザ、アクティブユーザ etc.)によってセッションの間隔(来訪間隔)が異なる
  • ページによってページ遷移の間隔が異なる
  • 同じユーザはだいたい同じような時間帯にアクセスする

っで、これらの仮定を表現するのに Markov renewal process が良さそうだったので採用したつもりです。「こんなの Markov renewal process じゃない!」と言われそうなので、あくまで「つもり」です。

20150504152106

次のコード(余計な処理は省略)がセッションごとのアクセスを表現しているところです。

        page <- sample(PAGES, 1, prob = INIT_PAGE_PROB)
        access_count <- access_count_per_session()
        repeat {
            current_row <- current_row + 1L
            log_times[current_row] <- time
            log_user_ids[current_row] <- user_id
            log_pages[current_row] <- page
            access_count <- access_count - 1
            if (access_count == 0) {
                break
            }
            time <- time + page_interval_time(page)
            page <- sample(PAGES, 1, prob = PAGE_TRANS_PROB[page, ])
        }     

まず、access_count_per_session() で平均 3 のポアソン分布からセッションのアクセス回数を取得し、page_interval_time(page) で負の二項分布(というより幾何分布)から現在のページから次のページにアクセスする際の間隔を取得しています。

セッション間のアクセスも同様な感じで表現しています。

擬似アクセスログを使って単純な分析をしてみる

gist のスクリプトを source で読み込むと access_logs が作成されます。要 data.table です。

> source("https://gist.githubusercontent.com/abicky/dfdeaec9efded25b733a/raw/ce84de8e07f396345229bc03d97ea31c6e785322/access_logs.R")
https:// URLs are not supported by the default method: trying "libcurl"
> access_logs
              time   user_id  page      idate    itime
     1: 1430611600 896697200 page1 2015-05-03 09:06:40
     2: 1430611601 896697200 page2 2015-05-03 09:06:41
     3: 1430611603 896697200 page1 2015-05-03 09:06:43
     4: 1430698335 896697200 page1 2015-05-04 09:12:15
     5: 1431477553 896697200 page1 2015-05-13 09:39:13
    ---                                               
237665: 1431221588 568116239 page1 2015-05-10 10:33:08
237666: 1431221602 568116239 page2 2015-05-10 10:33:22
237667: 1431221605 568116239 page1 2015-05-10 10:33:25
237668: 1431563407 568116239 page1 2015-05-14 09:30:07
237669: 1431563471 568116239 page3 2015-05-14 09:31:11

なんかアクセスログっぽいですよね!!

経過日数ごとのユーザ数

> first_access_datetime <- unique(access_logs[, .(user_id, idate, itime)][order(user_id, idate, itime)], by = "user_id")
> setnames(first_access_datetime, c("idate", "itime"), c("first_idate", "first_itime"))
> merged_logs <- merge(access_logs, first_access_datetime, by = "user_id")
> merged_logs[, elapsed_days := idate - first_idate]
> elapsed_days <- as.integer(unique(merged_logs, by = c("user_id", "elapsed_days"))$elapsed_days)
> library(MASS)
> truehist(elapsed_days, prob = FALSE, h = 1)

20150504152107

アクセス時間のヒストグラム

> library(MASS)
> hour <- hour(access_logs$itime)
> truehist(hour, prob = FALSE, h = 1)

20150504152108

なんかどちらの結果を見てもログっぽいですよね!!
というわけで、R を使ったアクセスログの分析の練習などに使ってもらえると幸いです。