Введение

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

Я знаю, что это много. В этой статье мы не будем слишком углубляться в математические формулы. Вместо этого мы сосредоточимся на рабочем процессе SVM и рассмотрим пример (набор данных Titanic) на Python.

⚡ Код будет предоставлен в последнем разделе этой статьи.

Терминология

Прежде чем мы углубимся в SVM, давайте рассмотрим некоторые термины. Чтобы лучше понять термины, мы используем приведенный ниже график в качестве демонстрации. Скажем, мы хотим классифицировать, является ли человек мужчиной или женщиной, основываясь на его/ее возрасте и росте.

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

В SVM мы используем классификатор опорных векторов для классификации, и этот классификатор на самом деле является гиперплоскостью. В этом примере классификатор (синяя линия) представляет собой просто линейную одномерную плоскость. Однако классификатор может быть многомерным.

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

  • Мягкая маржа

Следующий термин, который нам нужно знать, — это мягкая маржа. (Жесткое) Отступ – это расстояние между гиперплоскостью и точками данных, ближайшими к гиперплоскости в каждой группе, а Мягкое поле – это поле, допускающее неправильную классификацию. В частности, мы хотим максимизировать мягкую маржу, так как мы хотим, чтобы две группы были как можно дальше друг от друга.

В этом примере у нас есть мягкая маржа. Учитывая синюю линию (классификатор опорных векторов), мы классифицируем зеленую точку под синей линией как женщину, а истинную метку — как мужчину!

⚡ Мы можем правильно классифицировать все обучающие данные (с жестким запасом). Однако чрезвычайно высокая точность обучающих данных часто является признаком переобучения.

  • Векторы поддержки

Опорные векторы — это точки данных В и Внутри мягкой границы. Эти точки данных важны, поскольку они определяют положение гиперплоскости, которое является порогом классификации. В этом примере 3 точки данных в фиолетовых кругах — это наши опорные векторы, которые используются для поддержки оптимальной гиперплоскости (также известной как классификатор опорных векторов).

Рабочий процесс

1. Полупреобразование данных в более высокое измерение

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

Более того, SVM не преобразует данные явно, а использует трюк ядра. Допустим, мы начинаем с одного параметра — Возраст и хотим добавить дополнительный параметр — Возраст². SVM не вычисляет явные значения, а просто использует попарное сходство между наблюдениями. Главный вывод здесь заключается в том, что SVM использует трюк ядра для преобразования данных более дешевым в вычислительном отношении способом.

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

2. Найдите оптимальный классификатор опорных векторов

После полупреобразования данных нам нужно найти оптимальный классификатор опорных векторов, который максимизирует мягкую маржу. Чтобы быть более конкретным, мы хотим разделить ярлыки (например, женский/мужской) наиболее различимым способом, но мы также хотим допустить некоторые неправильные классификации, чтобы избежать переобучения.

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

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

Теперь, когда мы изучили рабочий процесс SVM, мы можем перейти к части кодирования! Фактически, мы будем использовать SVC (классификатор опорных векторов) в Python.

  • C (по умолчанию — 1,0): параметр регуляризации / стоимость неправильной классификации (зависит от того, как вы хотите избежать неправильной классификации в обучающих данных). Когда C больше, SVM пытается правильно классифицировать все обучающие выборки, поэтому гиперплоскость, как правило, имеет меньший запас. Таким образом, высокий C сопряжен с риском переобучения.
  • kernel (по умолчанию — rbf): функции ядра, используемые для проецирования данных в высокомерное пространство, включая linear, poly, rbf, sigmoid и precomputed.
  • degree (по умолчанию — 3): Степень полиномиальной функции ядра (poly). Если вы выберете другие функции ядра, этот параметр будет проигнорирован.
  • gamma (по умолчанию — scale): определяет область принятия решения (область влияния) или веса точек данных с точки зрения расстояния. Проще говоря, gamma определяет, насколько кривизна будет у границы решения. Когда gamma высокое, учитываются только близкие точки данных, поэтому граница будет изогнутой и очень хорошо соответствует обучающим данным. Когда gamma равно auto, все точки данных учитываются и имеют одинаковый вес. ⚡ gamma полезен только тогда, когда граница МОГУТ быть изогнутой, поэтому он бесполезен в функции ядра linear.

Пример Титаника

Подводя итог, мы хотим предсказать, выживет ли пассажир в событии Титаник. Мы предварительно обработали набор данных до и выбрали нужные нам независимые переменные XPclass, Sex, Age, SibSp, Parch, Fare, а также зависимую переменную ySurvived. Набор данных выглядит так —

Далее мы разделяем данные на обучающую и тестовую выборку в соотношении 80/20. А именно, мы используем 80% данных для обучения модели, 20% данных для оценки модели.

x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=65)

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

⚡ Мы используем StandardScalar в Python. Следует отметить, что мы стандартизируем набор для тестирования на основе масштаба набора для обучения, поскольку данные для тестирования являются новыми. Мы не знаем и не должны знать характеристику (т. е. среднее/стандартное значение) невидимых данных, иначе информация о тестовом наборе просочится в модель, и оценка модели будет >предвзятый.

# Standardize
scalar = StandardScaler().fit(x_train)
x_train_transformed = scalar.transform(x_train)
x_test_transformed = scalar.transform(x_test)

Хорошо, теперь мы можем выбрать некоторые гиперпараметры-кандидаты и использовать поиск по сетке, чтобы выяснить, какая комбинация параметров лучше всего подходит для нашего набора данных. Для упрощения в этом примере мы настроим только параметры kernel и C (см. Как настроить параметры).

# Cross validation for hyper-parameter tuning
hyperparameter_score_list = []
for kernel in ['linear', 'poly', 'rbf', 'sigmoid']:
    for c in np.arange(0.5,3,0.5):
        svm = SVC(kernel=kernel, C=c)
        scores = cross_validate(svm, x_train_transformed, y_train, cv=10, scoring='accuracy')
        mean_score = np.mean(scores['test_score'])
        hyperparameter_score_list.append([kernel, c, mean_score])
# Choose the hyper-parameters (with highest average accuracy)
myTable = PrettyTable(["Kernel", "C", "Avg accuracy"])
for row in hyperparameter_score_list:
    myTable.add_row([row[0], row[1], round(row[2],3)])
print(myTable)

Понятно, что SVM с kernel=’rbf' и C=2.0/2.5 имеет одинаковую максимальную среднюю точность, 838. Чтобы лучше понять, как C влияет на производительность SVM, давайте нарисуем линейный график!

⚡ Мы построим график как оценки обучения, так и оценки тестирования, чтобы увидеть, есть ли серьезная проблема переобучения. Переобученная модель может быть нестабильной (и потенциально бесполезной).

# Try different C
c_range = np.arange(0.1, 3, 0.1)
test_svm = [] 
train_svm = []
for c in c_range:
    svm_classifier = SVC(kernel='rbf', C=c)
    svm_classifier.fit(x_train_transformed, y_train)
    train_svm.append(svm_classifier.score(x_train_transformed, y_train))
    test_svm.append(svm_classifier.score(x_test_transformed, y_test))
# Line plot of training/testing score
fig = plt.figure(figsize=(10, 7))
plt.plot(c_range, train_svm, c='orange', label='Train')
plt.plot(c_range, test_svm, c='m', label='Test')
plt.xlabel('C')
plt.xticks(c_range)
plt.ylabel('Accuracy score')
plt.ylim(0.7, 1)
plt.legend(prop={'size': 14}, loc=1)
plt.title('Accuracy score vs. C of SVM (rbf kernel function)', size=16)
plt.show()

Во-первых, когда C увеличивается, балл обучения обычно увеличивается, а балл тестирования уменьшается. Этот результат совсем не удивителен.

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

Однако SVM может изучить обучающий набор слишком хорошо, чтобы не уловить общую тенденцию. А именно, он изучает шумы и особенности отклоняющихся образцов, что ухудшает его работу на тестовом наборе (невидимые данные). Это явление точно известно как переобучение.

Во-вторых, когда C равно 0,5, SVM работает лучше всего — результат тестирования 0,79. Хотя модель по-прежнему соответствует данным (оценка обучения 0,84), степень переобучения приемлема. Следовательно, мы заключаем, что SVM с kernel=’rbf' и C=0.5 работает довольно хорошо в этом конкретном разделении обучения/тестирования (необходимо провести дополнительные тесты, чтобы убедиться, что эти параметры являются оптимальными).

⚡ Эта степень переобучения может НЕ быть приемлемой в областях, требующих чрезвычайной стабильности модели (например, в медицине).

💛 Если вам понравилась эта статья, обязательно подпишитесь на меня! Это действительно воодушевляет меня и мотивирует продолжать делиться. Большое спасибо.

Рекомендации

  1. https://www.analyticsvidhya.com/blog/2021/10/support-vector-machinessvm-a-complete-guide-for-beginners/
  2. https://towardsdatascience.com/so-why-the-heck-are-they-call-support-vector-machines-52fc72c990a1
  3. https://medium.com/machine-learning-101/chapter-2-svm-support-vector-machine-theory-f0812effc72

Кодирование