2015年7月22日水曜日

h2oでanomaly detectionを動かしてみる~後編~

データアナリティクス・グループの梅田です。



今回は、前編の内容を踏まえて、h2oのanomaly detectionのAPIに実際にデータを与えて動かしてみます。

異常検知の実験ということで、簡易的なアクセスログを想定した、以下のような内容のダミーデータを用意しました。

  • 100人のユーザがランダムな順番でアクセスしてくるシステムのログを想定した内容
  • 各ユーザは、固有のIPアドレスを持つ環境から、固有のID(4桁の数字)を入力してアクセスしてくる
  • 各ユーザの環境は、以下6種類のいずれかで、対応するUser-Agentがログに記録される。ユーザが環境を変えることはない。
    Windows環境+IE11、Windows環境+Chrome、Windows環境+Firefox、iPhone、iPad、Android
  • アクセス時に、ID・IPアドレス・User-Agentが記録される

データの構成は以下のようになっています。

IDIPAddressUserAgentAccessTime
425857.78.99.121Mozilla/5.0 (Windows NT 6.1;…2015/04/01 0:00:01
475362.83.104.126Mozilla/5.0 (Linux; Android 5.1;…2015/04/01 0:00:02

この状況で、上記の法則どおりのログ9863行の中に、性質が異なるログ137行を混入させて、計10000件のログとしました。
”性質が異なる”の内訳は次の3パターンです。
  1. 他の誰とも一致しないIPアドレス・環境(Mac環境のUser-Agent)から、他に誰も使っていないID(5桁の数字)でアクセスしてくる
  2. ID:5347番を装ってアクセスしてきているが、IPアドレスとUser-Agentが、本来の持ち主のものと異なっている(他の誰とも一致しない)
  3. ID:2179番と同一の環境から、他に誰も使っていないID(5桁の数字)でアクセスしてきた
R上でh2oを起動して、このデータを読み込ませ、anomaly detectionを動かしてみます。
前編で記載したように、autoencoder=Tを指定してディープラーニングのモデルを構築します。
今回のモデルは、以下のパラメータを与えて構築しました。目的変数(y)は、データの1列目(ID)としています。
構築したモデルと元データをh2o.anomalyに与えて実行します。

datafile_path <- "./accesslogdata.csv"
datafile <- h2o.importFile(localH2O, path = datafile_path, key="datafile")

dlmodel<-h2o.deeplearning(x=seq(1,4), y=1,
data=datafile,
classification=T,
hidden=c(20,20),
activation="Rectifier",
autoencoder=T,
ignore_const_cols=F)

anomaly_data <- h2o.anomaly(data=datafile,model=dlmodel)

計算結果をファイルに出力してみると、データの各行に対応する平均二乗誤差が出力されていました。

"Reconstruction.MSE"
3.4291465862408354E-4
3.428401589909364E-4


これだけでは出力値の傾向がわからないので、Rの機能を使って散布図で図示してみました。X軸がデータのインデックス(行番号)、Y軸が平均二乗誤差の値です。

result<-as.data.frame(anomaly_data)
plot(result$Reconstruction.MSE,pch=20,col=rgb(1,0,0))
すると、大多数の値が0.00034より少し多いくらいの範囲に集中しているのに対し、そこから離れたところに値が約0.000356の集団と、値が約0.000424の集団ができています。元データと照合すると、それぞれa,cのパターンと対応していました。

今回のデータでは、IDごとに環境が決まっており、そのIDを目的変数とするモデルで計算を行ったので、単純にIDの値が5桁である、パターンa,cの行が傾向の違う値となったようです。パターンbのデータに対しても平均二乗誤差値は計算されていたものの、他のIDの値と似た値になり、他のデータと比べて明確な差分は出ませんでした。

この後、モデル作成時のパラメータである隠れ層の数をhidden=c(50,50)、hidden=c(20,20,20)に変えて実行してみましたが、前者は最初の実行時と同じ結果になり、特に変化は見られませんでした。後者は「モデルが不安定でanomaly計算ができない」とのことでエラーとなってしまいました。我流実行ゆえ、理論的にありえないモデル作成をしてしまったのでしょう。

結果として、簡単な異常検知ができることはわかりましたが、真価を発揮させるにはそれなりの調整が必要そうです。引き続き調べてみたいと思います。


0 件のコメント:

コメントを投稿