はじめに
graphical lasso を用いた異常検知を行ってみた。参考資料は末尾に記載した。今回は時系列、多変量、かつ異常と正常のラベルデータが付随しているデータセットであるSECOM Data Setを使用した。この記事のシリーズでは、
- R で graphical lasso を用いた異常検知 その1:基礎分析
- R で graphical lasso を用いた異常検知 その2:前処理
- R で graphical lasso を用いた異常検知 その3:モデル構築 ← 今ここ!
- R で graphical lasso で用いた異常検知 その4:異常度の算出
の順番で書いていく。本記事では前処理の結果をもとに、データを正常データと異常データで分けてモデル構築を行っていく。以下、コードは 1., 2. の記事のコードが実行済みであるとする。
正常データと異常データの取り出し
label 項目の値に従ってデータを分けていく。分けたデータでネットワークの作成を行う。
コード
d <- df.num.rem.join.omit.sdsfil.dup.scale
df.norm <- d[d$label == -1,]
dim(df.norm)
df.abn <- d[d$label == 1,]
dim(df.abn)
出力
[1] 1271 424
[1] 98 424
glasso パッケージを用いたモデル構築
今回は正則化パラメータは rho = 0.4 で行う。
コード
library(glasso)
f <- function(df){
x <- df %>% select(-label) %>% select(-datetime) %>% as.matrix()
fit <- glasso(s = cov(x), rho = 0.4)
return(fit)
}
fit.norm <- f(df.norm)
fit.abn <- f(df.abn)
正常データと異常データのネットワークの比較
それぞれの精度行列からネットワーク図を作成する。400項目以上あるので、単純な図示では見難いと思うが、一応結果を載せておく。もし、もっとスマートな可視化方法をご存じの方が居れば是非コメント下さい!
コード
r <- ifelse(fit.norm$wi != 0, TRUE, FALSE)
diag(r) <- 0
colnames(r) <- df.norm %>% select(-label) %>% select(-datetime) %>% colnames()
rownames(r) <- df.norm %>% select(-label) %>% select(-datetime) %>% colnames()
r_abn <- ifelse(fit.abn$wi != 0, TRUE, FALSE)
diag(r_abn) <- 0
colnames(r_abn) <- df.abn %>% select(-label) %>% select(-datetime) %>% colnames()
rownames(r_abn) <- df.abn %>% select(-label) %>% select(-datetime) %>% colnames()
library(qgraph)
qgraph(r, layout = "circle")
qgraph(r_abn, layout = "circle")
正常と異常で変数同士の関連性が変化しているのがわかる。この違いの定量化は次の記事で行う。
おわりに
本記事ではRのglasso
パッケージを用いて正常データ、異常データのモデル化と、ネットワークの推定を行った。このネットワークの差を用いて、次の記事では異常度を定義し異常検知を行っていく。