PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // ToBagSplitter.cc 00004 // 00005 // Copyright (C) 2004 Olivier Delalleau 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: ToBagSplitter.cc 9052 2008-05-23 20:57:32Z tihocan $ 00037 ******************************************************* */ 00038 00039 // Authors: Olivier Delalleau 00040 00044 #include "ToBagSplitter.h" 00045 #include <plearn/var/SumOverBagsVariable.h> 00046 #include <plearn/vmat/SelectColumnsVMatrix.h> 00047 #include <plearn/vmat/SelectRowsVMatrix.h> 00048 00049 namespace PLearn { 00050 using namespace std; 00051 00053 // ToBagSplitter // 00055 ToBagSplitter::ToBagSplitter(): 00056 expected_size_of_bag(10), 00057 provide_target(false), 00058 remove_bag(false) 00059 {} 00060 00061 PLEARN_IMPLEMENT_OBJECT(ToBagSplitter, 00062 "A Splitter that makes any existing splitter operate on bags only.", 00063 "The dataset provided must contain bag information, as described in\n" 00064 "SumOverBagsVariable." 00065 ); 00066 00068 // declareOptions // 00070 void ToBagSplitter::declareOptions(OptionList& ol) 00071 { 00072 declareOption(ol, "expected_size_of_bag", 00073 &ToBagSplitter::expected_size_of_bag, 00074 OptionBase::buildoption, 00075 "The expected size of each bag (optional)."); 00076 00077 declareOption(ol, "sub_splitter", 00078 &ToBagSplitter::sub_splitter, OptionBase::buildoption, 00079 "The underlying splitter we want to make operate on bags."); 00080 00081 declareOption(ol, "remove_bag", 00082 &ToBagSplitter::remove_bag, OptionBase::buildoption, 00083 "If true, then the bag column will be removed from the data splits."); 00084 00085 declareOption(ol, "provide_target", 00086 &ToBagSplitter::provide_target, OptionBase::buildoption, 00087 "If true, then the target (without the bag info) of a bag will be\n" 00088 "provided to the underlying splitter. This target is obtained from\n" 00089 "the first sample in each bag."); 00090 00091 // Now call the parent class' declareOptions 00092 inherited::declareOptions(ol); 00093 } 00094 00096 // build // 00098 void ToBagSplitter::build() 00099 { 00100 inherited::build(); 00101 build_(); 00102 } 00103 00105 // build_ // 00107 void ToBagSplitter::build_() 00108 { 00109 if (dataset) { 00110 // Prepare the bags index list. 00111 int max_ninstances = 1; 00112 // The first column in bags_store gives the number of instances in the bag, 00113 // and the following columns give the indices of the corresponding rows in 00114 // the original dataset. 00115 Mat bags_store(dataset->length() / expected_size_of_bag + 1, expected_size_of_bag + 1); 00116 int num_bag = 0; 00117 int num_instance = 0; 00118 int bag_signal_column = dataset->inputsize() + dataset->targetsize() - 1; // Bag signal in the last target column. 00119 for (int i = 0; i < dataset->length(); i++) { 00120 while (num_instance + 1 >= bags_store.width()) { 00121 // Need to resize bags_store. 00122 bags_store.resize(bags_store.length(), bags_store.width() * 2, 0, true); 00123 } 00124 if (num_instance >= max_ninstances) { 00125 max_ninstances = num_instance + 1; 00126 } 00127 bags_store(num_bag, num_instance + 1) = i; 00128 num_instance++; 00129 if (int(dataset->get(i, bag_signal_column)) & SumOverBagsVariable::TARGET_COLUMN_LAST) { 00130 // Last element of a bag. 00131 bags_store(num_bag, 0) = num_instance; // Store the number of instances in this bag. 00132 num_bag++; 00133 num_instance = 0; 00134 if (num_bag >= bags_store.length()) { 00135 // Need to resize bags_store. 00136 bags_store.resize(bags_store.length() * 2, bags_store.width(), 0, true); 00137 } 00138 } 00139 } 00140 // Resize to the minimum size needed. 00141 bags_store.resize(num_bag, max_ninstances + 1, 0, true); 00142 int bags_store_is = max_ninstances + 1; 00143 int bags_store_ts = 0; 00144 if (provide_target) { 00145 if (dataset->targetsize() <= 1) 00146 PLWARNING("In ToBagSplitter::build_ - 'provide_target' is true," 00147 " but the dataset does not seem to have any target " 00148 "besides the bag information: no target provided to " 00149 "the underlying splitter"); 00150 else { 00151 bags_store_ts = dataset->targetsize() - 1; 00152 bags_store.resize(bags_store.length(), 00153 bags_store.width() + bags_store_ts, 00154 0, true); 00155 Vec input, target; 00156 real weight; 00157 for (int i = 0; i < bags_store.length(); i++) { 00158 dataset->getExample(int(round(bags_store(i, 1))), 00159 input, target, weight); 00160 bags_store(i).subVec(bags_store_is, bags_store_ts) << 00161 target.subVec(0, bags_store_ts); 00162 } 00163 } 00164 } 00165 bags_index = VMat(bags_store); 00166 bags_index->defineSizes(bags_store_is, bags_store_ts, 0); 00167 //bags_index->savePMAT("HOME:tmp/bid.pmat"); 00168 // Provide this index to the sub_splitter. 00169 sub_splitter->setDataSet(bags_index); 00170 } 00171 } 00172 00174 // getSplit // 00176 TVec<VMat> ToBagSplitter::getSplit(int k) 00177 { 00178 TVec<VMat> sub_splits = sub_splitter->getSplit(k); 00179 TVec<VMat> result; 00180 for (int i = 0; i < sub_splits.length(); i++) { 00181 // Get the list of corresponding indices in the original dataset. 00182 Mat indices = sub_splits[i].toMat(); 00183 // Turn it into a TVec<int>. 00184 TVec<int> indices_int; 00185 for (int j = 0; j < indices.length(); j++) { 00186 for (int q = 0; q < indices(j, 0); q++) { 00187 int indice = int(indices(j, q + 1)); 00188 indices_int.append(indice); 00189 } 00190 } 00191 VMat selected_rows = new SelectRowsVMatrix(dataset, indices_int); 00192 if (remove_bag) { 00193 // Remove the bag column. 00194 int bag_column = selected_rows->inputsize() + 00195 selected_rows->targetsize() - 1; 00196 TVec<int> removed_col(1, bag_column); 00197 PP<SelectColumnsVMatrix> new_sel = 00198 new SelectColumnsVMatrix(selected_rows, removed_col, false); 00199 new_sel->inverse_fields_selection = true; 00200 new_sel->defineSizes(selected_rows->inputsize(), 00201 selected_rows->targetsize() - 1, 00202 selected_rows->weightsize(), 00203 selected_rows->extrasize()); 00204 new_sel->build(); 00205 selected_rows = get_pointer(new_sel); 00206 } 00207 result.append(selected_rows); 00208 } 00209 return result; 00210 } 00211 00213 // makeDeepCopyFromShallowCopy // 00215 void ToBagSplitter::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00216 { 00217 inherited::makeDeepCopyFromShallowCopy(copies); 00218 00219 deepCopyField(bags_index, copies); 00220 deepCopyField(sub_splitter, copies); 00221 00222 } 00223 00225 // nSetsPerSplit // 00227 int ToBagSplitter::nSetsPerSplit() const 00228 { 00229 // ### Return the number of sets per split 00230 return sub_splitter->nSetsPerSplit(); 00231 } 00232 00234 // nsplits // 00236 int ToBagSplitter::nsplits() const 00237 { 00238 return sub_splitter->nsplits(); 00239 } 00240 00242 // setDataSet // 00244 void ToBagSplitter::setDataSet(VMat the_dataset) { 00245 inherited::setDataSet(the_dataset); 00246 // Need to recompute the bags index. 00247 build(); 00248 } 00249 00250 } // end of namespace PLearn 00251 00252 00253 /* 00254 Local Variables: 00255 mode:c++ 00256 c-basic-offset:4 00257 c-file-style:"stroustrup" 00258 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00259 indent-tabs-mode:nil 00260 fill-column:79 00261 End: 00262 */ 00263 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :