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