João Neto “Support Vector Machines”

x1s <- c(.5,1,1,2,3,3.5,     1,3.5,4,5,5.5,6)
x2s <- c(3.5,1,2.5,2,1,1.2,  5.8,3,4,5,4,1)
ys <- c(rep(+1,6),          rep(-1,6))
my.data <- data.frame(x1=x1s, x2=x2s, type=as.factor(ys))
my.data
x1 x2 type
0.5 3.5 1
1.0 1.0 1
1.0 2.5 1
2.0 2.0 1
3.0 1.0 1
3.5 1.2 1
1.0 5.8 -1
3.5 3.0 -1
4.0 4.0 -1
5.0 5.0 -1
5.5 4.0 -1
6.0 1.0 -1
plot(my.data[,-3],col=(ys+3)/2, pch=19); abline(h=0,v=0,lty=3)

library(e1071)
svm.model <- svm(type ~ ., data=my.data, type='C-classification', kernel='linear',scale=FALSE)

plot(my.data[,-3],col=(ys+3)/2, pch=19, xlim=c(-1,6), ylim=c(-1,6)); abline(h=0,v=0,lty=3)
points(my.data[svm.model$index,c(1,2)],col="blue",cex=2) 
# show the support vectors

t(svm.model$coefs)#t転置
##      [,1]       [,2]       [,3]
## [1,]    1 -0.6487805 -0.3512195
svm.model$SV
##     x1  x2
## 6  3.5 1.2
## 8  3.5 3.0
## 12 6.0 1.0
# get parameters of hiperplane
w <- t(svm.model$coefs) %*% svm.model$SV
w#法線ベクトル
##              x1        x2
## [1,] -0.8780489 -1.097561
b <- -svm.model$rho
# in this 2D case the hyperplane is the line w[1,1]*x1 + w[1,2]*x2 + b = 0
abline(a=-b/w[1,2], b=-w[1,1]/w[1,2], col="blue", lty=3)#a切片
abline(a=3,b=-w[1,1]/w[1,2])

observations <- data.frame(x1=c(1,3.5),x2=c(4,3.5))
observations
x1 x2
1.0 4.0
3.5 3.5
plot(my.data[,-3],col=(ys+3)/2, pch=19, xlim=c(-1,6), ylim=c(-1,6)); abline(h=0,v=0,lty=3)
points(observations[1,], col="green", pch=19)
points(observations[2,], col="blue", pch=19)
abline(a=-b/w[1,2], b=-w[1,1]/w[1,2], col="blue", lty=3)

predict(svm.model, observations) # the results are right
##  1  2 
##  1 -1 
## Levels: -1 1

1 線形識別モデルの構成.

   \(z=w^Tx+w_0\) による等高線を考える。

1.1 等高線.

   \(z=ax+by+c\) による等高線を考える。

1.1.1 判別境界線.

z=0 のときが境界線です。
簡単のため法線ベクトル (a,b)=(1,1) とし、c=-5,-6 として表示します。
   \(y=-x-c\).

plot(my.data[,-3],col=(ys+3)/2, pch=19, xlim=c(0,6), ylim=c(0,6))
abline(h=0,v=0,lty=3)
a=1;b=1;c=-5
  abline((-c)/b,-b/a,col="blue", lty=3)
a=1;b=1;c=-6
  abline((-c)/b,-b/a,col="blue", lty=3)

2群の中間を通るようなcを求めると.
  c=-5.6 となります。(計算略).

zを変化させて等高線を表示します。

plot(my.data[,-3],col=(ys+3)/2, pch=19, xlim=c(0,6), ylim=c(0,6))
abline(h=0,v=0,lty=3)

a=1;b=1;c=-5.6
z=0
  abline((z-c)/b,-b/a,col="blue", lty=3)
for (i in 1:3) {
  z <- z + 1
  abline((z-c)/b,-b/a,col="black", lty=3)
}
z=0
for (i in 1:3) {
  z <- z - 1
  abline((z-c)/b,-b/a,col="red", lty=3)
}

z=1, z=-1 の等高線がサポートベクトルを通るように等高線の幅を調整します。右辺の係数を1.1倍します。

plot(my.data[,-3],col=(ys+3)/2, pch=19, xlim=c(0,6), ylim=c(0,6))
abline(h=0,v=0,lty=3)

a=1;b=1;c=-5.6
k=1.1
a=1*k;b=1*k;c=-5.6*k
z=0
  abline((z-c)/b,-b/a,col="blue", lty=3)
for (i in 1:3) {
  z <- z + 1
  abline((z-c)/b,-b/a,col="black", lty=3)
}
z=0
for (i in 1:3) {
  z <- z - 1
  abline((z-c)/b,-b/a,col="red", lty=3)
}

法線ベクトル(a,b)を変えて、サポートベクトルとのマージンが最大となる方向を探す。これがSVMの考え方だと思います。
(a,b)=(1,2)

plot(my.data[,-3],col=(ys+3)/2, pch=19, xlim=c(0,6), ylim=c(0,6))
abline(h=0,v=0,lty=3)

a=2;b=1;c=-5.6
k=1.1
a=2*k;b=1*k;c=-5.6*k
z=0
  abline((z-c)/b,-b/a,col="blue", lty=3)
for (i in 1:3) {
  z <- z + 1
  abline((z-c)/b,-b/a,col="black", lty=3)
}
z=0
for (i in 1:3) {
  z <- z - 1
  abline((z-c)/b,-b/a,col="red", lty=3)
}

これは、マージンが小さくなっています。