Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через JupyterLite или Binder.
Сравнение ядерной гребневой регрессии и SVR
И ядерная гребневая регрессия (KRR), и SVR обучают нелинейную функцию, используя ядерный трюк: они обучают линейную функцию в пространстве, заданном соответствующим ядром, которая соответствует нелинейной функции в исходном пространстве. Методы различаются функциями потерь (гребневая регрессия и функция потерь, нечувствительная к эпсилон-ошибке). В отличие от SVR, KRR можно обучить в замкнутой форме, и обычно она работает быстрее на наборах данных среднего размера. С другой стороны, обученная модель не является разреженной и поэтому медленнее SVR при прогнозировании.
В этом примере оба метода применяются к искусственному набору данных, состоящему из синусоидальной целевой функции и сильного шума, добавленного к каждой пятой точке данных.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Генерация примера данных
import numpy as np rng = np.random.RandomState(42) X = 5 * rng.rand(10000, 1) y = np.sin(X).ravel() # Add noise to targets y[::5] += 3 * (0.5 - rng.rand(X.shape[0] // 5)) X_plot = np.linspace(0, 5, 100000)[:, None]
Создание моделей регрессии на основе ядер
from sklearn.kernel_ridge import KernelRidge
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVR
train_size = 100
svr = GridSearchCV(
SVR(kernel="rbf", gamma=0.1),
param_grid={"C": [1e0, 1e1, 1e2, 1e3], "gamma": np.logspace(-2, 2, 5)},
)
kr = GridSearchCV(
KernelRidge(kernel="rbf", gamma=0.1),
param_grid={"alpha": [1e0, 0.1, 1e-2, 1e-3], "gamma": np.logspace(-2, 2, 5)},
)
Сравнение времени работы SVR и ядерной гребневой регрессии
import time
t0 = time.time()
svr.fit(X[:train_size], y[:train_size])
svr_fit = time.time() - t0
print(f"Best SVR with params: {svr.best_params_} and R2 score: {svr.best_score_:.3f}")
print("SVR complexity and bandwidth selected and model fitted in %.3f s" % svr_fit)
t0 = time.time()
kr.fit(X[:train_size], y[:train_size])
kr_fit = time.time() - t0
print(f"Best KRR with params: {kr.best_params_} and R2 score: {kr.best_score_:.3f}")
print("KRR complexity and bandwidth selected and model fitted in %.3f s" % kr_fit)
sv_ratio = svr.best_estimator_.support_.shape[0] / train_size
print("Support vector ratio: %.3f" % sv_ratio)
t0 = time.time()
y_svr = svr.predict(X_plot)
svr_predict = time.time() - t0
print("SVR prediction for %d inputs in %.3f s" % (X_plot.shape[0], svr_predict))
t0 = time.time()
y_kr = kr.predict(X_plot)
kr_predict = time.time() - t0
print("KRR prediction for %d inputs in %.3f s" % (X_plot.shape[0], kr_predict))
Best SVR with params: {'C': 1.0, 'gamma': np.float64(0.1)} and R2 score: 0.737
SVR complexity and bandwidth selected and model fitted in 0.574 s
Best KRR with params: {'alpha': 0.1, 'gamma': np.float64(0.1)} and R2 score: 0.723
KRR complexity and bandwidth selected and model fitted in 0.231 s
Support vector ratio: 0.340
SVR prediction for 100000 inputs in 0.152 s
KRR prediction for 100000 inputs in 0.100 s
Результаты
import matplotlib.pyplot as plt
sv_ind = svr.best_estimator_.support_
plt.scatter(
X[sv_ind],
y[sv_ind],
c="r",
s=50,
label="SVR support vectors",
zorder=2,
edgecolors=(0, 0, 0),
)
plt.scatter(X[:100], y[:100], c="k", label="data", zorder=1, edgecolors=(0, 0, 0))
plt.plot(
X_plot,
y_svr,
c="r",
label="SVR (fit: %.3fs, predict: %.3fs)" % (svr_fit, svr_predict),
)
plt.plot(
X_plot, y_kr, c="g", label="KRR (fit: %.3fs, predict: %.3fs)" % (kr_fit, kr_predict)
)
plt.xlabel("data")
plt.ylabel("target")
plt.title("SVR versus Kernel Ridge")
_ = plt.legend()

На предыдущем графике сравниваются обученные модели KRR и SVR, когда сложность/регуляризация и ширина полосы RBF-ядра оптимизируются с помощью поиска по сетке. Обученные функции очень похожи, однако обучение KRR примерно в 3–4 раза быстрее, чем обучение SVR (в обоих случаях с поиском по сетке).
Теоретически прогнозирование 100000 целевых значений может выполняться примерно в три раза быстрее с помощью SVR, поскольку эта модель разреженная и использует в качестве опорных векторов лишь примерно 1/3 обучающих точек. Однако на практике это не обязательно так: из-за особенностей реализации вычисления ядерной функции для каждой модели KRR может работать так же быстро или даже быстрее, несмотря на большее число арифметических операций.
Визуализация времени обучения и прогнозирования
plt.figure()
sizes = np.logspace(1, 3.8, 7).astype(int)
for name, estimator in {
"KRR": KernelRidge(kernel="rbf", alpha=0.01, gamma=10),
"SVR": SVR(kernel="rbf", C=1e2, gamma=10),
}.items():
train_time = []
test_time = []
for train_test_size in sizes:
t0 = time.time()
estimator.fit(X[:train_test_size], y[:train_test_size])
train_time.append(time.time() - t0)
t0 = time.time()
estimator.predict(X_plot[:1000])
test_time.append(time.time() - t0)
plt.plot(
sizes,
train_time,
"o-",
color="r" if name == "SVR" else "g",
label="%s (train)" % name,
)
plt.plot(
sizes,
test_time,
"o--",
color="r" if name == "SVR" else "g",
label="%s (test)" % name,
)
plt.xscale("log")
plt.yscale("log")
plt.xlabel("Train size")
plt.ylabel("Time (seconds)")
plt.title("Execution Time")
_ = plt.legend(loc="best")

На этом графике сравнивается время обучения и прогнозирования для KRR и SVR при разных размерах обучающей выборки. На обучающих выборках среднего размера (менее нескольких тысяч объектов) KRR обучается быстрее SVR; однако на более крупных выборках SVR масштабируется лучше. Что касается времени прогнозирования, благодаря разреженному решению SVR должна работать быстрее KRR при любом размере обучающей выборки, однако на практике это не всегда так из-за особенностей реализации. Обратите внимание, что степень разреженности и, следовательно, время прогнозирования зависят от параметров epsilon и C модели SVR.
Визуализация кривых обучения
from sklearn.model_selection import LearningCurveDisplay
_, ax = plt.subplots()
svr = SVR(kernel="rbf", C=1e1, gamma=0.1)
kr = KernelRidge(kernel="rbf", alpha=0.1, gamma=0.1)
common_params = {
"X": X[:100],
"y": y[:100],
"train_sizes": np.linspace(0.1, 1, 10),
"scoring": "neg_mean_squared_error",
"negate_score": True,
"score_name": "Mean Squared Error",
"score_type": "test",
"std_display_style": None,
"ax": ax,
}
LearningCurveDisplay.from_estimator(svr, **common_params)
LearningCurveDisplay.from_estimator(kr, **common_params)
ax.set_title("Learning curves")
ax.legend(handles=ax.get_legend_handles_labels()[0], labels=["SVR", "KRR"])
plt.show()

Общее время выполнения скрипта: (0 минут 8.625 секунд)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/miscellaneous/plot_kernel_ridge_regression.html