PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 2003-2005 Olivier Delalleau 00005 // 00006 // Redistribution and use in source and binary forms, with or without 00007 // modification, are permitted provided that the following conditions are met: 00008 // 00009 // 1. Redistributions of source code must retain the above copyright 00010 // notice, this list of conditions and the following disclaimer. 00011 // 00012 // 2. Redistributions in binary form must reproduce the above copyright 00013 // notice, this list of conditions and the following disclaimer in the 00014 // documentation and/or other materials provided with the distribution. 00015 // 00016 // 3. The name of the authors may not be used to endorse or promote 00017 // products derived from this software without specific prior written 00018 // permission. 00019 // 00020 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00021 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00022 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00023 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00025 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00026 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00027 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00028 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 // 00031 // This file is part of the PLearn library. For more information on the PLearn 00032 // library, go to the PLearn Web site at www.plearn.org 00033 00034 00035 /* ******************************************************* 00036 * $Id: BootstrapVMatrix.cc 10155 2009-04-28 20:57:25Z nouiz $ 00037 ******************************************************* */ 00038 00039 #include "BootstrapVMatrix.h" 00040 #include <plearn/math/random.h> 00041 #include <plearn/math/TMat_sort.h> 00042 00043 namespace PLearn { 00044 using namespace std; 00045 00048 PLEARN_IMPLEMENT_OBJECT(BootstrapVMatrix, 00049 "A VMatrix that sees a bootstrap subset of its parent VMatrix.", 00050 "It means that a random sample of the source will be taken. Samples\n" 00051 "may or may not be repeated depending on the value of the option\n" 00052 "'allow_repetitions' (the default behavior is not to repeat samples)." 00053 ); 00054 00056 // BootstrapVMatrix // 00058 BootstrapVMatrix::BootstrapVMatrix(): 00059 rgen(new PRandom()), 00060 frac(0.6667), 00061 n_elems(-1), 00062 operate_on_bags(false), 00063 own_seed(-3), // Temporary hack value to detect use of deprecated option. 00064 seed(1827), // Default fixed seed value (safer than time-dependent). 00065 shuffle(false), 00066 allow_repetitions(false) 00067 {} 00068 00069 BootstrapVMatrix::BootstrapVMatrix(VMat m, real the_frac, bool the_shuffle, 00070 int32_t the_seed, bool allow_rep): 00071 rgen(new PRandom()), 00072 frac(the_frac), 00073 n_elems(-1), 00074 operate_on_bags(false), 00075 own_seed(-3), 00076 seed(the_seed), 00077 shuffle(the_shuffle), 00078 allow_repetitions(allow_rep) 00079 { 00080 this->source = m; 00081 build(); 00082 } 00083 00084 BootstrapVMatrix::BootstrapVMatrix(VMat m, real the_frac, 00085 PP<PRandom> the_rgen, 00086 bool the_shuffle, 00087 bool allow_rep): 00088 rgen(the_rgen), 00089 frac(the_frac), 00090 n_elems(-1), 00091 operate_on_bags(false), 00092 own_seed(-3), 00093 shuffle(the_shuffle), 00094 allow_repetitions(allow_rep) 00095 { 00096 PLASSERT( the_rgen ); 00097 // We obtain the seed value that was actually used to initialize the Boost 00098 // random number generator, to ensure this VMat is always the same after 00099 // consecutive builds. 00100 seed = int32_t(the_rgen->get_the_seed()); 00101 this->source = m; 00102 build(); 00103 } 00104 00106 // declareOptions // 00108 void BootstrapVMatrix::declareOptions(OptionList &ol) 00109 { 00110 declareOption(ol, "shuffle", &BootstrapVMatrix::shuffle, OptionBase::buildoption, 00111 "If set to 1, the indices will be shuffled instead of being sorted."); 00112 00113 declareOption(ol, "frac", &BootstrapVMatrix::frac, OptionBase::buildoption, 00114 "The fraction of elements we keep."); 00115 00116 declareOption(ol, "n_elems", &BootstrapVMatrix::n_elems, OptionBase::buildoption, 00117 "The absolute number of elements we keep (will override 'frac' if provided)."); 00118 00119 declareOption(ol, "seed", &BootstrapVMatrix::seed, OptionBase::buildoption, 00120 "Random generator seed (-1 = from clock and 0 = no initialization)."); 00121 00122 declareOption(ol, "allow_repetitions", &BootstrapVMatrix::allow_repetitions, 00123 OptionBase::buildoption, 00124 "Wether examples should be allowed to appear each more than once.", 00125 OptionBase::advanced_level); 00126 00127 declareOption(ol, "operate_on_bags", &BootstrapVMatrix::operate_on_bags, 00128 OptionBase::buildoption, 00129 "Wether to operate on bags rather than individual samples (see help\n" 00130 "of SumOverBagsVariable for details on bags).", 00131 OptionBase::advanced_level); 00132 00133 declareOption(ol, "own_seed", &BootstrapVMatrix::own_seed, 00134 (OptionBase::learntoption | OptionBase::nosave), 00135 "DEPRECATED: old random generator seed", 00136 OptionBase::deprecated_level); 00137 00138 inherited::declareOptions(ol); 00139 00140 // Hide the 'indices' option, because it will be overridden at build time. 00141 redeclareOption(ol, "indices", &BootstrapVMatrix::indices, OptionBase::nosave,""); 00142 redeclareOption(ol, "indices_vmat", &BootstrapVMatrix::indices_vmat, OptionBase::nosave,""); 00143 } 00144 00146 // build // 00148 void BootstrapVMatrix::build() 00149 { 00150 inherited::build(); 00151 build_(); 00152 } 00153 00155 // build_ // 00157 void BootstrapVMatrix::build_() 00158 { 00159 if (source) 00160 { 00161 updateMtime(source); 00162 // Ensure we are not using the deprecated 'own_seed' option. 00163 if (own_seed != -3) { 00164 PLDEPRECATED("In BootstrapVMatrix::build_ - The 'own_seed' option " 00165 "is deprecated: please use 'seed' instead"); 00166 PLASSERT( seed == 0 ); // Old default value for 'seed' was 0. 00167 seed = own_seed; 00168 own_seed = -3; 00169 } 00170 00171 // Initialize RNG. 00172 rgen->manual_seed(seed); 00173 00174 // Create bootstrap sample. 00175 int l= source.length(); 00176 00177 TVec< TVec<int> > bag_to_indices; 00178 if (operate_on_bags) { 00179 // Analyze bags in the source. 00180 Vec input, target; 00181 real weight; 00182 for (int i = 0; i < l; i++) { 00183 source->getExample(i, input, target, weight); 00184 #ifndef NDEBUG 00185 // Safety checks on bag information. 00186 real bi = target.lastElement(); 00187 PLASSERT( is_equal(round(bi), bi) ); 00188 int bii = int(round(bi)); 00189 PLASSERT( bii >= 0 && bii <= 3 ); 00190 #endif 00191 int bag_info = int(round(target.lastElement())); 00192 if (bag_info % 2 == 1) 00193 bag_to_indices.append(TVec<int>()); 00194 bag_to_indices.lastElement().append(i); 00195 } 00196 l = bag_to_indices.length(); 00197 } 00198 00199 int nsamp= (n_elems >= 0) ? n_elems : int(round(frac*l)); 00200 00201 if(allow_repetitions) 00202 { 00203 indices.resize(nsamp); 00204 for(int i= 0; i < nsamp; ++i) 00205 indices[i]= rgen->uniform_multinomial_sample(l); 00206 } 00207 else 00208 { 00209 indices = TVec<int>(0, l-1, 1); // Range-vector 00210 rgen->shuffleElements(indices); 00211 indices = indices.subVec(0, min(indices.size(), nsamp)); 00212 } 00213 if (!shuffle) 00214 sortElements(indices); 00215 00216 if (operate_on_bags) { 00217 // Convert bag indices back to sample indices. 00218 TVec<int> bag_indices = indices.copy(); 00219 indices.resize(0); 00220 for (int i = 0; i < bag_indices.length(); i++) 00221 indices.append(bag_to_indices[bag_indices[i]]); 00222 } 00223 00224 //if we only shuffle the rows, we remove a useless warning. 00225 if(frac == 1 && allow_repetitions == 0 && rows_to_remove == 0 && shuffle == 1) 00226 warn_if_all_rows_selected=false; 00227 // Because we changed the indices, a rebuild may be needed. 00228 inherited::build(); 00229 } 00230 } 00231 00233 // makeDeepCopyFromShallowCopy // 00235 void BootstrapVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00236 { 00237 inherited::makeDeepCopyFromShallowCopy(copies); 00238 deepCopyField(rgen, copies); 00239 } 00240 00241 } // end of namespace PLearn 00242 00243 00244 /* 00245 Local Variables: 00246 mode:c++ 00247 c-basic-offset:4 00248 c-file-style:"stroustrup" 00249 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00250 indent-tabs-mode:nil 00251 fill-column:79 00252 End: 00253 */ 00254 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :