64 _currentModelName(
""),
69 xmlKeepBlanksDefault(0);
71 _doc = xmlParseFile(_pmmlFile.c_str());
74 _rootNode = xmlDocGetRootElement(_doc);
78 throw string(
"Unable to read PMML file.");
80 catch ( std::string msg )
101 _currentModelName(
""),
116 cout <<
"~PMMLlib" << endl;
124 void PMMLlib::SetCurrentModel(std::string modelName,
127 _currentModelName = modelName;
128 _currentModelType = type;
132 _currentModelNode = GetNeuralNetPtr(modelName);
135 _currentModelNode = GetRegressionPtr(modelName);
138 throw string(
"Unknown PMML type.");
141 if ( _currentModelNode == NULL )
142 throw string(
"Model not found.");
150 void PMMLlib::SetCurrentModel(std::string modelName)
152 if (_rootNode == NULL)
153 throw string(
"No PMML file set.");
154 xmlNodePtr node = NULL;
156 node = _rootNode->children;
159 string nodeModelName = _getProp(node,
string(
"modelName"));
160 if ( nodeModelName == modelName )
163 _currentModelNode = node;
164 _currentModelName = modelName;
165 _currentModelType = GetCurrentModelType();
171 std::ostringstream oss;
173 string msg =
"SetCurrentModel(modelName) : found " + oss.str() +
" model(s) in PMML file.\n";
174 msg +=
"Use SetCurrentModel(modelName,type).";
183 void PMMLlib::SetCurrentModel()
188 std::ostringstream oss;
190 string msg =
"SetCurrentModel() : found " + oss.str() +
" model(s) in PMML file.\n";
191 msg +=
"Use SetCurrentModel(modelName) or SetCurrentModel(modelName,type).";
194 _currentModelNode = GetChildByName(_rootNode,
"NeuralNetwork");
195 _currentModelType =
kANN;
196 if (_currentModelNode == NULL)
198 _currentModelNode = GetChildByName(_rootNode,
"RegressionModel");
199 _currentModelType =
kLR;
201 if (_currentModelNode == NULL)
203 string msg(
"Couldn't get node in SetCurrentModel().");
206 _currentModelName = _getProp(_currentModelNode,
string(
"modelName"));
213 std::string PMMLlib::makeLog()
const
216 out <<
"**\n**** Display of PMMLlib ****" << endl;
217 out <<
" ** _pmmlFile[" << _pmmlFile <<
"]" << endl;
218 out <<
" ** _log[" << (_log?1:0) <<
"]" << endl;
219 out <<
"**\n**** End of display of PMMLlib ****" << endl;
226 void PMMLlib::printLog()
const
228 string log = makeLog();
238 void PMMLlib::SetRootNode()
240 xmlChar * xs = _stringToXmlChar(
"1.0");
241 _doc = xmlNewDoc(xs);
244 xmlChar *xp = _stringToXmlChar(
"PMML");
245 _rootNode = xmlNewNode(0, xp);
248 xmlNewProp(_rootNode, (
const xmlChar*)
"xmlns", (
const xmlChar*)
"http://www.dmg.org/PMML-4_1");
249 xmlNewProp(_rootNode, (
const xmlChar*)
"version", (
const xmlChar*)
"4.1");
251 xmlDocSetRootElement(_doc, _rootNode);
263 void PMMLlib::SetHeader(std::string copyright,
264 std::string description,
266 std::string appVersion,
267 std::string annotation)
269 xmlNodePtr headerNode = xmlNewChild(_rootNode, 0, (
const xmlChar*)
"Header", 0);
270 xmlNewProp(headerNode, (
const xmlChar*)
"copyright", (
const xmlChar*)(copyright.c_str()));
271 xmlNewProp(headerNode, (
const xmlChar*)
"description", (
const xmlChar*)(description.c_str()));
273 xmlNodePtr appNode = xmlNewChild(headerNode, 0, (
const xmlChar*)
"Application", 0);
274 xmlNewProp(appNode, (
const xmlChar*)
"name", (
const xmlChar*)(appName.c_str()));
275 xmlNewProp(appNode, (
const xmlChar*)
"version", (
const xmlChar*)(appVersion.c_str()));
277 xmlNewChild(headerNode, 0, (
const xmlChar*)
"Annotation", (
const xmlChar*)(annotation.c_str()));
286 void PMMLlib::AddMiningSchema(std::string name,
287 std::string usageType)
289 xmlNodePtr netNode = _currentModelNode;
292 xmlNodePtr miningSchemaNode = GetChildByName(netNode,
"MiningSchema");
293 if(!miningSchemaNode)
295 miningSchemaNode = xmlNewChild(netNode, 0, (
const xmlChar*)
"MiningSchema", 0);
299 xmlNodePtr miningFieldNode = xmlNewChild(miningSchemaNode, 0, (
const xmlChar*)
"MiningField", 0);
300 xmlNewProp(miningFieldNode, (
const xmlChar*)
"name", (
const xmlChar*)(name.c_str()) );
301 xmlNewProp(miningFieldNode, (
const xmlChar*)
"usageType", (
const xmlChar*)(usageType.c_str()) );
310 xmlNodePtr PMMLlib::GetChildByName(xmlNodePtr node,
311 std::string nodeName)
316 xmlNodePtr childNode = node->children;
317 if ( childNode == NULL )
320 const xmlChar* name = childNode->name;
323 strName = _xmlCharToString(name);
325 while( (childNode != NULL) && (strName != nodeName) )
327 childNode = childNode->next;
328 if ( childNode == NULL )
330 name = childNode->name;
332 strName = _xmlCharToString(name);
341 void PMMLlib::CountModels()
344 nCount = CountNeuralNetModels() + CountRegressionModels();
346 cout <<
" ** End Of Count Models nCount[" << nCount <<
"]" << endl;
354 int PMMLlib::CountNeuralNetModels()
357 xmlNodePtr ptr = GetChildByName(_rootNode,
"NeuralNetwork");
359 while (ptr != NULL && _xmlCharToString(ptr->name) ==
"NeuralNetwork")
363 cout <<
" ** nCount[" << nCount <<
"]" << endl;
367 cout <<
" ** End Of CountNetworks nCount[" << nCount <<
"]" << endl;
375 int PMMLlib::CountRegressionModels()
378 xmlNodePtr ptr = GetChildByName(_rootNode,
"RegressionModel");
380 while (ptr != NULL && _xmlCharToString(ptr->name) ==
"RegressionModel")
384 cout <<
" ** nCount[" << nCount <<
"]" << endl;
388 cout <<
" ** End Of CountRegressions nCount[" << nCount <<
"]" << endl;
396 int PMMLlib::GetModelsNb()
406 std::string PMMLlib::GetModelName(xmlNodePtr node)
409 name = _getProp(node,
string(
"modelName") );
419 xmlNodePtr PMMLlib::GetPtr(
int index,
422 xmlNodePtr node = NULL;
426 _rootNode = xmlDocGetRootElement(_doc);
427 node = GetChildByName(_rootNode, name);
430 while ((
i != index) && (node != NULL))
445 xmlNodePtr PMMLlib::GetPtr(std::string myModelName,
446 std::string nodeName)
448 xmlNodePtr node = NULL;
451 node = GetChildByName(_rootNode, nodeName);
454 string modelName = _getProp(node,
string(
"modelName"));
456 while ( (node != NULL) && modelName != myModelName )
461 modelName = _getProp(node,
string(
"modelName"));
473 std::string PMMLlib::GetTypeString()
476 switch(_currentModelType)
479 name =
"NeuralNetwork";
482 name =
"RegressionModel";
485 throw string(
"Unknown PMML type.");
499 if ( ! _currentModelNode )
501 string name = _xmlCharToString(_currentModelNode->name);
502 if ( name ==
"NeuralNetwork" )
504 else if ( name ==
"RegressionModel" )
514 std::string PMMLlib::GetCurrentModelName()
516 if ( ! _currentModelNode )
518 string name = _getProp(_currentModelNode,
string(
"modelName"));
525 void PMMLlib::UnlinkNode()
527 xmlNodePtr ptr = _currentModelNode ;
528 xmlUnlinkNode( ptr );
535 void PMMLlib::BackupNode()
538 string name = GetTypeString();
542 ss << _currentModelName <<
"_" << nCrtIndex;
543 xmlNodePtr ptr = GetPtr(ss.str(), name);
548 cout <<
" ** nCrtIndex[" << nCrtIndex <<
"]" << endl;
551 ss << _currentModelName <<
"_" << nCrtIndex;
552 ptr = GetPtr(ss.str(), name);
555 cout <<
" *** Node \"" << _currentModelName <<
"\" found, then backup it with index [" << nCrtIndex <<
"]" << endl;
557 xmlUnsetProp(_currentModelNode, (
const xmlChar*)
"modelName");
558 xmlNewProp(_currentModelNode, (
const xmlChar*)
"modelName", (
const xmlChar*)(ss.str().c_str()));
564 void PMMLlib::Write()
576 void PMMLlib::Write(std::string file)
579 int ret = xmlSaveFormatFile( file.c_str(), _doc, 1);
582 std::string msg(
" *** Error :: unable to write the PMML file \"" + file +
"\"") ;
587 cout <<
" *** Write the PMML file \"" << file <<
"\"" << endl;
596 void PMMLlib::ExportCpp(std::string file,
597 std::string functionName,
600 if ( _currentModelType ==
kANN )
601 ExportNeuralNetworkCpp(file,functionName, header);
602 else if ( _currentModelType ==
kLR )
604 ExportLinearRegressionCpp(file, functionName, header);
607 throw string(
"ExportCpp : PMML type not handled.");
616 void PMMLlib::ExportFortran(std::string file,
617 std::string functionName,
620 if ( _currentModelType ==
kANN )
621 ExportNeuralNetworkFortran(file,functionName, header);
622 else if ( _currentModelType ==
kLR )
623 ExportLinearRegressionFortran(file,functionName, header);
625 throw string(
"ExportFortran : PMML type not handled.");
634 void PMMLlib::ExportPython(std::string file,
635 std::string functionName,
638 if ( _currentModelType ==
kANN )
639 ExportNeuralNetworkPython(file,functionName, header);
640 else if ( _currentModelType ==
kLR )
641 ExportLinearRegressionPython(file,functionName, header);
643 throw string(
"ExportPython : PMML type not handled.");
653 std::string PMMLlib::ExportPyStr(std::string functionName,
656 if ( _currentModelType ==
kANN )
657 return ExportNeuralNetworkPyStr(functionName, header);
658 else if ( _currentModelType ==
kLR )
659 return ExportLinearRegressionPyStr(functionName, header);
661 throw string(
"ExportPyStr : PMML type not handled.");
669 std::string PMMLlib::_xmlCharToString(
const xmlChar *xs)
const
671 size_t i, L = xmlStrlen(xs);
674 for (
i=0; *xs; s[
i++] = *xs++);
683 xmlChar * PMMLlib::_stringToXmlChar(
const std::string &s)
const
685 return xmlCharStrdup(s.c_str());
694 std::string PMMLlib::_getProp(
const xmlNodePtr node,
695 std::string
const & prop )
const
697 std::string name(
"");
700 xmlChar *xp = _stringToXmlChar(prop);
702 attr = xmlGetProp(node, xp );
705 name = _xmlCharToString(attr );
728 void PMMLlib::CheckNeuralNetwork()
730 if ( _currentModelType !=
kANN )
731 throw string(
"Use this method with NeuralNetwork models.");
739 xmlNodePtr PMMLlib::GetNeuralNetPtr(
int index)
741 return GetPtr(index, GetTypeString() );
749 xmlNodePtr PMMLlib::GetNeuralNetPtr(std::string name)
751 return GetPtr(name, GetTypeString() );
759 std::string PMMLlib::ReadNetworkStructure()
761 CheckNeuralNetwork();
763 string structure(
"");
765 xmlNodePtr inputNodes = GetChildByName(_currentModelNode,
"NeuralInputs");
766 if ( inputNodes != NULL )
768 xmlNodePtr inputNode = GetChildByName(inputNodes,
"NeuralInput");
769 if ( inputNode != NULL )
771 while (inputNode != NULL)
773 xmlNodePtr child = GetChildByName(inputNode,
"DerivedField");
776 xmlNodePtr fieldName = child->children;
777 if ( fieldName != NULL )
779 string field = _getProp(fieldName,
string(
"field"));
784 inputNode = inputNode->next;
787 structure.erase(structure.size()-1);
791 xmlNodePtr node_layer = GetChildByName(_currentModelNode,
"NeuralLayer");
792 if ( node_layer != NULL )
794 string name = string((
const char*)(node_layer->name));
797 while ( node_layer != NULL &&
798 (
string((
const char*)(node_layer->name)) ==
"NeuralLayer") &&
799 node_layer->next != NULL &&
800 (
string((
const char*)(node_layer->next->name)) !=
"NeuralOutputs") )
803 string nbneurons = _getProp(node_layer,
string(
"numberOfNeurons"));
804 structure += nbneurons;
806 node_layer = node_layer->next;
810 xmlNodePtr node_outputs = GetChildByName(_currentModelNode,
"NeuralOutputs");
811 if ( node_outputs != NULL )
813 xmlNodePtr node_output = GetChildByName(node_outputs,
"NeuralOutput");
814 if ( node_output != NULL )
816 while (node_output != NULL)
819 xmlNodePtr child = GetChildByName(node_output,
"DerivedField");
822 xmlNodePtr fieldName = child->children;
823 if ( fieldName != NULL )
825 if (
string((
const char*)(fieldName->name)) ==
"NormContinuous")
828 string field = _getProp(fieldName,
string(
"field"));
833 node_output = node_output->next;
836 structure.erase(structure.size()-1);
847 int PMMLlib::GetNbInputs()
849 CheckNeuralNetwork();
852 xmlNodePtr node_inputs = GetChildByName(_currentModelNode,
"NeuralInputs");
853 if ( node_inputs == NULL )
856 node_inputs = node_inputs->children;
857 while (node_inputs != NULL)
860 node_inputs = node_inputs->next;
871 int PMMLlib::GetNbOutputs()
873 CheckNeuralNetwork();
876 xmlNodePtr node_outputs = GetChildByName(_currentModelNode,
"NeuralOutputs");
877 if ( node_outputs == NULL )
880 node_outputs = node_outputs->children;
882 while (node_outputs != NULL)
885 node_outputs = node_outputs->next;
897 std::string PMMLlib::GetNameInput(
int index)
899 CheckNeuralNetwork();
902 xmlNodePtr node_inputs = GetChildByName(_currentModelNode,
"NeuralInputs");
903 if ( node_inputs == NULL )
906 node_inputs = node_inputs->children;
907 if ( node_inputs == NULL )
910 for(
int i = 0;
i<index;
i++)
912 node_inputs = node_inputs->next;
913 if ( node_inputs == NULL )
917 node_inputs = node_inputs->children;
918 if ( node_inputs == NULL )
921 node_inputs = node_inputs->children;
922 if ( node_inputs == NULL )
925 name = _getProp(node_inputs,
string(
"field"));
936 std::string PMMLlib::GetNameOutput(
int index)
938 CheckNeuralNetwork();
941 xmlNodePtr node_outputs = GetChildByName(_currentModelNode,
"NeuralOutputs");
942 if ( node_outputs == NULL )
944 node_outputs = node_outputs->children;
945 if ( node_outputs == NULL )
947 for(
int i = 0;
i<index;
i++)
949 node_outputs = node_outputs->next;
950 if ( node_outputs == NULL )
954 node_outputs = node_outputs->children;
955 if ( node_outputs == NULL )
957 node_outputs = node_outputs->children;
958 if ( node_outputs == NULL )
961 name = _getProp(node_outputs,
string(
"field") );
971 int PMMLlib::GetNormalizationType()
973 CheckNeuralNetwork();
975 xmlNodePtr node_inputs = GetChildByName(_currentModelNode,
"NeuralInputs");
976 node_inputs = GetChildByName(node_inputs,
"NeuralInput");
977 xmlNodePtr nodeTmp = GetChildByName(node_inputs,
"DerivedField");
978 xmlNodePtr node_field = nodeTmp->children;
979 xmlNodePtr node_linearnorm;
981 double dorig1, dnorm1;
982 double dorig2, dnorm2;
983 if (
string((
const char*)(node_field->name)) ==
"NormContinuous")
986 node_linearnorm = node_field->children;
987 str_tmp = _getProp(node_linearnorm,
string(
"orig"));
988 dorig1 = atof(str_tmp.c_str());
989 str_tmp = _getProp(node_linearnorm,
string(
"norm"));
990 dnorm1 = atof(str_tmp.c_str());
991 node_linearnorm = node_linearnorm->next;
992 str_tmp = _getProp(node_linearnorm,
string(
"orig"));
993 dorig2 = atof(str_tmp.c_str());
994 str_tmp = _getProp(node_linearnorm,
string(
"norm"));
995 dnorm2 = atof(str_tmp.c_str());
996 if ( dnorm1 * dnorm2 < -0.5 )
1005 string msg(
"Unable to retrieve the normalization type.");
1016 void PMMLlib::GetNormalisationInput(
int index,
1019 CheckNeuralNetwork();
1022 xmlNodePtr node_inputs = GetChildByName(_currentModelNode,
"NeuralInputs");
1023 if ( node_inputs == NULL )
1025 node_inputs = GetChildByName(node_inputs,
"NeuralInput");
1026 if ( node_inputs == NULL )
1029 for(
int i=0;
i<index;
i++)
1031 node_inputs = node_inputs->next;
1032 if ( node_inputs == NULL )
1035 xmlNodePtr tmpNode = GetChildByName(node_inputs,
"DerivedField");
1036 if ( tmpNode == NULL )
1038 xmlNodePtr node_field = GetChildByName(tmpNode,
"NormContinuous");
1039 if ( node_field == NULL )
1041 if (
string((
const char*)(node_field->name)) ==
"NormContinuous")
1045 xmlNodePtr node_linearnorm = node_field->children;
1046 str_tmp = _getProp(node_linearnorm,
string(
"orig"));
1047 double dorig1 = atof(str_tmp.c_str());
1048 str_tmp = _getProp(node_linearnorm,
string(
"norm"));
1049 double dnorm1 = atof(str_tmp.c_str());
1050 node_linearnorm = node_linearnorm->next;
1051 str_tmp = _getProp(node_linearnorm,
string(
"orig"));
1052 double dorig2 = atof(str_tmp.c_str());
1053 str_tmp = _getProp(node_linearnorm,
string(
"norm"));
1054 double dnorm2 = atof(str_tmp.c_str());
1055 if ( dnorm1 * dnorm2 < -0.5 )
1065 dnorm[1] = -1.0 * dnorm1 * dorig2;
1076 void PMMLlib::GetNormalisationOutput(
int index,
1079 CheckNeuralNetwork();
1083 xmlNodePtr node_outputs = GetChildByName(_currentModelNode,
"NeuralOutputs");
1084 if ( node_outputs == NULL )
1086 node_outputs = GetChildByName(node_outputs,
"NeuralOutput");
1087 if ( node_outputs == NULL )
1090 for(
int i=0;
i< index;
i++)
1092 node_outputs = node_outputs->next;
1093 if ( node_outputs == NULL )
1096 xmlNodePtr tmpNode = GetChildByName(node_outputs,
"DerivedField");
1097 if ( tmpNode == NULL )
1099 xmlNodePtr node_field = GetChildByName(tmpNode,
"NormContinuous");
1100 if ( node_field == NULL )
1103 if (
string((
const char*)(node_field->name)) ==
"NormContinuous")
1107 xmlNodePtr node_linearnorm = node_field->children;
1108 str_tmp = _getProp(node_linearnorm,
string(
"orig"));
1109 double dorig1 = atof(str_tmp.c_str());
1110 str_tmp = _getProp(node_linearnorm,
string(
"norm"));
1111 double dnorm1 = atof(str_tmp.c_str());
1112 node_linearnorm = node_linearnorm->next;
1113 str_tmp = _getProp(node_linearnorm,
string(
"orig"));
1114 double dorig2 = atof(str_tmp.c_str());
1115 str_tmp = _getProp(node_linearnorm,
string(
"norm"));
1116 double dnorm2 = atof(str_tmp.c_str());
1117 if ( dnorm1 * dnorm2 < -0.5 )
1127 dnorm[1] = -1.0 * dorig2 * dnorm1;
1137 int PMMLlib::GetNbHiddenLayers()
1139 CheckNeuralNetwork();
1142 xmlNodePtr node_layers = GetChildByName(_currentModelNode,
"NeuralLayer");
1143 if ( node_layers == NULL )
1146 while (
string((
const char*)(node_layers->name)) ==
"NeuralLayer")
1149 node_layers = node_layers->next;
1150 if ( node_layers == NULL )
1160 int PMMLlib::GetNbLayers()
1162 return (GetNbHiddenLayers() + 2);
1170 int PMMLlib::GetNbNeuronsAtLayer(
int index)
1172 CheckNeuralNetwork();
1175 xmlNodePtr node_layers = GetChildByName(_currentModelNode,
"NeuralLayer");
1176 if ( node_layers == NULL )
1180 for(
int i=0;
i<index;
i++)
1182 node_layers = node_layers->next;
1183 if ( node_layers == NULL )
1187 xmlNodePtr node_neurons = GetChildByName(node_layers,
"Neuron");
1188 while(node_neurons != NULL)
1191 node_neurons = node_neurons->next;
1204 double PMMLlib::GetNeuronBias(
int layer_index,
1207 CheckNeuralNetwork();
1210 xmlNodePtr node_layers = GetChildByName(_currentModelNode,
"NeuralLayer");
1211 if ( node_layers == NULL )
1214 for(
int i=0;
i<layer_index;
i++)
1216 node_layers = node_layers->next;
1217 if ( node_layers == NULL )
1220 xmlNodePtr node_neurons = GetChildByName(node_layers,
"Neuron");
1222 for(
int j=0;j<neu_index;j++)
1224 node_neurons = node_neurons->next;
1225 if ( node_neurons == NULL )
1228 string str_tmp = _getProp(node_neurons,
string(
"bias"));
1229 bias = atof(str_tmp.c_str());
1241 double PMMLlib::GetPrecNeuronSynapse(
int layer_index,
1245 CheckNeuralNetwork();
1248 xmlNodePtr node_layers = GetChildByName(_currentModelNode,
"NeuralLayer");
1249 if ( node_layers == NULL )
1252 for(
int i=0;
i<layer_index;
i++)
1254 node_layers = node_layers->next;
1255 if ( node_layers == NULL )
1258 xmlNodePtr node_neurons = GetChildByName(node_layers,
"Neuron");
1260 for(
int i=0;
i<neu_index;
i++)
1262 node_neurons = node_neurons->next;
1263 if ( node_neurons == NULL )
1266 xmlNodePtr node_con = GetChildByName(node_neurons,
"Con");
1268 for(
int i=0;
i<prec_index;
i++)
1270 node_con = node_con->next;
1271 if ( node_con == NULL )
1274 string str_tmp = _getProp(node_con,
string(
"weight"));
1275 weight = atof(str_tmp.c_str());
1286 void PMMLlib::SetNeuralNetName(
int index,
1289 CheckNeuralNetwork();
1294 xmlNodePtr node_ann = GetChildByName(_rootNode,
"NeuralNetwork");
1295 while ((
i != index) && (node_ann != NULL))
1297 node_ann = node_ann->next;
1300 xmlNewProp(node_ann, (
const xmlChar*)
"modelName", (
const xmlChar*)(name.c_str()));
1302 xmlSaveFormatFile(
string(_pmmlFile+
".pmml").c_str(), _doc, 1);
1317 void PMMLlib::AddDataField(std::string fieldName,
1318 std::string displayName,
1320 std::string dataType,
1321 std::string closure,
1327 xmlNodePtr dataDictNode = GetChildByName(_rootNode,
"DataDictionary");
1330 dataDictNode = xmlNewChild(_rootNode, 0, (
const xmlChar*)
"DataDictionary", 0);
1334 xmlNodePtr dataFieldNode = xmlNewChild(dataDictNode, 0, (
const xmlChar*)
"DataField", 0);
1335 xmlNewProp(dataFieldNode, (
const xmlChar*)
"name", (
const xmlChar*)(fieldName.c_str()) );
1336 xmlNewProp(dataFieldNode, (
const xmlChar*)
"displayName", (
const xmlChar*)(displayName.c_str()) );
1337 xmlNewProp(dataFieldNode, (
const xmlChar*)
"optype", (
const xmlChar*)(optype.c_str()) );
1338 xmlNewProp(dataFieldNode, (
const xmlChar*)
"dataType", (
const xmlChar*)(dataType.c_str()) );
1342 xmlNodePtr intervalNode = xmlNewChild(dataFieldNode, 0, (
const xmlChar*)
"Interval", 0);
1343 xmlNewProp(intervalNode, (
const xmlChar*)
"closure", (
const xmlChar*)(closure.c_str()) );
1345 ss << scientific << leftMargin;
1346 xmlNewProp(intervalNode, (
const xmlChar*)
"leftMargin", (
const xmlChar*)(ss.str().c_str()) );
1348 ss << scientific << rightMargin;
1349 xmlNewProp(intervalNode, (
const xmlChar*)
"rightMargin", (
const xmlChar*)(ss.str().c_str()) );
1359 void PMMLlib::AddNeuralNetwork(std::string modelName,
1362 _currentModelType =
kANN;
1363 _currentModelName = modelName;
1365 CheckNeuralNetwork();
1368 switch(functionName)
1371 function =
"regression";
1375 xmlNodePtr netNode = xmlNewChild(_rootNode, 0, (
const xmlChar*)
"NeuralNetwork", 0);
1376 xmlNewProp(netNode, (
const xmlChar*)
"modelName", (
const xmlChar*)(_currentModelName.c_str()) );
1377 xmlNewProp(netNode, (
const xmlChar*)
"functionName", (
const xmlChar*)(
function.c_str()) );
1378 xmlNewProp(netNode, (
const xmlChar*)
"numberOfLayers", (
const xmlChar*)
"0" );
1379 _currentModelNode = netNode;
1394 void PMMLlib::AddNeuralInput(
int id,
1395 std::string inputName,
1397 std::string dataType,
1398 double orig1,
double norm1,
1399 double orig2,
double norm2)
1401 CheckNeuralNetwork();
1403 xmlNodePtr netNode = _currentModelNode;
1405 xmlNodePtr neuralInputsNode = GetChildByName(netNode,
"NeuralInputs");
1406 if(!neuralInputsNode)
1408 neuralInputsNode = xmlNewChild(netNode, 0, (
const xmlChar*)
"NeuralInputs", 0);
1409 xmlNewProp(neuralInputsNode, (
const xmlChar*)
"numberOfInputs", (
const xmlChar*)
"0" );
1412 string numberOfInputsStr = _getProp(neuralInputsNode,
string(
"numberOfInputs"));
1414 istringstream( numberOfInputsStr ) >> numberOfInputs;
1417 ss << numberOfInputs;
1418 xmlSetProp(neuralInputsNode, (
const xmlChar*)
"numberOfInputs", (
const xmlChar*)(ss.str().c_str()) );
1420 xmlNodePtr neuralInputNode = xmlNewChild(neuralInputsNode, 0, (
const xmlChar*)
"NeuralInput", 0);
1421 ss.str(
""); ss << id;
1422 xmlNewProp(neuralInputNode, (
const xmlChar*)
"id", (
const xmlChar*)(ss.str().c_str()) );
1424 xmlNodePtr derivedFieldNode = xmlNewChild(neuralInputNode, 0, (
const xmlChar*)
"DerivedField", 0);
1425 xmlNewProp(derivedFieldNode, (
const xmlChar*)
"optype", (
const xmlChar*)(optype.c_str()) );
1426 xmlNewProp(derivedFieldNode, (
const xmlChar*)
"dataType", (
const xmlChar*)(dataType.c_str()) );
1428 xmlNodePtr normcontNode = xmlNewChild(derivedFieldNode, 0, (
const xmlChar*)
"NormContinuous", 0);
1429 xmlNewProp(normcontNode, (
const xmlChar*)
"field", (
const xmlChar*)(inputName.c_str()) );
1431 xmlNodePtr node_linearnorm1 = xmlNewChild(normcontNode, 0, (
const xmlChar*)
"LinearNorm", 0);
1432 ss.str(
""); ss << scientific << orig1;
1433 xmlNewProp(node_linearnorm1, (
const xmlChar*)
"orig", (
const xmlChar*)(ss.str().c_str()) );
1434 ss.str(
""); ss << scientific << norm1;
1435 xmlNewProp(node_linearnorm1, (
const xmlChar*)
"norm", (
const xmlChar*)(ss.str().c_str()) );
1436 xmlNodePtr node_linearnorm2 = xmlNewChild(normcontNode, 0, (
const xmlChar*)
"LinearNorm", 0);
1437 ss.str(
""); ss << scientific << orig2;
1438 xmlNewProp(node_linearnorm2, (
const xmlChar*)
"orig", (
const xmlChar*)(ss.str().c_str()) );
1439 ss.str(
""); ss << scientific << norm2;
1440 xmlNewProp(node_linearnorm2, (
const xmlChar*)
"norm", (
const xmlChar*)(ss.str().c_str()) );
1455 void PMMLlib::AddNeuralOutput(
int outputNeuron,
1456 std::string outputName,
1458 std::string dataType,
1459 double orig1,
double norm1,
1460 double orig2,
double norm2)
1462 CheckNeuralNetwork();
1464 xmlNodePtr netNode = _currentModelNode;
1466 xmlNodePtr neuralOutputsNode = GetChildByName(netNode,
"NeuralOutputs");
1467 if(!neuralOutputsNode)
1469 neuralOutputsNode = xmlNewChild(netNode, 0, (
const xmlChar*)
"NeuralOutputs", 0);
1470 xmlNewProp(neuralOutputsNode, (
const xmlChar*)
"numberOfOutputs", (
const xmlChar*)
"0" );
1473 string numberOfOutputsStr = _getProp(neuralOutputsNode,
string(
"numberOfOutputs"));
1474 int numberOfOutputs;
1475 istringstream( numberOfOutputsStr ) >> numberOfOutputs;
1478 ss << numberOfOutputs;
1479 xmlSetProp(neuralOutputsNode, (
const xmlChar*)
"numberOfOutputs", (
const xmlChar*)(ss.str().c_str()) );
1482 xmlNodePtr neuralOutputNode = xmlNewChild(neuralOutputsNode, 0, (
const xmlChar*)
"NeuralOutput", 0);
1483 ss.str(
""); ss << outputNeuron;
1484 xmlNewProp(neuralOutputNode, (
const xmlChar*)
"outputNeuron", (
const xmlChar*)(ss.str().c_str()) );
1486 xmlNodePtr derivedFieldNode = xmlNewChild(neuralOutputNode, 0, (
const xmlChar*)
"DerivedField", 0);
1487 xmlNewProp(derivedFieldNode, (
const xmlChar*)
"optype", (
const xmlChar*)(optype.c_str()) );
1488 xmlNewProp(derivedFieldNode, (
const xmlChar*)
"dataType", (
const xmlChar*)(dataType.c_str()) );
1490 xmlNodePtr normcontNode = xmlNewChild(derivedFieldNode, 0, (
const xmlChar*)
"NormContinuous", 0);
1491 xmlNewProp(normcontNode, (
const xmlChar*)
"field", (
const xmlChar*)(outputName.c_str()) );
1493 xmlNodePtr node_linearnorm1 = xmlNewChild(normcontNode, 0, (
const xmlChar*)
"LinearNorm", 0);
1494 ss.str(
""); ss << scientific << orig1;
1495 xmlNewProp(node_linearnorm1, (
const xmlChar*)
"orig", (
const xmlChar*)(ss.str().c_str()) );
1496 ss.str(
""); ss << scientific << norm1;
1497 xmlNewProp(node_linearnorm1, (
const xmlChar*)
"norm", (
const xmlChar*)(ss.str().c_str()) );
1498 xmlNodePtr node_linearnorm2 = xmlNewChild(normcontNode, 0, (
const xmlChar*)
"LinearNorm", 0);
1499 ss.str(
""); ss << scientific << orig2;
1500 xmlNewProp(node_linearnorm2, (
const xmlChar*)
"orig", (
const xmlChar*)(ss.str().c_str()) );
1501 ss.str(
""); ss << scientific << norm2;
1502 xmlNewProp(node_linearnorm2, (
const xmlChar*)
"norm", (
const xmlChar*)(ss.str().c_str()) );
1512 CheckNeuralNetwork();
1514 string functionName;
1515 switch(activationFunction)
1518 functionName =
"identity";
1521 functionName =
"tanh";
1524 functionName =
"logistic";
1527 xmlNodePtr netNode = _currentModelNode;
1529 string numberOfLayersStr = _getProp(_currentModelNode,
string(
"numberOfLayers"));
1531 istringstream( numberOfLayersStr ) >> numberOfLayers;
1534 ss << numberOfLayers;
1535 xmlSetProp(netNode, (
const xmlChar*)
"numberOfLayers", (
const xmlChar*)(ss.str().c_str()) );
1537 xmlNodePtr neuralLayerNode = xmlNewChild(netNode, 0, (
const xmlChar*)
"NeuralLayer", 0);
1538 xmlNewProp(neuralLayerNode, (
const xmlChar*)
"activationFunction", (
const xmlChar*)(functionName.c_str()) );
1539 xmlNewProp(neuralLayerNode, (
const xmlChar*)
"numberOfNeurons", (
const xmlChar*)
"0" );
1541 _currentNode = neuralLayerNode;
1553 void PMMLlib::AddNeuron(
int id,
1557 vector<double> weights)
1559 CheckNeuralNetwork();
1564 string numberOfNeuronsStr = _getProp(_currentNode,
string(
"numberOfNeurons"));
1565 int numberOfNeurons;
1566 istringstream( numberOfNeuronsStr ) >> numberOfNeurons;
1568 ss << numberOfNeurons;
1569 xmlSetProp(_currentNode, (
const xmlChar*)
"numberOfNeurons", (
const xmlChar*)(ss.str().c_str()) );
1572 xmlNodePtr neuronNode = xmlNewChild(_currentNode, 0, (
const xmlChar*)
"Neuron", 0);
1573 ss.str(
""); ss << id;
1574 xmlNewProp(neuronNode, (
const xmlChar*)
"id", (
const xmlChar*)(ss.str().c_str()) );
1575 ss.str(
""); ss << scientific << bias;
1576 xmlNewProp(neuronNode, (
const xmlChar*)
"bias", (
const xmlChar*)(ss.str().c_str()) );
1579 for(
int k=0 ; k<conNb ; k++)
1581 xmlNodePtr conNode = xmlNewChild(neuronNode, 0, (
const xmlChar*)
"Con", 0);
1582 ss.str(
""); ss << firstFrom+k;
1583 xmlNewProp(conNode, (
const xmlChar*)
"from", (
const xmlChar*)(ss.str().c_str()) );
1584 ss.str(
""); ss << scientific << weights[k];
1585 xmlNewProp(conNode, (
const xmlChar*)
"weight", (
const xmlChar*)(ss.str().c_str()) );
1602 void PMMLlib::fillVectorsForExport(
int nInput,
1606 vector<double> &minInput,
1607 vector<double> &maxInput,
1608 vector<double> &minOutput,
1609 vector<double> &maxOutput,
1610 vector<double> &valW )
1612 CheckNeuralNetwork();
1614 xmlNodePtr netNode = _currentModelNode ;
1617 for(
int i=0 ;
i<nInput ;
i++)
1619 xmlNodePtr node_inputs = GetChildByName(netNode,
"NeuralInputs");
1620 node_inputs = node_inputs->children;
1621 for(
int j = 0;j<
i;j++)
1623 node_inputs = node_inputs->next;
1625 node_inputs = node_inputs->children;
1626 node_inputs = node_inputs->children;
1627 node_inputs = node_inputs->children;
1628 string strOrig1 = _getProp(node_inputs,
string(
"orig") );
1629 double orig1 = atof( strOrig1.c_str() );
1630 string strNorm1 = _getProp(node_inputs,
string(
"norm") );
1631 double norm1 = atof( strNorm1.c_str() );
1632 node_inputs = node_inputs->next;
1633 string strOrig2 = _getProp(node_inputs,
string(
"orig") );
1634 double orig2 = atof( strOrig2.c_str() );
1635 string strNorm2 = _getProp(node_inputs,
string(
"norm") );
1638 minInput[
i] = orig1;
1639 maxInput[
i] = orig2;
1643 minInput[
i] = orig2;
1644 maxInput[
i] = -1.0*norm1*orig2;
1647 xmlNodePtr node_outputs = GetChildByName(netNode,
"NeuralOutputs");
1648 node_outputs = node_outputs->children;
1649 node_outputs = node_outputs->children;
1650 node_outputs = node_outputs->children;
1651 node_outputs = node_outputs->children;
1652 string strOrig1 = _getProp(node_outputs,
string(
"orig") );
1653 double orig1 = atof( strOrig1.c_str() );
1654 string strNorm1 = _getProp(node_outputs,
string(
"norm") );
1655 double norm1 = atof( strNorm1.c_str() );
1656 node_outputs = node_outputs->next;
1657 string strOrig2 = _getProp(node_outputs,
string(
"orig") );
1658 double orig2 = atof( strOrig2.c_str() );
1661 minOutput[0] = orig1;
1662 maxOutput[0] = orig2;
1666 minOutput[0] = orig2;
1667 maxOutput[0] = -1.0*norm1*orig2;
1670 for(
int j=0 ; j<nHidden ; j++)
1672 valW[j*(nInput+nOutput+1)+2] = GetNeuronBias( 0, j);
1673 for(
int i=0 ;
i<nInput ;
i++)
1675 valW[j*(nInput+nOutput+1)+3+
i] = GetPrecNeuronSynapse( 0, j,
i);
1678 for(
int j=0 ; j<nOutput ; j++)
1680 valW[0] = GetNeuronBias( 1, j);
1681 for(
int i=0 ;
i<nHidden ;
i++)
1683 valW[
i*(nInput+nOutput+1)+1] = GetPrecNeuronSynapse( 1, j,
i);
1695 void PMMLlib::ExportNeuralNetworkCpp(std::string file,
1696 std::string functionName,
1699 CheckNeuralNetwork();
1702 int nInput = GetNbInputs();
1703 int nOutput = GetNbOutputs();
1704 int nHidden = GetNbNeuronsAtLayer(0);
1705 int nNeurons = nInput+nOutput+nHidden;
1706 int nWeights = nHidden*(nInput+nOutput+1)+nOutput;
1707 int normType = GetNormalizationType();
1709 vector<double> minInput(nInput);
1710 vector<double> maxInput(nInput);
1711 vector<double> minOutput(nOutput);
1712 vector<double> maxOutput(nOutput);
1713 vector<double> valW(nWeights);
1714 fillVectorsForExport(nInput,nOutput,nHidden,normType,minInput,maxInput,minOutput,maxOutput,valW);
1716 ofstream sourcefile(file.c_str());
1720 sourcefile <<
"#define ActivationFunction(sum) ( tanh(sum) )" << endl;
1724 sourcefile <<
"#define ActivationFunction(sum) ( 1.0 / ( 1.0 + exp( -1.0 * sum )) )" << endl;
1727 sourcefile <<
"void " << functionName <<
"(double *param, double *res)" << endl;
1728 sourcefile <<
"{" << endl;
1730 sourcefile <<
" ////////////////////////////// " << endl;
1731 sourcefile <<
" //" << endl;
1733 header =
" // " + header;
1735 while ((pos = header.find(
"\n", pos)) != std::string::npos)
1737 header.replace(pos, 1,
"\n //");
1740 sourcefile << header << endl;
1741 sourcefile <<
" //" << endl;
1742 sourcefile <<
" ////////////////////////////// " << endl;
1744 sourcefile <<
" int nInput = " << nInput <<
";" << endl;
1745 sourcefile <<
" int nOutput = " << nOutput <<
";" << endl;
1747 sourcefile <<
" int nHidden = " << nHidden <<
";" << endl;
1748 sourcefile <<
" const int nNeurones = " << nNeurons <<
";" << endl;
1749 sourcefile <<
" double " << functionName <<
"_act[nNeurones];" << endl;
1751 sourcefile <<
" // --- Preprocessing of the inputs and outputs" << endl;
1752 sourcefile <<
" double " << functionName <<
"_minInput[] = {" << endl <<
" ";
1753 for(
int i=0 ;
i<nInput ;
i++)
1755 sourcefile << minInput[
i] <<
", ";
1757 sourcefile <<
"\n ";
1761 sourcefile <<
" };" << endl;
1763 sourcefile <<
" double " << functionName <<
"_minOutput[] = {" << endl <<
" ";
1764 sourcefile << minOutput[0] <<
", ";
1765 sourcefile <<
" };" << endl;
1767 sourcefile <<
" double " << functionName <<
"_maxInput[] = {" << endl <<
" ";
1768 for(
int i=0 ;
i<nInput ;
i++)
1770 sourcefile << maxInput[
i] <<
", ";
1772 sourcefile <<
"\n ";
1776 sourcefile <<
" };" << endl;
1778 sourcefile <<
" double " << functionName <<
"_maxOutput[] = {" << endl <<
" ";
1779 sourcefile << maxOutput[0] <<
", ";
1780 sourcefile <<
" };" << endl;
1783 sourcefile <<
" // --- Values of the weights" << endl;
1784 sourcefile <<
" double " << functionName <<
"_valW[] = {" << endl <<
" ";
1785 for(
int i=0 ;
i<nWeights ;
i++)
1787 sourcefile << valW[
i] <<
", ";
1789 sourcefile << endl <<
" ";
1791 sourcefile << endl <<
" };"<<endl;
1793 sourcefile <<
" // --- Constants";
1795 sourcefile <<
" int indNeurone = 0;"<<endl;
1796 sourcefile <<
" int CrtW;"<<endl;
1797 sourcefile <<
" double sum;"<<endl;
1801 sourcefile <<
" // --- Input Layers"<<endl;
1802 sourcefile <<
" for(int i = 0; i < nInput; i++) {"<<endl;
1805 sourcefile <<
" " << functionName <<
"_act[indNeurone++] = 2.0 * ( param[i] - "
1806 << functionName <<
"_minInput[i] ) / ( " << functionName <<
"_maxInput[i] - "
1807 << functionName <<
"_minInput[i] ) - 1.0;"<<endl;
1811 sourcefile <<
" " << functionName <<
"_act[indNeurone++] = ( param[i] - "
1812 << functionName <<
"_minInput[i] ) / " << functionName <<
"_maxInput[i];"
1815 sourcefile <<
" }"<<endl;
1820 sourcefile <<
" // --- Hidden Layers"<<endl;
1821 sourcefile <<
" for (int member = 0; member < nHidden; member++) {"<<endl;
1822 sourcefile <<
" int CrtW = member * ( nInput + 2) + 2;" << endl;
1823 sourcefile <<
" sum = " << functionName <<
"_valW[CrtW++];" << endl;
1824 sourcefile <<
" for (int source = 0; source < nInput; source++) {" << endl;
1825 sourcefile <<
" sum += " << functionName <<
"_act[source] * " << functionName <<
"_valW[CrtW++];" << endl;
1826 sourcefile <<
" }" << endl;
1827 sourcefile <<
" " << functionName <<
"_act[indNeurone++] = ActivationFunction(sum);" << endl;
1828 sourcefile <<
" }"<<endl;
1831 sourcefile <<
" // --- Output"<<endl;
1832 sourcefile <<
" for (int member = 0; member < nOutput; member++) {"<<endl;
1833 sourcefile <<
" sum = " << functionName <<
"_valW[0];"<<endl;
1834 sourcefile <<
" for (int source = 0; source < nHidden; source++) {"<<endl;
1835 sourcefile <<
" CrtW = source * ( nInput + 2) + 1;"<<endl;
1836 sourcefile <<
" sum += " << functionName <<
"_act[nInput+source] * " << functionName <<
"_valW[CrtW];"<<endl;
1837 sourcefile <<
" }"<<endl;
1838 sourcefile <<
" " << functionName <<
"_act[indNeurone++] = sum;"<<endl;
1841 sourcefile <<
" res[member] = " << functionName
1842 <<
"_minOutput[member] + 0.5 * ( " << functionName
1843 <<
"_maxOutput[member] - " << functionName
1844 <<
"_minOutput[member] ) * ( sum + 1.0);" << endl;
1848 sourcefile <<
" res[member] = " << functionName
1849 <<
"_minOutput[member] + " << functionName
1850 <<
"_maxOutput[member] * sum;" << endl;
1852 sourcefile <<
" }"<<endl;
1854 sourcefile <<
"}" << endl;
1865 void PMMLlib::ExportNeuralNetworkFortran(std::string file,
1866 std::string functionName,
1869 CheckNeuralNetwork();
1872 int nInput = GetNbInputs();
1873 int nOutput = GetNbOutputs();
1874 int nHidden = GetNbNeuronsAtLayer(0);
1875 int nWeights = nHidden*(nInput+nOutput+1)+nOutput;
1876 int normType = GetNormalizationType();
1878 vector<double> minInput(nInput);
1879 vector<double> maxInput(nInput);
1880 vector<double> minOutput(nOutput);
1881 vector<double> maxOutput(nOutput);
1882 vector<double> valW(nWeights);
1883 fillVectorsForExport(nInput,nOutput,nHidden,normType,minInput,maxInput,minOutput,maxOutput,valW);
1885 ofstream sourcefile(file.c_str());
1887 sourcefile <<
" SUBROUTINE " << functionName <<
"(";
1888 for(
int i=0 ;
i<GetNbInputs() ;
i++)
1890 sourcefile << GetNameInput(
i) <<
",";
1892 sourcefile << GetNameOutput(0) <<
")" << endl;
1894 sourcefile <<
"C --- *********************************************" << endl;
1895 sourcefile <<
"C --- " << endl;
1897 header =
"C --- " + header;
1899 while ((pos = header.find(
"\n", pos)) != std::string::npos)
1901 header.replace(pos, 1,
"\nC --- ");
1904 sourcefile << header << endl;
1905 sourcefile <<
"C --- " << endl;
1906 sourcefile <<
"C --- *********************************************" << endl;
1908 sourcefile <<
" IMPLICIT DOUBLE PRECISION (V)" << endl;
1909 for(
int i=0 ;
i<GetNbInputs() ;
i++)
1911 sourcefile <<
" DOUBLE PRECISION " << GetNameInput(
i) << endl;
1913 sourcefile <<
" DOUBLE PRECISION " << GetNameOutput(0) << endl;
1916 sourcefile <<
"C --- Preprocessing of the inputs" << endl;
1917 for(
int i=0 ;
i<GetNbInputs() ;
i++)
1919 sourcefile <<
" VXN" << GetNameInput(
i) <<
" = ";
1923 sourcefile <<
"2.D0 * ( " << GetNameInput(
i) <<
" - " << minInput[
i] <<
"D0 ) / " << maxInput[
i] - minInput[
i] <<
"D0 - 1.0" << endl;
1927 sourcefile <<
"( " << GetNameInput(
i) <<
" - " << minInput[
i] <<
"D0 ) / " << maxInput[
i] <<
"D0" << endl;
1933 sourcefile <<
"C --- Values of the weights" << endl;
1934 for(
int i=0 ;
i<nWeights ;
i++)
1936 sourcefile <<
" VW" <<
i+1 <<
" = " << valW[
i] << endl;
1940 for(
int member = 0; member < nHidden; member++)
1942 sourcefile <<
"C --- hidden neural number " << member+1 << endl;
1943 int CrtW = member * ( nInput + 2) + 3;
1944 sourcefile <<
" VAct" << member+1 <<
" = VW" << CrtW++ << endl;
1945 for (
int source = 0; source < nInput; source++)
1947 sourcefile <<
" 1 + VW"<< CrtW++ <<
" * VXN" << GetNameInput(source) << endl;
1954 sourcefile <<
" VPot" << member+1 <<
" = 2.D0 / (1.D0 + DEXP(-2.D0 * VAct" << member+1 <<
")) - 1.D0" << endl;
1958 sourcefile <<
" VPot" << member+1 <<
" = 1.D0 / (1.D0 + DEXP(-1.D0 * VAct" << member+1 <<
"))" << endl;
1964 sourcefile <<
"C --- Output" << endl;
1965 sourcefile <<
" VOut = VW1" << endl;
1966 for(
int source=0 ; source < nHidden ; source++)
1968 int CrtW = source * ( nInput + 2) + 2;
1969 sourcefile <<
" 1 + VW"<< CrtW <<
" * VPot" << source+1 << endl;
1974 sourcefile <<
"C --- Pretraitment of the output" << endl;
1977 sourcefile <<
" VDelta = " << 0.5*(maxOutput[0]-minOutput[0]) <<
"D0 * ( VOut + 1.0D0)" << endl;
1978 sourcefile <<
" " << GetNameOutput(0) <<
" = " << minOutput[0] <<
"D0 + VDelta" << endl;
1983 sourcefile <<
" " << GetNameOutput(0) <<
" = "<< minOutput[0] <<
"D0 + " << maxOutput[0] <<
"D0 * VOut;" << endl;
1987 sourcefile <<
"C --- " << endl;
1988 sourcefile <<
" RETURN" << endl;
1989 sourcefile <<
" END" << endl;
2001 void PMMLlib::ExportNeuralNetworkPython(std::string file,
2002 std::string functionName,
2005 string str(ExportNeuralNetworkPyStr(functionName, header));
2007 ofstream exportfile(file.c_str());
2020 std::string PMMLlib::ExportNeuralNetworkPyStr(std::string functionName,
2023 CheckNeuralNetwork();
2028 int nInput = GetNbInputs();
2029 int nOutput = GetNbOutputs();
2030 int nHidden = GetNbNeuronsAtLayer(0);
2031 int nNeurons = nInput+nOutput+nHidden;
2032 int nWeights = nHidden*(nInput+nOutput+1)+nOutput;
2033 int normType = GetNormalizationType();
2035 vector<double> minInput(nInput);
2036 vector<double> maxInput(nInput);
2037 vector<double> minOutput(nOutput);
2038 vector<double> maxOutput(nOutput);
2039 vector<double> valW(nWeights);
2040 fillVectorsForExport(nInput,nOutput,nHidden,normType,minInput,maxInput,minOutput,maxOutput,valW);
2043 out <<
"#!/usr/bin/env python3" << endl;
2044 out <<
"# -*- coding: utf-8 -*-" << endl;
2046 out <<
"from math import tanh, exp" << endl;
2052 out <<
"def ActivationFunction(sum): " << endl;
2053 out <<
" return tanh(sum); " << endl;
2057 out <<
"def ActivationFunction(sum): " << endl;
2058 out <<
" return ( 1.0 / ( 1.0 + exp( -1.0 * sum ) ) ); " << endl;
2062 out <<
"def " << functionName <<
"(param):" << endl;
2066 out <<
" ############################## " << endl;
2067 out <<
" #" << endl;
2069 header =
" # " + header;
2071 while ((pos = header.find(
"\n", pos)) != std::string::npos)
2073 header.replace(pos, 1,
"\n #");
2076 out << header << endl;
2077 out <<
" #" << endl;
2078 out <<
" ############################## " << endl;
2082 out <<
" nInput = " << nInput <<
";" << endl;
2083 out <<
" nOutput = " << nOutput <<
";" << endl;
2084 out <<
" nHidden = " << nHidden <<
";" << endl;
2085 out <<
" nNeurones = " << nNeurons <<
";" << endl;
2086 out <<
" " << functionName <<
"_act = [];" << endl;
2087 out <<
" res = [];" << endl;
2090 out <<
" # --- Preprocessing of the inputs and outputs" << endl;
2091 out <<
" " << functionName <<
"_minInput = [" << endl <<
" ";
2093 for(
int i=0 ;
i<nInput ;
i++)
2095 out << minInput[
i] <<
", ";
2102 out << endl <<
" ];" << endl;
2104 out <<
" " << functionName <<
"_minOutput = [" << endl <<
" ";
2105 out <<
" " << minOutput[0] ;
2106 out << endl <<
" ];" << endl;
2108 out <<
" " << functionName <<
"_maxInput = [" << endl <<
" ";
2109 for(
int i=0 ;
i<nInput ;
i++)
2111 out << maxInput[
i] <<
", ";
2118 out << endl <<
" ];" << endl;
2120 out <<
" " << functionName <<
"_maxOutput = [" << endl <<
" ";
2121 out <<
" " << maxOutput[0] ;
2122 out << endl <<
" ];" << endl;
2125 out <<
" # --- Values of the weights" << endl;
2126 out <<
" " << functionName <<
"_valW = [" << endl <<
" ";
2127 for(
int i=0 ;
i<nWeights ;
i++)
2129 out << valW[
i] <<
", ";
2136 out << endl <<
" ];"<<endl;
2138 out <<
" # --- Constants" << endl;
2139 out <<
" indNeurone = 0;" << endl;
2143 out <<
" # --- Input Layers" << endl;
2144 out <<
" for i in range(nInput) :" << endl;
2147 out <<
" " << functionName <<
"_act.append( 2.0 * ( param[i] - "
2148 << functionName <<
"_minInput[i] ) / ( " << functionName <<
"_maxInput[i] - "
2149 << functionName <<
"_minInput[i] ) - 1.0 ) ;"
2154 out <<
" " << functionName <<
"_act.append( ( param[i] - "
2155 << functionName <<
"_minInput[i] ) / " << functionName <<
"_maxInput[i] ) ;"
2158 out <<
" indNeurone += 1 ;" << endl;
2159 out <<
" pass" << endl;
2163 out <<
" # --- Hidden Layers" << endl;
2164 out <<
" for member in range(nHidden):" << endl;
2165 out <<
" CrtW = member * ( nInput + 2) + 2;" << endl;
2166 out <<
" sum = " << functionName <<
"_valW[CrtW];" << endl;
2167 out <<
" CrtW += 1 ;" << endl;
2168 out <<
" for source in range(nInput) :" << endl;
2169 out <<
" sum += " << functionName <<
"_act[source] * " << functionName <<
"_valW[CrtW];" << endl;
2170 out <<
" CrtW += 1 ;" << endl;
2171 out <<
" pass" << endl;
2172 out <<
" " << functionName <<
"_act.append( ActivationFunction(sum) ) ;" << endl;
2173 out <<
" indNeurone += 1 ;" << endl;
2174 out <<
" pass" << endl;
2178 out <<
" # --- Output"<<endl;
2179 out <<
" for member in range(nOutput):" << endl;
2180 out <<
" sum = " << functionName <<
"_valW[0];" << endl;
2181 out <<
" for source in range(nHidden):" << endl;
2182 out <<
" CrtW = source * ( nInput + 2) + 1;"<<endl;
2183 out <<
" sum += " << functionName <<
"_act[nInput+source] * " << functionName <<
"_valW[CrtW];" << endl;
2184 out <<
" pass" << endl;
2185 out <<
" " << functionName <<
"_act.append( sum );" << endl;
2186 out <<
" indNeurone += 1 ;" << endl;
2189 out <<
" res[member] = " << functionName
2190 <<
"_minOutput[member] + 0.5 * ( " << functionName
2191 <<
"_maxOutput[member] - " << functionName
2192 <<
"_minOutput[member] ) * ( sum + 1.0);" << endl;
2196 out <<
" res.append( " << functionName
2197 <<
"_minOutput[member] + " << functionName
2198 <<
"_maxOutput[member] * sum );" << endl;
2200 out <<
" pass" << endl;
2204 out <<
" return res;" << endl << endl;
2225 void PMMLlib::CheckRegression()
2227 if ( _currentModelType !=
kLR )
2228 throw string(
"Use this method with Regression models.");
2236 xmlNodePtr PMMLlib::GetRegressionPtr(std::string name)
2238 return GetPtr(name, GetTypeString() );
2248 void PMMLlib::AddRegressionModel(std::string modelName,
2250 std::string targetFieldName)
2252 _currentModelType =
kLR;
2253 _currentModelName = modelName;
2258 switch(functionName)
2261 function =
"regression";
2264 xmlNodePtr netNode = xmlNewChild(_rootNode, 0, (
const xmlChar*)
"RegressionModel", 0);
2265 xmlNewProp(netNode, (
const xmlChar*)
"functionName", (
const xmlChar*)(
function.c_str()) );
2266 xmlNewProp(netNode, (
const xmlChar*)
"modelName", (
const xmlChar*)(_currentModelName.c_str()) );
2267 xmlNewProp(netNode, (
const xmlChar*)
"targetFieldName", (
const xmlChar*)(targetFieldName.c_str()) );
2268 _currentModelNode = netNode ;
2276 void PMMLlib::AddRegressionTable()
2279 xmlNodePtr tableNode = xmlNewChild(_currentModelNode, 0, (
const xmlChar*)
"RegressionModel", 0);
2280 _currentNode = tableNode;
2288 void PMMLlib::AddRegressionTable(
double intercept)
2293 xmlNodePtr tableNode = xmlNewChild(_currentModelNode, 0, (
const xmlChar*)
"RegressionTable", 0);
2296 ss << scientific << intercept;
2297 xmlNewProp(tableNode, (
const xmlChar*)
"intercept", (
const xmlChar*)(ss.str().c_str()) );
2299 _currentNode = tableNode;
2309 void PMMLlib::AddNumericPredictor(std::string neuronName,
2315 xmlNodePtr numPrecNode = xmlNewChild(_currentNode, 0, (
const xmlChar*)
"NumericPredictor", 0);
2316 xmlNewProp(numPrecNode, (
const xmlChar*)
"name", (
const xmlChar*)(neuronName.c_str()) );
2317 ss.str(
""); ss << exponent;
2318 xmlNewProp(numPrecNode, (
const xmlChar*)
"exponent", (
const xmlChar*)(ss.str().c_str()) );
2319 ss.str(
""); ss << scientific << coefficient;
2320 xmlNewProp(numPrecNode, (
const xmlChar*)
"coefficient", (
const xmlChar*)(ss.str().c_str()) );
2329 void PMMLlib::AddPredictorTerm(
double coefficient,
2330 std::vector<std::string> fieldRef)
2334 xmlNodePtr predTermNode = xmlNewChild(_currentNode, 0, (
const xmlChar*)
"PredictorTerm", 0);
2335 ss.str(
""); ss << scientific << coefficient;
2336 xmlNewProp(predTermNode, (
const xmlChar*)
"coefficient", (
const xmlChar*)(ss.str().c_str()) );
2337 vector<string>::iterator it;
2338 for(it=fieldRef.begin() ; it!=fieldRef.end() ; it++)
2340 xmlNodePtr fieldRefNode = xmlNewChild(predTermNode, 0, (
const xmlChar*)
"FieldRef", 0);
2341 ss.str(
""); ss << (*it);
2342 xmlNewProp(fieldRefNode, (
const xmlChar*)
"field", (
const xmlChar*)(ss.str().c_str()) );
2351 bool PMMLlib::HasIntercept()
2355 xmlNodePtr tableNode = GetChildByName(_currentModelNode,
"RegressionTable");
2356 if ( tableNode == NULL )
2358 xmlChar *xp = _stringToXmlChar(
"intercept");
2360 attr = xmlGetProp(tableNode, xp);
2376 double PMMLlib::GetRegressionTableIntercept()
2380 xmlNodePtr tableNode = GetChildByName(_currentModelNode,
"RegressionTable");
2381 if ( tableNode == NULL )
2383 string strValue = _getProp(tableNode,
string(
"intercept") );
2384 return atof(strValue.c_str());
2392 int PMMLlib::GetNumericPredictorNb()
2397 xmlNodePtr tableNode = GetChildByName(_currentModelNode,
"RegressionTable");
2398 if ( tableNode == NULL )
2400 xmlNodePtr numPredNodes = tableNode->children;
2401 while (numPredNodes != NULL )
2403 if (
string((
const char*)(numPredNodes->name)) ==
"NumericPredictor" )
2405 numPredNodes = numPredNodes->next;
2415 int PMMLlib::GetPredictorTermNb()
2419 xmlNodePtr tableNode = GetChildByName(_currentModelNode,
"RegressionTable");
2420 if ( tableNode == NULL )
2422 xmlNodePtr numPredNodes = tableNode->children;
2423 while ( numPredNodes != NULL )
2425 if (
string((
const char*)(numPredNodes->name)) ==
"PredictorTerm" )
2427 numPredNodes = numPredNodes->next;
2438 std::string PMMLlib::GetNumericPredictorName(
int num_pred_index)
2442 xmlNodePtr numPredNodes = GetChildByName(_currentModelNode,
"RegressionTable");
2443 if ( numPredNodes == NULL )
2446 numPredNodes = GetChildByName(numPredNodes,
"NumericPredictor");
2447 if ( numPredNodes == NULL )
2450 for(
int i=0;
i<num_pred_index;
i++)
2452 numPredNodes = numPredNodes->next;
2453 if ( numPredNodes == NULL ||
2454 string((
const char*)(numPredNodes->name)) !=
"NumericPredictor" )
2457 strName = _getProp(numPredNodes,
string(
"name"));
2467 std::string PMMLlib::GetPredictorTermName(
int pred_term_index)
2471 xmlNodePtr fieldRefNodes = GetChildByName(_currentModelNode,
"RegressionTable");
2472 if ( fieldRefNodes == NULL )
2475 fieldRefNodes = GetChildByName(fieldRefNodes,
"PredictorTerm");
2476 if ( fieldRefNodes == NULL )
2479 for(
int i=0;
i<pred_term_index;
i++)
2481 fieldRefNodes = fieldRefNodes->next;
2482 if ( fieldRefNodes == NULL ||
2483 string((
const char*)(fieldRefNodes->name)) !=
"PredictorTerm" )
2487 fieldRefNodes = fieldRefNodes->children;
2488 while (fieldRefNodes != NULL)
2490 strName += _getProp(fieldRefNodes,
string(
"field"));
2491 fieldRefNodes = fieldRefNodes->next;
2503 double PMMLlib::GetNumericPredictorCoefficient(
int num_pred_index)
2508 xmlNodePtr numPredNodes = GetChildByName(_currentModelNode,
"RegressionTable");
2509 if ( numPredNodes == NULL )
2511 numPredNodes = GetChildByName(numPredNodes,
"NumericPredictor");
2512 if ( numPredNodes == NULL )
2515 for(
int i=0;
i<num_pred_index;
i++)
2517 numPredNodes = numPredNodes->next;
2518 if ( numPredNodes == NULL ||
2519 string((
const char*)(numPredNodes->name)) !=
"NumericPredictor" )
2522 string strValue = _getProp(numPredNodes,
string(
"coefficient"));
2523 coef = atof(strValue.c_str());
2534 double PMMLlib::GetPredictorTermCoefficient(
int pred_term_index)
2539 xmlNodePtr predTermNodes = GetChildByName(_currentModelNode,
"RegressionTable");
2540 if ( predTermNodes == NULL )
2542 predTermNodes = GetChildByName(predTermNodes,
"PredictorTerm");
2543 if ( predTermNodes == NULL )
2546 for(
int i=0;
i<pred_term_index;
i++)
2548 predTermNodes = predTermNodes->next;
2549 if ( predTermNodes == NULL ||
2550 string((
const char*)(predTermNodes->name)) !=
"PredictorTerm" )
2553 string strValue = _getProp(predTermNodes,
string(
"coefficient"));
2554 coef = atof(strValue.c_str());
2564 int PMMLlib::GetPredictorTermFieldRefNb(
int index)
2569 xmlNodePtr fieldRefNodes = GetChildByName(_currentModelNode,
"RegressionTable");
2570 if ( fieldRefNodes == NULL )
2572 fieldRefNodes = GetChildByName(fieldRefNodes,
"PredictorTerm");
2573 if ( fieldRefNodes == NULL )
2576 for(
int i=0;
i<index;
i++)
2578 fieldRefNodes = fieldRefNodes->next;
2579 if ( fieldRefNodes == NULL ||
2580 string((
const char*)(fieldRefNodes->name)) !=
"PredictorTerm" )
2583 fieldRefNodes = fieldRefNodes->children;
2584 while (fieldRefNodes != NULL)
2587 fieldRefNodes = fieldRefNodes->next;
2600 std::string PMMLlib::GetPredictorTermFieldRefName(
int pred_term_index,
int field_index)
2605 xmlNodePtr fieldRefNodes = GetChildByName(_currentModelNode,
"RegressionTable");
2606 if ( fieldRefNodes == NULL )
2608 fieldRefNodes = GetChildByName(fieldRefNodes,
"PredictorTerm");
2609 if ( fieldRefNodes == NULL )
2612 for(
int i=0;
i<pred_term_index;
i++)
2614 fieldRefNodes = fieldRefNodes->next;
2615 if ( fieldRefNodes == NULL ||
2616 string((
const char*)(fieldRefNodes->name)) !=
"PredictorTerm" )
2619 fieldRefNodes = fieldRefNodes->children;
2620 if ( fieldRefNodes == NULL )
2623 for(
int i=0;
i<field_index;
i++)
2625 fieldRefNodes = fieldRefNodes->next;
2626 if ( fieldRefNodes == NULL )
2629 strName = _getProp(fieldRefNodes,
string(
"field"));
2640 void PMMLlib::ExportLinearRegressionCpp(std::string file,
2641 std::string functionName,
2647 ofstream exportfile(file.c_str());
2649 exportfile <<
"void " << functionName <<
"(double *param, double *res)" << endl;
2650 exportfile <<
"{" << endl;
2652 exportfile <<
" ////////////////////////////// " << endl;
2653 exportfile <<
" //" << endl;
2655 header =
" // " + header;
2657 while ((pos = header.find(
"\n", pos)) != std::string::npos)
2659 header.replace(pos, 1,
"\n //");
2662 exportfile << header << endl;
2663 exportfile <<
" //" << endl;
2664 exportfile <<
" ////////////////////////////// " << endl << endl;
2666 double intercept = 0.0;
2667 if ( HasIntercept() )
2669 exportfile <<
" // Intercept"<< endl;
2670 intercept = GetRegressionTableIntercept();
2673 exportfile <<
" // No Intercept"<< endl;
2674 exportfile <<
" double y = " << intercept <<
";";
2675 exportfile << endl << endl;
2677 int nPred = GetNumericPredictorNb();
2678 for (
int i=0;
i<nPred;
i++)
2680 exportfile <<
" // Attribute : " << GetNumericPredictorName(
i) << endl;
2681 exportfile <<
" y += param["<<
i<<
"]*" << GetNumericPredictorCoefficient(
i) <<
";";
2682 exportfile << endl << endl;
2684 nPred = GetPredictorTermNb();
2685 for (
int i=0;
i<nPred;
i++)
2687 exportfile <<
" // Attribute : " << GetPredictorTermName(
i) << endl;
2688 exportfile <<
" y += param["<<(
i+nPred)<<
"]*" << GetPredictorTermCoefficient(
i) <<
";";
2689 exportfile << endl << endl;
2692 exportfile <<
" // Return the value"<< endl;
2693 exportfile <<
" res[0] = y;" << endl;
2694 exportfile <<
"}" << endl;
2705 void PMMLlib::ExportLinearRegressionFortran(std::string file,
2706 std::string functionName,
2711 int nNumPred = GetNumericPredictorNb();
2712 int nPredTerm = GetPredictorTermNb();
2713 vector<string>strParam(nNumPred+nPredTerm);
2714 for(
int i=0;
i<(nNumPred+nPredTerm);
i++)
2720 ofstream exportfile(file.c_str());
2722 exportfile <<
" SUBROUTINE " << functionName <<
"(";
2723 for(
int i=0;
i<(nNumPred+nPredTerm);
i++)
2725 exportfile << strParam[
i] <<
", ";
2727 exportfile <<
"RES)" << endl;
2730 exportfile <<
"C --- *********************************************" << endl;
2731 exportfile <<
"C --- " << endl;
2733 header =
"C --- " + header;
2735 while ((pos = header.find(
"\n", pos)) != std::string::npos)
2737 header.replace(pos, 1,
"\nC --- ");
2740 exportfile << header << endl;
2741 exportfile <<
"C --- " << endl;
2742 exportfile <<
"C --- *********************************************" << endl << endl;
2744 exportfile <<
" IMPLICIT DOUBLE PRECISION (P)" << endl;
2745 exportfile <<
" DOUBLE PRECISION RES" << endl;
2746 exportfile <<
" DOUBLE PRECISION Y" << endl;
2749 double intercept = 0.0;
2750 if ( HasIntercept() )
2752 exportfile <<
"C --- Intercept"<< endl;
2753 intercept = GetRegressionTableIntercept();
2756 exportfile <<
"C --- No Intercept"<< endl;
2757 exportfile <<
" Y = " << intercept <<
";";
2758 exportfile << endl << endl;
2760 for (
int i=0;
i<nNumPred;
i++)
2762 exportfile <<
"C --- Attribute : " << GetNumericPredictorName(
i) << endl;
2763 exportfile <<
" Y += P["<<
i<<
"]*" << GetNumericPredictorCoefficient(
i) <<
";";
2764 exportfile << endl << endl;
2767 for (
int i=0;
i<nPredTerm;
i++)
2769 exportfile <<
"C --- Attribute : " << GetPredictorTermName(
i) << endl;
2770 exportfile <<
" Y += P["<<(
i+nNumPred)<<
"]*" << GetPredictorTermCoefficient(
i) <<
";";
2771 exportfile << endl << endl;
2774 exportfile <<
"C --- Return the value"<< endl;
2775 exportfile <<
" RES = Y " << endl;
2776 exportfile <<
" RETURN" << endl;
2777 exportfile <<
" END" << endl;
2788 void PMMLlib::ExportLinearRegressionPython(std::string file,
2789 std::string functionName,
2792 string str(ExportLinearRegressionPyStr(functionName, header));
2794 ofstream exportfile(file.c_str());
2805 std::string PMMLlib::ExportLinearRegressionPyStr(std::string functionName,
2813 out <<
"#!/usr/bin/env python3" << endl;
2814 out <<
"# -*- coding: utf-8 -*-" << endl;
2818 out <<
"def " << functionName <<
"(param):" << endl;
2822 out <<
" ############################## " << endl;
2823 out <<
" # " << endl;
2825 header =
" # " + header;
2827 while ((pos = header.find(
"\n", pos)) != std::string::npos)
2829 header.replace(pos, 1,
"\n #");
2832 out << header << endl;
2833 out <<
" # " << endl;
2834 out <<
" ############################## " << endl << endl;
2836 double intercept = 0.0;
2837 if ( HasIntercept() )
2839 out <<
" # Intercept"<< endl;
2840 intercept = GetRegressionTableIntercept();
2843 out <<
" # No Intercept"<< endl;
2844 out <<
" y = " << intercept <<
";";
2845 out << endl << endl;
2847 int nPred = GetNumericPredictorNb();
2848 for (
int i=0;
i<nPred;
i++)
2850 out <<
" # Attribute : " << GetNumericPredictorName(
i) << endl;
2851 out <<
" y += param["<<
i<<
"]*" << GetNumericPredictorCoefficient(
i) <<
";";
2852 out << endl << endl;
2854 nPred = GetPredictorTermNb();
2855 for (
int i=0;
i<nPred;
i++)
2857 out <<
" # Attribute : " << GetPredictorTermName(
i) << endl;
2858 out <<
" y += param["<<(
i+nPred)<<
"]*" << GetPredictorTermCoefficient(
i) <<
";";
2859 out << endl << endl;
2862 out <<
" # Return the value"<< endl;
2863 out <<
" return [y];" << endl;
2873 std::string PMMLlib::ReadRegressionStructure()
2877 string structure(
"");
2878 string structureActive(
"");
2879 string structurePredicted(
"@");
2881 xmlNodePtr mNode = GetChildByName(_currentModelNode,
"MiningSchema");
2882 if ( mNode != NULL )
2884 xmlNodePtr dNode = GetChildByName(mNode,
"MiningField");
2885 while (dNode != NULL)
2887 string name = _getProp(dNode,
string(
"name"));
2888 string usage = _getProp(dNode,
string(
"usageType"));
2889 if ( usage ==
"active" )
2891 structureActive += name;
2892 structureActive +=
":";
2894 else if ( usage ==
"predicted" )
2896 structurePredicted += name;
2897 structurePredicted +=
":";
2900 dNode = dNode->next;
2903 if ( structureActive.length() > 0 )
2904 structureActive.erase(structureActive.size()-1);
2905 structurePredicted.erase(structurePredicted.size()-1);
2907 std::ostringstream oss;
2909 structure = structureActive +
"," + oss.str() +
"," + structurePredicted;
Header de la classe PMMLlib.
std::string NumberToString(T Number)