PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // ClassSeparationSplitter.cc 00004 // 00005 // Copyright (C) 2006 Hugo Larochelle 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 00037 ******************************************************* */ 00038 00039 // Authors: Hugo Larochelle 00040 00043 #include "SelectRowsVMatrix.h" 00044 #include "ClassSeparationSplitter.h" 00045 00046 namespace PLearn { 00047 using namespace std; 00048 00049 PLEARN_IMPLEMENT_OBJECT( 00050 ClassSeparationSplitter, 00051 "Splitter that separates examples of some classes (test) from the examples of other classes (train)", 00052 "This splitter is intended to measure inductive transfer performance from some tasks to another task" 00053 ); 00054 00055 ClassSeparationSplitter::ClassSeparationSplitter() 00056 :Splitter(), numsplits(-1), nclasses(-1), nclasses_test_set(1), select_classes_randomly(1), append_train(0), seed(-1) 00057 { 00058 random_gen = new PRandom(); 00059 } 00060 00061 void ClassSeparationSplitter::declareOptions(OptionList& ol) 00062 { 00063 declareOption(ol, "numsplits", &ClassSeparationSplitter::numsplits, OptionBase::buildoption, 00064 "Number of splits. If <= 0, then it is set to nclasses."); 00065 declareOption(ol, "nclasses", &ClassSeparationSplitter::nclasses, OptionBase::buildoption, 00066 "Number of classes."); 00067 declareOption(ol, "nclasses_test_set", &ClassSeparationSplitter::nclasses_test_set, OptionBase::buildoption, 00068 "Number of classes in the test sets."); 00069 declareOption(ol, "classes", &ClassSeparationSplitter::classes, OptionBase::buildoption, 00070 "Classes to isolate from the others, for each split. When this field is specified,\n" 00071 "then nclasses, nclasses_test_set and nsplit are ignored."); 00072 declareOption(ol, "select_classes_randomly", &ClassSeparationSplitter::select_classes_randomly, OptionBase::buildoption, 00073 "Indication that the classes should be chosen at random.\n" 00074 "Otherwise, the classes are selected by order of their index."); 00075 declareOption(ol, "append_train", &ClassSeparationSplitter::append_train, OptionBase::buildoption, 00076 "Indication that the training set should be appended to the split sets lists."); 00077 00078 declareOption(ol, "seed", &ClassSeparationSplitter::seed, OptionBase::buildoption, 00079 "Seed of random generator"); 00080 00081 // Now call the parent class' declareOptions 00082 inherited::declareOptions(ol); 00083 } 00084 00085 void ClassSeparationSplitter::build_() 00086 { 00087 if (seed != 0) 00088 random_gen->manual_seed(seed); 00089 00090 if(classes.length() == 0) 00091 { 00092 if(nclasses <= 0) PLERROR("In ClassSeparationSplitter::build_(): nclasses should be > 0"); 00093 if(nclasses_test_set <= 0) PLERROR("In ClassSeparationSplitter::build_(): nclasses_test_set should be > 0"); 00094 if(nclasses_test_set >= nclasses) PLERROR("In ClassSeparationSplitter::build_(): nclasses_test_set should be < nclasses"); 00095 if(numsplits <= 0) numsplits = nclasses; 00096 00097 classes.resize(numsplits); 00098 int it = 0; 00099 for(int i=0; i<numsplits; i++) 00100 { 00101 if(select_classes_randomly) 00102 { 00103 classes[i].resize(nclasses); 00104 for(int j=0; j<nclasses; j++) 00105 classes[i][j] = j; 00106 random_gen->shuffleElements(classes[i]); 00107 classes.resize(nclasses_test_set); 00108 } 00109 else 00110 { 00111 classes[i].resize(nclasses_test_set); 00112 for(int j=0; j<nclasses_test_set; j++) 00113 { 00114 classes[i][j] = it%nclasses; 00115 it++; 00116 } 00117 } 00118 } 00119 } 00120 } 00121 00122 // ### Nothing to add here, simply calls build_ 00123 void ClassSeparationSplitter::build() 00124 { 00125 inherited::build(); 00126 build_(); 00127 } 00128 00129 void ClassSeparationSplitter::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00130 { 00131 inherited::makeDeepCopyFromShallowCopy(copies); 00132 00133 deepCopyField(classes, copies); 00134 deepCopyField(random_gen, copies); 00135 00136 //PLERROR("ClassSeparationSplitter::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!"); 00137 } 00138 00139 int ClassSeparationSplitter::nsplits() const 00140 { 00141 return classes.length(); 00142 } 00143 00144 int ClassSeparationSplitter::nSetsPerSplit() const 00145 { 00146 return append_train ? 3 : 2; 00147 } 00148 00149 TVec<VMat> ClassSeparationSplitter::getSplit(int k) 00150 { 00151 00152 if (k >= nsplits()) 00153 PLERROR("ClassSeparationSplitter::getSplit() - k (%d) cannot be greater than " 00154 " the number of splits (%d)", k, nsplits()); 00155 00156 TVec<int> classes_k = classes[k]; 00157 Vec row(dataset->width()); 00158 TVec<int> indices(0); 00159 for(int i=0; i<dataset->length(); i++) 00160 { 00161 dataset->getRow(i,row); 00162 if(classes_k.find((int)row[dataset->inputsize()]) >= 0) 00163 { 00164 indices.push_back(i); 00165 } 00166 } 00167 00168 TVec<VMat> split(2); 00169 split[0] = new SelectRowsVMatrix(dataset,indices, true); 00170 split[1] = new SelectRowsVMatrix(dataset,indices); 00171 if(append_train) split.append(split[0]); 00172 return split; 00173 } 00174 00175 00176 } // end of namespace PLearn 00177 00178 00179 /* 00180 Local Variables: 00181 mode:c++ 00182 c-basic-offset:4 00183 c-file-style:"stroustrup" 00184 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00185 indent-tabs-mode:nil 00186 fill-column:79 00187 End: 00188 */ 00189 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :