PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // KernelDensityEstimator.cc 00004 // 00005 // Copyright (C) 2008 Dumitru Erhan 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 // Authors: Dumitru Erhan 00036 00040 #include "KernelDensityEstimator.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00045 PLEARN_IMPLEMENT_OBJECT( 00046 KernelDensityEstimator, 00047 "Performs kernel density estimation ('Parzen Windows') with ANY given kernel", 00048 "Does not take into account the input weights!" 00049 ); 00050 00052 // KernelDensityEstimator // 00054 KernelDensityEstimator::KernelDensityEstimator() 00055 : kernel_output_type("normal") 00056 { 00057 } 00058 00060 // declareOptions // 00062 void KernelDensityEstimator::declareOptions(OptionList& ol) 00063 { 00064 declareOption(ol, "kernel", &KernelDensityEstimator::kernel, 00065 OptionBase::buildoption, 00066 "The kernel used at each point in the training set"); 00067 00068 declareOption(ol, "kernel_output_type", &KernelDensityEstimator::kernel_output_type, 00069 OptionBase::buildoption, 00070 "Specifies whether the output of our kernel is logarithmic in the distance (\"log\") or normal (anything else)"); 00071 00072 // Now call the parent class' declareOptions(). 00073 inherited::declareOptions(ol); 00074 } 00075 00077 // build // 00079 void KernelDensityEstimator::build() 00080 { 00081 // ### Nothing to add here, simply calls build_(). 00082 inherited::build(); 00083 build_(); 00084 } 00085 00087 // build_ // 00089 void KernelDensityEstimator::build_() 00090 { 00091 } 00092 00094 // cdf // 00096 real KernelDensityEstimator::cdf(const Vec& y) const 00097 { 00098 PLERROR("cdf not implemented for KernelDensityEstimator"); return 0; 00099 } 00100 00102 // expectation // 00104 void KernelDensityEstimator::expectation(Vec& mu) const 00105 { 00106 PLERROR("expectation not implemented for KernelDensityEstimator"); 00107 } 00108 00109 // ### Remove this method if your distribution does not implement it. 00111 // forget // 00113 void KernelDensityEstimator::forget() 00114 { 00115 inherited::forget(); 00116 } 00117 00119 // generate // 00121 void KernelDensityEstimator::generate(Vec& y) const 00122 { 00123 PLERROR("generate not implemented for KernelDensityEstimator"); 00124 } 00125 00126 // ### Default version of inputsize returns learner->inputsize() 00127 // ### If this is not appropriate, you should uncomment this and define 00128 // ### it properly here: 00129 // int KernelDensityEstimator::inputsize() const {} 00130 00132 // log_density // 00134 real KernelDensityEstimator::log_density(const Vec& y) const 00135 { 00136 int numTrain = train_set.length(); 00137 Vec input, target; 00138 real weight; 00139 real result = 0.0; 00140 00141 // It can happen that for efficiency/numerical reasons, your kernel outputs 00142 // the logarithm of the actual value of the kernel at (input_i,y). 00143 if (kernel_output_type=="log") { 00144 real logprob = -INFINITY; 00145 for(int i=0; i<numTrain; i++) { 00146 train_set->getExample(i,input,target,weight); 00147 logprob = logadd(logprob,kernel->evaluate(input,y)); 00148 } 00149 logprob -= pl_log(real(numTrain)); 00150 result = logprob; 00151 } 00152 // Otherwise, it's just a log(\sum_i{k(input_i,y)} / numTrain) 00153 else if (kernel_output_type=="normal") { 00154 real sprob = 0.0; 00155 for(int i=0; i<numTrain; i++) { 00156 train_set->getExample(i,input,target,weight); 00157 sprob += kernel->evaluate(input,y); 00158 } 00159 sprob /= real(numTrain); 00160 result = pl_log(sprob); 00161 } 00162 else 00163 PLERROR("In KernelDensityEstimator::log_density kernel_output_type must be either \"log\" or \"normal\""); 00164 00165 return result; 00166 00167 } 00168 00170 // makeDeepCopyFromShallowCopy // 00172 void KernelDensityEstimator::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00173 { 00174 inherited::makeDeepCopyFromShallowCopy(copies); 00175 } 00176 00178 // resetGenerator // 00180 void KernelDensityEstimator::resetGenerator(long g_seed) 00181 { 00182 inherited::resetGenerator(g_seed); 00183 } 00184 00186 // survival_fn // 00188 real KernelDensityEstimator::survival_fn(const Vec& y) const 00189 { 00190 PLERROR("survival_fn not implemented for KernelDensityEstimator"); return 0; 00191 } 00192 00193 // ### Remove this method, if your distribution does not implement it. 00195 // train // 00197 void KernelDensityEstimator::train() 00198 { 00199 // PLERROR("train method not implemented for KernelDensityEstimator"); 00200 } 00201 00203 // variance // 00205 void KernelDensityEstimator::variance(Mat& covar) const 00206 { 00207 PLERROR("variance not implemented for KernelDensityEstimator"); 00208 } 00209 00210 } // end of namespace PLearn 00211 00212 00213 /* 00214 Local Variables: 00215 mode:c++ 00216 c-basic-offset:4 00217 c-file-style:"stroustrup" 00218 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00219 indent-tabs-mode:nil 00220 fill-column:79 00221 End: 00222 */ 00223 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :