SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GaussianProcessRegression.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Copyright (C) 2012 Jacob Walker
8  *
9  * Code adapted from Gaussian Process Machine Learning Toolbox
10  * http://www.gaussianprocess.org/gpml/code/matlab/doc/
11  *
12  */
13 
14 #include <shogun/lib/config.h>
15 #ifdef HAVE_EIGEN3
16 #ifdef HAVE_LAPACK
17 
18 #include <shogun/io/SGIO.h>
22 #include <shogun/kernel/Kernel.h>
25 
26 using namespace shogun;
27 
29 : CMachine()
30 {
31  init();
32 }
33 
35 : CMachine()
36 {
37  init();
38 
39  set_labels(lab);
40  set_features(data);
41  set_method(inf);
42 }
43 
44 void CGaussianProcessRegression::init()
45 {
46 
47  m_features = NULL;
48  m_method = NULL;
49  m_data = NULL;
50  m_return = GP_RETURN_MEANS;
51 
52  SG_ADD((CSGObject**) &m_features, "features", "Feature object.",
54  SG_ADD((CSGObject**) &m_method, "inference_method", "Inference Method.",
55  MS_AVAILABLE);
56 }
57 
58 void CGaussianProcessRegression::update_kernel_matrices()
59 {
60  CKernel* kernel = NULL;
61 
62  if (m_method)
63  kernel = m_method->get_kernel();
64 
65  if (kernel)
66  {
67  float64_t m_scale = m_method->get_scale();
68 
69  CFeatures* latent_features = m_method->get_latent_features();
70 
71  if (latent_features)
72  kernel->init(latent_features, m_data);
73  else
74  kernel->init(m_data, m_data);
75 
76  //K(X_test, X_train)
77  m_k_trts = kernel->get_kernel_matrix();
78 
79  for (index_t i = 0; i < m_k_trts.num_rows; i++)
80  {
81  for (index_t j = 0; j < m_k_trts.num_cols; j++)
82  m_k_trts(i,j) *= (m_scale*m_scale);
83  }
84 
85  kernel->init(m_data, m_data);
86 
87  m_k_tsts = kernel->get_kernel_matrix();
88 
89  for (index_t i = 0; i < m_k_tsts.num_rows; i++)
90  {
91  for (index_t j = 0; j < m_k_tsts.num_cols; j++)
92  m_k_tsts(i,j) *= (m_scale*m_scale);
93  }
94 
95  kernel->remove_lhs_and_rhs();
96 
97  SG_UNREF(kernel);
98  SG_UNREF(latent_features);
99  }
100 }
101 
103 {
104 
105  if (data)
106  {
107  if(data->get_feature_class() == C_COMBINED)
108  {
109  CDotFeatures* feat =
110  (CDotFeatures*)((CCombinedFeatures*)data)->
111  get_first_feature_obj();
112 
113  if (!feat->has_property(FP_DOT))
114  SG_ERROR("Specified features are not of type CFeatures\n");
115 
116  if (feat->get_feature_class() != C_DENSE)
117  SG_ERROR("Expected Simple Features\n");
118 
119  if (feat->get_feature_type() != F_DREAL)
120  SG_ERROR("Expected Real Features\n");
121 
122  SG_UNREF(feat);
123  }
124 
125  else
126  {
127  if (!data->has_property(FP_DOT))
128  SG_ERROR("Specified features are not of type CFeatures\n");
129 
130  if (data->get_feature_class() != C_DENSE)
131  SG_ERROR("Expected Simple Features\n");
132 
133  if (data->get_feature_type() != F_DREAL)
134  SG_ERROR("Expected Real Features\n");
135  }
136 
137  SG_UNREF(m_data);
138  SG_REF(data);
139  m_data = (CFeatures*)data;
140  update_kernel_matrices();
141  }
142 
143  else if (!m_data)
144  SG_ERROR("No testing features!\n");
145 
146  else if (update_parameter_hash())
147  update_kernel_matrices();
148 
149  if (m_return == GP_RETURN_COV)
150  {
151  CRegressionLabels* result =
153 
154  return result;
155  }
156 
157  if (m_return == GP_RETURN_MEANS)
158  {
159  CRegressionLabels* result =
161 
162  return result;
163  }
164 
165  else
166  {
167 
168  SGVector<float64_t> mean_vector = get_mean_vector();
170 
171  index_t size = mean_vector.vlen+cov_vector.vlen;
172 
173  SGVector<float64_t> result_vector(size);
174 
175  for (index_t i = 0; i < size; i++)
176  {
177  if (i < mean_vector.vlen)
178  result_vector[i] = mean_vector[i];
179  else
180  result_vector[i] = cov_vector[i-mean_vector.vlen];
181  }
182 
183  CRegressionLabels* result =
184  new CRegressionLabels(result_vector);
185 
186  return result;
187  }
188 
189 }
190 
192 {
193  return false;
194 }
195 
196 
198 {
199 
200  SGVector<float64_t> m_alpha = m_method->get_alpha();
201 
202  CMeanFunction* mean_function = m_method->get_mean();
203 
204  SGMatrix<float64_t> features;
205  if(m_data->get_feature_class() == C_COMBINED)
206  {
207  features = ((CDotFeatures*)((CCombinedFeatures*)m_data)->
208  get_first_feature_obj())->
209  get_computed_dot_feature_matrix();
210  }
211 
212  else
213  {
214  features = ((CDotFeatures*)m_data)->
215  get_computed_dot_feature_matrix();
216  }
217 
218  if (!mean_function)
219  SG_ERROR("Mean function is NULL!\n");
220 
221 
222  SGVector<float64_t> means = mean_function->get_mean_vector(features);
223 
224  SGVector< float64_t > result_vector(features.num_cols);
225 
226  //Here we multiply K*^t by alpha to receive the mean predictions.
227  cblas_dgemv(CblasColMajor, CblasTrans, m_k_trts.num_rows,
228  m_alpha.vlen, 1.0, m_k_trts.matrix,
229  m_k_trts.num_cols, m_alpha.vector, 1, 0.0,
230  result_vector.vector, 1);
231 
232  for (index_t i = 0; i < result_vector.vlen; i++)
233  result_vector[i] += means[i];
234 
235  CLikelihoodModel* lik = m_method->get_model();
236 
237  result_vector = lik->evaluate_means(result_vector);
238 
239  SG_UNREF(lik);
240  SG_UNREF(mean_function);
241 
242  return result_vector;
243 }
244 
245 
247 {
248 
249  if (!m_data)
250  SG_ERROR("No testing features!\n");
251 
252  SGVector<float64_t> diagonal = m_method->get_diagonal_vector();
253 
254  if (diagonal.vlen > 0)
255  {
256  SGVector<float64_t> diagonal2(m_data->get_num_vectors());
257 
258  SGMatrix<float64_t> temp1(m_data->get_num_vectors(), diagonal.vlen);
259 
260  SGMatrix<float64_t> m_L = m_method->get_cholesky();
261 
262  SGMatrix<float64_t> temp2(m_L.num_rows, m_L.num_cols);
263 
264  for (index_t i = 0; i < diagonal.vlen; i++)
265  {
266  for (index_t j = 0; j < m_data->get_num_vectors(); j++)
267  temp1(j,i) = diagonal[i]*m_k_trts(j,i);
268  }
269 
270  for (index_t i = 0; i < diagonal2.vlen; i++)
271  diagonal2[i] = 0;
272 
273  memcpy(temp2.matrix, m_L.matrix,
274  m_L.num_cols*m_L.num_rows*sizeof(float64_t));
275 
276 
277  temp2.transpose_matrix(temp2.matrix, temp2.num_rows, temp2.num_cols);
278 
279  SGVector<int32_t> ipiv(temp2.num_cols);
280 
281  //Solve L^T V = K(Train,Test)*Diagonal Vector Entries for V
282  clapack_dgetrf(CblasColMajor, temp2.num_rows, temp2.num_cols,
283  temp2.matrix, temp2.num_cols, ipiv.vector);
284 
285  clapack_dgetrs(CblasColMajor, CblasNoTrans,
286  temp2.num_rows, temp1.num_cols, temp2.matrix,
287  temp2.num_cols, ipiv.vector, temp1.matrix,
288  temp1.num_cols);
289 
290  for (index_t i = 0; i < temp1.num_rows; i++)
291  {
292  for (index_t j = 0; j < temp1.num_cols; j++)
293  temp1(i,j) = temp1(i,j)*temp1(i,j);
294  }
295 
296  for (index_t i = 0; i < temp1.num_cols; i++)
297  {
298  diagonal2[i] = 0;
299 
300  for (index_t j = 0; j < temp1.num_rows; j++)
301  diagonal2[i] += temp1(j,i);
302  }
303 
304 
305  SGVector<float64_t> result(m_k_tsts.num_cols);
306 
307  //Subtract V from K(Test,Test) to get covariances.
308  for (index_t i = 0; i < m_k_tsts.num_cols; i++)
309  result[i] = m_k_tsts(i,i) - diagonal2[i];
310 
311  CLikelihoodModel* lik = m_method->get_model();
312 
313  SG_UNREF(lik);
314 
315  return lik->evaluate_variances(result);
316  }
317 
318  else
319  {
320  SGMatrix<float64_t> m_L = m_method->get_cholesky();
321 
322  SGMatrix<float64_t> temp1(m_k_trts.num_rows, m_k_trts.num_cols);
323  SGMatrix<float64_t> temp2(m_L.num_rows, m_L.num_cols);
324 
325  memcpy(temp1.matrix, m_k_trts.matrix,
326  m_k_trts.num_cols*m_k_trts.num_rows*sizeof(float64_t));
327 
328  memcpy(temp2.matrix, m_L.matrix,
329  m_L.num_cols*m_L.num_rows*sizeof(float64_t));
330 
331  cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, m_L.num_rows,
332  m_k_trts.num_cols, m_L.num_rows, 1.0, m_L.matrix, m_L.num_cols,
333  m_k_trts.matrix, m_k_trts.num_cols, 0.0, temp1.matrix,
334  temp1.num_cols);
335 
336  for (index_t i = 0; i < temp1.num_rows; i++)
337  {
338  for (index_t j = 0; j < temp1.num_cols; j++)
339  temp1(i,j) *= m_k_trts(i,j);
340  }
341 
342  SGVector<float64_t> temp3(temp2.num_cols);
343 
344  for (index_t i = 0; i < temp1.num_cols; i++)
345  {
346  float64_t sum = 0;
347  for (index_t j = 0; j < temp1.num_rows; j++)
348  sum += temp1(j,i);
349  temp3[i] = sum;
350  }
351 
352  SGVector<float64_t> result(m_k_tsts.num_cols);
353 
354  for (index_t i = 0; i < m_k_tsts.num_cols; i++)
355  result[i] = m_k_tsts(i,i) + temp3[i];
356 
357  CLikelihoodModel* lik = m_method->get_model();
358 
359  SG_UNREF(lik);
360 
361  return lik->evaluate_variances(result);
362  }
363 }
364 
365 
367 {
368  SG_UNREF(m_features);
369  SG_UNREF(m_method);
370  SG_UNREF(m_data);
371 }
372 
374 {
375  m_method->set_kernel(k);
376 }
377 
379 {
382  return false;
383 }
384 
386 {
387  return m_method->get_kernel();
388 }
389 
391 {
394  return false;
395 }
396 #endif
397 #endif

SHOGUN Machine Learning Toolbox - Documentation