← Назад к вопросам
Объясните алгоритм машинного обучения SVM
2.0 Middle🔥 221 комментариев
#Машинное обучение
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Support Vector Machine (SVM): нахождение оптимальной разделяющей гиперплоскости
Основная идея
SVM ищет гиперплоскость (линию в 2D, плоскость в 3D, гиперплоскость в N-D), которая:
- Максимально разделяет два класса
- Имеет наибольший зазор (margin) от обоих классов
- Как можно ближе находится в центре между классами
2D пример:
Класс 1: x
Класс 2: o
x |
x | ← оптимальная гиперплоскость
xxx xxxx|
oooo |oo
o |
o
Маргин (зазор) максимален
История
1995: Vapnik и коллеги создают SVM
1995-2005: Становится очень популярным
2005-2024: Вытеснена нейросетями, но ещё используется
Математика (упрощённо)
Линейно разделяемый случай
Гиперплоскость: w·x + b = 0
Ограничения (constraints):
y_i * (w·x_i + b) >= 1, для всех i
Маргин = 2 / ||w||
Цель: максимизировать маргин
⟺ минимизировать ||w||²
Это задача квадратичного программирования
Ядра (Kernels): волшебство SVM
Линейная гиперплоскость не может разделить XOR или спиральные данные.
Решение: Kernel Trick - преобразование в более высокое измерение
В исходном пространстве (2D): НЕ разделяемо
x o x
o x o
x o x
После kernel преобразования в 3D: разделяемо!
/\
/ \ ← плоскость разделяет классы
/____\
Типы ядер
1. Linear (линейное ядро)
K(x_i, x_j) = x_i · x_j
Используется для:
- Линейно разделяемых данных
- Больших датасетов (быстро)
- Текстовых данных (часто линейны)
2. Polynomial (полиномиальное ядро)
K(x_i, x_j) = (x_i · x_j + c)^d
Параметры:
- d = степень (2, 3, ...)
- c = constant
Используется для:
- Умеренно нелинейных данных
- Когда есть полиномиальные отношения
3. RBF (Radial Basis Function)
K(x_i, x_j) = exp(-gamma * ||x_i - x_j||²)
Параметр:
- gamma = 1/(2*sigma²)
Используется для:
- Нелинейных данных (по умолчанию)
- Неизвестной структуры данных
- Самое универсальное ядро
4. Sigmoid
K(x_i, x_j) = tanh(alpha * x_i · x_j + c)
Редко используется, похож на нейросеть
Практическая реализация
from sklearn.svm import SVC
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
# Данные
X, y = make_classification(n_samples=200, n_features=2,
n_informative=2, n_redundant=0,
random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# SVM с линейным ядром
svm_linear = SVC(kernel='linear', C=1.0)
svm_linear.fit(X_train, y_train)
y_pred_linear = svm_linear.predict(X_test)
print(f"Linear SVM Accuracy: {accuracy_score(y_test, y_pred_linear):.3f}")
# SVM с RBF ядром
svm_rbf = SVC(kernel='rbf', C=1.0, gamma='scale')
svm_rbf.fit(X_train, y_train)
y_pred_rbf = svm_rbf.predict(X_test)
print(f"RBF SVM Accuracy: {accuracy_score(y_test, y_pred_rbf):.3f}")
# SVM с полиномиальным ядром
svm_poly = SVC(kernel='poly', C=1.0, degree=3)
svm_poly.fit(X_train, y_train)
y_pred_poly = svm_poly.predict(X_test)
print(f"Polynomial SVM Accuracy: {accuracy_score(y_test, y_pred_poly):.3f}")
Важные параметры
1. C (Regularization Parameter)
C = 1 / λ (где λ - параметр регуляризации)
C высокий (C=100):
- Модель штрафует ошибки на обучении
- Может переобучиться
- Маргин меньше
C низкий (C=0.01):
- Позволяет ошибки на обучении
- Более мягкая граница
- Маргин больше
- Лучшая обобщаемость
2. Gamma (для RBF ядра)
Gamma контролирует "коэффициент распространения" ядра
Гамма высокая (gamma=10):
- Каждая точка влияет только на ближайших соседей
- Может привести к переобучению
Гамма низкая (gamma=0.001):
- Каждая точка влияет далеко
- Более гладкая граница
- Может недообучиться
Векторы поддержки (Support Vectors)
НЕ ВСЕ точки данных одинаково важны!
Векторы поддержки = точки, которые:
- Находятся ближе всего к границе
- Определяют положение границы
- Влияют на результат
Другие точки можно удалить, граница не изменится
# Доступ к векторам поддержки
svm = SVC(kernel='rbf')
svm.fit(X_train, y_train)
print(f"Количество векторов поддержки: {len(svm.support_vectors_)}")
print(f"Всего точек: {len(X_train)}")
print(f"Процент: {100*len(svm.support_vectors_)/len(X_train):.1f}%")
# Визуализация
if X_train.shape[1] == 2: # только если 2 признака
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='viridis')
# отметь векторы поддержки
plt.scatter(svm.support_vectors_[:, 0], svm.support_vectors_[:, 1],
s=300, linewidth=1.5, edgecolors='black',
facecolors='none', label='Support Vectors')
plt.legend()
plt.show()
SVM для регрессии
from sklearn.svm import SVR
# Вместо классификации предсказываем непрерывное значение
X = np.array(range(100)).reshape(-1, 1)
y = np.sin(X).flatten()
svr = SVR(kernel='rbf', C=100, gamma='scale')
svr.fit(X, y)
y_pred = svr.predict(X)
# С параметром epsilon
# Модель позволяет ошибку epsilon без штрафа
svr_eps = SVR(kernel='rbf', C=100, epsilon=0.1)
Преимущества SVM
1. Хорошо для разделяющих задач
- Четкая теория
- Гарантированный глобальный оптимум
2. Работает в высоких измерениях
- Ядра позволяют работать с очень высокими размерностями
3. Гибкий
- Много ядер для разных типов данных
4. Хорошая обобщаемость
- Маржин максимизируется
5. Вычислительно эффективно
- Использует только векторы поддержки
- Быстрее нейросетей
Недостатки SVM
1. Медленен на больших данных
- Обучение O(n²) или O(n³)
- Для 1M+ строк не подходит
2. Сложная интерпретация
- Сложнее чем деревья решений
- Трудно объяснить решение
3. Требует нормализации
- Масштабируй признаки перед SVM
4. Выбор ядра критичен
- Неправильное ядро = плохое качество
- Требует экспериментирования
5. Вытеснен нейросетями
- Для нелинейных задач нейросети лучше
Когда использовать SVM
Используй SVM когда:
- Данные небольшие (< 100K строк)
- Задача бинарной классификации
- Данные не имеют очевидной структуры
- Нужна высокая точность
- Требуется интерпретируемость (частично)
НЕ используй SVM когда:
- Данные очень большие (> 1M строк)
- Есть нелинейная структура (используй нейросети)
- Нужна максимальная скорость обучения
- Нужна интерпретируемость (используй деревья)
- Мультиклассовая классификация (есть лучшие методы)
Тюнинг параметров
from sklearn.model_selection import GridSearchCV
params = {
'C': [0.1, 1, 10, 100],
'gamma': ['scale', 'auto', 0.001, 0.01],
'kernel': ['linear', 'rbf', 'poly']
}
grid_search = GridSearchCV(SVC(), params, cv=5)
grid_search.fit(X_train, y_train)
print(f"Лучшие параметры: {grid_search.best_params_}")
print(f"Лучший score: {grid_search.best_score_}")
Заключение
SVM - это мощный классификатор, основанный на поиске оптимальной разделяющей гиперплоскости с максимальным зазором. Ядра позволяют работать с нелинейными данными. Хотя SVM вытеснена нейросетями, она остаётся полезной для средних датасетов с чёткой структурой классов. Главное - правильно выбрать ядро и настроить параметры C и gamma.