SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KernelRidgeRegression.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  * Written (W) 2006 Mikio L. Braun
8  * Written (W) 1999-2009 Soeren Sonnenburg
9  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
10  */
11 
12 #include <shogun/lib/config.h>
13 
14 #ifdef HAVE_LAPACK
19 
20 using namespace shogun;
21 
24 {
25  init();
26 }
27 
30 {
31  init();
32 
33  m_tau=tau;
34  set_labels(lab);
35  set_kernel(k);
36  set_epsilon(0.0001);
37  m_train_func=m;
38 }
39 
40 void CKernelRidgeRegression::init()
41 {
42  m_tau=1e-6;
43 
44  SG_ADD(&m_tau, "tau", "Regularization parameter", MS_AVAILABLE);
45 }
46 
47 bool CKernelRidgeRegression::train_machine_pinv()
48 {
49  // Get kernel matrix
51  int32_t n = kernel_matrix.num_cols;
52  int32_t m = kernel_matrix.num_rows;
53  ASSERT(kernel_matrix.matrix && m>0 && n>0);
54 
55  for(int32_t i=0; i < n; i++)
56  kernel_matrix.matrix[i+i*n]+=m_tau;
57 
58  /* re-set alphas of kernel machine */
59  m_alpha=((CRegressionLabels*) m_labels)->get_labels_copy();
60 
61  /* tell kernel machine that all alphas are needed as'support vectors' */
63  m_svs.range_fill();
64 
65  if (get_alphas().vlen!=n)
66  {
67  SG_ERROR("Number of labels does not match number of kernel"
68  " columns (num_labels=%d cols=%d\n", m_alpha.vlen, n);
69  }
70 
71  clapack_dposv(CblasRowMajor,CblasUpper, n, 1, kernel_matrix.matrix, n,
72  m_alpha.vector, n);
73 
74  return true;
75 }
76 
77 bool CKernelRidgeRegression::train_machine_gs()
78 {
79  int32_t n = kernel->get_num_vec_rhs();
80  int32_t m = kernel->get_num_vec_lhs();
81  ASSERT(m>0 && n>0);
82 
83  // re-set alphas of kernel machine
85  float64_t alpha_old;
86 
87  b=((CRegressionLabels*) m_labels)->get_labels_copy();
88  m_alpha=((CRegressionLabels*) m_labels)->get_labels_copy();
89  m_alpha.zero();
90 
91  // tell kernel machine that all alphas are needed as 'support vectors'
93  m_svs.range_fill();
94 
95  if (get_alphas().vlen!=n)
96  {
97  SG_ERROR("Number of labels does not match number of kernel"
98  " columns (num_labels=%d cols=%d\n", m_alpha.vlen, n);
99  }
100 
101  // Gauss-Seidel iterative method
102  float64_t sigma, err, d;
103  bool flag=true;
104  while(flag)
105  {
106  err=0.0;
107  for(int32_t i=0; i<n; i++)
108  {
109  sigma=b[i];
110  for(int32_t j=0; j<n; j++)
111  if (i!=j)
112  sigma-=kernel->kernel(j, i)*m_alpha[j];
113  alpha_old=m_alpha[i];
114  m_alpha[i]=sigma/(kernel->kernel(i, i)+m_tau);
115  d=fabs(alpha_old-m_alpha[i]);
116  if(d>err)
117  err=d;
118  }
119  if (err<=m_epsilon)
120  flag=false;
121  }
122 
123  return true;
124 }
125 
127 {
128  if (!m_labels)
129  SG_ERROR("No labels set\n");
130 
132  SG_ERROR("Real labels needed for kernel ridge regression.\n");
133 
134  if (data)
135  {
136  if (m_labels->get_num_labels() != data->get_num_vectors())
137  SG_ERROR("Number of training vectors does not match number of labels\n");
138  kernel->init(data, data);
139  }
141 
142  switch (m_train_func)
143  {
144  case PINV:
145  return train_machine_pinv();
146  break;
147  case GS:
148  return train_machine_gs();
149  break;
150  default:
151  return train_machine_pinv();
152  break;
153  }
154 }
155 
156 bool CKernelRidgeRegression::load(FILE* srcfile)
157 {
160  return false;
161 }
162 
163 bool CKernelRidgeRegression::save(FILE* dstfile)
164 {
167  return false;
168 }
169 #endif

SHOGUN Machine Learning Toolbox - Documentation