SHOGUN
v2.0.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 set_epsilon(0.0001); 00037 m_train_func=m; 00038 } 00039 00040 void CKernelRidgeRegression::init() 00041 { 00042 m_tau=1e-6; 00043 00044 SG_ADD(&m_tau, "tau", "Regularization parameter", MS_AVAILABLE); 00045 } 00046 00047 bool CKernelRidgeRegression::train_machine_pinv() 00048 { 00049 // Get kernel matrix 00050 SGMatrix<float64_t> kernel_matrix=kernel->get_kernel_matrix<float64_t>(); 00051 int32_t n = kernel_matrix.num_cols; 00052 int32_t m = kernel_matrix.num_rows; 00053 ASSERT(kernel_matrix.matrix && m>0 && n>0); 00054 00055 for(int32_t i=0; i < n; i++) 00056 kernel_matrix.matrix[i+i*n]+=m_tau; 00057 00058 /* re-set alphas of kernel machine */ 00059 m_alpha=((CRegressionLabels*) m_labels)->get_labels_copy(); 00060 00061 /* tell kernel machine that all alphas are needed as'support vectors' */ 00062 m_svs=SGVector<index_t>(m_alpha.vlen); 00063 m_svs.range_fill(); 00064 00065 if (get_alphas().vlen!=n) 00066 { 00067 SG_ERROR("Number of labels does not match number of kernel" 00068 " columns (num_labels=%d cols=%d\n", m_alpha.vlen, n); 00069 } 00070 00071 clapack_dposv(CblasRowMajor,CblasUpper, n, 1, kernel_matrix.matrix, n, 00072 m_alpha.vector, n); 00073 00074 return true; 00075 } 00076 00077 bool CKernelRidgeRegression::train_machine_gs() 00078 { 00079 int32_t n = kernel->get_num_vec_rhs(); 00080 int32_t m = kernel->get_num_vec_lhs(); 00081 ASSERT(m>0 && n>0); 00082 00083 // re-set alphas of kernel machine 00084 SGVector<float64_t> b; 00085 float64_t alpha_old; 00086 00087 b=((CRegressionLabels*) m_labels)->get_labels_copy(); 00088 m_alpha=((CRegressionLabels*) m_labels)->get_labels_copy(); 00089 m_alpha.zero(); 00090 00091 // tell kernel machine that all alphas are needed as 'support vectors' 00092 m_svs=SGVector<index_t>(m_alpha.vlen); 00093 m_svs.range_fill(); 00094 00095 if (get_alphas().vlen!=n) 00096 { 00097 SG_ERROR("Number of labels does not match number of kernel" 00098 " columns (num_labels=%d cols=%d\n", m_alpha.vlen, n); 00099 } 00100 00101 // Gauss-Seidel iterative method 00102 float64_t sigma, err, d; 00103 bool flag=true; 00104 while(flag) 00105 { 00106 err=0.0; 00107 for(int32_t i=0; i<n; i++) 00108 { 00109 sigma=b[i]; 00110 for(int32_t j=0; j<n; j++) 00111 if (i!=j) 00112 sigma-=kernel->kernel(j, i)*m_alpha[j]; 00113 alpha_old=m_alpha[i]; 00114 m_alpha[i]=sigma/(kernel->kernel(i, i)+m_tau); 00115 d=fabs(alpha_old-m_alpha[i]); 00116 if(d>err) 00117 err=d; 00118 } 00119 if (err<=m_epsilon) 00120 flag=false; 00121 } 00122 00123 return true; 00124 } 00125 00126 bool CKernelRidgeRegression::train_machine(CFeatures *data) 00127 { 00128 if (!m_labels) 00129 SG_ERROR("No labels set\n"); 00130 00131 if (m_labels->get_label_type() != LT_REGRESSION) 00132 SG_ERROR("Real labels needed for kernel ridge regression.\n"); 00133 00134 if (data) 00135 { 00136 if (m_labels->get_num_labels() != data->get_num_vectors()) 00137 SG_ERROR("Number of training vectors does not match number of labels\n"); 00138 kernel->init(data, data); 00139 } 00140 ASSERT(kernel && kernel->has_features()); 00141 00142 switch (m_train_func) 00143 { 00144 case PINV: 00145 return train_machine_pinv(); 00146 break; 00147 case GS: 00148 return train_machine_gs(); 00149 break; 00150 default: 00151 return train_machine_pinv(); 00152 break; 00153 } 00154 } 00155 00156 bool CKernelRidgeRegression::load(FILE* srcfile) 00157 { 00158 SG_SET_LOCALE_C; 00159 SG_RESET_LOCALE; 00160 return false; 00161 } 00162 00163 bool CKernelRidgeRegression::save(FILE* dstfile) 00164 { 00165 SG_SET_LOCALE_C; 00166 SG_RESET_LOCALE; 00167 return false; 00168 } 00169 #endif