PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // BaseRegressorWrapper.cc 00004 // Copyright (c) 1998-2002 Pascal Vincent 00005 // Copyright (C) 1999-2002 Yoshua Bengio and University of Montreal 00006 // Copyright (c) 2002 Jean-Sebastien Senecal, Xavier Saint-Mleux, Rejean Ducharme 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 00037 /* ******************************************************************************** 00038 * $Id: BaseRegressorWrapper.cc, v 1.0 2004/07/19 10:00:00 Bengio/Kegl/Godbout * 00039 * This file is part of the PLearn library. * 00040 ******************************************************************************** */ 00041 00042 #include "BaseRegressorWrapper.h" 00043 #include "BaseRegressorConfidence.h" 00044 #include "RegressionTree.h" 00045 #include <plearn/vmat/MeanImputationVMatrix.h> 00046 #include <plearn/base/stringutils.h> 00047 #include "RegressionTreeRegisters.h" 00048 00049 namespace PLearn { 00050 using namespace std; 00051 00052 PLEARN_IMPLEMENT_OBJECT(BaseRegressorWrapper, 00053 "A PLearner to wrap around a generic regressor to serve as a base learner to LocalMedBoost.", 00054 "Algorithm built to serve as a base regressor for the LocalMedBoost algorithm.\n" 00055 "It separates a confidence fonction from the output when making a prediction.\n" 00056 "It also computes mse, base confidence and base reward costs as expected by the boosting algorithm.\n" 00057 "To do that, it reformats output and cost in the format expected by boosting.\n" 00058 "It is intended also to implement in the fututre, various confidence functions.\n" 00059 "We could also use it to implement various missing value imputation strategies.\n" 00060 ); 00061 00062 BaseRegressorWrapper::BaseRegressorWrapper() 00063 : loss_function_weight(1.0), 00064 mean_imputation(0), 00065 regression_tree(0), 00066 use_confidence_function(0), 00067 use_base_regressor_confidence(0) 00068 { 00069 } 00070 00071 BaseRegressorWrapper::~BaseRegressorWrapper() 00072 { 00073 } 00074 00075 void BaseRegressorWrapper::declareOptions(OptionList& ol) 00076 { 00077 declareOption(ol, "loss_function_weight", &BaseRegressorWrapper::loss_function_weight, OptionBase::buildoption, 00078 "The hyper parameter to balance the error and the confidence factor.\n"); 00079 declareOption(ol, "mean_imputation", &BaseRegressorWrapper::mean_imputation, OptionBase::buildoption, 00080 "If set to 1, the algorithm will compute the mean vector of the input variables from the training set,\n" 00081 "and replace missing values with the computed means.\n"); 00082 declareOption(ol, "regression_tree", &BaseRegressorWrapper::regression_tree, OptionBase::buildoption, 00083 "If set to 1, the tree_regressor_template is used instead of the base_regressor_template.\n" 00084 "It permits to sort the train set only once for all boosting iterations.\n"); 00085 declareOption(ol, "use_confidence_function", &BaseRegressorWrapper::use_confidence_function, OptionBase::buildoption, 00086 "If set to 1, the confidence_function_template is used to build a confidence estimates on the base regressor prediction.\n" 00087 "Otherwise, if the confidence from the base regressor is not used, the confidence is always set to 1.0.\n"); 00088 declareOption(ol, "use_base_regressor_confidence", &BaseRegressorWrapper::use_base_regressor_confidence, OptionBase::buildoption, 00089 "If set to 1, the confidence is taken from the second output of the base regressor.\n"); 00090 declareOption(ol, "base_regressor_template", &BaseRegressorWrapper::base_regressor_template, OptionBase::buildoption, 00091 "The template for the base regressor to be boosted.\n"); 00092 declareOption(ol, "tree_regressor_template", &BaseRegressorWrapper::tree_regressor_template, OptionBase::buildoption, 00093 "The template for a RegressionTree base regressor when the regression_tree option is set to 1.\n"); 00094 declareOption(ol, "confidence_function_template", &BaseRegressorWrapper::confidence_function_template, OptionBase::buildoption, 00095 "The template for the confidence function to be learnt from the train set.\n"); 00096 declareOption(ol, "sorted_train_set", &BaseRegressorWrapper::sorted_train_set, OptionBase::buildoption, 00097 "A sorted train set when using a tree as a base regressor\n"); 00098 00099 declareOption(ol, "base_regressor", &BaseRegressorWrapper::base_regressor, OptionBase::learntoption, 00100 "The base regressor built from the template.\n"); 00101 declareOption(ol, "confidence_function", &BaseRegressorWrapper::confidence_function, OptionBase::learntoption, 00102 "The confidence function learnt from the train set.\n"); 00103 declareOption(ol, "base_regressor_train_set", &BaseRegressorWrapper::base_regressor_train_set, OptionBase::learntoption, 00104 "The VMat train set prepared for the base regressor.\n" 00105 "It apllies the chosen missing value management strategies.\n"); 00106 declareOption(ol, "variable_means", &BaseRegressorWrapper::variable_means, OptionBase::learntoption, 00107 "The vector with the computed means on all input dimension to perform mean imputation if applicable.\n"); 00108 inherited::declareOptions(ol); 00109 } 00110 00111 void BaseRegressorWrapper::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00112 { 00113 inherited::makeDeepCopyFromShallowCopy(copies); 00114 deepCopyField(loss_function_weight, copies); 00115 deepCopyField(mean_imputation, copies); 00116 deepCopyField(regression_tree, copies); 00117 deepCopyField(use_confidence_function, copies); 00118 deepCopyField(use_base_regressor_confidence, copies); 00119 deepCopyField(base_regressor_template, copies); 00120 deepCopyField(tree_regressor_template, copies); 00121 deepCopyField(confidence_function_template, copies); 00122 deepCopyField(sorted_train_set, copies); 00123 deepCopyField(base_regressor, copies); 00124 deepCopyField(confidence_function, copies); 00125 deepCopyField(base_regressor_train_set, copies); 00126 } 00127 00128 void BaseRegressorWrapper::build() 00129 { 00130 inherited::build(); 00131 build_(); 00132 } 00133 00134 void BaseRegressorWrapper::build_() 00135 { 00136 if (train_set) 00137 { 00138 if (mean_imputation > 0) 00139 { 00140 PP<MeanImputationVMatrix> new_train_set = new MeanImputationVMatrix(train_set, 0.0); 00141 variable_means = new_train_set->getMeanVector(); 00142 base_regressor_train_set = VMat(new_train_set); 00143 } 00144 else 00145 { 00146 base_regressor_train_set = train_set; 00147 } 00148 if (regression_tree > 0) 00149 { 00150 tree_regressor = ::PLearn::deepCopy(tree_regressor_template); 00151 tree_regressor->setTrainingSet(VMat(sorted_train_set)); 00152 tree_regressor->setOption("loss_function_weight", tostring(loss_function_weight)); 00153 base_regressor = tree_regressor; 00154 } 00155 else 00156 { 00157 base_regressor = ::PLearn::deepCopy(base_regressor_template); 00158 } 00159 base_regressor->setTrainingSet(base_regressor_train_set, true); 00160 base_regressor->setTrainStatsCollector(new VecStatsCollector); 00161 if (use_confidence_function > 0) 00162 { 00163 confidence_function = ::PLearn::deepCopy(confidence_function_template); 00164 confidence_function->setTrainingSet(base_regressor_train_set, true); 00165 confidence_function->setTrainStatsCollector(new VecStatsCollector); 00166 confidence_function->train(); 00167 } 00168 } 00169 } 00170 00171 void BaseRegressorWrapper::train() 00172 { 00173 base_regressor->train(); 00174 /* 00175 cout << "testing the confidence function" << endl; 00176 Vec train_input; 00177 Vec train_target; 00178 Vec train_output; 00179 real train_weight; 00180 train_input->resize(train_set->inputsize()); 00181 train_target->resize(train_set->targetsize()); 00182 train_output->resize(2); 00183 for (int row = 0; row < 25; row++) 00184 { 00185 train_set->getExample(row, train_input, train_target, train_weight); 00186 cout << "row: " << row << " target: " << train_target[0]; 00187 computeOutput(train_input, train_output); 00188 } 00189 PLERROR("We are done for now"); 00190 */ 00191 } 00192 00193 void BaseRegressorWrapper::verbose(string the_msg, int the_level) 00194 { 00195 if (verbosity >= the_level) 00196 cout << the_msg << endl; 00197 } 00198 00199 void BaseRegressorWrapper::forget() 00200 { 00201 } 00202 00203 int BaseRegressorWrapper::outputsize() const 00204 { 00205 return 2; 00206 } 00207 00208 TVec<string> BaseRegressorWrapper::getTrainCostNames() const 00209 { 00210 TVec<string> return_msg(3); 00211 return_msg[0] = "mse"; 00212 return_msg[1] = "base confidence"; 00213 return_msg[2] = "base reward"; 00214 return return_msg; 00215 } 00216 00217 TVec<string> BaseRegressorWrapper::getTestCostNames() const 00218 { 00219 return getTrainCostNames(); 00220 } 00221 00222 void BaseRegressorWrapper::computeOutput(const Vec& inputv, Vec& outputv) const 00223 { 00224 Vec base_regressor_inputv; 00225 Vec base_regressor_outputv; 00226 Vec confidence_outputv; 00227 base_regressor_inputv.resize(train_set->inputsize()); 00228 base_regressor_outputv.resize(base_regressor->outputsize()); 00229 for (int variable = 0; variable < train_set->inputsize(); variable++) 00230 { 00231 base_regressor_inputv[variable] = inputv[variable]; 00232 if (mean_imputation > 0 && is_missing(inputv[variable]) ) base_regressor_inputv[variable] = variable_means[variable]; 00233 } 00234 base_regressor->computeOutput(base_regressor_inputv, base_regressor_outputv); 00235 outputv[0] = base_regressor_outputv[0]; 00236 // cout << "base regressor output: " << outputv[0]; 00237 if (use_base_regressor_confidence > 0) 00238 { 00239 outputv[1] = base_regressor_outputv[1]; 00240 } 00241 else 00242 { 00243 if (use_confidence_function > 0) 00244 { 00245 confidence_outputv.resize(confidence_function->outputsize()); 00246 confidence_outputv[0] = base_regressor_outputv[0]; 00247 confidence_function->computeOutput(base_regressor_inputv, confidence_outputv); 00248 outputv[1] = confidence_outputv[1]; 00249 } 00250 else 00251 { 00252 outputv[1] = 1.0; 00253 } 00254 } 00255 // cout << "confidence output: " << confidence_outputv[0]; 00256 // cout << " confidence: " << outputv[1] << endl; 00257 } 00258 00259 void BaseRegressorWrapper::computeOutputAndCosts(const Vec& inputv, const Vec& targetv, Vec& outputv, Vec& costsv) const 00260 { 00261 computeOutput(inputv, outputv); 00262 computeCostsFromOutputs(inputv, outputv, targetv, costsv); 00263 } 00264 00265 void BaseRegressorWrapper::computeCostsFromOutputs(const Vec& inputv, const Vec& outputv, const Vec& targetv, Vec& costsv) const 00266 { 00267 costsv[0] = pow((outputv[0] - targetv[0]), 2); 00268 costsv[1] = outputv[1]; 00269 costsv[2] = 1.0 - (2.0 * loss_function_weight * costsv[0]); 00270 } 00271 00272 void BaseRegressorWrapper::setSortedTrainSet(PP<RegressionTreeRegisters> the_sorted_train_set) 00273 { 00274 sorted_train_set = the_sorted_train_set; 00275 } 00276 00277 } // end of namespace PLearn 00278 00279 00280 /* 00281 Local Variables: 00282 mode:c++ 00283 c-basic-offset:4 00284 c-file-style:"stroustrup" 00285 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00286 indent-tabs-mode:nil 00287 fill-column:79 00288 End: 00289 */ 00290 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :