Coverage for rivapy/numerics/kernel_regression.py: 65%
26 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-05 14:27 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-05 14:27 +0000
1"""
2New BSD License
4Copyright (c) 2014 Jan Hendrik Metzen
5All rights reserved.
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions are met:
11 a. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13 b. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 c. Neither the name of the software's developer nor the names of
17 its contributors may be used to endorse or promote products
18 derived from this software without specific prior written
19 permission.
22THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
26ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32DAMAGE.
33"""
35"""The :mod:`sklearn.kernel_regressor` module implements the Kernel Regressor.
36"""
38import numpy as np
40from sklearn.metrics.pairwise import pairwise_kernels
41from sklearn.base import BaseEstimator, RegressorMixin
44class KernelRegression(BaseEstimator, RegressorMixin):
45 """Nadaraya-Watson kernel regression with automatic bandwidth selection.
46 This implements Nadaraya-Watson kernel regression with (optional) automatic
47 bandwith selection of the kernel via leave-one-out cross-validation. Kernel
48 regression is a simple non-parametric kernelized technique for learning
49 a non-linear relationship between input variable(s) and a target variable.
51 Parameters
52 ----------
53 kernel : string or callable, default="rbf"
54 Kernel map to be approximated. A callable should accept two arguments
55 and the keyword arguments passed to this object as kernel_params, and
56 should return a floating point number.
57 gamma : float, default=None
58 Gamma parameter for the RBF ("bandwidth"), polynomial,
59 exponential chi2 and sigmoid kernels. Interpretation of the default
60 value is left to the kernel; see the documentation for
61 sklearn.metrics.pairwise. Ignored by other kernels. If a sequence of
62 values is given, one of these values is selected which minimizes
63 the mean-squared-error of leave-one-out cross-validation.
65 See also
66 --------
67 sklearn.metrics.pairwise.kernel_metrics : List of built-in kernels.
68 """
70 def __init__(self, kernel="rbf", gamma=None):
71 self.kernel = kernel
72 self.gamma = gamma
74 def fit(self, X, y):
75 """Fit the model
76 Parameters
77 ----------
78 X : array-like of shape = [n_samples, n_features]
79 The training input samples.
80 y : array-like, shape = [n_samples]
81 The target values
82 Returns
83 -------
84 self : object
85 Returns self.
86 """
87 self.X = X
88 self.y = y
90 if hasattr(self.gamma, "__iter__"):
91 self.gamma = self._optimize_gamma(self.gamma)
93 return self
95 def predict(self, X):
96 """Predict target values for X.
97 Parameters
98 ----------
99 X : array-like of shape = [n_samples, n_features]
100 The input samples.
101 Returns
102 -------
103 y : array of shape = [n_samples]
104 The predicted target value.
105 """
106 K = pairwise_kernels(self.X, X, metric=self.kernel, gamma=self.gamma)
107 return (K * self.y[:, None]).sum(axis=0) / K.sum(axis=0)
109 def _optimize_gamma(self, gamma_values):
110 # Select specific value of gamma from the range of given gamma_values
111 # by minimizing mean-squared error in leave-one-out cross validation
112 mse = np.empty_like(gamma_values, dtype=np.float)
113 for i, gamma in enumerate(gamma_values):
114 K = pairwise_kernels(self.X, self.X, metric=self.kernel,
115 gamma=gamma)
116 np.fill_diagonal(K, 0) # leave-one-out
117 Ky = K * self.y[:, np.newaxis]
118 y_pred = Ky.sum(axis=0) / K.sum(axis=0)
119 mse[i] = ((y_pred - self.y) ** 2).mean()
121 return gamma_values[np.nanargmin(mse)]