| 33 | } |
| 34 | |
| 35 | int main() |
| 36 | { |
| 37 | // We will use column vectors to store our points. Here we make a convenient typedef |
| 38 | // for the kind of vector we will use. |
| 39 | typedef matrix<double,0,1> sample_type; |
| 40 | |
| 41 | // Then we select the kernel we want to use. For our present problem the radial basis |
| 42 | // kernel is quite effective. |
| 43 | typedef radial_basis_kernel<sample_type> kernel_type; |
| 44 | |
| 45 | // Now make the object responsible for training one-class SVMs. |
| 46 | svm_one_class_trainer<kernel_type> trainer; |
| 47 | // Here we set the width of the radial basis kernel to 4.0. Larger values make the |
| 48 | // width smaller and give the radial basis kernel more resolution. If you play with |
| 49 | // the value and observe the program output you will get a more intuitive feel for what |
| 50 | // that means. |
| 51 | trainer.set_kernel(kernel_type(4.0)); |
| 52 | |
| 53 | // Now sample some 2D points. The points will be located on the curve defined by the |
| 54 | // sinc() function. |
| 55 | std::vector<sample_type> samples; |
| 56 | sample_type m(2); |
| 57 | for (double x = -15; x <= 8; x += 0.3) |
| 58 | { |
| 59 | m(0) = x; |
| 60 | m(1) = sinc(x); |
| 61 | samples.push_back(m); |
| 62 | } |
| 63 | |
| 64 | // Now train a one-class SVM. The result is a function, df(), that outputs large |
| 65 | // values for points from the sinc() curve and smaller values for points that are |
| 66 | // anomalous (i.e. not on the sinc() curve in our case). |
| 67 | decision_function<kernel_type> df = trainer.train(samples); |
| 68 | |
| 69 | // So for example, let's look at the output from some points on the sinc() curve. |
| 70 | cout << "Points that are on the sinc function:\n"; |
| 71 | m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 72 | m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 73 | m(0) = -0; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 74 | m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 75 | m(0) = -4.1; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 76 | m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 77 | m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl; |
| 78 | |
| 79 | cout << endl; |
| 80 | // Now look at some outputs for points not on the sinc() curve. You will see that |
| 81 | // these values are all notably smaller. |
| 82 | cout << "Points that are NOT on the sinc function:\n"; |
| 83 | m(0) = -1.5; m(1) = sinc(m(0))+4; cout << " " << df(m) << endl; |
| 84 | m(0) = -1.5; m(1) = sinc(m(0))+3; cout << " " << df(m) << endl; |
| 85 | m(0) = -0; m(1) = -sinc(m(0)); cout << " " << df(m) << endl; |
| 86 | m(0) = -0.5; m(1) = -sinc(m(0)); cout << " " << df(m) << endl; |
| 87 | m(0) = -4.1; m(1) = sinc(m(0))+2; cout << " " << df(m) << endl; |
| 88 | m(0) = -1.5; m(1) = sinc(m(0))+0.9; cout << " " << df(m) << endl; |
| 89 | m(0) = -0.5; m(1) = sinc(m(0))+1; cout << " " << df(m) << endl; |
| 90 | |
| 91 | // The output is as follows: |
| 92 | /* |
nothing calls this directly
no test coverage detected