Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added example how to perform modelselection over sub-parameters of co…
…mbined kernels
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
examples/undocumented/libshogun/modelselection_combined_kernel_sub_parameters.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* Written (W) 2013 Heiko Strathmann | ||
*/ | ||
|
||
#include <shogun/base/init.h> | ||
#include <shogun/evaluation/CrossValidation.h> | ||
#include <shogun/evaluation/ContingencyTableEvaluation.h> | ||
#include <shogun/evaluation/StratifiedCrossValidationSplitting.h> | ||
#include <shogun/modelselection/GridSearchModelSelection.h> | ||
#include <shogun/modelselection/ModelSelectionParameters.h> | ||
#include <shogun/modelselection/ParameterCombination.h> | ||
#include <shogun/labels/BinaryLabels.h> | ||
#include <shogun/features/DenseFeatures.h> | ||
#include <shogun/classifier/svm/LibSVM.h> | ||
#include <shogun/classifier/mkl/MKLClassification.h> | ||
#include <shogun/kernel/GaussianKernel.h> | ||
#include <shogun/kernel/PolyKernel.h> | ||
#include <shogun/kernel/CombinedKernel.h> | ||
|
||
using namespace shogun; | ||
|
||
/** Creates a bunch of combined kernels with different sub-parameters. | ||
* This can be used for modelselection of subkernel parameters of combined | ||
* kernels | ||
*/ | ||
CModelSelectionParameters* build_combined_kernel_parameter_tree() | ||
{ | ||
CModelSelectionParameters* root=new CModelSelectionParameters(); | ||
|
||
/* kernel a should be Gaussian with certain parameters | ||
* kernel b should be polynomial with certain parameters | ||
* This will create a list of combined kernels with all parameter combinations | ||
* All CList instances here do reference counting (also the combine_kernels | ||
* method of CCombinedKernel | ||
*/ | ||
CList* kernels_a=new CList(true); | ||
CList* kernels_b=new CList(true); | ||
|
||
int32_t cache_size=10; | ||
kernels_a->append_element(new CGaussianKernel(cache_size, 2)); | ||
kernels_a->append_element(new CGaussianKernel(cache_size, 4)); | ||
|
||
kernels_b->append_element(new CPolyKernel(cache_size, 4)); | ||
kernels_b->append_element(new CPolyKernel(cache_size, 2)); | ||
|
||
CList* kernel_list=new CList(); | ||
kernel_list->append_element(kernels_a); | ||
kernel_list->append_element(kernels_b); | ||
|
||
CList* combinations=CCombinedKernel::combine_kernels(kernel_list); | ||
|
||
/* add all created combined kernels to parameters tree */ | ||
|
||
/* cast is safe since the above method guarantees the type */ | ||
CCombinedKernel* current=(CCombinedKernel*)(combinations->get_first_element()); | ||
SG_SPRINT("combined kernel combinations:\n"); | ||
index_t i=0; | ||
while (current) | ||
{ | ||
/* print out current kernel's subkernels */ | ||
SG_SPRINT("combined kernel %d:\n", i++); | ||
CPolyKernel* poly=(CPolyKernel*)current->get_kernel(0); | ||
CGaussianKernel* gaussian=(CGaussianKernel*)current->get_kernel(1); | ||
SG_SPRINT("kernel_a type: %s\n", poly->get_name()); | ||
SG_SPRINT("kernel_b type: %s\n", gaussian->get_name()); | ||
SG_SPRINT("kernel_a parameter: %d\n", poly->get_degree()); | ||
SG_SPRINT("kernel_b parameter: %f\n", gaussian->get_width()); | ||
SG_UNREF(poly); | ||
SG_UNREF(gaussian); | ||
|
||
CModelSelectionParameters* param_kernel= | ||
new CModelSelectionParameters("kernel", current); | ||
root->append_child(param_kernel); | ||
|
||
SG_UNREF(current); | ||
current=(CCombinedKernel*)(combinations->get_next_element()); | ||
} | ||
|
||
SG_UNREF(combinations); | ||
SG_UNREF(kernel_list); | ||
SG_UNREF(kernels_a); | ||
SG_UNREF(kernels_b); | ||
|
||
return root; | ||
} | ||
|
||
void modelselection_combined_kernel() | ||
{ | ||
int32_t num_subsets=3; | ||
int32_t num_vectors=20; | ||
int32_t dim_vectors=3; | ||
|
||
/* create some data and labels */ | ||
SGMatrix<float64_t> matrix(dim_vectors, num_vectors); | ||
CBinaryLabels* labels=new CBinaryLabels(num_vectors); | ||
|
||
for (int32_t i=0; i<num_vectors*dim_vectors; i++) | ||
matrix.matrix[i]=CMath::randn_double(); | ||
|
||
/* create num_feautres 2-dimensional vectors */ | ||
CDenseFeatures<float64_t>* features=new CDenseFeatures<float64_t>(matrix); | ||
|
||
/* create labels, two classes */ | ||
for (index_t i=0; i<num_vectors; ++i) | ||
labels->set_label(i, i%2==0 ? 1 : -1); | ||
|
||
/* create svm */ | ||
CMKL* classifier=new CMKLClassification(new CLibSVM()); | ||
classifier->set_interleaved_optimization_enabled(false); | ||
|
||
/* splitting strategy */ | ||
CStratifiedCrossValidationSplitting* splitting_strategy= | ||
new CStratifiedCrossValidationSplitting(labels, num_subsets); | ||
|
||
/* accuracy evaluation */ | ||
CContingencyTableEvaluation* evaluation_criterium= | ||
new CContingencyTableEvaluation(ACCURACY); | ||
|
||
/* cross validation class for evaluation in model selection */ | ||
CCrossValidation* cross=new CCrossValidation(classifier, features, labels, | ||
splitting_strategy, evaluation_criterium); | ||
cross->set_num_runs(1); | ||
|
||
/* model parameter selection, deletion is handled by modsel class (SG_UNREF) */ | ||
CModelSelectionParameters* param_tree=build_combined_kernel_parameter_tree(); | ||
param_tree->print_tree(); | ||
|
||
/* handles all of the above structures in memory */ | ||
CGridSearchModelSelection* grid_search=new CGridSearchModelSelection( | ||
param_tree, cross); | ||
|
||
bool print_state=true; | ||
CParameterCombination* best_combination=grid_search->select_model( | ||
print_state); | ||
best_combination->print_tree(); | ||
|
||
best_combination->apply_to_machine(classifier); | ||
|
||
/* print subkernel parameters, I know what the subkernel types are here */ | ||
CCombinedKernel* kernel=(CCombinedKernel*)classifier->get_kernel(); | ||
CGaussianKernel* gaussian=(CGaussianKernel*)kernel->get_kernel(1); | ||
CPolyKernel* poly=(CPolyKernel*)kernel->get_kernel(0); | ||
SG_SPRINT("gaussian width: %f\n", gaussian->get_width()); | ||
SG_SPRINT("poly degree: %d\n", poly->get_degree()); | ||
SG_UNREF(kernel); | ||
SG_UNREF(gaussian); | ||
SG_UNREF(poly); | ||
|
||
/* evaluate selected kernel again, use locking to be faster */ | ||
cross->set_autolock(true); | ||
|
||
/* larger number of runs to have tighter confidence intervals */ | ||
cross->set_num_runs(10); | ||
cross->set_conf_int_alpha(0.01); | ||
CCrossValidationResult* result=(CCrossValidationResult*)cross->evaluate(); | ||
|
||
if (result->get_result_type() != CROSSVALIDATION_RESULT) | ||
SG_SERROR("Evaluation result is not of type CCrossValidationResult!"); | ||
|
||
SG_SPRINT("result: "); | ||
result->print_result(); | ||
|
||
/* clean up destroy result parameter */ | ||
SG_UNREF(result); | ||
SG_UNREF(best_combination); | ||
SG_UNREF(grid_search); | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
init_shogun_with_defaults(); | ||
|
||
modelselection_combined_kernel(); | ||
|
||
exit_shogun(); | ||
|
||
return 0; | ||
} | ||
|
9e178a5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Thank you so much for this!
9e178a5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I can't seem to make this work using the python interface. Can I get an example of how to make this work in python? WHen I try to follow this example I just get segfaults when call the combinedKernel.combine_kernels() method