| 148 | // ---------------------------------------------------------------------------------------- |
| 149 | |
| 150 | void test_manifold_regularization ( |
| 151 | const double intrinsic_regularization_strength |
| 152 | ) |
| 153 | { |
| 154 | cout << "Testing manifold regularization with an intrinsic_regularization_strength of " |
| 155 | << intrinsic_regularization_strength << ".\n"; |
| 156 | |
| 157 | std::vector<sample_type> samples; |
| 158 | |
| 159 | // Declare an instance of the kernel we will be using. |
| 160 | const kernel_type kern(0.1); |
| 161 | |
| 162 | const unsigned long num_points = 100000; |
| 163 | |
| 164 | // create a large dataset with two concentric circles. There will be 100000 points on each circle |
| 165 | // for a total of 200000 samples. |
| 166 | generate_circle(samples, 2, num_points); // circle of radius 2 |
| 167 | generate_circle(samples, 4, num_points); // circle of radius 4 |
| 168 | |
| 169 | // Create a set of sample_pairs that tells us which samples are "close" and should thus |
| 170 | // be classified similarly. These edges will be used to define the manifold regularizer. |
| 171 | // To find these edges we use a simple function that samples point pairs randomly and |
| 172 | // returns the top 5% with the shortest edges. |
| 173 | std::vector<sample_pair> edges; |
| 174 | find_percent_shortest_edges_randomly(samples, squared_euclidean_distance(), 0.05, 1000000, time(0), edges); |
| 175 | |
| 176 | cout << "number of edges generated: " << edges.size() << endl; |
| 177 | |
| 178 | empirical_kernel_map<kernel_type> ekm; |
| 179 | |
| 180 | // Since the circles are not linearly separable we will use an empirical kernel map to |
| 181 | // map them into a space where they are separable. We create an empirical_kernel_map |
| 182 | // using a random subset of our data samples as basis samples. Note, however, that even |
| 183 | // though the circles are linearly separable in this new space given by the empirical_kernel_map |
| 184 | // we still won't be able to correctly classify all the points given just the 2 labeled examples. |
| 185 | // We will need to make use of the nearest neighbor information stored in edges. To do that |
| 186 | // we will use the linear_manifold_regularizer. |
| 187 | ekm.load(kern, randomly_subsample(samples, 50)); |
| 188 | |
| 189 | // Project all the samples into the span of our 50 basis samples |
| 190 | for (unsigned long i = 0; i < samples.size(); ++i) |
| 191 | samples[i] = ekm.project(samples[i]); |
| 192 | |
| 193 | |
| 194 | // Now create the manifold regularizer. The result is a transformation matrix that |
| 195 | // embodies the manifold assumption discussed above. |
| 196 | linear_manifold_regularizer<sample_type> lmr; |
| 197 | // use_gaussian_weights is a function object that tells lmr how to weight each edge. In this |
| 198 | // case we let the weight decay as edges get longer. So shorter edges are more important than |
| 199 | // longer edges. |
| 200 | lmr.build(samples, edges, use_gaussian_weights(0.1)); |
| 201 | const matrix<double> T = lmr.get_transformation_matrix(intrinsic_regularization_strength); |
| 202 | |
| 203 | // Apply the transformation generated by the linear_manifold_regularizer to |
| 204 | // all our samples. |
| 205 | for (unsigned long i = 0; i < samples.size(); ++i) |
| 206 | samples[i] = T*samples[i]; |
| 207 |
no test coverage detected