int main(int arc, char *argv[]) { //make tree DecisionTree *gameTree = new DecisionTree(); //current node Node *curr; string user; string question; string animal; string userInput = ""; int menu = 0; bool correct = true; //flag to determine if the user put in correct input cout << "Welcome to Animal Guessing Game!" << endl; while (menu != 8) { //print menu cout << "===========Main Menu============" << endl; cout << "1. Play the Game" << endl; cout << "2. How to play" << endl; cout << "3. How many possible animals?" << endl; cout << "4. Display all the animals" << endl; cout << "5. How many possible questions?" << endl; cout << "6. Load" <<endl; cout << "7. Save" <<endl; cout << "8. Quit" << endl; cin >> userInput; //reset value of correct correct = true; // check if the user entered an integer try { //try to convert it to integer //menu = stoi(userInput); menu = atoi(userInput.c_str()); } catch(invalid_argument&) { //if stoi failed, user didn't input an integer cout << "Please enter an integer for the menu options." << endl; correct = false; } catch(out_of_range&) { //user entered a number that is too large for the memory cout << "Please enter an integer that is in-range." << endl; correct = false; } //check if the user entered acceptable input if (correct) { switch(menu) { case 1: //play the game { //get the root to the tree curr = gameTree->getRoot(); //traverse through the tree cout << "Let's play! Think of an animal." << endl; //while the current node is a question while (!curr->isAnimal) { curr = gameTree->askQuestion(curr); } //reached the end of the questions cout << "Is it a " << curr->info << "?\n> "; cin >> user; for (int i = 0; i < user.length(); i++) { //Convert to lower case so that user can input "Yes" or "No" -KT user[i] = tolower(user[i]); } if (user.compare("yes") == 0) { //guessed the correct animal cout << "I win!" << endl; } else { gameTree->userWon(curr); } break; } case 2: //how to play { cout << "Here's how to play!" << endl; cout << "Think of an animal, and I'll try to guess what animal it is." << endl; cout << "I'll ask you yes or no questions about your animal, so know your stuff!" << endl; cout << "When I ask a question, only answer with 'yes' or 'no' (don't capitalize them)." << endl; cout << "If I guess your animal, I win. If I don't, you win!" << endl; cout << "Ready to play?" << endl; break; } case 3: //how many animals { int numAnimals = gameTree->countAnimals(); cout << "I currently know " << numAnimals << " animals. You'll never beat me!" << endl; break; } case 4: //show all animals { cout << "If you haven't played yet, seeing all the animals is cheating." << endl; cout << "Do you really want to display all animals?\n> "; cin >> user; for (int i = 0; i < user.length(); i++) { //Convert to lower case so that user can input "Yes" or "No" -KT user[i] = tolower(user[i]); } if (user.compare("yes") == 0) gameTree->displayAnimals(); else cout << "Good choice. Look at the animals after you play!" << endl; break; } case 5: //how many questions { int numQuestions = gameTree->countQuestions(); cout << "There are currently " << numQuestions << " possible questions that I could ask you." << endl; cout << "You better know your stuff!" << endl; break; } case 6: //load { cout<< "Enter file path (/home/user/Documents/tree.txt)" << endl; string path; cin.ignore(); getline(cin,path); gameTree->load(path); break; } case 7: //save { cout<< "Enter file path (/home/user/Documents/tree.txt)" << endl; string path; cin.ignore(); getline(cin,path); gameTree->save(path); break; } case 8: //quit { cout << "Thanks for playing!" << endl; break; } default: { cout << "Please enter an in-range integer for the menu options." << endl; break; } } } } delete gameTree; //Destructor called -KT cout << "See you next time!" << endl; return 0; }
int main(int argc, const char * argv[]) { //Parse the data filename from the argument list if( argc != 2 ){ cout << "Error: failed to parse data filename from command line. You should run this example with one argument pointing to the data filename!\n"; return EXIT_FAILURE; } const string filename = argv[1]; //Create a new DecisionTree instance DecisionTree dTree; //Set the node that the DecisionTree will use - different nodes may result in different decision boundaries //and some nodes may provide better accuracy than others on specific classification tasks //The current node options are: //- DecisionTreeClusterNode //- DecisionTreeThresholdNode dTree.setDecisionTreeNode( DecisionTreeClusterNode() ); //Set the number of steps that will be used to choose the best splitting values //More steps will give you a better model, but will take longer to train dTree.setNumSplittingSteps( 1000 ); //Set the maximum depth of the tree dTree.setMaxDepth( 10 ); //Set the minimum number of samples allowed per node dTree.setMinNumSamplesPerNode( 10 ); //Load some training data to train the classifier ClassificationData trainingData; if( !trainingData.load( filename ) ){ cout << "Failed to load training data: " << filename << endl; return EXIT_FAILURE; } //Use 20% of the training dataset to create a test dataset ClassificationData testData = trainingData.split( 80 ); //Train the classifier if( !dTree.train( trainingData ) ){ cout << "Failed to train classifier!\n"; return EXIT_FAILURE; } //Print the tree dTree.print(); //Save the model to a file if( !dTree.save("DecisionTreeModel.grt") ){ cout << "Failed to save the classifier model!\n"; return EXIT_FAILURE; } //Load the model from a file if( !dTree.load("DecisionTreeModel.grt") ){ cout << "Failed to load the classifier model!\n"; return EXIT_FAILURE; } //Test the accuracy of the model on the test data double accuracy = 0; for(UINT i=0; i<testData.getNumSamples(); i++){ //Get the i'th test sample UINT classLabel = testData[i].getClassLabel(); VectorDouble inputVector = testData[i].getSample(); //Perform a prediction using the classifier bool predictSuccess = dTree.predict( inputVector ); if( !predictSuccess ){ cout << "Failed to perform prediction for test sampel: " << i <<"\n"; return EXIT_FAILURE; } //Get the predicted class label UINT predictedClassLabel = dTree.getPredictedClassLabel(); VectorDouble classLikelihoods = dTree.getClassLikelihoods(); VectorDouble classDistances = dTree.getClassDistances(); //Update the accuracy if( classLabel == predictedClassLabel ) accuracy++; cout << "TestSample: " << i << " ClassLabel: " << classLabel << " PredictedClassLabel: " << predictedClassLabel << endl; } cout << "Test Accuracy: " << accuracy/double(testData.getNumSamples())*100.0 << "%" << endl; return EXIT_SUCCESS; }