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;
}
예제 #2
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;
}