Неделя 4: Метод опорных векторов (SVM) и ядерные методы
1. Теоретическая часть
1.1. Метод опорных векторов (SVM)
SVM — алгоритм для задач классификации и регрессии, который находит оптимальную разделяющую гиперплоскость с максимальным зазором (margin) между классами.
Геометрическая интерпретация
Опорные векторы — точки данных, ближайшие к гиперплоскости.
Задача оптимизации:
min𝜃12∥𝜃∥2θmin21∥θ∥2
при условии: 𝑦(𝑖)(𝜃𝑇𝑥(𝑖)+𝑏)≥1y(i)(θTx(i)+b)≥1 для всех 𝑖i.
Функция потерь (Hinge Loss)
𝐽(𝜃)=∑𝑖=1𝑚max(0,1−𝑦(𝑖)(𝜃𝑇𝑥(𝑖)+𝑏))+𝜆∥𝜃∥2J(θ)=i=1∑mmax(0,1−y(i)(θTx(i)+b))+λ∥θ∥2
1.2. Ядерный трюк (Kernel Trick)
Позволяет SVM работать с нелинейно разделимыми данными путем отображения признаков в пространство более высокой размерности.
Популярные ядра
Ядро
Формула
Линейное
𝐾(𝑥,𝑧)=𝑥𝑇𝑧K(x,z)=xTz
Полиномиальное
𝐾(𝑥,𝑧)=(𝑥𝑇𝑧+𝑐)𝑑K(x,z)=(xTz+c)d
RBF (Гауссово)
𝐾(𝑥,𝑧)=exp(−𝛾∥𝑥−𝑧∥2)K(x,z)=exp(−γ∥x−z∥2)
1.3. SVM для регрессии (SVR)
Аналогично классификации, но минимизирует ошибку в пределах заданной трубки (ε-insensitive tube).
2.1. Реализация SVM с ядрами
python
Copy
from sklearn.svm import SVC
from sklearn.datasets import make_moons
# Генерация нелинейных данных
X, y = make_moons(n_samples=100, noise=0.1, random_state=42)
# Линейное ядро
svm_linear = SVC(kernel='linear')
svm_linear.fit(X, y)
# Полиномиальное ядро
svm_poly = SVC(kernel='poly', degree=3, coef0=1)
svm_poly.fit(X, y)
# RBF ядро
svm_rbf = SVC(kernel='rbf', gamma=0.1)
svm_rbf.fit(X, y)
2.2. Визуализация решающих границ
python
Copy
def plot_decision_boundary(clf, X, y):
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k')
plt.title(f"Decision Boundary ({clf.kernel} kernel)")
plot_decision_boundary(svm_rbf, X, y)
2.3. Подбор гиперпараметров
python
Copy
from sklearn.model_selection import GridSearchCV
param_grid = {
'C': [0.1, 1, 10],
'gamma': [0.01, 0.1, 1],
'kernel': ['rbf', 'poly']
}
grid_search = GridSearchCV(SVC(), param_grid, cv=5)
grid_search.fit(X_train, y_train)
print("Best params:", grid_search.best_params_)
3. Домашнее задание
Задача 1: Сравнение ядер
1. Загрузите датасет make_circles.
2. Обучите SVM с линейным, полиномиальным и RBF ядрами.
3. Визуализируйте решающие границы для каждого случая.
Решение:
python
Copy
X, y = make_circles(n_samples=100, noise=0.05, factor=0.5)
kernels = ['linear', 'poly', 'rbf']
for kernel in kernels:
svm = SVC(kernel=kernel)
svm.fit(X, y)
plot_decision_boundary(svm, X, y)
Задача 2: Влияние параметров
Исследуйте влияние параметров:
Для RBF: gamma (0.01, 0.1, 1)
Для полиномиального: degree (2, 3, 4)
Решение:
python
Copy
gammas = [0.01, 0.1, 1]
for gamma in gammas:
svm = SVC(kernel='rbf', gamma=gamma)
svm.fit(X, y)
plot_decision_boundary(svm, X, y)
Задача 3: SVM для регрессии (SVR)
1. Загрузите датасет diabetes из sklearn.datasets.
2. Обучите SVR с RBF-ядром.
3. Сравните с линейной регрессией по метрике R².
Решение:
python
Copy
from sklearn.svm import SVR
from sklearn.datasets import load_diabetes
X, y = load_diabetes(return_X_y=True)
svr = SVR(kernel='rbf')
svr.fit(X_train, y_train)
y_pred = svr.predict(X_test)
print("SVR R²:", r2_score(y_test, y_pred))
Итоги недели
✅ Разобрали SVM для классификации и регрессии.
✅ Изучили ядерные методы (линейное, полиномиальное, RBF).
✅ Научились визуализировать решающие границы.
✅ Оптимизировали гиперпараметры через GridSearchCV.
Следующая тема: Деревья решений и ансамбли. 🌳