1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

R で graphical lasso を用いた異常検知 その2:前処理

Last updated at Posted at 2021-05-27

はじめに

graphical lasso を用いた異常検知を行ってみた。参考資料は末尾に記載した。今回は時系列、多変量、かつ異常と正常のラベルデータが付随しているデータセットであるSECOM Data Setを使用した。この記事のシリーズでは、

  1. R で graphical lasso を用いた異常検知 その1:基礎分析
  2. R で graphical lasso を用いた異常検知 その2:前処理  ← 今ここ!
  3. R で graphical lasso を用いた異常検知 その3:モデル構築
  4. 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")

secom_nas.png

欠損の処理

まず、欠損を含む列を分析対象から除外していく。今回は大幅に変数を減らしたいので、欠損の割合が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 でのモデル構築である。

参考文献(graphical lasso を用いた異常検知について)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?