2014-12-07 18:05:32 +08:00
|
|
|
"""
|
2014-12-09 02:46:31 +08:00
|
|
|
=============================================
|
|
|
|
|
Comparison of kernel ridge regression and SVR
|
|
|
|
|
=============================================
|
2014-12-07 18:05:32 +08:00
|
|
|
|
2014-12-09 02:46:31 +08:00
|
|
|
Both kernel ridge regression (KRR) and SVR learn a non-linear function by
|
|
|
|
|
employing the kernel trick, i.e., they learn a linear function in the space
|
|
|
|
|
induced by the respective kernel which corresponds to a non-linear function in
|
2015-01-10 02:59:27 +08:00
|
|
|
the original space. They differ in the loss functions (ridge versus
|
|
|
|
|
epsilon-insensitive loss). In contrast to SVR, fitting a KRR can be done in
|
|
|
|
|
closed-form and is typically faster for medium-sized datasets. On the other
|
|
|
|
|
hand, the learned model is non-sparse and thus slower than SVR at
|
2014-12-09 02:46:31 +08:00
|
|
|
prediction-time.
|
2014-12-07 18:05:32 +08:00
|
|
|
|
|
|
|
|
This example illustrates both methods on an artificial dataset, which
|
|
|
|
|
consists of a sinusoidal target function and strong noise added to every fifth
|
|
|
|
|
datapoint. The first figure compares the learned model of KRR and SVR when both
|
|
|
|
|
complexity/regularization and bandwidth of the RBF kernel are optimized using
|
|
|
|
|
grid-search. The learned functions are very similar; however, fitting KRR is
|
|
|
|
|
approx. seven times faster than fitting SVR (both with grid-search). However,
|
2015-01-10 02:59:27 +08:00
|
|
|
prediction of 100000 target values is more than tree times faster with SVR
|
|
|
|
|
since it has learned a sparse model using only approx. 1/3 of the 100 training
|
|
|
|
|
datapoints as support vectors.
|
2014-12-07 18:05:32 +08:00
|
|
|
|
|
|
|
|
The next figure compares the time for fitting and prediction of KRR and SVR for
|
|
|
|
|
different sizes of the training set. Fitting KRR is faster than SVR for medium-
|
|
|
|
|
sized training sets (less than 1000 samples); however, for larger training sets
|
|
|
|
|
SVR scales better. With regard to prediction time, SVR is faster than
|
|
|
|
|
KRR for all sizes of the training set because of the learned sparse
|
|
|
|
|
solution. Note that the degree of sparsity and thus the prediction time depends
|
2015-01-10 02:59:27 +08:00
|
|
|
on the parameters epsilon and C of the SVR.
|
2021-10-22 21:33:22 +08:00
|
|
|
|
2014-12-07 18:05:32 +08:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# Authors: Jan Hendrik Metzen <jhm@informatik.uni-bremen.de>
|
|
|
|
|
# License: BSD 3 clause
|
|
|
|
|
|
2014-11-30 17:16:14 +08:00
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
from sklearn.svm import SVR
|
2015-09-11 02:26:39 +08:00
|
|
|
from sklearn.model_selection import GridSearchCV
|
|
|
|
|
from sklearn.model_selection import learning_curve
|
2014-11-30 17:16:14 +08:00
|
|
|
from sklearn.kernel_ridge import KernelRidge
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
2022-03-18 21:57:12 +08:00
|
|
|
rng = np.random.RandomState(42)
|
2014-11-30 17:16:14 +08:00
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
2014-11-30 17:16:14 +08:00
|
|
|
# Generate sample data
|
2015-01-07 03:36:54 +08:00
|
|
|
X = 5 * rng.rand(10000, 1)
|
2014-11-30 17:16:14 +08:00
|
|
|
y = np.sin(X).ravel()
|
|
|
|
|
|
|
|
|
|
# Add noise to targets
|
2017-02-03 22:21:03 +08:00
|
|
|
y[::5] += 3 * (0.5 - rng.rand(X.shape[0] // 5))
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
X_plot = np.linspace(0, 5, 100000)[:, None]
|
|
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
2014-11-30 17:16:14 +08:00
|
|
|
# Fit regression model
|
2014-12-07 18:05:32 +08:00
|
|
|
train_size = 100
|
2019-07-14 22:26:41 +08:00
|
|
|
svr = GridSearchCV(
|
|
|
|
|
SVR(kernel="rbf", gamma=0.1),
|
2015-01-10 02:59:27 +08:00
|
|
|
param_grid={"C": [1e0, 1e1, 1e2, 1e3], "gamma": np.logspace(-2, 2, 5)},
|
|
|
|
|
)
|
2014-11-30 17:16:14 +08:00
|
|
|
|
2019-07-14 22:26:41 +08:00
|
|
|
kr = GridSearchCV(
|
|
|
|
|
KernelRidge(kernel="rbf", gamma=0.1),
|
2015-01-10 02:59:27 +08:00
|
|
|
param_grid={"alpha": [1e0, 0.1, 1e-2, 1e-3], "gamma": np.logspace(-2, 2, 5)},
|
|
|
|
|
)
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
t0 = time.time()
|
2014-12-07 18:05:32 +08:00
|
|
|
svr.fit(X[:train_size], y[:train_size])
|
|
|
|
|
svr_fit = time.time() - t0
|
|
|
|
|
print("SVR complexity and bandwidth selected and model fitted in %.3f s" % svr_fit)
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
t0 = time.time()
|
2014-12-07 18:05:32 +08:00
|
|
|
kr.fit(X[:train_size], y[:train_size])
|
|
|
|
|
kr_fit = time.time() - t0
|
|
|
|
|
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)
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
t0 = time.time()
|
|
|
|
|
y_svr = svr.predict(X_plot)
|
2014-12-07 18:05:32 +08:00
|
|
|
svr_predict = time.time() - t0
|
|
|
|
|
print("SVR prediction for %d inputs in %.3f s" % (X_plot.shape[0], svr_predict))
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
t0 = time.time()
|
|
|
|
|
y_kr = kr.predict(X_plot)
|
2014-12-07 18:05:32 +08:00
|
|
|
kr_predict = time.time() - t0
|
|
|
|
|
print("KRR prediction for %d inputs in %.3f s" % (X_plot.shape[0], kr_predict))
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
|
|
|
|
# Look at the results
|
2014-12-07 18:05:32 +08:00
|
|
|
sv_ind = svr.best_estimator_.support_
|
2015-12-16 11:29:51 +08:00
|
|
|
plt.scatter(
|
|
|
|
|
X[sv_ind],
|
|
|
|
|
y[sv_ind],
|
|
|
|
|
c="r",
|
|
|
|
|
s=50,
|
|
|
|
|
label="SVR support vectors",
|
2017-06-20 02:51:33 +08:00
|
|
|
zorder=2,
|
|
|
|
|
edgecolors=(0, 0, 0),
|
|
|
|
|
)
|
|
|
|
|
plt.scatter(X[:100], y[:100], c="k", label="data", zorder=1, edgecolors=(0, 0, 0))
|
2015-01-10 02:59:27 +08:00
|
|
|
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)
|
2021-10-07 16:13:00 +08:00
|
|
|
)
|
2014-11-30 17:16:14 +08:00
|
|
|
plt.xlabel("data")
|
|
|
|
|
plt.ylabel("target")
|
2014-12-07 18:05:32 +08:00
|
|
|
plt.title("SVR versus Kernel Ridge")
|
2014-11-30 17:16:14 +08:00
|
|
|
plt.legend()
|
|
|
|
|
|
|
|
|
|
# Visualize training and prediction time
|
|
|
|
|
plt.figure()
|
|
|
|
|
|
|
|
|
|
# Generate sample data
|
2015-01-07 03:36:54 +08:00
|
|
|
X = 5 * rng.rand(10000, 1)
|
2014-11-30 17:16:14 +08:00
|
|
|
y = np.sin(X).ravel()
|
2017-02-03 22:21:03 +08:00
|
|
|
y[::5] += 3 * (0.5 - rng.rand(X.shape[0] // 5))
|
2022-03-18 21:57:12 +08:00
|
|
|
sizes = np.logspace(1, 3.8, 7).astype(int)
|
2015-01-10 02:59:27 +08:00
|
|
|
for name, estimator in {
|
2022-03-18 21:57:12 +08:00
|
|
|
"KRR": KernelRidge(kernel="rbf", alpha=0.01, gamma=10),
|
|
|
|
|
"SVR": SVR(kernel="rbf", C=1e2, gamma=10),
|
2015-01-10 02:59:27 +08:00
|
|
|
}.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,
|
|
|
|
|
)
|
2014-11-30 17:16:14 +08:00
|
|
|
|
|
|
|
|
plt.xscale("log")
|
|
|
|
|
plt.yscale("log")
|
2014-12-07 18:05:32 +08:00
|
|
|
plt.xlabel("Train size")
|
2014-11-30 17:16:14 +08:00
|
|
|
plt.ylabel("Time (seconds)")
|
|
|
|
|
plt.title("Execution Time")
|
|
|
|
|
plt.legend(loc="best")
|
|
|
|
|
|
|
|
|
|
# Visualize learning curves
|
|
|
|
|
plt.figure()
|
|
|
|
|
|
2015-01-10 02:59:27 +08:00
|
|
|
svr = SVR(kernel="rbf", C=1e1, gamma=0.1)
|
|
|
|
|
kr = KernelRidge(kernel="rbf", alpha=0.1, gamma=0.1)
|
2014-11-30 17:16:14 +08:00
|
|
|
train_sizes, train_scores_svr, test_scores_svr = learning_curve(
|
2015-01-10 02:59:27 +08:00
|
|
|
svr,
|
|
|
|
|
X[:100],
|
|
|
|
|
y[:100],
|
|
|
|
|
train_sizes=np.linspace(0.1, 1, 10),
|
2016-09-06 17:25:11 +08:00
|
|
|
scoring="neg_mean_squared_error",
|
|
|
|
|
cv=10,
|
|
|
|
|
)
|
2014-11-30 17:16:14 +08:00
|
|
|
train_sizes_abs, train_scores_kr, test_scores_kr = learning_curve(
|
2015-01-10 02:59:27 +08:00
|
|
|
kr,
|
|
|
|
|
X[:100],
|
|
|
|
|
y[:100],
|
|
|
|
|
train_sizes=np.linspace(0.1, 1, 10),
|
2016-09-06 17:25:11 +08:00
|
|
|
scoring="neg_mean_squared_error",
|
|
|
|
|
cv=10,
|
|
|
|
|
)
|
2021-10-07 16:13:00 +08:00
|
|
|
|
2016-09-06 17:25:11 +08:00
|
|
|
plt.plot(train_sizes, -test_scores_svr.mean(1), "o-", color="r", label="SVR")
|
|
|
|
|
plt.plot(train_sizes, -test_scores_kr.mean(1), "o-", color="g", label="KRR")
|
2014-11-30 17:16:14 +08:00
|
|
|
plt.xlabel("Train size")
|
|
|
|
|
plt.ylabel("Mean Squared Error")
|
|
|
|
|
plt.title("Learning curves")
|
|
|
|
|
plt.legend(loc="best")
|
|
|
|
|
|
|
|
|
|
plt.show()
|