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
\(z=w^Tx+w_0\) による等高線を考える。
\(z=ax+by+c\) による等高線を考える。
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)
}
これは、マージンが小さくなっています。