def test_convert_class_values_to_floats():

    classifier = NaiveBayesClassifier()

    dataset = [['3.393533211', '2.331273381', '0'],
               ['3.110073483', '1.781539638', '0'],
               ['1.343808831', '3.368360954', '0'],
               ['3.582294042', '4.67917911', '0'],
               ['2.280362439', '2.866990263', '0'],
               ['7.423436942', '4.696522875', '1'],
               ['5.745051997', '3.533989803', '1'],
               ['9.172168622', '2.511101045', '1'],
               ['7.792783481', '3.424088941', '1'],
               ['7.939820817', '0.791637231', '1']]

    for i in range(0, len(dataset[0])-1):
        classifier.convert_class_values_to_floats(dataset, i)

    for i in range(0, len(dataset)):
        tested_row = random.randint(0, len(dataset)-1)
        tested_column = random.randint(0, len(dataset[0]) - 2)
        assert isinstance(dataset[tested_row][tested_column], float)
示例#2
0
class Iris:
    """

    Works on iris.csv dataset and interactively performs the following actions:\n
    1. Classify new data entered by user.\n
    2. Calculate the algorithm implementation accuracy.\n
    3. Show dataset description (iris.names file).\n
    4. Show dataset rows.

    """
    def __init__(self):

        self.dataset_filename = 'datasets/iris.csv'
        self.description_filename = 'datasets/iris.names'
        self.nbc = NaiveBayesClassifier()
        self.dataset = self.nbc.load_dataset_from_csv(self.dataset_filename)
        self.class_map = dict()

    def data_preprocessing(self):
        """

        Converts class names (strings) to ints and class values to floats.

        Args:
            None.

        Returns:
            Nothing.

        """

        seed(1)

        for i in range(len(self.dataset[0]) - 1):
            self.nbc.convert_class_values_to_floats(self.dataset, i)

        self.class_map = self.nbc.map_class_names_to_ints(
            self.dataset,
            len(self.dataset[0]) - 1)

    def classify_data(self):
        """

        Creates a new row with values inputted by the user, then classifies it to the proper class
        using Naive Bayes Classifier algorithm.

        Args:
            None.

        Returns:
            Nothing.

        """

        print('\nEnter the data to be classified.\n')

        attributes = {
            'Sepal length [cm]: ': 0.0,
            'Sepal width [cm]: ': 0.0,
            'Petal length [cm]: ': 0.0,
            'Petal width [cm]: ': 0.0
        }

        for attr in attributes:

            correct_input = False

            while correct_input == False:

                try:
                    attr_value = float(input(attr))
                    correct_input = True
                except:
                    print(
                        'Incorrect value! Please enter an integer or a floating point number.'
                    )

            attributes[attr] = attr_value

        print('\nEntered attributes:\n')

        for attr in attributes:
            print(f'{attr}{attributes[attr]}')

        print()

        confirm_sign = ''

        while confirm_sign not in ['y', 'Y', 'n', 'N']:
            confirm_sign = input('Confirm (y/n): ')

        if confirm_sign in ['n', 'N']:
            return

        model = self.nbc.calculate_class_parameters(self.dataset)
        label = self.nbc.predict(model, list(attributes.values()))

        for key, value in self.class_map.items():
            if value == label:
                print(f'\nThe entered entity was classified as: {key}')
                break

    def calculate_accuracy(self, n_folds=5):
        """

        Calculates algorithm accuracy by using evaluate_algorithm() function.

        Args:
            n_folds (int)
                Number of folds used in the k-fold cross validation split algorithm.

        Returns:
            accuracy
                Calculated classifier accuracy in percent.

        """

        scores = self.nbc.evaluate_algorithm(self.dataset, n_folds)

        print(
            '\n\nCalculating the accuracy of the classifier using the iris.csv dataset...'
        )
        print('\nResampling: k-fold cross validation split')

        accuracy = (sum(scores) / float(len(scores)))
        print(f'\nAccuracy ({n_folds} folds): {round(accuracy, 3)} %\n')

        return accuracy

    def show_dataset_description(self):
        """

        Prints the 'iris.names' file to the console output.

        Args:
            None.

        Returns:
            Nothing.

        """

        with open(self.description_filename, 'r') as f:

            csv_reader = csv.reader(f,
                                    delimiter=',',
                                    quotechar='"',
                                    quoting=csv.QUOTE_MINIMAL)

            for row in csv_reader:
                for word in row:
                    print(word, end='')
                print()

    def show_dataset_rows(self):
        """

        Prints the 'iris.csv' file to the console output.

        Args:
            None.

        Returns:
            Nothing.

        """

        with open(self.dataset_filename, 'r') as f:

            csv_reader = csv.reader(f,
                                    delimiter=',',
                                    quotechar='"',
                                    quoting=csv.QUOTE_MINIMAL)

            for row in csv_reader:
                for i in range(len(row) - 1):
                    print(row[i], end=',')
                print(row[len(row) - 1])

    def run(self):
        """

        Creates the interactive menu from which the user can execute the actions handled
        by the other methods in this class.

        Args:
            None.

        Returns:
            Nothing.

        """

        print('\n=================================')
        print('          Iris dataset')
        print('=================================\n')

        self.data_preprocessing()

        returned_from_function = True

        while True:

            if returned_from_function == True:
                print('\nChoose the action:')
                print('\n1. Classify new data.')
                print('2. Calculate algorithm accuracy.')
                print('3. Show dataset description.')
                print('4. Show dataset rows.')
                print('5. Go back to the main menu.\n')

            returned_from_function = False

            choice = input('Choice: ')

            if choice not in ['1', '2', '3', '4', '5']:
                print('Wrong choice! Please choose option 1-5.')

            elif choice == '1':

                try:
                    self.classify_data()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '2':

                try:
                    self.calculate_accuracy()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '3':

                try:
                    self.show_dataset_description()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '4':

                try:
                    self.show_dataset_rows()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '5':
                break

            else:
                raise
class PimaIndiansDiabetes:
    """

    Works on pima-indians-diabetes.csv dataset and interactively performs the following actions:\n
    1. Classify new data entered by user.\n
    2. Calculate the algorithm implementation accuracy.\n
    3. Show dataset description (pima-indians-diabetes.names file).\n
    4. Show dataset rows.

    """
    def __init__(self):

        self.dataset_filename = 'datasets/pima-indians-diabetes.csv'
        self.description_filename = 'datasets/pima-indians-diabetes.names'
        self.nbc = NaiveBayesClassifier()
        self.dataset = self.nbc.load_dataset_from_csv(self.dataset_filename)

    def data_preprocessing(self):
        """

        Converts class names (strings) to ints and class values to floats.

        Args:
            None.

        Returns:
            Nothing.

        """

        for i in range(len(self.dataset[0]) - 1):
            self.nbc.convert_class_values_to_floats(self.dataset, i)

        self.nbc.map_class_names_to_ints(self.dataset,
                                         len(self.dataset[0]) - 1,
                                         numbers_already=True)

    def classify_data(self):
        """

        Creates a new row with values inputted by the user, then classifies it to the proper class
        using Naive Bayes Classifier algorithm.

        Args:
            None.

        Returns:
            Nothing.

        """

        print('\nEnter the data to be classified.\n')

        attributes = {
            'Number of times pregnant: ':
            0.0,
            'Plasma glucose concentration a 2 hours in an oral glucose tolerance test: ':
            0.0,
            'Diastolic blood pressure (mm Hg): ':
            0.0,
            'Triceps skin fold thickness (mm): ':
            0.0,
            '2-Hour serum insulin (mu U/ml): ':
            0.0,
            'Body mass index (weight in kg/(height in m)^2): ':
            0.0,
            'Diabetes pedigree function: ':
            0.0,
            'Age (years): ':
            0.0
        }

        for attr in attributes:

            correct_input = False

            while correct_input == False:

                try:
                    attr_value = float(input(attr))
                    correct_input = True
                except:
                    print(
                        'Incorrect value! Please enter an integer or a floating point number.'
                    )

            attributes[attr] = attr_value

        print('\nEntered attributes:\n')

        for attr in attributes:
            print(f'{attr}{attributes[attr]}')

        print()

        confirm_sign = ''

        while confirm_sign not in ['y', 'Y', 'n', 'N']:
            confirm_sign = input('Confirm (y/n): ')

        if confirm_sign in ['n', 'N']:
            return

        model = self.nbc.calculate_class_parameters(self.dataset)
        label = self.nbc.predict(model, list(attributes.values()))

        # Original dataset contains class names represented as numbers,
        # so it's needed to print the labels explicitly
        if label == 0:
            print(f'\nThe entered entity was classified as: Negative')
        elif label == 1:
            print(f'\nThe entered entity was classified as: Positive')
        else:
            raise

    def calculate_accuracy(self, n_folds=5):
        """

        Calculates algorithm accuracy by using evaluate_algorithm() function.

        Args:
            n_folds (int)
                Number of folds used in the k-fold cross validation split algorithm.

        Returns:
            accuracy
                Calculated classifier accuracy in percent.

        """

        scores = self.nbc.evaluate_algorithm(self.dataset, n_folds)

        print(
            '\n\nCalculating the accuracy of the classifier using the pima-indians-diabetes.csv dataset...'
        )
        print('\nResampling: k-fold cross validation split')

        accuracy = (sum(scores) / float(len(scores)))
        print(f'\nAccuracy ({n_folds} folds): {round(accuracy, 3)} %\n')

        return accuracy

    def show_dataset_description(self):
        """

        Prints the 'pima-indians-diabetes.names' file to the console output.

        Args:
            None.

        Returns:
            Nothing.

        """

        with open(self.description_filename, 'r') as f:

            csv_reader = csv.reader(f,
                                    delimiter=',',
                                    quotechar='"',
                                    quoting=csv.QUOTE_MINIMAL)

            for row in csv_reader:
                for word in row:
                    print(word, end='')
                print()

    def show_dataset_rows(self):
        """

        Prints the 'pima-indians-diabetes.csv' file to the console output.

        Args:
            None.

        Returns:
            Nothing.

        """

        with open(self.dataset_filename, 'r') as f:

            csv_reader = csv.reader(f,
                                    delimiter=',',
                                    quotechar='"',
                                    quoting=csv.QUOTE_MINIMAL)

            for row in csv_reader:
                for i in range(len(row) - 1):
                    print(row[i], end=',')
                print(row[len(row) - 1])

    def run(self):
        """

        Creates the interactive menu from which the user can execute the actions handled
        by the other methods in this class.

        Args:
            None.

        Returns:
            Nothing.

        """

        seed(1)

        print('\n=================================')
        print('   Pima Indians Diabetes dataset')
        print('=================================')

        self.data_preprocessing()

        returned_from_function = True

        while True:

            if returned_from_function == True:
                print('\nChoose the action:')
                print('\n1. Classify new data.')
                print('2. Calculate algorithm accuracy.')
                print('3. Show dataset description.')
                print('4. Show dataset rows.')
                print('5. Go back to the main menu.\n')

            returned_from_function = False

            choice = input('Choice: ')

            if choice not in ['1', '2', '3', '4', '5']:
                print('Wrong choice! Please choose option 1-5.')

            elif choice == '1':

                try:
                    self.classify_data()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '2':

                try:
                    self.calculate_accuracy()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '3':

                try:
                    self.show_dataset_description()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '4':

                try:
                    self.show_dataset_rows()
                    returned_from_function = True
                    continue
                except KeyboardInterrupt:
                    returned_from_function = True
                    continue

            elif choice == '5':
                break

            else:
                raise