80 using std::stringstream;
85 ClassImp(TMVA::MethodSVM);
90 TMVA::MethodSVM::MethodSVM( const TString& jobName, const TString& methodTitle, DataSetInfo& theData,
91 const TString& theOption )
92 : MethodBase( jobName, Types::kSVM, methodTitle, theData, theOption)
102 , fSVKernelFunction(0)
105 , fDoubleSigmaSquared(0)
117 fNumVars = theData.GetVariableInfos().size();
118 for(
int i=0; i<fNumVars; i++){
119 fVarNames.push_back(theData.GetVariableInfos().at(i).GetTitle());
126 TMVA::MethodSVM::MethodSVM( DataSetInfo& theData,
const TString& theWeightFile)
127 : MethodBase( Types::kSVM, theData, theWeightFile)
137 , fSVKernelFunction(0)
140 , fDoubleSigmaSquared(0)
152 fNumVars = theData.GetVariableInfos().size();
153 for(
int i=0;i<fNumVars; i++){
154 fVarNames.push_back(theData.GetVariableInfos().at(i).GetTitle());
161 TMVA::MethodSVM::~MethodSVM()
163 fSupportVectors->clear();
164 for (UInt_t i=0; i<fInputData->size(); i++) {
165 delete fInputData->at(i);
167 if (fWgSet !=0) {
delete fWgSet; fWgSet=0; }
168 if (fSVKernelFunction !=0 ) {
delete fSVKernelFunction; fSVKernelFunction = 0; }
174 void TMVA::MethodSVM::Reset(
void )
177 fSupportVectors->clear();
178 for (UInt_t i=0; i<fInputData->size(); i++){
179 delete fInputData->at(i);
183 if (fWgSet !=0) { fWgSet=0; }
184 if (fSVKernelFunction !=0 ) { fSVKernelFunction = 0; }
186 Data()->DeleteResults(GetMethodName(), Types::kTraining, GetAnalysisType());
189 Log() << kDEBUG <<
" successfully(?) reset the method " << Endl;
195 Bool_t TMVA::MethodSVM::HasAnalysisType( Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets )
197 if (type == Types::kClassification && numberClasses == 2)
return kTRUE;
198 if (type == Types::kRegression && numberTargets == 1)
return kTRUE;
205 void TMVA::MethodSVM::Init()
208 SetNormalised( kTRUE );
213 fInputData =
new std::vector<TMVA::SVEvent*>(0);
214 fSupportVectors =
new std::vector<TMVA::SVEvent*>(0);
220 void TMVA::MethodSVM::DeclareOptions()
222 DeclareOptionRef( fTheKernel =
"RBF",
"Kernel",
"Pick which kernel ( RBF or MultiGauss )");
224 DeclareOptionRef( fGamma = 1.,
"Gamma",
"RBF kernel parameter: Gamma (size of the Kernel)");
226 DeclareOptionRef( fOrder = 3,
"Order",
"Polynomial Kernel parameter: polynomial order");
227 DeclareOptionRef( fTheta = 1.,
"Theta",
"Polynomial Kernel parameter: polynomial theta");
229 DeclareOptionRef( fGammas =
"",
"GammaList",
"MultiGauss parameters" );
232 DeclareOptionRef( fTune =
"All",
"Tune",
"Tune Parameters");
234 DeclareOptionRef( fMultiKernels =
"None",
"KernelList",
"Sum or product of kernels");
235 DeclareOptionRef( fLoss =
"hinge",
"Loss",
"Loss function");
237 DeclareOptionRef( fCost,
"C",
"Cost parameter" );
238 if (DoRegression()) {
243 DeclareOptionRef( fTolerance = 0.01,
"Tol",
"Tolerance parameter" );
244 DeclareOptionRef( fMaxIter = 1000,
"MaxIter",
"Maximum number of training loops" );
251 void TMVA::MethodSVM::DeclareCompatibilityOptions()
253 MethodBase::DeclareCompatibilityOptions();
254 DeclareOptionRef( fNSubSets = 1,
"NSubSets",
"Number of training subsets" );
255 DeclareOptionRef( fTheKernel =
"Gauss",
"Kernel",
"Uses kernel function");
257 DeclareOptionRef( fDoubleSigmaSquared = 2.,
"Sigma",
"Kernel parameter: sigma");
259 DeclareOptionRef( fOrder = 3,
"Order",
"Polynomial Kernel parameter: polynomial order");
261 DeclareOptionRef( fTheta = 1.,
"Theta",
"Sigmoid Kernel parameter: theta");
262 DeclareOptionRef( fKappa = 1.,
"Kappa",
"Sigmoid Kernel parameter: kappa");
268 void TMVA::MethodSVM::ProcessOptions()
270 if (IgnoreEventsWithNegWeightsInTraining()) {
271 Log() << kFATAL <<
"Mechanism to ignore events with negative weights in training not yet available for method: "
272 << GetMethodTypeName()
273 <<
" --> please remove \"IgnoreNegWeightsInTraining\" option from booking string."
281 void TMVA::MethodSVM::Train()
283 fIPyMaxIter = fMaxIter;
284 Data()->SetCurrentType(Types::kTraining);
286 Log() << kDEBUG <<
"Create event vector"<< Endl;
288 fDataSize = Data()->GetNEvents();
289 Int_t nSignal = Data()->GetNEvtSigTrain();
290 Int_t nBackground = Data()->GetNEvtBkgdTrain();
297 if(nSignal < nBackground){
299 CBkg = CSig*((double)nSignal/nBackground);
303 CSig = CBkg*((double)nSignal/nBackground);
307 for (Int_t ievnt=0; ievnt<Data()->GetNEvents(); ievnt++){
308 if (GetEvent(ievnt)->GetWeight() != 0){
309 if(DataInfo().IsSignal(GetEvent(ievnt))){
310 fInputData->push_back(
new SVEvent(GetEvent(ievnt), CSig, DataInfo().IsSignal\
314 fInputData->push_back(
new SVEvent(GetEvent(ievnt), CBkg, DataInfo().IsSignal\
323 if( fTheKernel ==
"RBF"){
324 fSVKernelFunction =
new SVKernelFunction( SVKernelFunction::kRBF, fGamma);
326 else if( fTheKernel ==
"MultiGauss" ){
332 if(fmGamma.size()!=0){ GetMGamma(fmGamma); }
334 for(Int_t ngammas=0; ngammas<fNumVars; ++ngammas){
335 fmGamma.push_back(1.0);
340 fSVKernelFunction =
new SVKernelFunction(fmGamma);
342 else if( fTheKernel ==
"Polynomial" ){
343 fSVKernelFunction =
new SVKernelFunction( SVKernelFunction::kPolynomial, fOrder,fTheta);
345 else if( fTheKernel ==
"Prod" ){
351 if(fmGamma.size()!=0){ GetMGamma(fmGamma); }
353 fSVKernelFunction =
new SVKernelFunction( SVKernelFunction::kProd, MakeKernelList(fMultiKernels,fTheKernel), fmGamma, fGamma, fOrder, fTheta );
355 else if( fTheKernel ==
"Sum" ){
361 if(fmGamma.size()!=0){ GetMGamma(fmGamma); }
363 fSVKernelFunction =
new SVKernelFunction( SVKernelFunction::kSum, MakeKernelList(fMultiKernels,fTheKernel), fmGamma, fGamma, fOrder, fTheta );
366 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." << Endl;
370 Log()<< kINFO <<
"Building SVM Working Set...with "<<fInputData->size()<<
" event instances"<< Endl;
371 Timer bldwstime( GetName());
372 fWgSet =
new SVWorkingSet( fInputData, fSVKernelFunction,fTolerance, DoRegression() );
373 Log() << kINFO <<
"Elapsed time for Working Set build: "<< bldwstime.GetElapsedTime()<<Endl;
376 Timer timer( GetName() );
377 Log() << kINFO <<
"Sorry, no computing time forecast available for SVM, please wait ..." << Endl;
379 if (fInteractive) fWgSet->SetIPythonInteractive(&fExitFromTraining, &fIPyCurrentIter);
381 fWgSet->Train(fMaxIter);
383 Log() << kINFO <<
"Elapsed time: " << timer.GetElapsedTime()
386 fBparm = fWgSet->GetBpar();
387 fSupportVectors = fWgSet->GetSupportVectors();
391 if (!fExitFromTraining) fIPyMaxIter = fIPyCurrentIter;
398 void TMVA::MethodSVM::AddWeightsXMLTo(
void* parent )
const
400 void* wght = gTools().AddChild(parent,
"Weights");
401 gTools().AddAttr(wght,
"fBparm",fBparm);
402 gTools().AddAttr(wght,
"fGamma",fGamma);
403 gTools().AddAttr(wght,
"fGammaList",fGammaList);
404 gTools().AddAttr(wght,
"fTheta",fTheta);
405 gTools().AddAttr(wght,
"fOrder",fOrder);
406 gTools().AddAttr(wght,
"NSupVec",fSupportVectors->size());
408 for (std::vector<TMVA::SVEvent*>::iterator veciter=fSupportVectors->begin();
409 veciter!=fSupportVectors->end() ; ++veciter ) {
410 TVectorD temp(GetNvar()+4);
411 temp[0] = (*veciter)->GetNs();
412 temp[1] = (*veciter)->GetTypeFlag();
413 temp[2] = (*veciter)->GetAlpha();
414 temp[3] = (*veciter)->GetAlpha_p();
415 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++)
416 temp[ivar+4] = (*(*veciter)->GetDataVector())[ivar];
417 gTools().WriteTVectorDToXML(wght,
"SupportVector",&temp);
420 void* maxnode = gTools().AddChild(wght,
"Maxima");
421 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++)
422 gTools().AddAttr(maxnode,
"Var"+gTools().StringFromInt(ivar), GetXmax(ivar));
423 void* minnode = gTools().AddChild(wght,
"Minima");
424 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++)
425 gTools().AddAttr(minnode,
"Var"+gTools().StringFromInt(ivar), GetXmin(ivar));
430 void TMVA::MethodSVM::ReadWeightsFromXML(
void* wghtnode )
432 gTools().ReadAttr( wghtnode,
"fBparm",fBparm );
433 gTools().ReadAttr( wghtnode,
"fGamma",fGamma);
434 gTools().ReadAttr( wghtnode,
"fGammaList",fGammaList);
435 gTools().ReadAttr( wghtnode,
"fOrder",fOrder);
436 gTools().ReadAttr( wghtnode,
"fTheta",fTheta);
438 gTools().ReadAttr( wghtnode,
"NSupVec",fNsupv );
441 Float_t alpha_p = 0.;
445 std::vector<Float_t>* svector =
new std::vector<Float_t>(GetNvar());
447 if (fMaxVars!=0)
delete fMaxVars;
448 fMaxVars =
new TVectorD( GetNvar() );
449 if (fMinVars!=0)
delete fMinVars;
450 fMinVars =
new TVectorD( GetNvar() );
451 if (fSupportVectors!=0) {
452 for (vector< SVEvent* >::iterator it = fSupportVectors->begin(); it!=fSupportVectors->end(); ++it)
454 delete fSupportVectors;
456 fSupportVectors =
new std::vector<TMVA::SVEvent*>(0);
457 void* supportvectornode = gTools().GetChild(wghtnode);
458 for (UInt_t ievt = 0; ievt < fNsupv; ievt++) {
459 TVectorD temp(GetNvar()+4);
460 gTools().ReadTVectorDFromXML(supportvectornode,
"SupportVector",&temp);
462 typeFlag=(int)temp[1];
465 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++) (*svector)[ivar]=temp[ivar+4];
467 fSupportVectors->push_back(
new SVEvent(svector,alpha,alpha_p,typeFlag));
468 supportvectornode = gTools().GetNextChild(supportvectornode);
471 void* maxminnode = supportvectornode;
472 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++)
473 gTools().ReadAttr( maxminnode,
"Var"+gTools().StringFromInt(ivar),(*fMaxVars)[ivar]);
474 maxminnode = gTools().GetNextChild(maxminnode);
475 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++)
476 gTools().ReadAttr( maxminnode,
"Var"+gTools().StringFromInt(ivar),(*fMinVars)[ivar]);
477 if (fSVKernelFunction!=0)
delete fSVKernelFunction;
478 if( fTheKernel ==
"RBF" ){
479 fSVKernelFunction =
new SVKernelFunction(SVKernelFunction::kRBF, fGamma);
481 else if( fTheKernel ==
"MultiGauss" ){
482 SetMGamma(fGammaList);
483 fSVKernelFunction =
new SVKernelFunction(fmGamma);
485 else if( fTheKernel ==
"Polynomial" ){
486 fSVKernelFunction =
new SVKernelFunction(SVKernelFunction::kPolynomial, fOrder, fTheta);
488 else if( fTheKernel ==
"Prod" ){
489 SetMGamma(fGammaList);
490 fSVKernelFunction =
new SVKernelFunction(SVKernelFunction::kSum, MakeKernelList(fMultiKernels,fTheKernel), fmGamma, fGamma, fOrder, fTheta);
492 else if( fTheKernel ==
"Sum" ){
493 SetMGamma(fGammaList);
494 fSVKernelFunction =
new SVKernelFunction(SVKernelFunction::kSum, MakeKernelList(fMultiKernels,fTheKernel), fmGamma, fGamma, fOrder, fTheta);
497 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." << Endl;
507 void TMVA::MethodSVM::WriteWeightsToStream( TFile& )
const
513 void TMVA::MethodSVM::ReadWeightsFromStream( std::istream& istr )
515 if (fSupportVectors !=0) {
delete fSupportVectors; fSupportVectors = 0;}
516 fSupportVectors =
new std::vector<TMVA::SVEvent*>(0);
524 fSupportVectors->reserve(fNsupv);
526 Float_t typeTalpha=0.;
530 std::vector<Float_t>* svector =
new std::vector<Float_t>(GetNvar());
532 fMaxVars =
new TVectorD( GetNvar() );
533 fMinVars =
new TVectorD( GetNvar() );
535 for (UInt_t ievt = 0; ievt < fNsupv; ievt++) {
538 typeFlag = typeTalpha<0?-1:1;
539 alpha = typeTalpha<0?-typeTalpha:typeTalpha;
540 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++) istr >> svector->at(ivar);
542 fSupportVectors->push_back(
new SVEvent(svector,alpha,typeFlag,ns));
545 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++) istr >> (*fMaxVars)[ivar];
547 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++) istr >> (*fMinVars)[ivar];
549 delete fSVKernelFunction;
550 if (fTheKernel ==
"Gauss" ) {
551 fSVKernelFunction =
new SVKernelFunction(1/fDoubleSigmaSquared);
554 SVKernelFunction::EKernelType k = SVKernelFunction::kLinear;
555 if(fTheKernel ==
"Linear") k = SVKernelFunction::kLinear;
556 else if (fTheKernel ==
"Polynomial") k = SVKernelFunction::kPolynomial;
557 else if (fTheKernel ==
"Sigmoid" ) k = SVKernelFunction::kSigmoidal;
559 Log() << kFATAL <<
"Unknown kernel function found in weight file!" << Endl;
561 fSVKernelFunction =
new SVKernelFunction();
562 fSVKernelFunction->setCompatibilityParams(k, fOrder, fTheta, fKappa);
570 void TMVA::MethodSVM::ReadWeightsFromStream( TFile& )
577 Double_t TMVA::MethodSVM::GetMvaValue( Double_t* err, Double_t* errUpper )
582 SVEvent* ev =
new SVEvent( GetEvent(), 0. );
584 for (UInt_t ievt = 0; ievt < fSupportVectors->size() ; ievt++) {
585 myMVA += ( fSupportVectors->at(ievt)->GetAlpha()
586 * fSupportVectors->at(ievt)->GetTypeFlag()
587 * fSVKernelFunction->Evaluate( fSupportVectors->at(ievt), ev ) );
595 NoErrorCalc(err, errUpper);
598 return 1.0/(1.0 + TMath::Exp(myMVA));
602 const std::vector<Float_t>& TMVA::MethodSVM::GetRegressionValues()
604 if( fRegressionReturnVal == NULL )
605 fRegressionReturnVal =
new std::vector<Float_t>();
606 fRegressionReturnVal->clear();
610 const Event *baseev = GetEvent();
611 SVEvent* ev =
new SVEvent( baseev,0. );
613 for (UInt_t ievt = 0; ievt < fSupportVectors->size() ; ievt++) {
614 myMVA += ( fSupportVectors->at(ievt)->GetDeltaAlpha()
615 *fSVKernelFunction->Evaluate( fSupportVectors->at(ievt), ev ) );
618 Event * evT =
new Event(*baseev);
619 evT->SetTarget(0,myMVA);
621 const Event* evT2 = GetTransformationHandler().InverseTransform( evT );
623 fRegressionReturnVal->push_back(evT2->GetTarget(0));
629 return *fRegressionReturnVal;
635 void TMVA::MethodSVM::MakeClassSpecific( std::ostream& fout,
const TString& className )
const
637 const int fNsupv = fSupportVectors->size();
638 fout <<
" // not implemented for class: \"" << className <<
"\"" << std::endl;
639 fout <<
" float fBparameter;" << std::endl;
640 fout <<
" int fNOfSuppVec;" << std::endl;
641 fout <<
" static float fAllSuppVectors[][" << fNsupv <<
"];" << std::endl;
642 fout <<
" static float fAlphaTypeCoef[" << fNsupv <<
"];" << std::endl;
644 fout <<
" // Kernel parameter(s) " << std::endl;
645 fout <<
" float fGamma;" << std::endl;
646 fout <<
"};" << std::endl;
647 fout <<
"" << std::endl;
650 fout <<
"inline void " << className <<
"::Initialize() " << std::endl;
651 fout <<
"{" << std::endl;
652 fout <<
" fBparameter = " << fBparm <<
";" << std::endl;
653 fout <<
" fNOfSuppVec = " << fNsupv <<
";" << std::endl;
654 fout <<
" fGamma = " << fGamma <<
";" <<std::endl;
655 fout <<
"}" << std::endl;
659 fout <<
"inline double " << className <<
"::GetMvaValue__(const std::vector<double>& inputValues ) const" << std::endl;
660 fout <<
"{" << std::endl;
661 fout <<
" double mvaval = 0; " << std::endl;
662 fout <<
" double temp = 0; " << std::endl;
664 fout <<
" for (int ievt = 0; ievt < fNOfSuppVec; ievt++ ){" << std::endl;
665 fout <<
" temp = 0;" << std::endl;
666 fout <<
" for ( unsigned int ivar = 0; ivar < GetNvar(); ivar++ ) {" << std::endl;
668 fout <<
" temp += (fAllSuppVectors[ivar][ievt] - inputValues[ivar]) " << std::endl;
669 fout <<
" * (fAllSuppVectors[ivar][ievt] - inputValues[ivar]); " << std::endl;
670 fout <<
" }" << std::endl;
671 fout <<
" mvaval += fAlphaTypeCoef[ievt] * exp( -fGamma * temp ); " << std::endl;
673 fout <<
" }" << std::endl;
674 fout <<
" mvaval -= fBparameter;" << std::endl;
675 fout <<
" return 1./(1. + exp(mvaval));" << std::endl;
676 fout <<
"}" << std::endl;
677 fout <<
"// Clean up" << std::endl;
678 fout <<
"inline void " << className <<
"::Clear() " << std::endl;
679 fout <<
"{" << std::endl;
680 fout <<
" // nothing to clear " << std::endl;
681 fout <<
"}" << std::endl;
682 fout <<
"" << std::endl;
685 fout <<
"float " << className <<
"::fAlphaTypeCoef[] =" << std::endl;
687 for (Int_t isv = 0; isv < fNsupv; isv++) {
688 fout << fSupportVectors->at(isv)->GetDeltaAlpha() * fSupportVectors->at(isv)->GetTypeFlag();
689 if (isv < fNsupv-1) fout <<
", ";
691 fout <<
" };" << std::endl << std::endl;
693 fout <<
"float " << className <<
"::fAllSuppVectors[][" << fNsupv <<
"] =" << std::endl;
695 for (UInt_t ivar = 0; ivar < GetNvar(); ivar++) {
698 for (Int_t isv = 0; isv < fNsupv; isv++){
699 fout << fSupportVectors->at(isv)->GetDataVector()->at(ivar);
700 if (isv < fNsupv-1) fout <<
", ";
703 if (ivar < GetNvar()-1) fout <<
", " << std::endl;
704 else fout << std::endl;
706 fout <<
"};" << std::endl<< std::endl;
715 void TMVA::MethodSVM::GetHelpMessage()
const
718 Log() << gTools().Color(
"bold") <<
"--- Short description:" << gTools().Color(
"reset") << Endl;
720 Log() <<
"The Support Vector Machine (SVM) builds a hyperplane separating" << Endl;
721 Log() <<
"signal and background events (vectors) using the minimal subset of " << Endl;
722 Log() <<
"all vectors used for training (support vectors). The extension to" << Endl;
723 Log() <<
"the non-linear case is performed by mapping input vectors into a " << Endl;
724 Log() <<
"higher-dimensional feature space in which linear separation is " << Endl;
725 Log() <<
"possible. The use of the kernel functions thereby eliminates the " << Endl;
726 Log() <<
"explicit transformation to the feature space. The implemented SVM " << Endl;
727 Log() <<
"algorithm performs the classification tasks using linear, polynomial, " << Endl;
728 Log() <<
"Gaussian and sigmoidal kernel functions. The Gaussian kernel allows " << Endl;
729 Log() <<
"to apply any discriminant shape in the input space." << Endl;
731 Log() << gTools().Color(
"bold") <<
"--- Performance optimisation:" << gTools().Color(
"reset") << Endl;
733 Log() <<
"SVM is a general purpose non-linear classification method, which " << Endl;
734 Log() <<
"does not require data preprocessing like decorrelation or Principal " << Endl;
735 Log() <<
"Component Analysis. It generalises quite well and can handle analyses " << Endl;
736 Log() <<
"with large numbers of input variables." << Endl;
738 Log() << gTools().Color(
"bold") <<
"--- Performance tuning via configuration options:" << gTools().Color(
"reset") << Endl;
740 Log() <<
"Optimal performance requires primarily a proper choice of the kernel " << Endl;
741 Log() <<
"parameters (the width \"Sigma\" in case of Gaussian kernel) and the" << Endl;
742 Log() <<
"cost parameter \"C\". The user must optimise them empirically by running" << Endl;
743 Log() <<
"SVM several times with different parameter sets. The time needed for " << Endl;
744 Log() <<
"each evaluation scales like the square of the number of training " << Endl;
745 Log() <<
"events so that a coarse preliminary tuning should be performed on " << Endl;
746 Log() <<
"reduced data sets." << Endl;
760 std::map<TString,Double_t> TMVA::MethodSVM::OptimizeTuningParameters(TString fomType, TString fitType)
763 std::map< TString,std::vector<Double_t> > optVars;
766 optVars= GetTuningOptions();
768 std::map< TString,std::vector<Double_t> >::iterator iter;
770 std::map<TString,TMVA::Interval*> tuneParameters;
771 std::map<TString,Double_t> tunedParameters;
774 Log() << kINFO <<
"Using the " << fTheKernel <<
" kernel." << Endl;
776 if( fTheKernel ==
"RBF" ){
778 tuneParameters.insert(std::pair<TString,Interval*>(
"Gamma",
new Interval(0.01,1.,100)));
779 tuneParameters.insert(std::pair<TString,Interval*>(
"C",
new Interval(0.01,1.,100)));
782 for(iter=optVars.begin(); iter!=optVars.end(); ++iter){
783 if( iter->first ==
"Gamma" || iter->first ==
"C"){
784 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
787 Log() << kWARNING << iter->first <<
" is not a recognised tuneable parameter." << Endl;
793 else if( fTheKernel ==
"Polynomial" ){
795 tuneParameters.insert(std::pair<TString,Interval*>(
"Order",
new Interval(1,10,10)));
796 tuneParameters.insert(std::pair<TString,Interval*>(
"Theta",
new Interval(0.01,1.,100)));
797 tuneParameters.insert(std::pair<TString,Interval*>(
"C",
new Interval(0.01,1.,100)));
800 for(iter=optVars.begin(); iter!=optVars.end(); ++iter){
801 if( iter->first ==
"Theta" || iter->first ==
"C"){
802 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
804 else if( iter->first ==
"Order"){
805 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
808 Log() << kWARNING << iter->first <<
" is not a recognised tuneable parameter." << Endl;
814 else if( fTheKernel ==
"MultiGauss" ){
816 for(
int i=0; i<fNumVars; i++){
818 s << fVarNames.at(i);
819 string str =
"Gamma_" + s.str();
820 tuneParameters.insert(std::pair<TString,Interval*>(str,
new Interval(0.01,1.,100)));
822 tuneParameters.insert(std::pair<TString,Interval*>(
"C",
new Interval(0.01,1.,100)));
824 for(iter=optVars.begin(); iter!=optVars.end(); ++iter){
825 if( iter->first ==
"GammaList"){
826 for(
int j=0; j<fNumVars; j++){
828 s << fVarNames.at(j);
829 string str =
"Gamma_" + s.str();
830 tuneParameters.insert(std::pair<TString,Interval*>(str,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
833 else if( iter->first ==
"C"){
834 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
837 Log() << kWARNING << iter->first <<
" is not a recognised tuneable parameter." << Endl;
843 else if( fTheKernel ==
"Prod" ){
844 std::stringstream tempstring(fMultiKernels);
846 while (std::getline(tempstring,value,
'*')){
848 tuneParameters.insert(std::pair<TString,Interval*>(
"Gamma",
new Interval(0.01,1.,100)));
850 else if(value ==
"MultiGauss"){
851 for(
int i=0; i<fNumVars; i++){
853 s << fVarNames.at(i);
854 string str =
"Gamma_" + s.str();
855 tuneParameters.insert(std::pair<TString,Interval*>(str,
new Interval(0.01,1.,100)));
858 else if(value ==
"Polynomial"){
859 tuneParameters.insert(std::pair<TString,Interval*>(
"Order",
new Interval(1,10,10)));
860 tuneParameters.insert(std::pair<TString,Interval*>(
"Theta",
new Interval(0.0,1.0,101)));
863 Log() << kWARNING << value <<
" is not a recognised kernel function." << Endl;
867 tuneParameters.insert(std::pair<TString,Interval*>(
"C",
new Interval(0.01,1.,100)));
869 else if( fTheKernel ==
"Sum" ){
870 std::stringstream tempstring(fMultiKernels);
872 while (std::getline(tempstring,value,
'+')){
874 tuneParameters.insert(std::pair<TString,Interval*>(
"Gamma",
new Interval(0.01,1.,100)));
876 else if(value ==
"MultiGauss"){
877 for(
int i=0; i<fNumVars; i++){
879 s << fVarNames.at(i);
880 string str =
"Gamma_" + s.str();
881 tuneParameters.insert(std::pair<TString,Interval*>(str,
new Interval(0.01,1.,100)));
884 else if(value ==
"Polynomial"){
885 tuneParameters.insert(std::pair<TString,Interval*>(
"Order",
new Interval(1,10,10)));
886 tuneParameters.insert(std::pair<TString,Interval*>(
"Theta",
new Interval(0.0,1.0,101)));
889 Log() << kWARNING << value <<
" is not a recognised kernel function." << Endl;
893 tuneParameters.insert(std::pair<TString,Interval*>(
"C",
new Interval(0.01,1.,100)));
896 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." << Endl;
899 Log() << kINFO <<
" the following SVM parameters will be tuned on the respective *grid*\n" << Endl;
900 std::map<TString,TMVA::Interval*>::iterator it;
901 for(it=tuneParameters.begin(); it!=tuneParameters.end(); ++it){
902 Log() << kWARNING << it->first <<Endl;
903 std::ostringstream oss;
904 (it->second)->Print(oss);
908 OptimizeConfigParameters optimize(
this, tuneParameters, fomType, fitType);
909 tunedParameters=optimize.optimize();
911 return tunedParameters;
917 void TMVA::MethodSVM::SetTuneParameters(std::map<TString,Double_t> tuneParameters)
919 std::map<TString,Double_t>::iterator it;
920 if( fTheKernel ==
"RBF" ){
921 for(it=tuneParameters.begin(); it!=tuneParameters.end(); ++it){
922 Log() << kWARNING << it->first <<
" = " << it->second << Endl;
923 if (it->first ==
"Gamma"){
924 SetGamma (it->second);
926 else if(it->first ==
"C"){
927 SetCost (it->second);
930 Log() << kFATAL <<
" SetParameter for " << it->first <<
" not implemented " << Endl;
934 else if( fTheKernel ==
"MultiGauss" ){
936 for(
int i=0; i<fNumVars; i++){
938 s << fVarNames.at(i);
939 string str =
"Gamma_" + s.str();
940 Log() << kWARNING << tuneParameters.find(str)->first <<
" = " << tuneParameters.find(str)->second << Endl;
941 fmGamma.push_back(tuneParameters.find(str)->second);
943 for(it=tuneParameters.begin(); it!=tuneParameters.end(); ++it){
944 if (it->first ==
"C"){
945 Log() << kWARNING << it->first <<
" = " << it->second << Endl;
951 else if( fTheKernel ==
"Polynomial" ){
952 for(it=tuneParameters.begin(); it!=tuneParameters.end(); ++it){
953 Log() << kWARNING << it->first <<
" = " << it->second << Endl;
954 if (it->first ==
"Order"){
955 SetOrder(it->second);
957 else if (it->first ==
"Theta"){
958 SetTheta(it->second);
960 else if(it->first ==
"C"){ SetCost (it->second);
962 else if(it->first ==
"Mult"){
966 Log() << kFATAL <<
" SetParameter for " << it->first <<
" not implemented " << Endl;
970 else if( fTheKernel ==
"Prod" || fTheKernel ==
"Sum"){
972 for(it=tuneParameters.begin(); it!=tuneParameters.end(); ++it){
973 bool foundParam =
false;
974 Log() << kWARNING << it->first <<
" = " << it->second << Endl;
975 for(
int i=0; i<fNumVars; i++){
977 s << fVarNames.at(i);
978 string str =
"Gamma_" + s.str();
979 if(it->first == str){
980 fmGamma.push_back(it->second);
984 if (it->first ==
"Gamma"){
985 SetGamma (it->second);
988 else if (it->first ==
"Order"){
989 SetOrder (it->second);
992 else if (it->first ==
"Theta"){
993 SetTheta (it->second);
996 else if (it->first ==
"C"){ SetCost (it->second);
997 SetCost (it->second);
1002 Log() << kFATAL <<
" SetParameter for " << it->first <<
" not implemented " << Endl;
1008 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." << Endl;
1018 void TMVA::MethodSVM::SetMGamma(std::string & mg){
1019 std::stringstream tempstring(mg);
1021 while (tempstring >> value){
1022 fmGamma.push_back(value);
1024 if (tempstring.peek() ==
','){
1025 tempstring.ignore();
1032 void TMVA::MethodSVM::GetMGamma(
const std::vector<float> & gammas){
1033 std::ostringstream tempstring;
1034 for(UInt_t i = 0; i<gammas.size(); ++i){
1035 tempstring << gammas.at(i);
1036 if(i!=(gammas.size()-1)){
1040 fGammaList= tempstring.str();
1054 std::vector<TMVA::SVKernelFunction::EKernelType> TMVA::MethodSVM::MakeKernelList(std::string multiKernels, TString kernel)
1056 std::vector<TMVA::SVKernelFunction::EKernelType> kernelsList;
1057 std::stringstream tempstring(multiKernels);
1060 while (std::getline(tempstring,value,
'*')){
1061 if(value ==
"RBF"){ kernelsList.push_back(SVKernelFunction::kRBF);}
1062 else if(value ==
"MultiGauss"){
1063 kernelsList.push_back(SVKernelFunction::kMultiGauss);
1068 else if(value ==
"Polynomial"){ kernelsList.push_back(SVKernelFunction::kPolynomial);}
1070 Log() << kWARNING << value <<
" is not a recognised kernel function." << Endl;
1075 else if(kernel==
"Sum"){
1076 while (std::getline(tempstring,value,
'+')){
1077 if(value ==
"RBF"){ kernelsList.push_back(SVKernelFunction::kRBF);}
1078 else if(value ==
"MultiGauss"){
1079 kernelsList.push_back(SVKernelFunction::kMultiGauss);
1084 else if(value ==
"Polynomial"){ kernelsList.push_back(SVKernelFunction::kPolynomial);}
1086 Log() << kWARNING << value <<
" is not a recognised kernel function." << Endl;
1092 Log() << kWARNING <<
"Unable to split MultiKernels. Delimiters */+ required." << Endl;
1106 std::map< TString,std::vector<Double_t> > TMVA::MethodSVM::GetTuningOptions()
1108 std::map< TString,std::vector<Double_t> > optVars;
1109 std::stringstream tempstring(fTune);
1111 while (std::getline(tempstring,value,
',')){
1112 unsigned first = value.find(
'[')+1;
1113 unsigned last = value.find_last_of(
']');
1114 std::string optParam = value.substr(0,first-1);
1115 std::stringstream strNew (value.substr(first,last-first));
1116 Double_t optInterval;
1117 std::vector<Double_t> tempVec;
1119 while (strNew >> optInterval){
1120 tempVec.push_back(optInterval);
1121 if (strNew.peek() ==
';'){
1126 if(i != 3 && i == tempVec.size()){
1127 if(optParam ==
"C" || optParam ==
"Gamma" || optParam ==
"GammaList" || optParam ==
"Theta"){
1130 tempVec.push_back(0.01);
1132 tempVec.push_back(1.);
1134 tempVec.push_back(100);
1137 else if(optParam ==
"Order"){
1140 tempVec.push_back(1);
1142 tempVec.push_back(10);
1144 tempVec.push_back(10);
1148 Log() << kWARNING << optParam <<
" is not a recognised tuneable parameter." << Endl;
1152 optVars.insert(std::pair<TString,std::vector<Double_t> >(optParam,tempVec));
1163 Double_t TMVA::MethodSVM::getLoss(TString lossFunction){
1164 Double_t loss = 0.0;
1165 Double_t sumW = 0.0;
1166 Double_t temp = 0.0;
1167 Data()->SetCurrentType(Types::kTesting);
1168 ResultsClassification* mvaRes =
dynamic_cast<ResultsClassification*
> ( Data()->GetResults(GetMethodName(),Types::kTesting, Types::kClassification) );
1169 for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
1170 const Event* ev = GetEvent(ievt);
1171 Float_t v = (*mvaRes)[ievt][0];
1172 Float_t w = ev->GetWeight();
1173 if(DataInfo().IsSignal(ev)){
1174 if(lossFunction ==
"hinge"){
1177 else if(lossFunction ==
"exp"){
1178 temp += w*TMath::Exp(-v);
1180 else if(lossFunction ==
"binomial"){
1181 temp += w*TMath::Log(1+TMath::Exp(-2*v));
1184 Log() << kWARNING << lossFunction <<
" is not a recognised loss function." << Endl;
1189 if(lossFunction ==
"hinge"){
1192 else if(lossFunction ==
"exp"){
1193 temp += w*TMath::Exp(-(1-v));
1195 else if(lossFunction ==
"binomial"){
1196 temp += w*TMath::Log(1+TMath::Exp(-2*(1-v)));
1199 Log() << kWARNING << lossFunction <<
" is not a recognised loss function." << Endl;