SVMの二次元プロット

SVM 2Dplot

スーパーpre記法によるソースコードの色分けR言語に対応していると聞いたので、早速ためしてみる。

ちなみに以下のRスクリプトは、Support Vector Machineによる2次元データ判別の様子をScholkopfの本の表紙(ISBN:0262194759)みたいにカッコよくプロットしたいという理由から、かつて作成していたもの。右の画像はExample2の実行結果。大きい画像はここに。

Support Vectorは二重丸、クラス間境界は実線で、境界を基準としたdecision valueによって色づけがしてある。実行にはパッケージe1071が必要。学生が発表のときPowerPointに貼り付ける程度の画像作成用途に最適かと思われる。

## Usage
# ---- args ----
# x: 二次元の訓練データ(列が変数の行列)
# label : 訓練データの行に対応するラベルベクトル
#     (factor:classify, numeric:regression)
# expand: 表示領域の拡大倍率
# resol : image表示の際の解像度
# color : image表示に使用する色
# ... : svm()に渡す引数(kernel="sigmoid"など)
#
# ---- value ----
# 返り値はsvm()の返り値と同じ

conplot.svm2d <- function( x, label, expand=1.2,
    resol=c(100,100), color=heat.colors(40), ... )
{
  require(e1071)
  rx <- range(x[,1])
  ry <- range(x[,2])
  rx <- rx + scale(rx, scale=F)*(expand-1)
  ry <- ry + scale(ry, scale=F)*(expand-1)
  tx <- seq(rx[1], rx[2], len=resol[1])
  ty <- seq(ry[1], ry[2], len=resol[2])
  grd <- expand.grid(tx, ty)
  model <- svm(x, label, ...)
  pred  <- predict(model, grd, decision.values=T)
  hmap  <- matrix(attr(pred, "decision.values"), resol[1], resol[2])
  image(tx, ty, hmap, xlab="", ylab="", col=color)
  contour(tx, ty, hmap, level=-1:1, drawlabels=F, lty=c(3,1,3), add=T)
  points(x[label == unique(label)[1],], pch=21, bg="black")
  points(x[label == unique(label)[2],], pch=21, bg="white")
  points(x[model$index,], cex=1.6)
  title("SVM - 2D plot (e1071)", family="serif")
  box()
  invisible(model)
}

## Example1: 2D-Gaussian
# library(MASS)
# x = rbind(mvrnorm(100,c(0,0),diag(2)), mvrnorm(100,c(3,3),diag(2)*2))
# label = rep(c(-1,1), each=100)
# conplot.svm2d(x, factor(label), kernel="radial", type="C")

## Example2: Circle in a Square Problem
# library(mlbench)
# train <- mlbench.circle(100)
# conplot.svm2d(train$x, train$cl, kernel="rad", type="C", gamma=4)