x1 <- runif(500) - 0.5
x2 <- runif(500) - 0.5
y <- as.factor(1 * (x1^2 - x2^2 > 0))
plot(x1[y == 0], x2[y == 0], col = "mediumpurple2", xlab = "X1", ylab = "X2", pch = 20)
points(x1[y == 1], x2[y == 1], col = "lightpink", pch=20)
logistic_model <- glm(y ~ x1 + x2, family = "binomial")
summary(logistic_model)
##
## Call:
## glm(formula = y ~ x1 + x2, family = "binomial")
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.01693 0.09000 -0.188 0.8508
## x1 -0.19454 0.31412 -0.619 0.5357
## x2 -0.72583 0.31841 -2.280 0.0226 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 693.08 on 499 degrees of freedom
## Residual deviance: 687.42 on 497 degrees of freedom
## AIC: 693.42
##
## Number of Fisher Scoring iterations: 4
data <- data.frame(x1, x2, y)
data$pred <- ifelse(predict(logistic_model, type = "response") > 0.5, 1, 0)
x1_color <- "mediumpurple2"
x2_color <- "lightpink"
plot(data$x1, data$x2, col = ifelse(data$pred == 1, x1_color, x2_color), pch = 20, xlab = "X1", ylab = "X2")
logistic_model_nonlinear <- glm(y ~ poly(x1, 2) + poly(x2, 2), data = data, family = "binomial")
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
data$pred_nonlinear <- ifelse(predict(logistic_model_nonlinear, type = "response") > 0.5, 1, 0)
plot(data$x1, data$x2, col = ifelse(data$pred_nonlinear == 1, x1_color, x2_color), pch = 20, xlab = "X1", ylab = "X2")
svm_model <- svm(y ~ ., data = data, kernel = "linear")
svm_pred <- predict(svm_model, data)
custom_colors <- c(x1_color, x2_color)
plot(data$x1, data$x2, col = custom_colors[svm_pred], pch = 20, xlab = "X1", ylab = "X2")
svm_model_nonlinear <- svm(y ~ ., data = data, kernel = "radial", gamma= 1)
svm_pred_nonlinear <- predict(svm_model_nonlinear, data)
plot(data$x1, data$x2, col = custom_colors[svm_pred_nonlinear], pch = 20, xlab = "X1", ylab = "X2")
Comparing all the plots, I can see that SVM with radial kernels are clearly showing the non-linear boundary.
Auto$mpg_binary <- ifelse(Auto$mpg > median(Auto$mpg), 1, 0)
Auto$mpg_binary <- as.factor(Auto$mpg_binary)
svm_auto <- tune(svm, mpg_binary ~ . - mpg, data = Auto, ranges = list(cost = c(0.1, 1, 10)))
summary(svm_auto)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 1
##
## - best performance: 0.08935897
##
## - Detailed performance results:
## cost error dispersion
## 1 0.1 0.16602564 0.05975575
## 2 1.0 0.08935897 0.04380206
## 3 10.0 0.09711538 0.05519876
Cost of 1 has the lowest error rate of 0.08423077.
svm_radial <- tune(svm, mpg_binary ~ . - mpg, data = Auto, kernel = "radial", ranges = list(cost = c(0.1, 1, 10), gamma = c(0.1, 1, 10)))
summary(svm_radial)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost gamma
## 1 1
##
## - best performance: 0.08429487
##
## - Detailed performance results:
## cost gamma error dispersion
## 1 0.1 0.1 0.08935897 0.05307427
## 2 1.0 0.1 0.08679487 0.05015153
## 3 10.0 0.1 0.08929487 0.03253208
## 4 0.1 1.0 0.52128205 0.14136381
## 5 1.0 1.0 0.08429487 0.04989877
## 6 10.0 1.0 0.08679487 0.05015153
## 7 0.1 10.0 0.55378205 0.04388459
## 8 1.0 10.0 0.51788462 0.03185187
## 9 10.0 10.0 0.51282051 0.03735835
svm_poly <- tune(svm, mpg_binary ~ . - mpg, data = Auto, kernel = "polynomial", degree = 2, ranges = list(cost = c(0.1, 1, 10)))
summary(svm_poly)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 10
##
## - best performance: 0.5077564
##
## - Detailed performance results:
## cost error dispersion
## 1 0.1 0.5462179 0.05788544
## 2 1.0 0.5462179 0.05788544
## 3 10.0 0.5077564 0.10993562
The best model for poly is cost of 10 with 2 degrees, and the best for radial is cost of 10 with 1 gamma.
best_linear = svm(mpg_binary ~ ., data = Auto, kernel = "linear", cost = 1)
best_poly = svm(mpg_binary ~ ., data = Auto, kernel = "polynomial", cost = 10, degree = 2)
best_radial = svm(mpg_binary ~ ., data = Auto, kernel = "radial", cost = 10, gamma = 1)
plotpairs = function(fit) {
for (name in names(Auto)[!(names(Auto) %in% c("mpg", "mpg_binary", "name"))]) {
plot(fit, Auto, as.formula(paste("mpg~", name, sep = "")))
}
}
plotpairs(best_linear)
plotpairs(best_poly)
plotpairs(best_radial)
set.seed(123)
index <- sample(1:nrow(OJ), 800)
train_data <- OJ[index, ]
test_data <- OJ[-index, ]
svm_OJ <- svm(Purchase ~ ., data = train_data, kernel = "linear", cost = 0.01)
summary(svm_OJ)
##
## Call:
## svm(formula = Purchase ~ ., data = train_data, kernel = "linear",
## cost = 0.01)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 0.01
##
## Number of Support Vectors: 442
##
## ( 220 222 )
##
##
## Number of Classes: 2
##
## Levels:
## CH MM
The levels of the response variable “Purchase” are listed as “CH” and “MM”. The classifier is performing binary classification, as there are 2 classes. There are 442 support vectors in total. Among them, 220 belong to CH and 222 belong to MM.
train_pred <- predict(svm_OJ, train_data)
test_pred <- predict(svm_OJ, test_data)
train_error <- mean(train_pred != train_data$Purchase)
test_error <- mean(test_pred != test_data$Purchase)
train_error
## [1] 0.165
test_error
## [1] 0.1777778
tune_out <- tune(svm, Purchase ~ ., data = train_data, kernel = "linear", ranges = list(cost = c(0.01, 0.1, 1, 10)))
summary(tune_out)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 1
##
## - best performance: 0.16875
##
## - Detailed performance results:
## cost error dispersion
## 1 0.01 0.17625 0.03143004
## 2 0.10 0.17250 0.03425801
## 3 1.00 0.16875 0.03596391
## 4 10.00 0.17250 0.02751262
svm_tuned <- svm(Purchase ~ ., data = train_data, kernel = "linear", cost = 1)
train_tuned <- predict(svm_tuned, train_data)
test_tuned <- predict(svm_tuned, test_data)
train_error_tuned <- mean(train_tuned != train_data$Purchase)
test_error_tuned <- mean(test_tuned != test_data$Purchase)
train_error_tuned
## [1] 0.16
test_error_tuned
## [1] 0.1555556
OJ_radial <- svm(Purchase ~ ., data = train_data, kernel = "radial")
summary(OJ_radial)
##
## Call:
## svm(formula = Purchase ~ ., data = train_data, kernel = "radial")
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: radial
## cost: 1
##
## Number of Support Vectors: 367
##
## ( 181 186 )
##
##
## Number of Classes: 2
##
## Levels:
## CH MM
train_radial <- predict(OJ_radial, train_data)
test_radial <- predict(OJ_radial, test_data)
train_error_radial <- mean(train_radial != train_data$Purchase)
test_error_radial <- mean(test_radial != test_data$Purchase)
train_error_radial
## [1] 0.13875
test_error_radial
## [1] 0.1888889
tune_out1 <- tune(svm, Purchase ~ ., data = train_data, kernel = "radial", ranges = list(cost = c(0.01, 0.1, 1, 10)))
summary(tune_out1)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 1
##
## - best performance: 0.1625
##
## - Detailed performance results:
## cost error dispersion
## 1 0.01 0.39125 0.04411554
## 2 0.10 0.18125 0.03691676
## 3 1.00 0.16250 0.03486083
## 4 10.00 0.16500 0.03622844
svm_tuned1 <- svm(Purchase ~ ., data = train_data, kernel = "radial", cost = 1)
train_tuned1 <- predict(svm_tuned1, train_data)
test_tuned1 <- predict(svm_tuned1, test_data)
train_error_tuned1 <- mean(train_tuned1 != train_data$Purchase)
test_error_tuned1 <- mean(test_tuned1 != test_data$Purchase)
train_error_tuned1
## [1] 0.13875
test_error_tuned1
## [1] 0.1888889
OJ_poly <- svm(Purchase ~ ., data = train_data, kernel = "polynomial", degree = 2)
summary(OJ_poly)
##
## Call:
## svm(formula = Purchase ~ ., data = train_data, kernel = "polynomial",
## degree = 2)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: polynomial
## cost: 1
## degree: 2
## coef.0: 0
##
## Number of Support Vectors: 445
##
## ( 219 226 )
##
##
## Number of Classes: 2
##
## Levels:
## CH MM
train_poly <- predict(OJ_poly, train_data)
test_poly <- predict(OJ_poly, test_data)
train_error_poly <- mean(train_poly != train_data$Purchase)
test_error_poly <- mean(test_poly != test_data$Purchase)
train_error_poly
## [1] 0.1725
test_error_poly
## [1] 0.2222222
poly_tune <- tune(svm, Purchase ~ ., data = train_data, kernel = "polynomial", degree = 2, ranges = list(cost = c(0.01, 0.1, 1, 10)))
summary(poly_tune)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 10
##
## - best performance: 0.17125
##
## - Detailed performance results:
## cost error dispersion
## 1 0.01 0.38750 0.04289846
## 2 0.10 0.30875 0.01772671
## 3 1.00 0.18375 0.03335936
## 4 10.00 0.17125 0.03729108
OJ_poly1 <- svm(Purchase ~ ., data = train_data, kernel = "polynomial", degree = 2, cost =10)
summary(OJ_poly1)
##
## Call:
## svm(formula = Purchase ~ ., data = train_data, kernel = "polynomial",
## degree = 2, cost = 10)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: polynomial
## cost: 10
## degree: 2
## coef.0: 0
##
## Number of Support Vectors: 337
##
## ( 168 169 )
##
##
## Number of Classes: 2
##
## Levels:
## CH MM
train_poly1 <- predict(OJ_poly1, train_data)
test_poly1 <- predict(OJ_poly1, test_data)
train_error_poly1 <- mean(train_poly1 != train_data$Purchase)
test_error_poly1 <- mean(test_poly1 != test_data$Purchase)
train_error_poly1
## [1] 0.14375
test_error_poly1
## [1] 0.2037037
Based on the test error rates, the linear SVM has the lowest test error rate (17.8%), followed by the radial SVM (18.9%) and the polynomial SVM (20.4%). Therefore, the linear SVM appears to be the best model among the three for this dataset.