9 #include "Helpers/XmlHelper.h" 18 SupportVectorMachine::SupportVectorMachine() :
19 m_isInitialized(false),
20 m_enableProbability(false),
23 m_standardizeFeatures(true),
27 m_kernelType(QUADRATIC),
28 m_kernelFunction(QuadraticKernel),
39 std::cout <<
"SupportVectorMachine: svm was already initialized" << std::endl;
40 return STATUS_CODE_ALREADY_INITIALIZED;
50 if (featureInfo.m_sigmaValue < std::numeric_limits<double>::epsilon())
52 std::cout <<
"SupportVectorMachine: could not standardize parameters because sigma value was too small" << std::endl;
53 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
65 std::cout <<
"SupportVectorMachine: the number of features in the xml file was inconsistent" << std::endl;
66 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
73 std::cout <<
"SupportVectorMachine: could not evaluate kernel because scale factor was too small" << std::endl;
74 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
78 return STATUS_CODE_SUCCESS;
85 TiXmlDocument xmlDocument(svmFileName);
87 if (!xmlDocument.LoadFile())
89 std::cout <<
"SupportVectorMachine::Initialize - Invalid xml file." << std::endl;
90 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
93 const TiXmlHandle xmlDocumentHandle(&xmlDocument);
94 TiXmlNode *pContainerXmlNode(TiXmlHandle(xmlDocumentHandle).FirstChildElement().Element());
97 while (pContainerXmlNode)
99 if (pContainerXmlNode->ValueStr() !=
"SupportVectorMachine")
100 throw StatusCodeException(STATUS_CODE_FAILURE);
102 const TiXmlHandle currentHandle(pContainerXmlNode);
104 std::string currentName;
105 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(currentHandle,
"Name", currentName));
107 if (currentName.empty() || (currentName.size() > 1000))
109 std::cout <<
"SupportVectorMachine::Initialize - Implausible svm name extracted from xml." << std::endl;
110 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
113 if (currentName == svmName)
116 pContainerXmlNode = pContainerXmlNode->NextSibling();
119 if (!pContainerXmlNode)
121 std::cout <<
"SupportVectorMachine: Could not find an svm by the name " << svmName << std::endl;
122 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
126 TiXmlHandle localHandle(pContainerXmlNode);
127 TiXmlElement *pCurrentXmlElement = localHandle.FirstChild().Element();
129 while (pCurrentXmlElement)
131 if (STATUS_CODE_SUCCESS != this->
ReadComponent(pCurrentXmlElement))
133 std::cout <<
"SupportVectorMachine: Unknown component in xml file" << std::endl;
134 throw StatusCodeException(STATUS_CODE_FAILURE);
137 pCurrentXmlElement = pCurrentXmlElement->NextSiblingElement();
145 const std::string componentName(pCurrentXmlElement->ValueStr());
146 const TiXmlHandle currentHandle(pCurrentXmlElement);
148 if ((std::string(
"Name") == componentName) || (std::string(
"Timestamp") == componentName))
149 return STATUS_CODE_SUCCESS;
151 if (std::string(
"Machine") == componentName)
154 if (std::string(
"Features") == componentName)
157 if (std::string(
"SupportVector") == componentName)
160 return STATUS_CODE_INVALID_PARAMETER;
168 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
169 "KernelType", kernelType));
172 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
175 double scaleFactor(0.);
176 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
177 "ScaleFactor", scaleFactor));
179 bool standardize(
true);
180 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
181 "Standardize", standardize));
183 bool enableProbability(
false);
184 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
185 "EnableProbability", enableProbability));
187 double probAParameter(0.);
188 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
189 "ProbAParameter", probAParameter));
191 double probBParameter(0.);
192 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
193 "ProbBParameter", probBParameter));
205 return STATUS_CODE_SUCCESS;
212 std::vector<double> muValues;
213 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(currentHandle,
214 "MuValues", muValues));
216 std::vector<double> sigmaValues;
217 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(currentHandle,
218 "SigmaValues", sigmaValues));
220 if (muValues.size() != sigmaValues.size())
222 std::cout <<
"SupportVectorMachine: could not add feature info because the size of mu (" << muValues.size() <<
") did not match " 223 "the size of sigma (" << sigmaValues.size() <<
")" << std::endl;
224 return STATUS_CODE_INVALID_PARAMETER;
229 for (std::size_t i = 0; i < muValues.size(); ++i)
232 return STATUS_CODE_SUCCESS;
240 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(currentHandle,
243 std::vector<double> values;
244 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(currentHandle,
248 for (
const double &
value : values)
249 valuesFeatureVector.emplace_back(
value);
252 return STATUS_CODE_SUCCESS;
261 std::cout <<
"SupportVectorMachine: could not perform classification because the svm was uninitialized" << std::endl;
262 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
267 std::cout <<
"SupportVectorMachine: could not perform classification because the initialized svm had no support vectors in the model" << std::endl;
268 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
277 standardizedFeatures.push_back(
m_featureInfoList.at(i).StandardizeParameter(features.at(i).Get()));
280 double classScore(0.);
283 classScore += supportVectorInfo.m_yAlpha *
287 return classScore +
m_bias;
static double CubicKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
An inhomogeneous cubic kernel.
pandora::StatusCode ReadComponent(pandora::TiXmlElement *pCurrentXmlElement)
Read the component at the current xml element.
pandora::StatusCode ReadSupportVector(const pandora::TiXmlHandle ¤tHandle)
Read the support vector component at the current xml handle.
MvaTypes::MvaFeatureVector MvaFeatureVector
bool m_enableProbability
Whether to enable probability calculations.
double m_scaleFactor
The kernel scale factor.
FeatureInfoVector m_featureInfoList
The list of FeatureInfo objects.
SVInfoList m_svInfoList
The list of SupportVectorInfo objects.
static double QuadraticKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
An inhomogeneous quadratic kernel.
static double LinearKernel(const LArMvaHelper::MvaFeatureVector &supportVector, const LArMvaHelper::MvaFeatureVector &features, const double scaleFactor=1.)
A linear kernel.
pandora::StatusCode ReadMachine(const pandora::TiXmlHandle ¤tHandle)
Read the machine component at the current xml handle.
bool m_standardizeFeatures
Whether to standardize the features.
Header file for the lar support vector machine class.
double m_bias
The bias term.
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.
KernelType m_kernelType
The kernel type.
pandora::StatusCode Initialize(const std::string ¶meterLocation, 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.
std::string value(boost::any const &)
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.
KernelType
KernelType enum.
double m_probBParameter
The score offset parameter for mapping to a probability using the logistic function.
pandora::StatusCode ReadFeatures(const pandora::TiXmlHandle ¤tHandle)
Read the feature component at the current xml handle.