e1071
set.seed(123)
x1 <- runif(200, 0, 1)
x2 <- runif(200, 0, 1)
y <- ((x1^2 + x2^2 - 2*x1*x2 < 0.25) & (x1+x2+x1^2)/(x1*x2) < 6) | (x1 + x2 < 0.3)
y <- factor(as.numeric(y)+1)
df <- data.frame(x1, x2, y)
png('svm1.png')
plot(x1, x2, col=y)
dev.off()
str(df)
## 'data.frame': 200 obs. of 3 variables:
## $ x1: num 0.288 0.788 0.409 0.883 0.94 ...
## $ x2: num 0.239 0.962 0.601 0.515 0.403 ...
## $ y : Factor w/ 2 levels "1","2": 1 2 2 2 1 1 1 1 1 1 ...
Możemy dopasować model, domyśle jądro to jądro radialne. Na wykresie widać: prawdziwe klasy - oznaczone kolorem znaczków “x” i “o” czerwony/czarny, klasy przewidywane przez model - pełny kolor różowy/cyjan, “x” - wektory podpierające, “o” - pozostałe punkty w danych.
library(e1071)
svm.default <- svm(y~., data=df)
png('svm2.png')
plot(svm.default, data=df, formula=x2~x1)
dev.off()
obs <- data.frame(x1=0.5, x2=0.6)
mod.svm <- svm(y~., data=df)
predict(mod.svm, newdata=obs)
## 1
## 2
## Levels: 1 2
mod.svm <- svm(y~., data=df, probability=TRUE)
predict(mod.svm, newdata=obs, probability=TRUE)
## 1
## 2
## attr(,"probabilities")
## 1 2
## 1 0.0004886053 0.9995114
## Levels: 1 2
attr(predict(mod.svm, newdata=obs, probability=TRUE), "probabilities")
## 1 2
## 1 0.0004886053 0.9995114
svm.rad <- svm(y~., data=df, kernel="radial")
svm.lin <- svm(y~., data=df, kernel="linear")
svm.pol <- svm(y~., data=df, kernel="polynomial", degree=3)
svm.sig <- svm(y~., data=df, kernel="sigmoid")
png('svm31.png')
plot(svm.rad, data=df)
dev.off()
png('svm32.png')
plot(svm.lin, data=df)
dev.off()
png('svm33.png')
plot(svm.pol, data=df)
dev.off()
png('svm34.png')
plot(svm.sig, data=df)
dev.off()
gamma
, parametr potrzebny do wszystkich jąder oprócz liniowego:
cost
- ten parametr, który stoi przy wyrazie odpowiadającym regularyzacji
degree
- jeśli jądro wielomianowe, to to odpowiada za stopień wielomianu
coef0
- do wielomianowego i sigmoidalnego
mod.inne.parametry <- svm(y~., data=df, gamma=0.1, cost=1.5)
par.svm <- tune.svm(y~., data=df,
gamma=c(0.01, 0.3, 0.5, 0.8, 1),
cost=c(1, 1.5, 2, 2.5, 3))
summary(par.svm)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## gamma cost
## 1 2.5
##
## - best performance: 0.045
##
## - Detailed performance results:
## gamma cost error dispersion
## 1 0.01 1.0 0.235 0.09442810
## 2 0.30 1.0 0.085 0.10013879
## 3 0.50 1.0 0.065 0.08181958
## 4 0.80 1.0 0.060 0.07745967
## 5 1.00 1.0 0.075 0.08249579
## 6 0.01 1.5 0.225 0.10069205
## 7 0.30 1.5 0.080 0.09775252
## 8 0.50 1.5 0.055 0.05986095
## 9 0.80 1.5 0.055 0.06433420
## 10 1.00 1.5 0.065 0.06687468
## 11 0.01 2.0 0.220 0.11105554
## 12 0.30 2.0 0.060 0.06992059
## 13 0.50 2.0 0.060 0.06582806
## 14 0.80 2.0 0.060 0.06582806
## 15 1.00 2.0 0.065 0.06258328
## 16 0.01 2.5 0.225 0.10865337
## 17 0.30 2.5 0.055 0.06851602
## 18 0.50 2.5 0.065 0.06687468
## 19 0.80 2.5 0.065 0.06258328
## 20 1.00 2.5 0.045 0.06433420
## 21 0.01 3.0 0.215 0.11067972
## 22 0.30 3.0 0.060 0.07745967
## 23 0.50 3.0 0.075 0.08249579
## 24 0.80 3.0 0.055 0.08316650
## 25 1.00 3.0 0.050 0.07817360
par.svm$best.parameters
## gamma cost
## 20 1 2.5
mod.svm.best <- svm(y~., data=df,
gamma=par.svm$best.parameters$gamma,
cost=par.svm$best.parameters$cost)
# plot(mod.svm.best, data=df)
Wykres przedstawia zależność błędu od parametrów:
png("svm4.png")
plot(par.svm)
dev.off()
kernlab
library(kernlab)
ksvm.default <- ksvm(y~., data=df)
predict(ksvm.default, newdata=obs)
## [1] 2
## Levels: 1 2
ksvm.prob <- ksvm(y~., data=df, prob.model=TRUE)
predict(ksvm.prob, newdata=obs, type="probabilities")
## 1 2
## [1,] 9.764555e-05 0.9999024
png("svm5.png")
plot(ksvm.default, data=df)
dev.off()