Продолжу обещанный рассказ о том, как можно применять полученную модель на практике, заодно попытаюсь более подробно раскрыть тему эксклюзивности TMVA.
Допустим, Вы работаете в проекте, требующем максимального быстродействия системы (геймдев, картографический сервис или же данные с коллайдера), тогда очевидно, что Ваш код написан на языке, который предельно близок к железу — C/C++. И однажды возникает необходимость добавить к сервису какую-то математику в зависимости от потребностей проекта. Обычно взгляд падает на змеиный язык, который имеет множество удобных математических библиотек для прототипирования идей, но при этом бесполезном в работе с действительно большим объёмом данных и поедающем словно удав все ресурсы машины.
В этом случае, Вам потребуется набирать людей в команду, которые будут рисовать на коленке кодить на питоне, т.к. разработка на промышленных ЯП обычно занимает несколько больше времени (обычно так, но на практике встречал людей, которые пишут годный С++ код за время среднестатистического питониста).
CERN'овская библиотека ROOT решает проблему прототипирования алгоритмов, ускоряя процесс разработки для ценителей плюсов.
"ROOT provides a toolbox like R or MATLAB for statistical analysis but allows a more rapid implementation of research into a production environment by using C++ also for prototyping ideas in macros. In addition, ROOT has the tools to store and filter massive amounts of data in an efficient way"
Вы можете компилировать код, можете просто писать макросы, важно — скорость разработки увеличивается, и для этого совсем не обязательно тратить время на поддержку не продакшн тулзов.
Вернемся непосредственно к Reader'у в TMVA. Как я уже говорил, он позволяет считывать построенную модель и применять её на данных со схожей структурой, можно выгрузить информацию (id, номер телефона, email) с определённой отсечкой скор.балла. Т.е. полученная в TMVA модель является переносимой…
Образец Reader'a:
{
cout <<" >>>> _____________________Reader application launched_________________________________________________________\n";
//подаём файл с данными для скоринга для чтения в ридер
TFile* realdata = new TFile("ForScoring.csv");
//создаём выходной root-файл
TFile *target = new TFile("real_data-mva.root","RECREATE" );
//объявляем класс ридера
TMVA::Reader *reader = new TMVA::Reader( "V:Color:!Silent" );
//переменные считываются с нулевого индекса
Float_t var[2];
reader->AddVariable ("Param0", &var[0]);
reader->AddVariable ("Param1", &var[1]);
reader->AddVariable ("Param2", &var[2]);
//reader->AddSpectator("id", &var[3]); //if we need download it
cout <<" >>>> All is good, next phase \n";
//считываем xml файл модели,лежащем в созданной директории weights
reader->BookMVA("SVM", "weights/TMVAClassification_SVM.weights.xml");
Float_t uservar[3];
//Long64_t id;
realdataTree->SetBranchAddress("Param0",&uservar[0]);
realdataTree->SetBranchAddress("Param1",&uservar[1]);
realdataTree->SetBranchAddress("Param2",&Param2);
//создаём переменную для записи id'шников и пишем в текстовый файл
Float_t SVM_response;
tree->Branch("SVM_response",&SVM_response);
outputListFileName = "Output_mva.csv";
cout << "opening file "<<outputListFileName <<"\n";
ofstream* outCsv = new ofstream(outputListFileName.c_str());
for (Long64_t ievt=0; ievt<realdataTree->GetEntries();ievt++)
{
if (ievt%5000000 == 0) std::cout << "--- ... Processing event: " << ievt <<std::endl;
realdataTree->GetEntry(ievt);
// в цикле можно для различных целей преобразовать входные переменные
var[0]=Param0;
var[1]=Param1;
var[2]=Param2;
//Выгружаем с отсечкой скор.балла 0.9 и выше
BDT_response=reader->EvaluateMVA("SVM");
if (SVM_response >= 0.9)
*outCsv << id << ";" << SVM_response <<"\n";
tree->Fill();
}
outCsv->close();
delete outCsv;
delete reader;
tree->Write();
target->Close();
}