LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
LArSupportVectorMachine.h
Go to the documentation of this file.
1 
8 #ifndef LAR_SUPPORT_VECTOR_MACHINE_H
9 #define LAR_SUPPORT_VECTOR_MACHINE_H 1
10 
12 
14 
15 #include "Pandora/StatusCodes.h"
16 
17 #include <functional>
18 #include <map>
19 #include <vector>
20 
21 //------------------------------------------------------------------------------------------------------------------------------------------
22 
23 namespace lar_content
24 {
25 
30 {
31 public:
32  typedef std::function<double(const LArMvaHelper::MvaFeatureVector &, const LArMvaHelper::MvaFeatureVector &, const double)> KernelFunction;
33 
38  {
40  LINEAR = 1,
41  QUADRATIC = 2,
42  CUBIC = 3,
44  };
45 
50 
59  pandora::StatusCode Initialize(const std::string &parameterLocation, const std::string &svmName);
60 
68  bool Classify(const LArMvaHelper::MvaFeatureVector &features) const;
69 
78 
86  double CalculateProbability(const LArMvaHelper::MvaFeatureVector &features) const;
87 
93  bool IsInitialized() const;
94 
100  unsigned int GetNFeatures() const;
101 
107  void SetKernelFunction(KernelFunction kernelFunction);
108 
109 private:
114  {
115  public:
122  SupportVectorInfo(const double yAlpha, LArMvaHelper::MvaFeatureVector supportVector);
123 
124  double m_yAlpha;
126  };
127 
132  {
133  public:
140  FeatureInfo(const double muValue, const double sigmaValue);
141 
145  FeatureInfo();
146 
154  double StandardizeParameter(const double parameter) const;
155 
156  double m_muValue;
157  double m_sigmaValue;
158  };
159 
160  typedef std::vector<SupportVectorInfo> SVInfoList;
161  typedef std::vector<FeatureInfo> FeatureInfoVector;
162 
163  typedef std::map<KernelType, KernelFunction> KernelMap;
164 
166 
170 
172  unsigned int m_nFeatures;
173  double m_bias;
174  double m_scaleFactor;
175 
176  SVInfoList m_svInfoList;
177  FeatureInfoVector m_featureInfoList;
178 
180  KernelFunction m_kernelFunction;
181  KernelMap m_kernelMap;
182 
189  void ReadXmlFile(const std::string &svmFileName, const std::string &svmName);
190 
198  pandora::StatusCode ReadComponent(pandora::TiXmlElement *pCurrentXmlElement);
199 
207  pandora::StatusCode ReadMachine(const pandora::TiXmlHandle &currentHandle);
208 
216  pandora::StatusCode ReadFeatures(const pandora::TiXmlHandle &currentHandle);
217 
225  pandora::StatusCode ReadSupportVector(const pandora::TiXmlHandle &currentHandle);
226 
235 
245  static double QuadraticKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor = 1.);
246 
256  static double CubicKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor = 1.);
257 
267  static double LinearKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor = 1.);
268 
278  static double GaussianRbfKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor = 1.);
279 };
280 
281 //------------------------------------------------------------------------------------------------------------------------------------------
282 
284 {
285  return (this->CalculateClassificationScoreImpl(features) > 0.);
286 }
287 
288 //------------------------------------------------------------------------------------------------------------------------------------------
289 
291 {
292  return this->CalculateClassificationScoreImpl(features);
293 }
294 
295 //------------------------------------------------------------------------------------------------------------------------------------------
296 
298 {
299  if (!m_enableProbability)
300  {
301  std::cout << "LArSupportVectorMachine: cannot calculate probabilities for this SVM" << std::endl;
302  throw pandora::STATUS_CODE_NOT_INITIALIZED;
303  }
304 
305  // Use the logistic function to map the linearly-transformed score on the interval (-inf,inf) to a probability on [0,1] - the two free
306  // parameters in the linear transformation are trained such that the logistic map produces an accurate probability
307  const double scaledScore = m_probAParameter * this->CalculateClassificationScoreImpl(features) + m_probBParameter;
308 
309  return 1. / (1. + std::exp(scaledScore));
310 }
311 
312 //------------------------------------------------------------------------------------------------------------------------------------------
313 
315 {
316  return m_isInitialized;
317 }
318 
319 //------------------------------------------------------------------------------------------------------------------------------------------
320 
321 inline unsigned int SupportVectorMachine::GetNFeatures() const
322 {
323  return m_nFeatures;
324 }
325 
326 //------------------------------------------------------------------------------------------------------------------------------------------
327 
329 {
330  m_kernelFunction = std::move(kernelFunction);
331 }
332 
333 //------------------------------------------------------------------------------------------------------------------------------------------
334 
335 inline double SupportVectorMachine::LinearKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor)
336 {
337  const double denominator(scaleFactor * scaleFactor);
338  if (denominator < std::numeric_limits<double>::epsilon())
339  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
340 
341  double total(0.);
342  for (unsigned int i = 0; i < features.size(); ++i)
343  total += supportVector.at(i).Get() * features.at(i).Get();
344 
345  return total / denominator;
346 }
347 
348 //------------------------------------------------------------------------------------------------------------------------------------------
349 
350 inline double SupportVectorMachine::QuadraticKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor)
351 {
352  const double denominator(scaleFactor * scaleFactor);
353  if (denominator < std::numeric_limits<double>::epsilon())
354  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
355 
356  double total(0.);
357  for (unsigned int i = 0; i < features.size(); ++i)
358  total += supportVector.at(i).Get() * features.at(i).Get();
359 
360  total = total / denominator + 1.;
361  return total * total;
362 }
363 
364 //------------------------------------------------------------------------------------------------------------------------------------------
365 
366 inline double SupportVectorMachine::CubicKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor)
367 {
368  const double denominator(scaleFactor * scaleFactor);
369  if (denominator < std::numeric_limits<double>::epsilon())
370  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
371 
372  double total(0.);
373  for (unsigned int i = 0; i < features.size(); ++i)
374  total += supportVector.at(i).Get() * features.at(i).Get();
375 
376  total = total / denominator + 1.;
377  return total * total * total;
378 }
379 
380 //------------------------------------------------------------------------------------------------------------------------------------------
381 
382 inline double SupportVectorMachine::GaussianRbfKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor)
383 {
384  double total(0.);
385  for (unsigned int i = 0; i < features.size(); ++i)
386  total += (supportVector.at(i).Get() - features.at(i).Get()) * (supportVector.at(i).Get() - features.at(i).Get());
387 
388  return std::exp(-scaleFactor * total);
389 }
390 
391 //------------------------------------------------------------------------------------------------------------------------------------------
392 
394  m_yAlpha(yAlpha),
395  m_supportVector(std::move(supportVector))
396 {
397 }
398 
399 //------------------------------------------------------------------------------------------------------------------------------------------
400 
401 inline SupportVectorMachine::FeatureInfo::FeatureInfo(const double muValue, const double sigmaValue) :
402  m_muValue(muValue),
403  m_sigmaValue(sigmaValue)
404 {
405 }
406 
407 //------------------------------------------------------------------------------------------------------------------------------------------
408 
410  m_muValue(0.),
411  m_sigmaValue(0.)
412 {
413 }
414 
415 //------------------------------------------------------------------------------------------------------------------------------------------
416 
417 inline double SupportVectorMachine::FeatureInfo::StandardizeParameter(const double parameter) const
418 {
419  if (m_sigmaValue < std::numeric_limits<double>::epsilon())
420  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
421 
422  return (parameter - m_muValue) / m_sigmaValue;
423 }
424 
425 } // namespace lar_content
426 
427 #endif // #ifndef LAR_SUPPORT_VECTOR_MACHINE_H
static double CubicKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
An inhomogeneous cubic kernel.
bool Classify(const LArMvaHelper::MvaFeatureVector &features) const
Make a classification for a set of input features, based on the trained model.
pandora::StatusCode ReadComponent(pandora::TiXmlElement *pCurrentXmlElement)
Read the component at the current xml element.
pandora::StatusCode ReadSupportVector(const pandora::TiXmlHandle &currentHandle)
Read the support vector component at the current xml handle.
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:58
std::vector< SupportVectorInfo > SVInfoList
bool m_enableProbability
Whether to enable probability calculations.
double m_scaleFactor
The kernel scale factor.
FeatureInfoVector m_featureInfoList
The list of FeatureInfo objects.
double CalculateClassificationScore(const LArMvaHelper::MvaFeatureVector &features) const
Calculate the classification score for a set of input features, based on the trained model...
MvaInterface class.
STL namespace.
std::vector< FeatureInfo > FeatureInfoVector
SVInfoList m_svInfoList
The list of SupportVectorInfo objects.
bool IsInitialized() const
Query whether this svm is initialized.
static double QuadraticKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
An inhomogeneous quadratic kernel.
void SetKernelFunction(KernelFunction kernelFunction)
Set the kernel function to use.
static double LinearKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
A linear kernel.
pandora::StatusCode ReadMachine(const pandora::TiXmlHandle &currentHandle)
Read the machine component at the current xml handle.
double m_muValue
The average value of this feature.
bool m_standardizeFeatures
Whether to standardize the features.
LArMvaHelper::MvaFeatureVector m_supportVector
The support vector.
void ReadXmlFile(const std::string &svmFileName, const std::string &svmName)
Read the svm parameters from an xml file.
KernelMap m_kernelMap
Map from the kernel types to the kernel functions.
KernelFunction m_kernelFunction
The kernel function.
double StandardizeParameter(const double parameter) const
Standardize a parameter corresponding to this feature.
FeatureInfo()
Default constructor to allow default-construction of (uninitialized) svms.
KernelType m_kernelType
The kernel type.
pandora::StatusCode Initialize(const std::string &parameterLocation, const std::string &svmName)
Initialize the svm using a serialized model.
double m_probAParameter
The first-order score coefficient for mapping to a probability using the logistic function...
unsigned int m_nFeatures
The number of features.
double m_yAlpha
The alpha-value multiplied by the y-value for the support vector.
std::function< double(const LArMvaHelper::MvaFeatureVector &, const LArMvaHelper::MvaFeatureVector &, const double)> KernelFunction
std::map< KernelType, KernelFunction > KernelMap
double CalculateProbability(const LArMvaHelper::MvaFeatureVector &features) const
Calculate the classification probability for a set of input features, based on the trained model...
static double GaussianRbfKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
A gaussian RBF kernel.
double CalculateClassificationScoreImpl(const LArMvaHelper::MvaFeatureVector &features) const
Implementation method for calculating the classification score using the trained model.
bool m_isInitialized
Whether this svm has been initialized.
double m_probBParameter
The score offset parameter for mapping to a probability using the logistic function.
pandora::StatusCode ReadFeatures(const pandora::TiXmlHandle &currentHandle)
Read the feature component at the current xml handle.
SupportVectorInfo(const double yAlpha, LArMvaHelper::MvaFeatureVector supportVector)
Constructor.
unsigned int GetNFeatures() const
Get the number of features.
Header file for the lar multivariate analysis interface class.