1
+ import numpy as np
2
+ from scipy .optimize import minimize
3
+
4
+ class GaussianProcessRegressor :
5
+ def __init__ (self , kernel = 'rbf' , noise = 1e-8 ):
6
+ """
7
+ Initialize the Gaussian Process Regressor.
8
+
9
+ Args:
10
+ kernel (str): The type of kernel to use. Currently only 'rbf' is implemented.
11
+ noise (float): The noise level for the diagonal of the covariance matrix.
12
+ """
13
+ self .kernel = kernel
14
+ self .noise = noise
15
+ self .X_train = None
16
+ self .y_train = None
17
+ self .params = None
18
+
19
+ def rbf_kernel (self , X1 , X2 , l = 1.0 , sigma_f = 1.0 ):
20
+ """
21
+ Radial Basis Function (RBF) kernel, also known as squared exponential kernel.
22
+
23
+ K(x, x') = σ^2 * exp(-1/(2l^2) * ||x - x'||^2)
24
+
25
+ Args:
26
+ X1, X2 (numpy.ndarray): Input arrays
27
+ l (float): Length scale parameter
28
+ sigma_f (float): Signal variance parameter
29
+
30
+ Returns:
31
+ numpy.ndarray: Kernel matrix
32
+ """
33
+ sqdist = np .sum (X1 ** 2 , 1 ).reshape (- 1 , 1 ) + np .sum (X2 ** 2 , 1 ) - 2 * np .dot (X1 , X2 .T )
34
+ return sigma_f ** 2 * np .exp (- 0.5 / l ** 2 * sqdist )
35
+
36
+ def negative_log_likelihood (self , params ):
37
+ """
38
+ Compute the negative log likelihood.
39
+ This is the function we want to minimize to find optimal kernel parameters.
40
+
41
+ Args:
42
+ params (list): List containing kernel parameters [l, sigma_f]
43
+
44
+ Returns:
45
+ float: Negative log likelihood
46
+ """
47
+ l , sigma_f = params
48
+ K = self .rbf_kernel (self .X_train , self .X_train , l , sigma_f ) + self .noise ** 2 * np .eye (len (self .X_train ))
49
+ return 0.5 * np .log (np .linalg .det (K )) + \
50
+ 0.5 * self .y_train .T .dot (np .linalg .inv (K ).dot (self .y_train )) + \
51
+ 0.5 * len (self .X_train ) * np .log (2 * np .pi )
52
+
53
+ def fit (self , X , y ):
54
+ """
55
+ Fit the GPR model to the training data.
56
+
57
+ Args:
58
+ X (numpy.ndarray): Training input data
59
+ y (numpy.ndarray): Training target data
60
+ """
61
+ self .X_train = X
62
+ self .y_train = y
63
+
64
+ # Optimize kernel parameters using L-BFGS-B algorithm
65
+ res = minimize (self .negative_log_likelihood , [1 , 1 ],
66
+ bounds = ((1e-5 , None ), (1e-5 , None )),
67
+ method = 'L-BFGS-B' )
68
+ self .params = res .x
69
+
70
+ def predict (self , X_test , return_std = False ):
71
+ """
72
+ Make predictions on test data.
73
+
74
+ Args:
75
+ X_test (numpy.ndarray): Test input data
76
+ return_std (bool): If True, return standard deviation along with mean
77
+
78
+ Returns:
79
+ tuple or numpy.ndarray: Mean predictions (and standard deviations if return_std=True)
80
+ """
81
+ l , sigma_f = self .params
82
+
83
+ # Compute relevant kernel matrices
84
+ K = self .rbf_kernel (self .X_train , self .X_train , l , sigma_f ) + self .noise ** 2 * np .eye (len (self .X_train ))
85
+ K_s = self .rbf_kernel (self .X_train , X_test , l , sigma_f )
86
+ K_ss = self .rbf_kernel (X_test , X_test , l , sigma_f ) + 1e-8 * np .eye (len (X_test ))
87
+
88
+ K_inv = np .linalg .inv (K )
89
+
90
+ # Compute predictive mean
91
+ mu_s = K_s .T .dot (K_inv ).dot (self .y_train )
92
+
93
+ # Compute predictive variance
94
+ var_s = K_ss - K_s .T .dot (K_inv ).dot (K_s )
95
+
96
+ return (mu_s , np .sqrt (np .diag (var_s ))) if return_std else mu_s
97
+
98
+ # Example usage
99
+ if __name__ == "__main__" :
100
+ # Generate some sample data
101
+ X = np .array ([1 , 3 , 5 , 6 , 7 , 8 ]).reshape (- 1 , 1 )
102
+ y = np .sin (X ).ravel ()
103
+
104
+ # Create and fit the model
105
+ gpr = GaussianProcessRegressor ()
106
+ gpr .fit (X , y )
107
+
108
+ # Make predictions
109
+ X_test = np .linspace (0 , 10 , 100 ).reshape (- 1 , 1 )
110
+ mu_s , std_s = gpr .predict (X_test , return_std = True )
111
+
112
+ print ("Predicted mean:" , mu_s )
113
+ print ("Predicted standard deviation:" , std_s )
114
+
115
+ # Note: To visualize results, you would typically use matplotlib here
116
+ # to plot the original data, predictions, and confidence intervals
0 commit comments