3.6 節 支持ベクトルデータ記述法に基づく異常判定

本に載せなかったカラーの等高線図のRコードです (すみませんがコードに関する質問は受け付けておりません)。

支持ベクトルデータ記述法 (Support vector data description; SVDD) はいわゆる1クラス支持ベクトル分類器 (one-class support vector machine) と等価であることが知られています。「SVMによる異常検知」ということです。

まず必要なライブラリーを読み、乱数のシードを決めた上で、乱数でデータを作ります。

library(kernlab)
set.seed(1)
# two-dimensional distribution
x <- rbind(matrix(rnorm(120),ncol=2),matrix(rnorm(120,mean=3),ncol=2))
x <- scale(x)

\(\nu=0.1\) にして、SVDDのモデルを学習します。学習する部分は1行で書けてしまいます。便利です。

rbf <- rbfdot(sigma=0.5)
ocsvm <- ksvm(x,type="one-svc",kernel=rbf,nu=0.1)

支持ベクトル、つまり、分離境界を頑張って支えてくれているベクトルを黒く塗って散布図を作ってみましょう。

colorcode<- rep(0, nrow(x))
colorcode[ocsvm@alphaindex] <-1
plot(x, pch=21, bg=colorcode)

これだと味気ないのでカラーの等高線図を作ってみましょう。これは多少面倒です。説明は省きますがまず2つほど関数を定義します。

getR2s.ocsvm  <- function(x_selected, ocsvm, knl,CC=1){
  
  idx.onSphere <- which(ocsvm@alpha != CC)
  R2s <- rep(-1, length(idx.onSphere))
  
  # Computing R2
  XX <- ocsvm@xmatrix
  iid <- 1
  for(idx in idx.onSphere){
    x.onSphere <- ocsvm@xmatrix[idx,]
    R2s[iid] <- getR2.ocsvm(x.onSphere, ocsvm, knl,CC)
    iid <- iid + 1 
  }
  return(R2s)
}
getR2.ocsvm <- function(x_selected, ocsvm, knl,CC=1){
  XX <- ocsvm@xmatrix
  Knn <- kernelMatrix(knl,t(x_selected),t(x_selected)) # must be 1 for rbf kernel
  Ka <- kernelMult(knl,x=XX,y=XX,z=ocsvm@alpha)
  aKa <- ocsvm@alpha %*% Ka 

  K <- kernelMatrix(knl,x=XX,y=t(x_selected)) # column vector
  aK <- ocsvm@alpha %*% K
  return(Knn + aKa -2.* aK)
}

可視化の色は、SVDDにおける超球の半径\(R^2\)に関係していますので、その情報を取り出します。

# Select on-sphere samples to check the value of R
R2s <- getR2s.ocsvm(x_selected,ocsvm,rbf)

最後に等高線図を書きます。お使いのPCの能力によっては、数分時間がかかるかもしれません。

# Drawing contor
N1 <- 100
N2 <- 100
x1min <- min(ocsvm@xmatrix[,1])
x1max <- max(ocsvm@xmatrix[,1])
x2min <- min(ocsvm@xmatrix[,2])
x2max <- max(ocsvm@xmatrix[,2])
x1s <- seq(x1min,x1max, length=N1)
x2s <- seq(x2min,x2max, length=N2)
zz <- matrix(0,nr=N2,nc=N1)
for(ind in 1:N1){
  for(ind2 in 1:N2){
  xin <- c(x1s[ind],x2s[ind2])
  zz[ind,ind2] <- getR2.ocsvm(xin,ocsvm,rbf) - mean(R2s)
}}
d <- list(x=x1s,y=x2s,z=zz)
image(d,col = terrain.colors(9))
contour(d,add=T)
points(x,pch=21,bg=colorcode,cex=1.5)

LS0tDQp0aXRsZTogIuWFpemWgCDmqZ/morDlrabnv5LjgavjgojjgovnlbDluLjmpJznn6UiDQphdXRob3I6ICLkupXmiYsg5YmbIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIDMuNiDnr4Ag5pSv5oyB44OZ44Kv44OI44Or44OH44O844K/6KiY6L+w5rOV44Gr5Z+644Gl44GP55Ww5bi45Yik5a6aDQoNCuacrOOBq+i8ieOBm+OBquOBi+OBo+OBn+OCq+ODqeODvOOBruetiemrmOe3muWbs+OBrlLjgrPjg7zjg4njgafjgZkgKOOBmeOBv+OBvuOBm+OCk+OBjOOCs+ODvOODieOBq+mWouOBmeOCi+izquWVj+OBr+WPl+OBkeS7mOOBkeOBpuOBiuOCiuOBvuOBm+OCkynjgIINCg0K5pSv5oyB44OZ44Kv44OI44Or44OH44O844K/6KiY6L+w5rOVIChTdXBwb3J0IHZlY3RvciBkYXRhIGRlc2NyaXB0aW9uOyBTVkREKSDjga/jgYTjgo/jgobjgosx44Kv44Op44K55pSv5oyB44OZ44Kv44OI44Or5YiG6aGe5ZmoIChvbmUtY2xhc3Mgc3VwcG9ydCB2ZWN0b3IgbWFjaGluZSkg44Go562J5L6h44Gn44GC44KL44GT44Go44GM55+l44KJ44KM44Gm44GE44G+44GZ44CC44CMU1ZN44Gr44KI44KL55Ww5bi45qSc55+l44CN44Go44GE44GG44GT44Go44Gn44GZ44CCDQoNCuOBvuOBmuW/heimgeOBquODqeOCpOODluODqeODquODvOOCkuiqreOBv+OAgeS5seaVsOOBruOCt+ODvOODieOCkuaxuuOCgeOBn+S4iuOBp+OAgeS5seaVsOOBp+ODh+ODvOOCv+OCkuS9nOOCiuOBvuOBmeOAgg0KDQpgYGB7cn0NCmxpYnJhcnkoa2VybmxhYikNCnNldC5zZWVkKDEpDQojIHR3by1kaW1lbnNpb25hbCBkaXN0cmlidXRpb24NCnggPC0gcmJpbmQobWF0cml4KHJub3JtKDEyMCksbmNvbD0yKSxtYXRyaXgocm5vcm0oMTIwLG1lYW49MyksbmNvbD0yKSkNCnggPC0gc2NhbGUoeCkNCmBgYA0KDQokXG51PTAuMSQg44Gr44GX44Gm44CBU1ZEROOBruODouODh+ODq+OCkuWtpue/kuOBl+OBvuOBmeOAguWtpue/kuOBmeOCi+mDqOWIhuOBrzHooYzjgafmm7jjgZHjgabjgZfjgb7jgYTjgb7jgZnjgILkvr/liKnjgafjgZnjgIINCg0KYGBge3J9DQpyYmYgPC0gcmJmZG90KHNpZ21hPTAuNSkNCm9jc3ZtIDwtIGtzdm0oeCx0eXBlPSJvbmUtc3ZjIixrZXJuZWw9cmJmLG51PTAuMSkNCmBgYA0KDQrmlK/mjIHjg5njgq/jg4jjg6vjgIHjgaTjgb7jgorjgIHliIbpm6LlooPnlYzjgpLpoJHlvLXjgaPjgabmlK/jgYjjgabjgY/jgozjgabjgYTjgovjg5njgq/jg4jjg6vjgpLpu5LjgY/loZfjgaPjgabmlaPluIPlm7PjgpLkvZzjgaPjgabjgb/jgb7jgZfjgofjgYbjgIINCg0KYGBge3J9DQpjb2xvcmNvZGU8LSByZXAoMCwgbnJvdyh4KSkNCmNvbG9yY29kZVtvY3N2bUBhbHBoYWluZGV4XSA8LTENCnBsb3QoeCwgcGNoPTIxLCBiZz1jb2xvcmNvZGUpDQpgYGANCuOBk+OCjOOBoOOBqOWRs+awl+OBquOBhOOBruOBp+OCq+ODqeODvOOBruetiemrmOe3muWbs+OCkuS9nOOBo+OBpuOBv+OBvuOBl+OCh+OBhuOAguOBk+OCjOOBr+WkmuWwkemdouWAkuOBp+OBmeOAguiqrOaYjuOBr+ecgeOBjeOBvuOBmeOBjOOBvuOBmu+8kuOBpOOBu+OBqemWouaVsOOCkuWumue+qeOBl+OBvuOBmeOAgg0KDQpgYGB7cn0NCmdldFIycy5vY3N2bSAgPC0gZnVuY3Rpb24oeF9zZWxlY3RlZCwgb2Nzdm0sIGtubCxDQz0xKXsNCiAgDQogIGlkeC5vblNwaGVyZSA8LSB3aGljaChvY3N2bUBhbHBoYSAhPSBDQykNCiAgUjJzIDwtIHJlcCgtMSwgbGVuZ3RoKGlkeC5vblNwaGVyZSkpDQogIA0KICAjIENvbXB1dGluZyBSMg0KICBYWCA8LSBvY3N2bUB4bWF0cml4DQogIGlpZCA8LSAxDQogIGZvcihpZHggaW4gaWR4Lm9uU3BoZXJlKXsNCiAgICB4Lm9uU3BoZXJlIDwtIG9jc3ZtQHhtYXRyaXhbaWR4LF0NCiAgICBSMnNbaWlkXSA8LSBnZXRSMi5vY3N2bSh4Lm9uU3BoZXJlLCBvY3N2bSwga25sLENDKQ0KICAgIGlpZCA8LSBpaWQgKyAxIA0KICB9DQogIHJldHVybihSMnMpDQp9DQpnZXRSMi5vY3N2bSA8LSBmdW5jdGlvbih4X3NlbGVjdGVkLCBvY3N2bSwga25sLENDPTEpew0KICBYWCA8LSBvY3N2bUB4bWF0cml4DQogIEtubiA8LSBrZXJuZWxNYXRyaXgoa25sLHQoeF9zZWxlY3RlZCksdCh4X3NlbGVjdGVkKSkgIyBtdXN0IGJlIDEgZm9yIHJiZiBrZXJuZWwNCiAgS2EgPC0ga2VybmVsTXVsdChrbmwseD1YWCx5PVhYLHo9b2Nzdm1AYWxwaGEpDQogIGFLYSA8LSBvY3N2bUBhbHBoYSAlKiUgS2EgDQoNCiAgSyA8LSBrZXJuZWxNYXRyaXgoa25sLHg9WFgseT10KHhfc2VsZWN0ZWQpKSAjIGNvbHVtbiB2ZWN0b3INCiAgYUsgPC0gb2Nzdm1AYWxwaGEgJSolIEsNCiAgcmV0dXJuKEtubiArIGFLYSAtMi4qIGFLKQ0KfQ0KYGBgDQoNCuWPr+imluWMluOBruiJsuOBr+OAgVNWRETjgavjgYrjgZHjgovotoXnkIPjga7ljYrlvoQkUl4yJOOBq+mWouS/guOBl+OBpuOBhOOBvuOBmeOBruOBp+OAgeOBneOBruaDheWgseOCkuWPluOCiuWHuuOBl+OBvuOBmeOAgg0KDQpgYGB7cn0NCiMgU2VsZWN0IG9uLXNwaGVyZSBzYW1wbGVzIHRvIGNoZWNrIHRoZSB2YWx1ZSBvZiBSDQpSMnMgPC0gZ2V0UjJzLm9jc3ZtKHhfc2VsZWN0ZWQsb2Nzdm0scmJmKQ0KYGBgDQoNCuacgOW+jOOBq+etiemrmOe3muWbs+OCkuabuOOBjeOBvuOBmeOAguOBiuS9v+OBhOOBrlBD44Gu6IO95Yqb44Gr44KI44Gj44Gm44Gv44CB5pWw5YiG5pmC6ZaT44GM44GL44GL44KL44GL44KC44GX44KM44G+44Gb44KT44CCDQoNCmBgYHtyfQ0KIyBEcmF3aW5nIGNvbnRvcg0KTjEgPC0gMTAwDQpOMiA8LSAxMDANCngxbWluIDwtIG1pbihvY3N2bUB4bWF0cml4WywxXSkNCngxbWF4IDwtIG1heChvY3N2bUB4bWF0cml4WywxXSkNCngybWluIDwtIG1pbihvY3N2bUB4bWF0cml4WywyXSkNCngybWF4IDwtIG1heChvY3N2bUB4bWF0cml4WywyXSkNCngxcyA8LSBzZXEoeDFtaW4seDFtYXgsIGxlbmd0aD1OMSkNCngycyA8LSBzZXEoeDJtaW4seDJtYXgsIGxlbmd0aD1OMikNCnp6IDwtIG1hdHJpeCgwLG5yPU4yLG5jPU4xKQ0KZm9yKGluZCBpbiAxOk4xKXsNCiAgZm9yKGluZDIgaW4gMTpOMil7DQogIHhpbiA8LSBjKHgxc1tpbmRdLHgyc1tpbmQyXSkNCiAgenpbaW5kLGluZDJdIDwtIGdldFIyLm9jc3ZtKHhpbixvY3N2bSxyYmYpIC0gbWVhbihSMnMpDQp9fQ0KZCA8LSBsaXN0KHg9eDFzLHk9eDJzLHo9enopDQppbWFnZShkLGNvbCA9IHRlcnJhaW4uY29sb3JzKDkpKQ0KY29udG91cihkLGFkZD1UKQ0KcG9pbnRzKHgscGNoPTIxLGJnPWNvbG9yY29kZSxjZXg9MS41KQ0KYGBgDQoNCg==