Алгоритм машины опорных векторов

Опубликовано: 16 Июля, 2021

Машина опорных векторов (SVM) - это контролируемый алгоритм машинного обучения, используемый как для классификации, так и для регрессии. Хотя мы также говорим, что проблемы регрессии лучше всего подходят для классификации. Цель алгоритма SVM - найти гиперплоскость в N-мерном пространстве, которая четко классифицирует точки данных. Размер гиперплоскости зависит от количества элементов. Если количество входных объектов равно двум, то гиперплоскость представляет собой просто линию. Если количество входных объектов равно трем, то гиперплоскость становится двумерной плоскостью. Когда количество функций превышает три, становится сложно представить.

Давайте рассмотрим две независимые переменные x1, x2 и одну зависимую переменную, которая представляет собой синий или красный кружок.

Линейно разделяемые точки данных

Из рисунка выше очень ясно, что существует несколько линий (наша гиперплоскость здесь - линия, потому что мы рассматриваем только две входные функции x1, x2), которые разделяют наши точки данных или проводят классификацию между красными и синими кругами. Итак, как нам выбрать лучшую линию или лучшую гиперплоскость, которая разделяет наши точки данных.

Выбор лучшей гиперплоскости:

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

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

Рассмотрим сценарий, показанный ниже.

Здесь у нас есть один синий шар на границе красного шара. Итак, как SVM классифицирует данные? Это просто! Синий шар в границе красных шаров выделяется из синих шаров. Алгоритм SVM имеет характеристики игнорировать выбросы и находит лучшую гиперплоскость, которая максимизирует запас. SVM устойчив к выбросам.


Таким образом, в этом типе точек данных SVM находит максимальный запас, как это было сделано с предыдущими наборами данных, и добавляет штраф каждый раз, когда точка пересекает границу. Таким образом, маржа в таких случаях называется мягкой маржей. Когда для набора данных существует мягкий запас, SVM пытается минимизировать (1 / маржа + (штраф)) . Потеря шарнира - часто применяемое наказание. При отсутствии нарушений потеря петли отсутствует. При нарушении петля потеря пропорциональна расстоянию нарушения.

До сих пор мы говорили о линейно разделяемых данных (группа синих шаров и красных шаров разделяется прямой / линейной линией). Что делать, если данные нельзя разделить линейно?

Скажем, наши данные выглядят так, как показано на рисунке выше. VSM решает эту проблему, создавая новую переменную с помощью ядра. Мы вызываем точку x i на линии и создаем новую переменную y i как функцию расстояния от исходной точки o. Поэтому, если мы построим график, мы получим что-то вроде того, что показано ниже


В этом случае новая переменная y создается как функция расстояния от начала координат. Нелинейная функция, которая создает новую переменную, называется ядром.

Ядро SVM:

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

Преимущества SVM:

  • Эффективен в корпусах больших размеров
  • Его память эффективна, поскольку он использует подмножество обучающих точек в функции принятия решений, называемых опорными векторами.
  • Для функций принятия решений можно указать различные функции ядра, а также можно указать собственные ядра.

Реализация SVM на Python:

Цель: предсказать, является ли рак доброкачественным или злокачественным.

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

Набор данных: https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+(Original)

Python




# import libraries
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
% matplotlib inline
# Importing Data file
data = pd.read_csv( 'bc2.csv' )
dataset = pd.DataFrame(data)
dataset.columns

Выход:

 Индекс (['ID', 'ClumpThickness', 'Cell Size', 'Cell Shape', 'Marginal Adhesion',
«Размер единичных эпителиальных клеток», «Голые ядра», «Нормальные ядрышки», «Чистый хроматин», 
'Митозы', 'Класс'], dtype = 'объект')

Python




dataset.info()

Выход:

 <класс 'pandas.core.frame.DataFrame'>
RangeIndex: 699 записей, от 0 до 698
Столбцы данных (всего 11 столбцов):
ID 699 ненулевой int64
ClumpThickness 699 ненулевое значение int64
Размер ячейки 699 ненулевое значение int64
Форма ячейки 699 ненулевое значение int64
Маргинальная адгезия 699 ненулевое значение int64
Размер одиночной эпителиальной клетки 699, ненулевое значение int64
Bare Nuclei 699 ненулевой объект
Нормальные ядрышки 699 ненулевые int64
Чистый хроматин 699 ненулевой int64
Mitoses 699 ненулевой int64
Класс 699 ненулевой int64
dtypes: int64 (10), объект (1)
использование памяти: 60,1+ КБ

Python




dataset.describe().transpose()

Выход:

считать иметь в виду стандартное мин 25% 50% 75% Максимум
Я БЫ 699 1.071704e + 06 617095.729819 61634,0 870688,5 1171710,0 1238298,0 13454352,0
Толщина комка 699 4.417740e + 00 2,815741 1.0 2.0 4.0 6.0 10.0
Размер ячейки 699,0 4.417740e + 00 2,815741 1.0 1.0 1.0 5.0 10.0
Форма ячейки 699,0 3.134478e + 00 3,051459 1.0 1.0 1.0 5.0 10.0
Маргинальное прилипание 699,0 2.806867e + 00 2,971913 1.0 1.0 1.0 4.0 10.0
Размер одиночных эпителиальных клеток 699,0 3.216023e + 00 2,855379 1.0 2.0 2.0 4.0 10.0
Нормальные ядрышки 699,0 3.437768e + 00 2,214300 1.0 2.0 3.0 5.0 10.0
Чистый хроматин 699,0 2,866953e + 00 2,438364 1.0 1.0 1.0 4.0 10.0
Митозы 699,0 1.589413e + 00 3,053634 1.0 1.0 1.0 1.0 10.0
класс 699,0 2.689557e + 00 1,715078 2.0 2.0 2.0 4.0 4.0

Python




dataset = dataset.replace( '?' , np.nan)
dataset = dataset. apply ( lambda x: x.fillna(x.median()),axis = 0 )
# converting the hp column from object 'Bare Nuclei'/ string type to float
dataset[ 'Bare Nuclei' ] = dataset[ 'Bare Nuclei' ].astype( 'float64' )
dataset.isnull(). sum ()

Выход:

 ID 0
Толщина комка 0
Размер ячейки 0
Форма ячейки 0
Маргинальная адгезия 0
Размер одиночных эпителиальных клеток 0
Голые ядра 0
Нормальные ядрышки 0
Блочный хроматин 0
Митозы 0
Класс 0
dtype: int64

Python




from sklearn.model_selection import train_test_split
# To calculate the accuracy score of the model
from sklearn.metrics import accuracy_score, confusion_matrix
target = dataset[ "Class" ]
features = dataset.drop([ "ID" , "Class" ], axis = 1 )
X_train, X_test, y_train, y_test = train_test_split(features,target, test_size = 0.2 , random_state = 10 )
from sklearn.svm import SVC
# Building a Support Vector Machine on train data
svc_model = SVC(C = . 1 , kernel = 'linear' , gamma = 1 )
svc_model.fit(X_train, y_train)
prediction = svc_model .predict(X_test)
# check the accuracy on the training set
print (svc_model.score(X_train, y_train))
print (svc_model.score(X_test, y_test))

Выход:

 0,9749552772808586
0,9642857142857143

Python




print ( "Confusion Matrix: " ,confusion_matrix(prediction,y_test))

Выход:

 Матрица неточностей:
[[95 2]
[3 40]]

Python




# Building a Support Vector Machine on train data
svc_model = SVC(kernel = 'rbf' )
svc_model.fit(X_train, y_train)

Выход:

 SVC (C = 1.0, cache_size = 200, class_weight = None, coef0 = 0.0,
 solution_function_shape = 'ovr', степень = 3, gamma = 'auto_deprecated',
 ядро = 'rbf', max_iter = -1, вероятность = False, random_state = None,
 shrinking = True, tol = 0.001, verbose = False)

Python




print (svc_model.score(X_train, y_train))
print (svc_model.score(X_test, y_test))

Выход:

 0,998211091234347
0,9571428571428572

Python




#Building a Support Vector Machine on train data(changing the kernel)
svc_model = SVC(kernel = 'poly' )
svc_model.fit(X_train, y_train)
prediction = svc_model.predict(X_test)
print (svc_model.score(X_train, y_train))
print (svc_model.score(X_test, y_test))

Выход:

 1.0
0,9357142857142857

Python




svc_model = SVC(kernel = 'sigmoid' )
svc_model.fit(X_train, y_train)
prediction = svc_model.predict(X_test)
print (svc_model.score(X_train, y_train))
print (svc_model.score(X_test, y_test))

Выход:

 0,3434704830053667
0,32857142857142857