82

library(quadprog)

# 関数の定義
svm.1 <- function(X, y, C) {
  eps <- 0.0001
  n <- nrow(X)
  Dmat <- matrix(nrow = n, ncol = n)
  for (i in 1:n)
    for (j in 1:n)
      Dmat[i, j] <- sum(X[i, ] * X[j, ]) * y[i] * y[j]
  Dmat <- Dmat + eps * diag(n)
  dvec <- rep(1, n)
  Amat <- matrix(nrow = (2 * n + 1), ncol = n)
  Amat[1, ] <- y
  Amat[2:(n + 1), 1:n] <- -diag(n)
  Amat[(n + 2):(2 * n + 1), 1:n] <- diag(n)
  Amat <- t(Amat)
  bvec <- c(0, rep(-C,n), rep(0,n))
  meq <- 1
  alpha <- solve.QP(Dmat, dvec, Amat, bvec = bvec, meq = 1)$solution
  beta <- drop((alpha * y) %*% X)
  index <- (1:n)[eps < alpha & alpha < C - eps]
  beta.0 <- mean(y[index] - X[index, ] %*% beta)
  return(list(beta = beta, beta.0 = beta.0[1]))
}

# svm.1を用いた実行
a <- rnorm(1)
b <- rnorm(1)
n <- 100
X <- matrix(rnorm(n * 2), ncol = 2, nrow =n)
y <- sign(a * X[, 1] + b * X[, 2] + 0.3 * rnorm(n))
plot(-3:3, -3:3, xlab = "X[, 1]", ylab = "X[, 2]", type = "n")
for (i in 1:n) {
  if (y[i] == 1) {
    points(X[i, 1], X[i, 2], col = "red")
  } else {
    points(X[i, 1], X[i, 2], col = "blue")
  }
}
qq <- svm.1(X, y, 10)
abline(-qq$beta.0 / qq$beta[2], -qq$beta[1] / qq$beta[2])

83

K.poly <- function(x, y) {
  return((1 + t(x) %*% y) ^ 2)
}

84

K.linear <- function(x, y) {
  return(t(x) %*% y)
}

85

svm.2 <- function(X, y, C, K) {  
  eps <- 0.0001
  n <- nrow(X)
  Dmat <- matrix(nrow = n, ncol = n)
  for (i in 1:n)
    for(j in 1:n)
      Dmat[i, j] <- K(X[i, ], X[j, ]) * y[i] * y[j]
  Dmat <- Dmat + eps * diag(n)
  dvec <- rep(1, n)
  Amat <- matrix(nrow = (2 * n + 1), ncol = n)
  Amat[1, ] <- y
  Amat[2:(n + 1), 1:n] <- -diag(n)
  Amat[(n + 2):(2 * n + 1), 1:n] <- diag(n)
  Amat <- t(Amat)
  bvec <- c(0, -C * rep(1, n), rep(0, n))
  meq <- 1
  alpha <- solve.QP(Dmat, dvec, Amat, bvec = bvec, meq = 1)$solution
  index <- (1:n)[eps < alpha & alpha < C - eps]
  beta <- drop((alpha * y) %*% X)
  beta.0 <- mean(y[index] - X[index, ] %*% beta)
  return(list(alpha = alpha, beta.0 = beta.0))
}
# 関数の定義
plot.kernel <- function(K, lty) {
  qq <- svm.2(X, y, 1, K)
  alpha <- qq$alpha
  beta.0 <- qq$beta.0

  f <- function(u, v) {
    x <- c(u, v)
    S <- beta.0
    for (i in 1:n)
      S <- S + alpha[i]*y[i]*K(X[i,],x)
    return(S)
  }
  
  u <- seq(-2, 2, .1)
  v <- seq(-2, 2, .1)
  w <- array(dim = c(41, 41))
  for (i in 1:41)
    for (j in 1:41)
      w[i, j] <- f(u[i], v[j])
  contour(u, v, w, level = 0, add = TRUE, lty = lty)
}

# 実行
a <- 3
b <- -1
n <- 200
X <- matrix(rnorm(n * 2), ncol = 2, nrow = n)
y <- sign(a * X[, 1] + b * X[, 2] ^ 2 + 0.3 * rnorm(n))
plot(-3:3, -3:3, xlab = "X[, 1]", ylab = "X[, 2]", type = "n")
for (i in 1:n) {
  if (y[i] == 1) {
    points(X[i, 1], X[i, 2], col = "red")
  } else {
    points(X[i, 1], X[i, 2], col = "blue")
  }
}
plot.kernel(K.linear, 1)
plot.kernel(K.poly, 2)

86

library(e1071)

x <- matrix(rnorm(200 * 2), ncol = 2)
x[1:100, ] <- x[1:100, ] + 2
x[101:150, ] <- x[101:150, ] - 2
y <- c(rep(1, 150), rep(2, 50))
dat <- data.frame(x = x, y = as.factor(y))
train <- sample(200, 100)
svmfit <- svm(y ~ ., data = dat[train, ], kernel = "radial",
              gamma = 1, cost = 1)
plot(svmfit, dat[train, ])

x <- matrix(rnorm(200 * 2), ncol = 2)
x[1:100, ] <- x[1:100, ] + 2
x[101:150, ] <- x[101:150, ] - 2
y <- c(rep(1, 150), rep(2, 50))
dat <- data.frame(x = x, y = as.factor(y))
train <- sample(200, 100)
svmfit <- svm(y ~ ., data = dat[train, ], kernel = "radial",
              gamma = 1, cost = 100)
plot(svmfit, dat[train, ])

tune.out <- tune(svm, y ~ ., data = dat[train, ], kernel = "radial",
                 ranges = list(cost = c(0.1, 1, 10, 100, 1000),
                               gamma = c(0.5, 1, 2, 3, 4)))
summary (tune.out)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma
##     1     3
## 
## - best performance: 0.09 
## 
## - Detailed performance results:
##     cost gamma error dispersion
## 1  1e-01   0.5  0.25 0.12692955
## 2  1e+00   0.5  0.11 0.07378648
## 3  1e+01   0.5  0.12 0.07888106
## 4  1e+02   0.5  0.11 0.07378648
## 5  1e+03   0.5  0.14 0.06992059
## 6  1e-01   1.0  0.22 0.14757296
## 7  1e+00   1.0  0.11 0.07378648
## 8  1e+01   1.0  0.11 0.07378648
## 9  1e+02   1.0  0.13 0.08232726
## 10 1e+03   1.0  0.18 0.07888106
## 11 1e-01   2.0  0.22 0.14757296
## 12 1e+00   2.0  0.10 0.06666667
## 13 1e+01   2.0  0.12 0.09189366
## 14 1e+02   2.0  0.19 0.07378648
## 15 1e+03   2.0  0.18 0.11352924
## 16 1e-01   3.0  0.25 0.12692955
## 17 1e+00   3.0  0.09 0.07378648
## 18 1e+01   3.0  0.12 0.09189366
## 19 1e+02   3.0  0.18 0.09189366
## 20 1e+03   3.0  0.16 0.08432740
## 21 1e-01   4.0  0.25 0.12692955
## 22 1e+00   4.0  0.09 0.07378648
## 23 1e+01   4.0  0.14 0.09660918
## 24 1e+02   4.0  0.15 0.11785113
## 25 1e+03   4.0  0.17 0.08232726

87

df <- iris
x <- df[, 1:4]
y <- as.factor(df[, 5])
m <- 30
train <- sample(1:150, 150 - m)
x.train <- x[train, ]
y.train <- y[train]
dat <- data.frame(x.train, y.train)
svmfit <- svm(y.train ~ ., data = dat, kernel = "radial", cost = 10, gamma = 1)
x.test <- x[-train, ]
y.test <- y[-train]
table(y.test, predict(svmfit, x.test))
##             
## y.test       setosa versicolor virginica
##   setosa         11          0         0
##   versicolor      0         11         1
##   virginica       0          1         6