SHOGUN
v3.2.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2006 Mikio L. Braun 00008 * Written (W) 1999-2009 Soeren Sonnenburg 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 */ 00011 00012 #include <shogun/lib/config.h> 00013 00014 #ifdef HAVE_LAPACK 00015 #include <shogun/regression/KernelRidgeRegression.h> 00016 #include <shogun/mathematics/lapack.h> 00017 #include <shogun/mathematics/Math.h> 00018 #include <shogun/labels/RegressionLabels.h> 00019 00020 using namespace shogun; 00021 00022 CKernelRidgeRegression::CKernelRidgeRegression() 00023 : CKernelMachine() 00024 { 00025 init(); 00026 } 00027 00028 CKernelRidgeRegression::CKernelRidgeRegression(float64_t tau, CKernel* k, CLabels* lab, ETrainingType m) 00029 : CKernelMachine() 00030 { 00031 init(); 00032 00033 m_tau=tau; 00034 set_labels(lab); 00035 set_kernel(k); 00036 m_train_func=m; 00037 } 00038 00039 void CKernelRidgeRegression::init() 00040 { 00041 m_tau=1e-6; 00042 m_epsilon=0.0001; 00043 SG_ADD(&m_tau, "tau", "Regularization parameter", MS_AVAILABLE); 00044 } 00045 00046 bool CKernelRidgeRegression::train_machine_pinv() 00047 { 00048 // Get kernel matrix 00049 SGMatrix<float64_t> kernel_matrix=kernel->get_kernel_matrix<float64_t>(); 00050 int32_t n = kernel_matrix.num_cols; 00051 int32_t m = kernel_matrix.num_rows; 00052 ASSERT(kernel_matrix.matrix && m>0 && n>0) 00053 00054 for(int32_t i=0; i < n; i++) 00055 kernel_matrix.matrix[i+i*n]+=m_tau; 00056 00057 /* re-set alphas of kernel machine */ 00058 m_alpha=((CRegressionLabels*) m_labels)->get_labels_copy(); 00059 00060 /* tell kernel machine that all alphas are needed as'support vectors' */ 00061 m_svs=SGVector<index_t>(m_alpha.vlen); 00062 m_svs.range_fill(); 00063 00064 if (get_alphas().vlen!=n) 00065 { 00066 SG_ERROR("Number of labels does not match number of kernel" 00067 " columns (num_labels=%d cols=%d\n", m_alpha.vlen, n); 00068 } 00069 00070 clapack_dposv(CblasRowMajor,CblasUpper, n, 1, kernel_matrix.matrix, n, 00071 m_alpha.vector, n); 00072 00073 return true; 00074 } 00075 00076 bool CKernelRidgeRegression::train_machine_gs() 00077 { 00078 int32_t n = kernel->get_num_vec_rhs(); 00079 int32_t m = kernel->get_num_vec_lhs(); 00080 ASSERT(m>0 && n>0) 00081 00082 // re-set alphas of kernel machine 00083 SGVector<float64_t> b; 00084 float64_t alpha_old; 00085 00086 b=((CRegressionLabels*) m_labels)->get_labels_copy(); 00087 m_alpha=((CRegressionLabels*) m_labels)->get_labels_copy(); 00088 m_alpha.zero(); 00089 00090 // tell kernel machine that all alphas are needed as 'support vectors' 00091 m_svs=SGVector<index_t>(m_alpha.vlen); 00092 m_svs.range_fill(); 00093 00094 if (get_alphas().vlen!=n) 00095 { 00096 SG_ERROR("Number of labels does not match number of kernel" 00097 " columns (num_labels=%d cols=%d\n", m_alpha.vlen, n); 00098 } 00099 00100 // Gauss-Seidel iterative method 00101 float64_t sigma, err, d; 00102 bool flag=true; 00103 while(flag) 00104 { 00105 err=0.0; 00106 for(int32_t i=0; i<n; i++) 00107 { 00108 sigma=b[i]; 00109 for(int32_t j=0; j<n; j++) 00110 if (i!=j) 00111 sigma-=kernel->kernel(j, i)*m_alpha[j]; 00112 alpha_old=m_alpha[i]; 00113 m_alpha[i]=sigma/(kernel->kernel(i, i)+m_tau); 00114 d=fabs(alpha_old-m_alpha[i]); 00115 if(d>err) 00116 err=d; 00117 } 00118 if (err<=m_epsilon) 00119 flag=false; 00120 } 00121 00122 return true; 00123 } 00124 00125 bool CKernelRidgeRegression::train_machine(CFeatures *data) 00126 { 00127 if (!m_labels) 00128 SG_ERROR("No labels set\n") 00129 00130 if (m_labels->get_label_type() != LT_REGRESSION) 00131 SG_ERROR("Real labels needed for kernel ridge regression.\n") 00132 00133 if (data) 00134 { 00135 if (m_labels->get_num_labels() != data->get_num_vectors()) 00136 SG_ERROR("Number of training vectors does not match number of labels\n") 00137 kernel->init(data, data); 00138 } 00139 ASSERT(kernel && kernel->has_features()) 00140 00141 switch (m_train_func) 00142 { 00143 case PINV: 00144 return train_machine_pinv(); 00145 break; 00146 case GS: 00147 return train_machine_gs(); 00148 break; 00149 default: 00150 return train_machine_pinv(); 00151 break; 00152 } 00153 } 00154 00155 bool CKernelRidgeRegression::load(FILE* srcfile) 00156 { 00157 SG_SET_LOCALE_C; 00158 SG_RESET_LOCALE; 00159 return false; 00160 } 00161 00162 bool CKernelRidgeRegression::save(FILE* dstfile) 00163 { 00164 SG_SET_LOCALE_C; 00165 SG_RESET_LOCALE; 00166 return false; 00167 } 00168 #endif