«Если вы не можете объяснить это просто, значит, вы недостаточно хорошо это понимаете».
- Альберт Эйнштейн

Ранее мы узнали о Linear SVM, о том, как она работает и как ее реализовать с помощью sklearn. Сегодня мы узнаем о Kernel SVM или нелинейной SVM.

Наборы данных, над которыми вы будете работать или над которыми работаете, не всегда могут быть линейными. Один из подходов к обработке нелинейных наборов данных состоит в добавлении дополнительных функций, таких как полиномиальные функции; в некоторых случаях это может привести к линейно разделяемому набору данных. Рассмотрим левый график на рис. 1: он представляет собой простой набор данных с одним признаком x1. Как видите, этот набор данных нельзя разделить линейно. Но если вы добавите вторую функцию x2 = (x1) 2, результирующий 2D-набор данных будет идеально линейно разделимым.

Давайте узнаем о некоторых ядрах, используемых в SVM.

Полиномиальное ядро

Так что же такое полиномиальные особенности? полиномиальные признаки - это производные признаки от заданных признаков в наборе данных. Например, у нас есть набор данных с одним признаком x, и мы хотим найти полиномиальные признаки со степенью 3, тогда полиномиальные признаки будут x, x², x³. Если бы у нас были другие функции, каждая из них была бы преобразована аналогичным образом.

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

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

from sklearn.datasets import make_moons
X,y = make_moons(n_samples=100,noise=0.15)

Посмотрим, как выглядят наши данные

plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.cool)
plt.show()

Из приведенного выше графика видно, что наши данные разделены нелинейно. Итак, теперь реализуем ядро ​​SVM

poly_kernel_svm = Pipeline([
    ('scaler',StandardScaler()),
    ('svm_clf',SVC(kernel='poly',degree=3,coef0=1,C=5))
])
poly_kernel_svm.fit(X,y)

Гауссовское ядро ​​RBF

Прежде чем понять гауссовский RBF, сначала нам нужно понять особенности сходства.

Особенности сходства

Вы можете пропустить эту часть, если не хотите глубоко разбираться в гауссовском RBF.

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

Это функция в форме колокола, меняющая значение от 0 (очень далеко от ориентира) до 1 (на ориентире). Теперь мы готовы вычислить новые функции. Например, давайте посмотрим на экземпляр x1 = –1: он расположен на расстоянии 1 от первого ориентира и 2 от второго ориентира. Следовательно, его новые характеристики: x2 = exp (–0,3 × 12) ≈ 0,74 и x3 = exp (–0,3 × 22) ≈ 0,30. На графике справа на рис. 2 показан преобразованный набор данных (без исходных функций). Как видите, теперь он линейно разделим.

Ядро Gaussian RBF с использованием SVM

Метод функций подобия может быть полезен с любым алгоритмом машинного обучения, но вычисление всех дополнительных функций может оказаться дорогостоящим в вычислительном отношении, особенно на больших обучающих наборах. Однако один раз
трюк с ядром творит чудеса с SVM: он позволяет получить такой же результат, как если бы вы добавили много подобных функций, без необходимости их добавления. Давайте попробуем ядро ​​Gaussian RBF, используя класс SVC:

rbf_kernel_svm_clf = Pipeline([("scaler", StandardScaler()),
         ("svm_clf", SVC(kernel="rbf", gamma=5, C=0.001))])
rbf_kernel_svm_clf.fit(X, y)

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

На графиках ниже показаны разные результаты для разных значений C и гаммы.

SVM регрессия

алгоритм SVM довольно универсален: он не только поддерживает линейную и нелинейную классификацию, но также поддерживает линейную и нелинейную регрессию. Уловка состоит в том, чтобы обратить цель вспять: вместо того, чтобы пытаться уместить максимально возможную улицу между двумя классами, ограничивая при этом нарушения полей, SVM Regression пытается уместить как можно больше экземпляров на улице, ограничивая при этом нарушения полей (т. Е. Экземпляры вне улицы) . Ширина улицы контролируется гиперпараметром ε.

Реализуя линейный SVR, вы можете сгенерировать любой линейный набор данных, соответствующий модели. Вы можете сгенерировать его, используя метод make_regression, доступный в sklearn.datasets.

svm_reg =LinearSVR(epsilon=1.5)
svm_reg.fit(X,y)

Подобно SVC, у нас есть SVR с ядрами.

svm_poly_reg = SVR(kernel='poly',degree=2,epsilon=0.1)
svm_poly_reg.fit(X,y)

Итак, это все для нелинейного SVM и с бонусом SVR. Надеюсь, что вы найдете ее полезной.

Спасибо

Александр Гончар Бен Вебер Payman Taei Эухенио Кулурчелло Игорь Бобряков Тим Снит Кан Нишида Civis Analytics Команда AV Адриана Валенсия Редакторы TDS К команде AI DataSeries МАШИНОСТРОЕНИЯ Анвей Мешрам

Присоединяйтесь к FAUN: Веб-сайт 💻 | Подкаст 🎙️ | Twitter 🐦 | Facebook 👥 | Instagram 📷 | Группа Facebook 🗣️ | Группа Linkedin 💬 | Slack 📱 | Cloud Native Новости 📰 | Еще .

Если этот пост был полезен, нажмите несколько раз кнопку хлопка 👏 ниже, чтобы выразить поддержку автору 👇