10 nodeType =
"DecisionTreeTripleFeatureNode";
23 if( (x[ featureIndexA ] - x[ featureIndexB ]) >= (x[ featureIndexC ] - x[ featureIndexB ]) )
return true;
55 for(UINT i=0; i<depth; i++) tab +=
"\t";
57 stream << tab <<
"depth: " << depth;
58 stream <<
" nodeSize: " << nodeSize;
59 stream <<
" featureIndexA: " << featureIndexA;
60 stream <<
" featureIndexB: " << featureIndexB;
61 stream <<
" featureIndexC: " << featureIndexC;
62 stream <<
" isLeafNode: " << isLeafNode << endl;
64 stream << tab <<
"ClassProbabilities: ";
65 for(UINT i=0; i<classProbabilities.size(); i++){
66 stream << classProbabilities[i] <<
"\t";
70 if( leftChild != NULL ){
71 stream << tab <<
"LeftChild: " << endl;
75 if( rightChild != NULL ){
76 stream << tab <<
"RightChild: " << endl;
93 node->isLeafNode = isLeafNode;
94 node->nodeID = nodeID;
95 node->predictedNodeID = predictedNodeID;
96 node->nodeSize = nodeSize;
97 node->featureIndexA = featureIndexA;
98 node->featureIndexB = featureIndexB;
99 node->featureIndexC = featureIndexC;
100 node->classProbabilities = classProbabilities;
105 node->leftChild->setParent( node );
111 node->rightChild->setParent( node );
122 return featureIndexA;
126 return featureIndexB;
130 return featureIndexC;
134 this->nodeSize = nodeSize;
135 this->featureIndexA = featureIndexA;
136 this->featureIndexB = featureIndexB;
137 this->featureIndexC = featureIndexC;
138 this->classProbabilities = classProbabilities;
142 bool DecisionTreeTripleFeatureNode::computeBestSpiltBestIterativeSpilt(
const UINT &numSplittingSteps,
const ClassificationData &trainingData,
const vector< UINT > &features,
const vector< UINT > &classLabels, UINT &featureIndex,
double &minError ){
144 return computeBestSpilt( numSplittingSteps, trainingData, features, classLabels, featureIndex, minError);
147 bool DecisionTreeTripleFeatureNode::computeBestSpiltBestRandomSpilt(
const UINT &numSplittingSteps,
const ClassificationData &trainingData,
const vector< UINT > &features,
const vector< UINT > &classLabels, UINT &featureIndex,
double &minError ){
149 return computeBestSpilt( numSplittingSteps, trainingData, features, classLabels, featureIndex, minError);
152 bool DecisionTreeTripleFeatureNode::computeBestSpilt(
const UINT &numSplittingSteps,
const ClassificationData &trainingData,
const vector< UINT > &features,
const vector< UINT > &classLabels, UINT &featureIndex,
double &minError ){
155 const UINT N = (UINT)features.size();
156 const UINT K = (UINT)classLabels.size();
158 if( N == 0 )
return false;
160 minError = numeric_limits<double>::max();
162 UINT bestFeatureIndexA = 0;
163 UINT bestFeatureIndexB = 0;
164 UINT bestFeatureIndexC = 0;
166 double giniIndexL = 0;
167 double giniIndexR = 0;
170 vector< UINT > groupIndex(M);
171 VectorDouble groupCounter(2,0);
172 vector< MinMax > ranges = trainingData.
getRanges();
177 UINT numRandomFeatures = numSplittingSteps > N ? N : numSplittingSteps;
178 vector< UINT > randomFeatures = random.
getRandomSubset( 0, N, numRandomFeatures );
181 for(UINT n=0; n<numRandomFeatures; n++){
184 featureIndexB = features[ randomFeatures[n] ];
185 featureIndexA = features[ randomFeatures[ random.
getRandomNumberInt(0,numRandomFeatures) ] ];
186 featureIndexC = features[ randomFeatures[ random.
getRandomNumberInt(0,numRandomFeatures) ] ];
189 groupCounter[0] = groupCounter[1] = 0;
190 classProbabilities.setAllValues(0);
191 for(UINT i=0; i<M; i++){
192 groupIndex[i] =
predict( trainingData[i].getSample() ) ? 1 : 0;
193 groupCounter[ groupIndex[i] ]++;
194 classProbabilities[ getClassLabelIndexValue(trainingData[i].getClassLabel(),classLabels) ][ groupIndex[i] ]++;
198 for(UINT k=0; k<K; k++){
199 classProbabilities[k][0] = groupCounter[0]>0 ? classProbabilities[k][0]/groupCounter[0] : 0;
200 classProbabilities[k][1] = groupCounter[1]>0 ? classProbabilities[k][1]/groupCounter[1] : 0;
204 giniIndexL = giniIndexR = 0;
205 for(UINT k=0; k<K; k++){
206 giniIndexL += classProbabilities[k][0] * (1.0-classProbabilities[k][0]);
207 giniIndexR += classProbabilities[k][1] * (1.0-classProbabilities[k][1]);
209 weightL = groupCounter[0]/M;
210 weightR = groupCounter[1]/M;
211 error = (giniIndexL*weightL) + (giniIndexR*weightR);
214 if( error < minError ){
216 bestFeatureIndexA = featureIndexA;
217 bestFeatureIndexB = featureIndexB;
218 bestFeatureIndexC = featureIndexC;
222 trainingLog <<
"Best features indexs: [" << bestFeatureIndexA <<
"," << bestFeatureIndexB <<
"," << bestFeatureIndexC <<
"] Min Error: " << minError << endl;
225 featureIndex = bestFeatureIndexB;
228 set(M,bestFeatureIndexA,bestFeatureIndexB,bestFeatureIndexC,trainingData.getClassProbabilities(classLabels));
235 if( !file.is_open() )
237 errorLog <<
"saveParametersToFile(fstream &file) - File is not open!" << endl;
243 errorLog <<
"saveParametersToFile(fstream &file) - Failed to save DecisionTreeNode parameters to file!" << endl;
248 file <<
"FeatureIndexA: " << featureIndexA << endl;
249 file <<
"FeatureIndexB: " << featureIndexB << endl;
250 file <<
"FeatureIndexC: " << featureIndexC << endl;
259 errorLog <<
"loadParametersFromFile(fstream &file) - File is not open!" << endl;
265 errorLog <<
"loadParametersFromFile(fstream &file) - Failed to load DecisionTreeNode parameters from file!" << endl;
272 if( word !=
"FeatureIndexA:" ){
273 errorLog <<
"loadParametersFromFile(fstream &file) - Failed to find FeatureIndexA header!" << endl;
276 file >> featureIndexA;
279 if( word !=
"FeatureIndexB:" ){
280 errorLog <<
"loadParametersFromFile(fstream &file) - Failed to find FeatureIndexB header!" << endl;
283 file >> featureIndexB;
286 if( word !=
"FeatureIndexC:" ){
287 errorLog <<
"loadParametersFromFile(fstream &file) - Failed to find FeatureIndexC header!" << endl;
290 file >> featureIndexC;
virtual Node * deepCopyNode() const
This file implements a DecisionTreeTripleFeatureNode, which is a specific type of node used for a Dec...
virtual bool saveParametersToFile(fstream &file) const
std::vector< unsigned int > getRandomSubset(const unsigned int startRange, const unsigned int endRange, const unsigned int subsetSize)
UINT getNumSamples() const
virtual bool getModel(ostream &stream) const
DecisionTreeTripleFeatureNode * deepCopy() const
virtual bool print() const
virtual bool loadParametersFromFile(fstream &file)
UINT getFeatureIndexB() const
virtual bool getModel(ostream &stream) const
int getRandomNumberInt(int minRange, int maxRange)
virtual bool saveParametersToFile(fstream &file) const
UINT getFeatureIndexC() const
virtual bool loadParametersFromFile(fstream &file)
bool set(const UINT nodeSize, const UINT featureIndexA, const UINT featureIndexB, const UINT featureIndexC, const VectorDouble &classProbabilities)
vector< MinMax > getRanges() const
virtual ~DecisionTreeTripleFeatureNode()
DecisionTreeTripleFeatureNode()
virtual Node * deepCopyNode() const
virtual bool predict(const VectorDouble &x)
UINT getFeatureIndexA() const