| 41 | // ---------------------------------------------------------------------------------------- |
| 42 | |
| 43 | int main() |
| 44 | { |
| 45 | try |
| 46 | { |
| 47 | std::vector<sample_type> samples; |
| 48 | std::vector<double> labels; |
| 49 | |
| 50 | // First, get our labeled set of training data |
| 51 | generate_data(samples, labels); |
| 52 | |
| 53 | cout << "samples.size(): "<< samples.size() << endl; |
| 54 | |
| 55 | // The main object in this example program is the one_vs_one_trainer. It is essentially |
| 56 | // a container class for regular binary classifier trainer objects. In particular, it |
| 57 | // uses the any_trainer object to store any kind of trainer object that implements a |
| 58 | // .train(samples,labels) function which returns some kind of learned decision function. |
| 59 | // It uses these binary classifiers to construct a voting multiclass classifier. If |
| 60 | // there are N classes then it trains N*(N-1)/2 binary classifiers, one for each pair of |
| 61 | // labels, which then vote on the label of a sample. |
| 62 | // |
| 63 | // In this example program we will work with a one_vs_one_trainer object which stores any |
| 64 | // kind of trainer that uses our sample_type samples. |
| 65 | typedef one_vs_one_trainer<any_trainer<sample_type> > ovo_trainer; |
| 66 | |
| 67 | |
| 68 | // Finally, make the one_vs_one_trainer. |
| 69 | ovo_trainer trainer; |
| 70 | |
| 71 | |
| 72 | // Next, we will make two different binary classification trainer objects. One |
| 73 | // which uses kernel ridge regression and RBF kernels and another which uses a |
| 74 | // support vector machine and polynomial kernels. The particular details don't matter. |
| 75 | // The point of this part of the example is that you can use any kind of trainer object |
| 76 | // with the one_vs_one_trainer. |
| 77 | typedef polynomial_kernel<sample_type> poly_kernel; |
| 78 | typedef radial_basis_kernel<sample_type> rbf_kernel; |
| 79 | |
| 80 | // make the binary trainers and set some parameters |
| 81 | krr_trainer<rbf_kernel> rbf_trainer; |
| 82 | svm_nu_trainer<poly_kernel> poly_trainer; |
| 83 | poly_trainer.set_kernel(poly_kernel(0.1, 1, 2)); |
| 84 | rbf_trainer.set_kernel(rbf_kernel(0.1)); |
| 85 | |
| 86 | |
| 87 | // Now tell the one_vs_one_trainer that, by default, it should use the rbf_trainer |
| 88 | // to solve the individual binary classification subproblems. |
| 89 | trainer.set_trainer(rbf_trainer); |
| 90 | // We can also get more specific. Here we tell the one_vs_one_trainer to use the |
| 91 | // poly_trainer to solve the class 1 vs class 2 subproblem. All the others will |
| 92 | // still be solved with the rbf_trainer. |
| 93 | trainer.set_trainer(poly_trainer, 1, 2); |
| 94 | |
| 95 | // Now let's do 5-fold cross-validation using the one_vs_one_trainer we just setup. |
| 96 | // As an aside, always shuffle the order of the samples before doing cross validation. |
| 97 | // For a discussion of why this is a good idea see the svm_ex.cpp example. |
| 98 | randomize_samples(samples, labels); |
| 99 | cout << "cross validation: \n" << cross_validate_multiclass_trainer(trainer, samples, labels, 5) << endl; |
| 100 | // The output is shown below. It is the confusion matrix which describes the results. Each row |
nothing calls this directly
no test coverage detected