はじめに
graphical lasso を用いた異常検知を行ってみた。参考資料は末尾に記載した。今回は時系列、多変量、かつ異常と正常のラベルデータが付随しているデータセットであるSECOM Data Setを使用した。この記事のシリーズでは、
- R で graphical lasso を用いた異常検知 その1:基礎分析
- R で graphical lasso を用いた異常検知 その2:前処理 ← 今ここ!
- R で graphical lasso を用いた異常検知 その3:モデル構築
- R で graphical lasso で用いた異常検知 その4:異常度の算出
の順番で書いていく。本記事では基礎分析の結果をもとに、モデル構築しやすいデータに加工を行っていく。以下、コードは 1. の記事のコードが実行済みであるとする。
数値項目の抜き出し
本来のデータセットであれば、量的変数のみでなく質的変数も含まれている。今回のデータセットは全て量的変数で構成されいるので、この操作をしてもデータの項目数は変わらないが、他のデータセットで分析を行う際には必要な手順である。
df.num <- df %>% select_if(Negate(is.character))
dim(df.num)
[1] 1567 590
#欠損の可視化
各項目で欠損がどれくらいの割合あるのか、可視化する。
na.count <- apply(is.na(df.num), 2, sum)
na.per <- na.count / nrow(df.num) * 100
barplot(na.per, ylab="Percentage of NAs [%]", xlab="Columns")
欠損の処理
まず、欠損を含む列を分析対象から除外していく。今回は大幅に変数を減らしたいので、欠損の割合が10%以上の項目をデータフレームから除外する。
threshold <- 10 #%
df.num.rem <- df.num
for (i in 1:length(na.per)) {
if (na.per[i] > threshold) {
df.num.rem <- df.num.rem %>% select(-names(na.per)[i])
}
}
dim(df.num.rem)
[1] 1567 538
この処理により 52 項目が削られた。
次に行方向にもデータを除外していく。欠損を含む行を削除したいので、その前にラベルデータとの結合をしてから処理をする。
#ラベルデータの結合
colnames(df_label) <- c("label", "datetime")
df.num.rem.join <- cbind(df_label, df.num.rem)
#行を削除
df.num.rem.join.omit <- na.omit(df.num.rem.join)
dim(df.num.rem.join.omit)
[1] 1393 540
174行のデータが除外されたのが分かる。
標準偏差=0の場合の処理
基礎分析の時に確認した一定値を取るデータについても分析対象から除外したいので、その項目の削除を行う。
sds <- df.num.rem.join.omit %>% select(-label) %>% select(-datetime) %>% summarise_all(sd)
tmp_sds_fil <- df.num.rem.join.omit %>% select(-label) %>% select(-datetime)
tmp_sds_fil <- tmp_sds_fil[,!(sds == 0.0)]
df.num.rem.join.omit.sdsfil <- cbind(data.frame(df.num.rem.join.omit$label), data.frame(df.num.rem.join.omit$datetime), tmp_sds_fil)
colnames(df.num.rem.join.omit.sdsfil)[1:2] <- c("label", "datetime")
dim(df.num.rem.join.omit.sdsfil)
[1] 1393 424
この処理により116項目が除外された。
データの重複の処理
日付を確認するといくつか重複した行があるのが見受けられる。今回の分析ではそういった項目も除外していく。
df.num.rem.join.omit.sdsfil.dup <- df.num.rem.join.omit.sdsfil[!duplicated(df.num.rem.join.omit.sdsfil$datetime),]
dim(df.num.rem.join.omit.sdsfil.dup)
[1] 1369 424
この処理によって24行のデータが除外された。
データの標準化
データ行、項目の整理が終わったので、残りのデータを標準化していく。これもscale
関数で簡単にできる。
tmp_scale <- df.num.rem.join.omit.sdsfil.dup %>% select(-label) %>% select(-datetime) %>% scale()
df.num.rem.join.omit.sdsfil.dup.scale <- cbind(data.frame(df.num.rem.join.omit.sdsfil.dup$label), data.frame(df.num.rem.join.omit.sdsfil.dup$datetime), tmp_scale)
colnames(df.num.rem.join.omit.sdsfil.dup.scale)[1:2] <- c("label", "datetime")
以上でデータの前処理は終了である。
おわりに
本記事では基礎分析の結果からモデル学習がしやすい形へのデータ加工を行った。この加工済みのデータセットを用いて、次はいよいよ graphical lasso でのモデル構築である。