LogLikelihoodClassifier.C
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <fstream>
00038 #include <iostream>
00039 #include <iomanip>
00040 #include <string>
00041 #include <cstdlib>
00042 #include <limits>
00043 #include <cmath>
00044 #include <map>
00045 #include <numeric>
00046 #include "Util/Assert.H"
00047 #include "Util/log.H"
00048 #include "LogLikelihoodClassifier.H"
00049
00050
00051 LogLikelihoodClassifier::LogLikelihoodClassifier(int k)
00052 {
00053 itsK=k;
00054 }
00055
00056 float LogLikelihoodClassifier::calcLogLikelihood(const std::vector<float>& sample, const std::vector<float>& model)
00057 {
00058 float ll=0;
00059 ASSERT(sample.size()==model.size());
00060 for(uint i=0;i<sample.size();i++)
00061 {
00062 ASSERT(model[i]!=0);
00063
00064 ll+=sample[i]*log(model[i]);
00065 }
00066 ASSERT(!isnan(ll));
00067 return ll;
00068 }
00069
00070 void LogLikelihoodClassifier::addModel(std::vector<float> hist, int id)
00071 {
00072 if(itsHistLength <= 0)
00073 itsHistLength = hist.size();
00074 ASSERT(hist.size() == itsHistLength);
00075
00076 if(itsModels.find(id) == itsModels.end())
00077 itsModels[id] = std::vector<std::vector<float> >();
00078 itsModels[id].push_back(hist);
00079 }
00080
00081 void LogLikelihoodClassifier::setModels(MapModelVector models)
00082 {
00083 itsModels = models;
00084 }
00085
00086 LogLikelihoodClassifier::MapModelVector LogLikelihoodClassifier::getModels()
00087 {
00088 return itsModels;
00089 }
00090
00091
00092 int LogLikelihoodClassifier::predict(const std::vector<float>& hist)
00093 {
00094 std::map<int,double>pdf = predictPDF(hist);
00095 std::map<int,double>::const_iterator piter;
00096 double maxVal=-std::numeric_limits<double>::max();
00097 int maxClass = -1;
00098 for(piter=pdf.begin();piter!=pdf.end();piter++)
00099 {
00100
00101 if(piter->second > maxVal)
00102 {
00103 maxClass=piter->first;
00104 maxVal=piter->second;
00105 }
00106 }
00107 return maxClass;
00108 }
00109
00110 std::map<int,double> LogLikelihoodClassifier::predictPDF(const std::vector<float>& hist)
00111 {
00112
00113
00114
00115
00116
00117 std::list<float> maxLL = std::list<float>(itsK,-std::numeric_limits<float>::max());
00118 std::list<int> maxLLPos = std::list<int>(itsK,0);
00119 MapModelVector::const_iterator mmitr = itsModels.begin(), mmstop = itsModels.end();
00120 std::map<int,std::list<float> > maxLLClass;
00121
00122 for(;mmitr!=mmstop;mmitr++)
00123 {
00124 maxLLClass[mmitr->first] = std::list<float>(itsK,-std::numeric_limits<double>::max());
00125 for(uint i=0;i<mmitr->second.size();i++)
00126 {
00127
00128 float ll = calcLogLikelihood(mmitr->second[i],hist);
00129 bool found=false;
00130
00131 std::list<float>::iterator maxClassIter = maxLLClass[mmitr->first].begin(), maxClassStop=maxLLClass[mmitr->first].end();
00132
00133 for(;maxClassIter!=maxClassStop;maxClassIter++)
00134 {
00135 if(*maxClassIter < ll)
00136 {
00137 maxLLClass[mmitr->first].insert(maxClassIter,ll);
00138 found=true;
00139 break;
00140 }
00141 }
00142
00143 if(found)
00144 {
00145 ASSERT(maxLL.size()==maxLLPos.size());
00146 std::list<float>::iterator maxLLIter = maxLL.begin(), maxLLStop=maxLL.end();
00147 std::list<int>::iterator maxLLPosIter = maxLLPos.begin();
00148 for(;maxLLIter!=maxLLStop;maxLLIter++,maxLLPosIter++)
00149 {
00150 if(*maxLLIter < ll)
00151 {
00152 maxLL.insert(maxLLIter,ll);
00153 maxLLPos.insert(maxLLPosIter,mmitr->first);
00154 break;
00155 }
00156 }
00157 }
00158
00159 if(found)
00160 {
00161 if(maxLLClass[mmitr->first].size()>itsK)
00162 {
00163 maxLLClass[mmitr->first].resize(itsK);
00164 }
00165 if(maxLL.size()>itsK)
00166 {
00167 maxLL.resize(itsK);
00168 maxLLPos.resize(itsK);
00169 }
00170 }
00171 }
00172 }
00173
00174 std::map<int,int> numEntries;
00175 for(std::list<int>::const_iterator lit=maxLLPos.begin();lit!=maxLLPos.end();lit++)
00176 {
00177 numEntries[*lit]++;
00178 }
00179
00180 std::map<int,std::list<float> >::iterator maxClassIter = maxLLClass.begin(), maxClassStop=maxLLClass.end();
00181 for(;maxClassIter!=maxClassStop;maxClassIter++)
00182 {
00183
00184 maxClassIter->second.resize(std::max(numEntries[maxClassIter->first],1));
00185 }
00186 std::map<int,double> pdf;
00187 nearestNeighborVotePDF(maxLLClass,pdf);
00188 return pdf;
00189 }
00190
00191 void LogLikelihoodClassifier::nearestNeighborVotePDF(const std::map<int,std::list<float> >& logLikelihood, std::map<int,double>& pdf)
00192 {
00193 std::map<int,std::list<float> >::const_iterator llIter = logLikelihood.begin(), llStop = logLikelihood.end();
00194 float nrm=0;
00195 int numClasses=0;
00196 float minVal = std::numeric_limits<float>::max();
00197 float offset=0;
00198 for(;llIter!=llStop;llIter++)
00199 {
00200 float val=std::accumulate(llIter->second.begin(),llIter->second.end(),0);
00201 pdf[llIter->first] = val;
00202 nrm+=val;
00203 if(val<minVal)
00204 minVal=val;
00205 numClasses++;
00206 }
00207 ASSERT(numClasses>0 && nrm != 0);
00208
00209
00210 std::map<int,double>::iterator piter;
00211
00212 if(fabs(nrm-minVal*numClasses) > 0.0001)
00213 {
00214 nrm-=minVal*numClasses;
00215 offset=minVal;
00216 }
00217 for(piter=pdf.begin();piter!=pdf.end();piter++)
00218 {
00219 piter->second=(piter->second-offset)/nrm;
00220 ASSERT(!isnan(piter->second));
00221 }
00222 }
00223
00224
00225
00226
00227 uint LogLikelihoodClassifier::getNumModels()
00228 {
00229 return itsModels.size();
00230 }
00231
00232
00233
00234