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)
}
これは、マージンが小さくなっています。