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

1""" 

2New BSD License 

3 

4Copyright (c) 2014 Jan Hendrik Metzen 

5All rights reserved. 

6 

7 

8Redistribution and use in source and binary forms, with or without 

9modification, are permitted provided that the following conditions are met: 

10 

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.  

20 

21 

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""" 

34 

35"""The :mod:`sklearn.kernel_regressor` module implements the Kernel Regressor. 

36""" 

37 

38import numpy as np 

39 

40from sklearn.metrics.pairwise import pairwise_kernels 

41from sklearn.base import BaseEstimator, RegressorMixin 

42 

43 

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. 

50 

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. 

64  

65 See also 

66 -------- 

67 sklearn.metrics.pairwise.kernel_metrics : List of built-in kernels. 

68 """ 

69 

70 def __init__(self, kernel="rbf", gamma=None): 

71 self.kernel = kernel 

72 self.gamma = gamma 

73 

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 

89 

90 if hasattr(self.gamma, "__iter__"): 

91 self.gamma = self._optimize_gamma(self.gamma) 

92 

93 return self 

94 

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) 

108 

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() 

120 

121 return gamma_values[np.nanargmin(mse)]