どらちゃんのポッケ

R・統計・技術メモなど勉強ログ置き場

TwitterのAnomalyDetectionパッケージを使って、自分のライフログの異常検知をしてみた

TwitterのAnomalyDetectionパッケージ

  • githubにライブラリが置いてある

    • https://github.com/twitter/AnomalyDetection
    • このパッケージ、ソースコードとか、書き方とかも非常に参考になると思います
      • Travis CI configとかも書いてあるので、RであってもCIをキチンとやっているようだ
      • テストはtest_thatをつかって、異常検知された個数をアサーションしているみたい
      • ちゃんとパッケージをつくったことがないので、とても参考になる
      • さすが、Twitterさんです・・・。自分はR書ける方かもしれないという自信が一気になくなりました。
  • 概要

    • Twitterのブログに詳細なモノが記載されてます
    • Seasonal Hybrid ESD (S-H-ESD) というあるアルゴリズムで異常検知をしている
      • Percentage Points for a Generalized ESD Many-Outlier Procedureっていう論文らしいが、このアルゴリズムの詳細はざっと調べても引っかからなかった・・・
    • AnomalyDetectionTsメソッドで、異常検知する
    • help(AnomalyDetectionTs)でCRAN形式のhelpが表示されるが、大まかなパラメータは下記の通り
      • 渡すデータは、timestampと値のデータフレーム
      • max_anomsで最大何%のデータを異常とするのかの設定
      • alphaで有意水準の設定
      • directionでポジ・ネガ・両方の異常を検知するのかの設定

試してみた

  • Fitbitで毎日貯めている1日の総歩数の異常検知をやってみました
  • 使用するデータは、2014/1/1~2014/12/31までの1日の歩数(下記の感じ)
    •           date  step
        1 2014-01-01  6433
        2 2014-01-02  7435
        3 2014-01-03  1279
        4 2014-01-04  4731
        5 2014-01-05  4043
        6 2014-01-06 10235
      
  • 手順としては以下の通り
    1. Fitbitから1年分データを引っこ抜く(CSV
    2. 前処理(NAとか、数字の,とか)
    3. Rで解析

コード

  • 色々あれですが・・・

      install.packages("devtools")
      //proxyがある場合
      //library(httr)
      //set_config(
      //  use_proxy(url="proxy.server.address", port=port)
      //)
      devtools::install_github("twitter/AnomalyDetection")
      library(AnomalyDetection)
    
      d<- read.csv("fitbit_export_20150108.csv")
      dd <- d[c("date","step")]
      dd$date <- strptime(dd$date,"%Y.%m.%d")
      dd$step <- as.numeric(as.character(dd$step))
      dd <- dd[dd["step"] != 0,]
      dd <- na.omit(dd)
    
      res = AnomalyDetectionTs(dd, max_anoms=0.10, direction='both', alpha = 0.10, plot=TRUE)
      res$plot
      res$anoms
    

結果

  • グラフ

f:id:sleeping_micchi:20150110004246p:plain

  • 異常点

      > res$anoms
         timestamp anoms
      1 2014-02-10 16219
    
  • ということで、2014-02-10の16219が異常ということになりました

    • そいういえば、この日は、横浜行って、色々歩いたなぁと思い出しました
    • いろいろパラメータを変えてやってみましたが、何回やっても異常点は1つしかでてきませんでした
    • んー、アルゴリズムを理解しないと、使うには困りそうな気がします
    • あと、リアルタイムに異常かどうかを計算させるにはシンドイので、そういった用途にはJubutausの異常検知を使った方がよいと思います(Jubutaus以外のリアルタイム処理を知らないだけですが・・・)