PLearn 0.1
BootstrapVMatrix.cc
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines