Машина опорных векторов - отличный инструмент как для классификации, так и для решения задач регрессии, поскольку он позволяет эффективно работать с выбросами и является отличным инструментом для компромисса между смещением и дисперсией. Он использует функцию ядра с D = размерность для преобразования модели из низко (одномерных) в высокоразмерные (2-3) наблюдения или радиальное ядро ​​(аналогично KNN Принимает ближайшее наблюдение) для более продвинутых моделей.

Классификаторы опорных векторов

Представьте, что вы - менеджер по персоналу в охранной компании, и вам нужно нанять парней на должности телохранителей. Главный критерий - рост. Итак, вы классифицируете наблюдения как X≤1,80 см ≤ Y. В этом одномерном наборе данных порог так просто определить. В самом деле, вам даже не нужно использовать классификатор опорных векторов.

Но что, если у вас есть сложный набор данных с различными переменными? Представьте, что ниже мы пытаемся выяснить, есть ли у человека диабет или нет. В этом случае классификаторы опорных векторов могут помочь вам с задачей. На рисунке ниже вы снова видите модель классификации, однако на этот раз классификация выполняется с помощью классификатора опорных векторов, а порог устанавливается максимальным расстоянием между двумя классами наблюдения, называемого классификатором максимальной маржи.

Но что, если одно наблюдение с диабетом произойдет среди людей, не страдающих диабетом, как на картинке ниже?
В этом случае SVC может допустить ошибочную классификацию ради компромисса смещения-дисперсии. Это означает, что классификатор будет переносить данные о диабете среди не диабетиков и классифицирует их как несуществующие.

Машины опорных векторов

Хотя вышеупомянутый метод отлично подходит для классификации двумерных данных, иногда у нас есть набор данных, который не подлежит классификации с простым порогом. В этом случае пора использовать машины опорных векторов.

Мы будем использовать встроенный набор данных Iris в R и визуализировать его, чтобы увидеть, как наблюдения расположены в наборе данных. Этот набор данных будет хорошо работать для SVM, поскольку у него есть перекрывающиеся наблюдения. Таким образом, квадратичная или кубическая полиномиальная модель отлично с этим справится.

data = iris
pairs(data[,1:4], pch = 19,  cex = 0.5,
      col = data$Species)

Теперь, после визуализации набора данных, мы попытаемся запустить функцию полиномиального ядра с 10-кратной выборкой и выберем лучшую модель.

Давайте посмотрим на несколько примеров того, как полиномиальная функция будет работать с набором данных, где классификация непростая и есть много совпадений.

Возвращаясь к нашему набору данных Iris. Это библиотеки, которые вам нужно будет скачать.

library(tidyverse)
library(dplyr)
library(ggplot2)
library(e1071)

После того, как вы их загрузили. Нам нужно разделить наш набор данных на обучающие и тестовые подмножества, с помощью которых мы будем обучать, прогнозировать и в конечном итоге определять точность нашей модели.

#Train-Test data----
set.seed(1,sample.kind = "Rejection")
tr_index = sample(1:nrow(data), nrow(data)*0.7)
train_data = data[tr_index,]
test_data = data[-tr_index,]

Использование set.seed помогает всегда получать один и тот же образец.

Мне нравится этот пакет, потому что он имеет встроенную 10-кратную функцию перекрестной проверки, которая помогает вам получить лучшие параметры стоимости и степени.

set.seed(1,sample.kind = "Rejection")
tune.out=tune(svm, #Tuning
              Species ~ .,
              data = train_data,
              kernel="polynomial",
              ranges=list(cost=c(0.1,1,10,100,1000),
                          degree=1:5))
summary(tune.out)
svm.pred.best = predict(tune.out$best.model,
                        newdata=test_data)
table(svm.pred.best, test_data$Species)

Точность модели. Когда значение истинно, оно возвращает истину. Истина рассчитывается как 1, а для среднего вы получите 1, если количество прогнозов равно количеству фактических переменных ответа тестового набора данных.

mean(svm.pred.best == test_data$Species)

Для радиального ядра вам просто нужно написать «радиальный» вместо «полиномиальный».

svm1 = svm(Species~.,
           data = train_data,
           kernel = "radial",
           cost = 1,
           gamma = 1)