Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через 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()
SVR versus Kernel Ridge

На предыдущем графике сравниваются обученные модели 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")
Execution Time

На этом графике сравнивается время обучения и прогнозирования для 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()
Learning curves

Общее время выполнения скрипта: (0 минут 8.625 секунд)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_kernel_ridge_regression.ipynb

Download Python source code: plot_kernel_ridge_regression.py

Download zipped: plot_kernel_ridge_regression.zip

Связанные примеры

Регрессия методом опорных векторов (SVR) с линейными и нелинейными ядрами

Параметры RBF SVM

Вероятностные прогнозы с классификацией на основе гауссовских процессов (GPC)

Пример распознавания лиц с использованием собственных лиц и SVM

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API