| 165 | // ---------------------------------------------------------------------------------------- |
| 166 | |
| 167 | void test_empirical_kernel_map ( |
| 168 | const std::vector<sample_type>& samples, |
| 169 | const std::vector<double>& labels, |
| 170 | const empirical_kernel_map<kernel_type>& ekm |
| 171 | ) |
| 172 | { |
| 173 | |
| 174 | std::vector<sample_type> projected_samples; |
| 175 | |
| 176 | // The first thing we do is compute the nonlinearly projected vectors using the |
| 177 | // empirical_kernel_map. |
| 178 | for (unsigned long i = 0; i < samples.size(); ++i) |
| 179 | { |
| 180 | projected_samples.push_back(ekm.project(samples[i])); |
| 181 | } |
| 182 | |
| 183 | // Note that a kernel matrix is just a matrix M such that M(i,j) == kernel(samples[i],samples[j]). |
| 184 | // So below we are computing the normal kernel matrix as given by the radial_basis_kernel and the |
| 185 | // input samples. We also compute the kernel matrix for all the projected_samples as given by the |
| 186 | // linear_kernel. Note that the linear_kernel just computes normal dot products. So what we want to |
| 187 | // see is that the dot products between all the projected_samples samples are the same as the outputs |
| 188 | // of the kernel function for their respective untransformed input samples. If they match then |
| 189 | // we know that the empirical_kernel_map is working properly. |
| 190 | const matrix<double> normal_kernel_matrix = kernel_matrix(ekm.get_kernel(), samples); |
| 191 | const matrix<double> new_kernel_matrix = kernel_matrix(linear_kernel<sample_type>(), projected_samples); |
| 192 | |
| 193 | cout << "Max kernel matrix error: " << max(abs(normal_kernel_matrix - new_kernel_matrix)) << endl; |
| 194 | cout << "Mean kernel matrix error: " << mean(abs(normal_kernel_matrix - new_kernel_matrix)) << endl; |
| 195 | /* |
| 196 | Example outputs from these cout statements. |
| 197 | For the case where we use all samples as basis samples: |
| 198 | Max kernel matrix error: 7.32747e-15 |
| 199 | Mean kernel matrix error: 7.47789e-16 |
| 200 | |
| 201 | For the case where we use only 26 samples as basis samples: |
| 202 | Max kernel matrix error: 0.000953573 |
| 203 | Mean kernel matrix error: 2.26008e-05 |
| 204 | |
| 205 | |
| 206 | Note that if we use enough basis samples we can perfectly span the space of input samples. |
| 207 | In that case we get errors that are essentially just rounding noise (Moreover, using all the |
| 208 | samples is always enough since they are always within their own span). Once we start |
| 209 | to use fewer basis samples we may begin to get approximation error. In the second case we |
| 210 | used 26 and we can see that the data doesn't really lay exactly in a 26 dimensional subspace. |
| 211 | But it is pretty close. |
| 212 | */ |
| 213 | |
| 214 | |
| 215 | |
| 216 | // Now let's do something more interesting. The following loop finds the centroids |
| 217 | // of the two classes of data. |
| 218 | sample_type class1_center; |
| 219 | sample_type class2_center; |
| 220 | for (unsigned long i = 0; i < projected_samples.size(); ++i) |
| 221 | { |
| 222 | if (labels[i] == 1) |
| 223 | class1_center += projected_samples[i]; |
| 224 | else |
no test coverage detected