28 DecisionTree::DecisionTree(
const DecisionTreeNode &decisionTreeNode,
const UINT minNumSamplesPerNode,
const UINT maxDepth,
const bool removeFeaturesAtEachSpilt,
const UINT trainingMode,
const UINT numSplittingSteps,
const bool useScaling)
31 this->decisionTreeNode = NULL;
32 this->minNumSamplesPerNode = minNumSamplesPerNode;
33 this->maxDepth = maxDepth;
34 this->removeFeaturesAtEachSpilt = removeFeaturesAtEachSpilt;
35 this->trainingMode = trainingMode;
36 this->numSplittingSteps = numSplittingSteps;
37 this->useScaling = useScaling;
38 this->supportsNullRejection =
true;
39 Classifier::classType =
"DecisionTree";
40 classifierType = Classifier::classType;
41 classifierMode = STANDARD_CLASSIFIER_MODE;
42 Classifier::debugLog.setProceedingText(
"[DEBUG DecisionTree]");
43 Classifier::errorLog.setProceedingText(
"[ERROR DecisionTree]");
44 Classifier::trainingLog.setProceedingText(
"[TRAINING DecisionTree]");
45 Classifier::warningLog.setProceedingText(
"[WARNING DecisionTree]");
47 this->decisionTreeNode = decisionTreeNode.
deepCopy();
53 decisionTreeNode = NULL;
54 Classifier::classType =
"DecisionTree";
55 classifierType = Classifier::classType;
56 classifierMode = STANDARD_CLASSIFIER_MODE;
57 Classifier:: debugLog.setProceedingText(
"[DEBUG DecisionTree]");
58 Classifier::errorLog.setProceedingText(
"[ERROR DecisionTree]");
59 Classifier::trainingLog.setProceedingText(
"[TRAINING DecisionTree]");
60 Classifier::warningLog.setProceedingText(
"[WARNING DecisionTree]");
68 if( decisionTreeNode != NULL ){
69 delete decisionTreeNode;
70 decisionTreeNode = NULL;
85 if( this->decisionTreeNode != NULL ){
86 delete decisionTreeNode;
87 decisionTreeNode = NULL;
91 this->minNumSamplesPerNode = rhs.minNumSamplesPerNode;
92 this->maxDepth = rhs.maxDepth;
93 this->removeFeaturesAtEachSpilt = rhs.removeFeaturesAtEachSpilt;
94 this->trainingMode = rhs.trainingMode;
95 this->numSplittingSteps = rhs.numSplittingSteps;
96 this->nodeClusters = rhs.nodeClusters;
106 if( classifier == NULL )
return false;
121 if( this->decisionTreeNode != NULL ){
122 delete decisionTreeNode;
123 decisionTreeNode = NULL;
127 this->minNumSamplesPerNode = ptr->minNumSamplesPerNode;
128 this->maxDepth = ptr->maxDepth;
129 this->removeFeaturesAtEachSpilt = ptr->removeFeaturesAtEachSpilt;
130 this->trainingMode = ptr->trainingMode;
131 this->numSplittingSteps = ptr->numSplittingSteps;
132 this->nodeClusters = ptr->nodeClusters;
145 if( decisionTreeNode == NULL ){
146 Classifier::errorLog <<
"train_(ClassificationData &trainingData) - The decision tree node has not been set! You must set this first before training a model." << endl;
155 Classifier::errorLog <<
"train_(ClassificationData &trainingData) - Training data has zero samples!" << endl;
159 numInputDimensions = N;
167 trainingData.
scale(0, 1);
172 if( useNullRejection ){
173 trainingDataCopy = trainingData;
177 vector< UINT > features(N);
178 for(UINT i=0; i<N; i++){
184 tree = buildTree( trainingData, NULL, features, classLabels, nodeID );
188 Classifier::errorLog <<
"train_(ClassificationData &trainingData) - Failed to build tree!" << endl;
196 if( useNullRejection ){
197 VectorDouble classLikelihoods( numClasses );
198 vector< UINT > predictions(M);
199 VectorDouble distances(M);
200 VectorDouble classCounter( numClasses, 0 );
203 for(UINT i=0; i<M; i++){
205 if( !tree->
predict( trainingDataCopy[i].getSample(), classLikelihoods ) ){
206 Classifier::errorLog <<
"predict_(VectorDouble &inputVector) - Failed to predict!" << endl;
212 distances[i] = getNodeDistance(trainingDataCopy[i].getSample(), tree->
getPredictedNodeID() );
214 classCounter[ predictions[i] ]++;
218 classClusterMean.clear();
219 classClusterStdDev.clear();
220 classClusterMean.resize( numClasses, 0 );
221 classClusterStdDev.resize( numClasses, 0.01 );
223 for(UINT i=0; i<M; i++){
224 classClusterMean[ predictions[i] ] += distances[ i ];
226 for(UINT k=0; k<numClasses; k++){
227 classClusterMean[k] /= MAX( classCounter[k], 1 );
231 for(UINT i=0; i<M; i++){
232 classClusterStdDev[ predictions[i] ] += MLBase::SQR( distances[ i ] - classClusterMean[ predictions[i] ] );
234 for(UINT k=0; k<numClasses; k++){
235 classClusterStdDev[k] = sqrt( classClusterStdDev[k] / MAX( classCounter[k], 1 ) );
248 predictedClassLabel = 0;
253 Classifier::errorLog <<
"predict_(VectorDouble &inputVector) - Model Not Trained!" << endl;
258 Classifier::errorLog <<
"predict_(VectorDouble &inputVector) - DecisionTree pointer is null!" << endl;
262 if( inputVector.size() != numInputDimensions ){
263 Classifier::errorLog <<
"predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() <<
") does not match the num features in the model (" << numInputDimensions << endl;
269 for(UINT n=0; n<numInputDimensions; n++){
270 inputVector[n] =
scale(inputVector[n], ranges[n].minValue, ranges[n].maxValue, 0, 1);
274 if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0);
275 if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0);
278 if( !tree->
predict( inputVector, classLikelihoods ) ){
279 Classifier::errorLog <<
"predict_(VectorDouble &inputVector) - Failed to predict!" << endl;
287 for(UINT k=0; k<numClasses; k++){
288 if( classLikelihoods[k] > maxLikelihood ){
289 maxLikelihood = classLikelihoods[k];
295 if( useNullRejection ){
300 if( grt_isnan(leafDistance) ){
301 Classifier::errorLog <<
"predict_(VectorDouble &inputVector) - Failed to match leaf node ID to compute node distance!" << endl;
306 std::fill(classDistances.begin(),classDistances.end(),0);
307 classDistances[ maxIndex ] = leafDistance;
310 if( leafDistance <= nullRejectionThresholds[ maxIndex ] ){
311 predictedClassLabel = classLabels[ maxIndex ];
312 }
else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
316 predictedClassLabel = classLabels[ maxIndex ];
328 nodeClusters.clear();
345 Classifier::warningLog <<
"recomputeNullRejectionThresholds() - Failed to recompute null rejection thresholds, the model has not been trained!" << endl;
349 if( !useNullRejection ){
350 Classifier::warningLog <<
"recomputeNullRejectionThresholds() - Failed to recompute null rejection thresholds, null rejection is not enabled!" << endl;
354 nullRejectionThresholds.resize( numClasses );
357 for(UINT k=0; k<numClasses; k++){
358 nullRejectionThresholds[k] = classClusterMean[k] + (classClusterStdDev[k]*nullRejectionCoeff);
368 Classifier::errorLog <<
"saveModelToFile(fstream &file) - The file is not open!" << endl;
373 file <<
"GRT_DECISION_TREE_MODEL_FILE_V4.0\n";
377 Classifier::errorLog <<
"saveModelToFile(fstream &file) - Failed to save classifier base settings to file!" << endl;
381 if( decisionTreeNode != NULL ){
382 file <<
"DecisionTreeNodeType: " << decisionTreeNode->
getNodeType() << endl;
384 Classifier::errorLog <<
"saveModelToFile(fstream &file) - Failed to save decisionTreeNode settings to file!" << endl;
388 file <<
"DecisionTreeNodeType: " <<
"NULL" << endl;
391 file <<
"MinNumSamplesPerNode: " << minNumSamplesPerNode << endl;
392 file <<
"MaxDepth: " << maxDepth << endl;
393 file <<
"RemoveFeaturesAtEachSpilt: " << removeFeaturesAtEachSpilt << endl;
394 file <<
"TrainingMode: " << trainingMode << endl;
395 file <<
"NumSplittingSteps: " << numSplittingSteps << endl;
396 file <<
"TreeBuilt: " << (tree != NULL ? 1 : 0) << endl;
401 Classifier::errorLog <<
"saveModelToFile(fstream &file) - Failed to save tree to file!" << endl;
406 if( useNullRejection ){
408 file <<
"ClassClusterMean:";
409 for(UINT k=0; k<numClasses; k++){
410 file <<
" " << classClusterMean[k];
414 file <<
"ClassClusterStdDev:";
415 for(UINT k=0; k<numClasses; k++){
416 file <<
" " << classClusterStdDev[k];
420 file <<
"NumNodes: " << nodeClusters.size() << endl;
421 file <<
"NodeClusters:\n";
423 std::map< UINT, VectorDouble >::const_iterator iter = nodeClusters.begin();
425 while( iter != nodeClusters.end() ){
431 for(UINT j=0; j<numInputDimensions; j++){
432 file <<
" " << iter->second[j];
449 if( decisionTreeNode != NULL ){
450 delete decisionTreeNode;
451 decisionTreeNode = NULL;
454 if( !file.is_open() )
456 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not open file to load model" << endl;
464 if( word ==
"GRT_DECISION_TREE_MODEL_FILE_V1.0" ){
468 if( word ==
"GRT_DECISION_TREE_MODEL_FILE_V2.0" ){
469 return loadLegacyModelFromFile_v2( file );
472 if( word ==
"GRT_DECISION_TREE_MODEL_FILE_V3.0" ){
473 return loadLegacyModelFromFile_v3( file );
477 if( word !=
"GRT_DECISION_TREE_MODEL_FILE_V4.0" ){
478 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find Model File Header" << endl;
484 Classifier::errorLog <<
"loadModelFromFile(string filename) - Failed to load base settings from file!" << endl;
489 if(word !=
"DecisionTreeNodeType:"){
490 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the DecisionTreeNodeType!" << endl;
495 if( word !=
"NULL" ){
499 if( decisionTreeNode == NULL ){
500 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not create new DecisionTreeNode from type: " << word << endl;
505 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to load decisionTreeNode settings from file!" << endl;
509 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to load decisionTreeNode! DecisionTreeNodeType is NULL!" << endl;
514 if(word !=
"MinNumSamplesPerNode:"){
515 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MinNumSamplesPerNode!" << endl;
518 file >> minNumSamplesPerNode;
521 if(word !=
"MaxDepth:"){
522 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MaxDepth!" << endl;
528 if(word !=
"RemoveFeaturesAtEachSpilt:"){
529 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the RemoveFeaturesAtEachSpilt!" << endl;
532 file >> removeFeaturesAtEachSpilt;
535 if(word !=
"TrainingMode:"){
536 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TrainingMode!" << endl;
539 file >> trainingMode;
542 if(word !=
"NumSplittingSteps:"){
543 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NumSplittingSteps!" << endl;
546 file >> numSplittingSteps;
549 if(word !=
"TreeBuilt:"){
550 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TreeBuilt!" << endl;
558 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the Tree!" << endl;
567 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to create new DecisionTreeNode!" << endl;
571 tree->setParent( NULL );
574 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to load tree from file!" << endl;
579 if( useNullRejection ){
582 classClusterMean.resize( numClasses );
583 classClusterStdDev.resize( numClasses );
586 if(word !=
"ClassClusterMean:"){
587 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the ClassClusterMean header!" << endl;
590 for(UINT k=0; k<numClasses; k++){
591 file >> classClusterMean[k];
595 if(word !=
"ClassClusterStdDev:"){
596 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the ClassClusterStdDev header!" << endl;
599 for(UINT k=0; k<numClasses; k++){
600 file >> classClusterStdDev[k];
604 if(word !=
"NumNodes:"){
605 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NumNodes header!" << endl;
611 if(word !=
"NodeClusters:"){
612 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NodeClusters header!" << endl;
617 VectorDouble cluster( numInputDimensions );
618 for(UINT i=0; i<numNodes; i++){
623 for(UINT j=0; j<numInputDimensions; j++){
628 nodeClusters[ nodeID ] = cluster;
636 maxLikelihood = DEFAULT_NULL_LIKELIHOOD_VALUE;
637 bestDistance = DEFAULT_NULL_DISTANCE_VALUE;
638 classLikelihoods.resize(numClasses,DEFAULT_NULL_LIKELIHOOD_VALUE);
639 classDistances.resize(numClasses,DEFAULT_NULL_DISTANCE_VALUE);
664 if( decisionTreeNode == NULL ){
668 return decisionTreeNode->
deepCopy();
677 if( decisionTreeNode != NULL ){
678 delete decisionTreeNode;
679 decisionTreeNode = NULL;
681 this->decisionTreeNode = node.
deepCopy();
711 node->initNode( parent, depth, nodeID );
714 if( trainingData.
getNumClasses() == 1 || features.size() == 0 || M < minNumSamplesPerNode || depth >= maxDepth ){
720 if( useNullRejection ){
721 nodeClusters[ nodeID ] = trainingData.
getMean();
724 Classifier::trainingLog <<
"Reached leaf node. Depth: " << depth <<
" NumSamples: " << trainingData.
getNumSamples() << endl;
730 UINT featureIndex = 0;
733 if( !node->
computeBestSpilt( trainingMode, numSplittingSteps, trainingData, features, classLabels, featureIndex, minError ) ){
738 Classifier::trainingLog <<
"Depth: " << depth <<
" FeatureIndex: " << featureIndex <<
" MinError: " << minError << endl;
741 if( removeFeaturesAtEachSpilt ){
742 for(
size_t i=0; i<features.size(); i++){
743 if( features[i] == featureIndex ){
744 features.erase( features.begin()+i );
758 for(UINT i=0; i<M; i++){
759 if( node->
predict( trainingData[i].getSample() ) ){
760 rhs.addSample(trainingData[i].getClassLabel(), trainingData[i].getSample());
761 }
else lhs.addSample(trainingData[i].getClassLabel(), trainingData[i].getSample());
765 trainingData.
clear();
768 UINT leftNodeID = ++nodeID;
769 UINT rightNodeID = ++nodeID;
772 node->setLeftChild( buildTree( lhs, node, features, classLabels, leftNodeID ) );
773 node->setRightChild( buildTree( rhs, node, features, classLabels, rightNodeID ) );
776 if( useNullRejection ){
777 nodeClusters[ leftNodeID ] = lhs.getMean();
778 nodeClusters[ rightNodeID ] = rhs.getMean();
784 double DecisionTree::getNodeDistance(
const VectorDouble &x,
const UINT nodeID ){
787 std::map< UINT,VectorDouble >::iterator iter = nodeClusters.find( nodeID );
790 if( iter == nodeClusters.end() )
return NAN;
793 return getNodeDistance( x, iter->second );
796 double DecisionTree::getNodeDistance(
const VectorDouble &x,
const VectorDouble &y ){
799 const size_t N = x.size();
801 for(
size_t i=0; i<N; i++){
802 distance += MLBase::SQR( x[i] - y[i] );
814 if(word !=
"NumFeatures:"){
815 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find NumFeatures!" << endl;
818 file >> numInputDimensions;
821 if(word !=
"NumClasses:"){
822 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find NumClasses!" << endl;
828 if(word !=
"UseScaling:"){
829 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find UseScaling!" << endl;
835 if(word !=
"UseNullRejection:"){
836 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find UseNullRejection!" << endl;
839 file >> useNullRejection;
844 ranges.resize( numInputDimensions );
847 if(word !=
"Ranges:"){
848 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the Ranges!" << endl;
851 for(UINT n=0; n<ranges.size(); n++){
852 file >> ranges[n].minValue;
853 file >> ranges[n].maxValue;
858 if(word !=
"NumSplittingSteps:"){
859 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NumSplittingSteps!" << endl;
862 file >> numSplittingSteps;
865 if(word !=
"MinNumSamplesPerNode:"){
866 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MinNumSamplesPerNode!" << endl;
869 file >> minNumSamplesPerNode;
872 if(word !=
"MaxDepth:"){
873 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MaxDepth!" << endl;
879 if(word !=
"RemoveFeaturesAtEachSpilt:"){
880 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the RemoveFeaturesAtEachSpilt!" << endl;
883 file >> removeFeaturesAtEachSpilt;
886 if(word !=
"TrainingMode:"){
887 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TrainingMode!" << endl;
890 file >> trainingMode;
893 if(word !=
"TreeBuilt:"){
894 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TreeBuilt!" << endl;
902 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the Tree!" << endl;
911 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to create new DecisionTreeNode!" << endl;
915 tree->setParent( NULL );
918 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to load tree from file!" << endl;
926 bool DecisionTree::loadLegacyModelFromFile_v2( fstream &file ){
932 Classifier::errorLog <<
"loadModelFromFile(string filename) - Failed to load base settings from file!" << endl;
937 if(word !=
"NumSplittingSteps:"){
938 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NumSplittingSteps!" << endl;
941 file >> numSplittingSteps;
944 if(word !=
"MinNumSamplesPerNode:"){
945 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MinNumSamplesPerNode!" << endl;
948 file >> minNumSamplesPerNode;
951 if(word !=
"MaxDepth:"){
952 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MaxDepth!" << endl;
958 if(word !=
"RemoveFeaturesAtEachSpilt:"){
959 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the RemoveFeaturesAtEachSpilt!" << endl;
962 file >> removeFeaturesAtEachSpilt;
965 if(word !=
"TrainingMode:"){
966 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TrainingMode!" << endl;
969 file >> trainingMode;
972 if(word !=
"TreeBuilt:"){
973 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TreeBuilt!" << endl;
981 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the Tree!" << endl;
990 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to create new DecisionTreeNode!" << endl;
994 tree->setParent( NULL );
997 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to load tree from file!" << endl;
1005 maxLikelihood = DEFAULT_NULL_LIKELIHOOD_VALUE;
1006 bestDistance = DEFAULT_NULL_DISTANCE_VALUE;
1007 classLikelihoods.resize(numClasses,DEFAULT_NULL_LIKELIHOOD_VALUE);
1008 classDistances.resize(numClasses,DEFAULT_NULL_DISTANCE_VALUE);
1014 bool DecisionTree::loadLegacyModelFromFile_v3( fstream &file ){
1020 Classifier::errorLog <<
"loadModelFromFile(string filename) - Failed to load base settings from file!" << endl;
1025 if(word !=
"NumSplittingSteps:"){
1026 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NumSplittingSteps!" << endl;
1029 file >> numSplittingSteps;
1032 if(word !=
"MinNumSamplesPerNode:"){
1033 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MinNumSamplesPerNode!" << endl;
1036 file >> minNumSamplesPerNode;
1039 if(word !=
"MaxDepth:"){
1040 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the MaxDepth!" << endl;
1046 if(word !=
"RemoveFeaturesAtEachSpilt:"){
1047 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the RemoveFeaturesAtEachSpilt!" << endl;
1050 file >> removeFeaturesAtEachSpilt;
1053 if(word !=
"TrainingMode:"){
1054 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TrainingMode!" << endl;
1057 file >> trainingMode;
1060 if(word !=
"TreeBuilt:"){
1061 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the TreeBuilt!" << endl;
1068 if(word !=
"Tree:"){
1069 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the Tree!" << endl;
1078 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to create new DecisionTreeNode!" << endl;
1082 tree->setParent( NULL );
1085 Classifier::errorLog <<
"loadModelFromFile(fstream &file) - Failed to load tree from file!" << endl;
1090 if( useNullRejection ){
1093 classClusterMean.resize( numClasses );
1094 classClusterStdDev.resize( numClasses );
1097 if(word !=
"ClassClusterMean:"){
1098 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the ClassClusterMean header!" << endl;
1101 for(UINT k=0; k<numClasses; k++){
1102 file >> classClusterMean[k];
1106 if(word !=
"ClassClusterStdDev:"){
1107 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the ClassClusterStdDev header!" << endl;
1110 for(UINT k=0; k<numClasses; k++){
1111 file >> classClusterStdDev[k];
1115 if(word !=
"NumNodes:"){
1116 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NumNodes header!" << endl;
1122 if(word !=
"NodeClusters:"){
1123 Classifier::errorLog <<
"loadModelFromFile(string filename) - Could not find the NodeClusters header!" << endl;
1128 VectorDouble cluster( numInputDimensions );
1129 for(UINT i=0; i<numNodes; i++){
1134 for(UINT j=0; j<numInputDimensions; j++){
1139 nodeClusters[ nodeID ] = cluster;
1147 maxLikelihood = DEFAULT_NULL_LIKELIHOOD_VALUE;
1148 bestDistance = DEFAULT_NULL_DISTANCE_VALUE;
1149 classLikelihoods.resize(numClasses,DEFAULT_NULL_LIKELIHOOD_VALUE);
1150 classDistances.resize(numClasses,DEFAULT_NULL_DISTANCE_VALUE);
DecisionTree(const DecisionTreeNode &decisionTreeNode=DecisionTreeClusterNode(), const UINT minNumSamplesPerNode=5, const UINT maxDepth=10, const bool removeFeaturesAtEachSpilt=false, const UINT trainingMode=BEST_ITERATIVE_SPILT, const UINT numSplittingSteps=100, const bool useScaling=false)
This class implements a basic Decision Tree classifier. Decision Trees are conceptually simple classi...
virtual Node * deepCopyNode() const
virtual bool deepCopyFrom(const Classifier *classifier)
UINT getPredictedNodeID() const
VectorDouble getMean() const
vector< UINT > getClassLabels() const
static unsigned int getMaxIndex(const std::vector< double > &x)
bool copyBaseVariables(const Classifier *classifier)
virtual ~DecisionTree(void)
virtual bool loadFromFile(fstream &file)
UINT getNumDimensions() const
bool setLeafNode(const UINT nodeSize, const VectorDouble &classProbabilities)
virtual bool getModel(ostream &stream) const
bool loadBaseSettingsFromFile(fstream &file)
UINT getNumSamples() const
virtual bool saveToFile(fstream &file) const
virtual bool getModel(ostream &stream) const
UINT getNumClasses() const
virtual bool recomputeNullRejectionThresholds()
string getNodeType() const
virtual bool loadModelFromFile(fstream &file)
virtual bool train_(ClassificationData &trainingData)
bool saveBaseSettingsToFile(fstream &file) const
double scale(const double &x, const double &minSource, const double &maxSource, const double &minTarget, const double &maxTarget, const bool constrain=false)
bool loadLegacyModelFromFile_v1(fstream &file)
DecisionTreeNode * deepCopy() const
bool scale(const double minTarget, const double maxTarget)
DecisionTreeNode * deepCopyTree() const
bool setDecisionTreeNode(const DecisionTreeNode &node)
DecisionTreeNode * deepCopyDecisionTreeNode() const
virtual bool predict(const VectorDouble &x)
Node * createNewInstance() const
virtual bool predict(const VectorDouble &x, VectorDouble &classLikelihoods)
DecisionTree & operator=(const DecisionTree &rhs)
vector< MinMax > getRanges() const
virtual bool saveModelToFile(fstream &file) const
string getClassifierType() const
virtual bool predict_(VectorDouble &inputVector)
static Node * createInstanceFromString(string const &nodeType)
const DecisionTreeNode * getTree() const
virtual bool computeBestSpilt(const UINT &trainingMode, const UINT &numSplittingSteps, const ClassificationData &trainingData, const vector< UINT > &features, const vector< UINT > &classLabels, UINT &featureIndex, double &minError)