Example #1
0
    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(
            self.chatbot,
            statement_comparison_function=comparisons.sentiment_comparison)

        # Make sure the required NLTK data files are downloaded
        for function in utils.get_initialization_functions(
                self.search_algorithm, 'compare_statements').values():
            function()
Example #2
0
class SearchComparisonFunctionSpacySimilarityTests(ChatBotTestCase):
    """
    Test that the search algorithm works correctly with the
    spacy similarity comparison function.
    """
    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(
            self.chatbot,
            statement_comparison_function=comparisons.spacy_similarity)

    def test_get_closest_statement(self):
        """
        Note, the content of the in_response_to field for each of the
        test statements is only required because the logic adapter will
        filter out any statements that are not in response to a known statement.
        """
        self.chatbot.storage.create_many([
            Statement(text='This is a lovely bog.',
                      in_response_to='This is a lovely bog.'),
            Statement(text='This is a beautiful swamp.',
                      in_response_to='This is a beautiful swamp.'),
            Statement(text='It smells like a swamp.',
                      in_response_to='It smells like a swamp.')
        ])

        statement = Statement(text='This is a lovely swamp.')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 2)

        results_text = [result.text for result in results]

        self.assertIn('This is a lovely bog.', results_text)
        self.assertIn('This is a beautiful swamp.', results_text)
        self.assertGreater(results[0].confidence, 0)
        self.assertGreater(results[1].confidence, 0)

    def test_different_punctuation(self):
        self.chatbot.storage.create_many([
            Statement(text='Who are you?'),
            Statement(text='Are you good?'),
            Statement(text='You are good')
        ])

        statement = Statement(text='Are you good')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'Are you good?')
Example #3
0
class SearchComparisonFunctionSentimentComparisonTests(ChatBotTestCase):
    """
    Test that the search algorithm works correctly with the
    sentiment comparison function by using the similarity
    of sentiment polarity.
    """

    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(
            self.chatbot,
            statement_comparison_function=comparisons.sentiment_comparison
        )

        # Make sure the required NLTK data files are downloaded
        for function in utils.get_initialization_functions(
            self.search_algorithm,
            'compare_statements'
        ):
            function()

    def test_exact_input(self):
        self.chatbot.storage.create(text='What is your favorite flavor of ice cream?')
        self.chatbot.storage.create(text='I enjoy raspberry ice cream.')
        self.chatbot.storage.create(text='I am glad to hear that.')
        self.chatbot.storage.create(text='Thank you.')

        happy_statement = Statement(text='I enjoy raspberry ice cream.')
        results = list(self.search_algorithm.search(happy_statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'I enjoy raspberry ice cream.')
        self.assertEqual(results[0].confidence, 1)

    def test_close_input(self):
        self.chatbot.storage.create(text='What is your favorite flavor of ice cream?')
        self.chatbot.storage.create(text='I enjoy raspberry ice cream.')
        self.chatbot.storage.create(text='I am glad to hear that.')
        self.chatbot.storage.create(text='Thank you, what is yours?')
        self.chatbot.storage.create(text='Mine is chocolate.')

        happy_statement = Statement(text='I enjoy raspberry.')
        results = list(self.search_algorithm.search(happy_statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'I enjoy raspberry ice cream.')
        self.assertAlmostEqual(results[0].confidence, 0.75, places=1)
Example #4
0
class SearchComparisonFunctionSpacySimilarityTests(ChatBotTestCase):
    """
    Test that the search algorithm works correctly with the
    spacy similarity comparison function.
    """

    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(
            self.chatbot,
            statement_comparison_function=comparisons.SpacySimilarity
        )

    def test_get_closest_statement(self):
        """
        Note, the content of the in_response_to field for each of the
        test statements is only required because the logic adapter will
        filter out any statements that are not in response to a known statement.
        """
        self.chatbot.storage.create_many([
            Statement(text='This is a lovely bog.', in_response_to='This is a lovely bog.'),
            Statement(text='This is a beautiful swamp.', in_response_to='This is a beautiful swamp.'),
            Statement(text='It smells like a swamp.', in_response_to='It smells like a swamp.')
        ])

        statement = Statement(text='This is a lovely swamp.')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'This is a beautiful swamp.')
        self.assertGreater(results[0].confidence, 0)

    def test_different_punctuation(self):
        self.chatbot.storage.create_many([
            Statement(text='Who are you?'),
            Statement(text='Are you good?'),
            Statement(text='You are good')
        ])

        statement = Statement(text='Are you good')
        results = list(self.search_algorithm.search(statement))

        self.assertEqual(len(results), 2, msg=[r.search_text for r in results])
        # Note: the last statement in the list always has the highest confidence
        self.assertEqual(results[-1].text, 'Are you good?')
Example #5
0
class SearchTestCase(ChatBotTestCase):

    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(self.chatbot)

    def test_search_no_results(self):
        """
        An exception should be raised if there is no data to return.
        """
        statement = Statement(text='What is your quest?')

        with self.assertRaises(StopIteration):
            next(self.search_algorithm.search(statement))

    def test_search_cast_to_list_no_results(self):
        """
        An empty list should be returned when the generator is
        cast to a list and there are no results to return.
        """
        statement = Statement(text='What is your quest?')

        results = list(self.search_algorithm.search(statement))

        self.assertEqual(results, [])

    def test_search_additional_parameters(self):
        """
        It should be possible to pass additional parameters in to use for searching.
        """
        self.chatbot.storage.create_many([
            Statement(text='A', conversation='test_1'),
            Statement(text='A', conversation='test_2')
        ])

        statement = Statement(text='A')

        results = list(self.search_algorithm.search(
            statement, conversation='test_1'
        ))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'A')
        self.assertEqual(results[0].conversation, 'test_1')
Example #6
0
class SearchTestCase(ChatBotTestCase):

    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(self.chatbot)

    def test_search_no_results(self):
        """
        An exception should be raised if there is no data to return.
        """
        statement = Statement(text='What is your quest?')

        with self.assertRaises(StopIteration):
            next(self.search_algorithm.search(statement))

    def test_search_cast_to_list_no_results(self):
        """
        An empty list should be returned when the generator is
        cast to a list and there are no results to return.
        """
        statement = Statement(text='What is your quest?')

        results = list(self.search_algorithm.search(statement))

        self.assertEqual(results, [])

    def test_search_additional_parameters(self):
        """
        It should be possible to pass additional parameters in to use for searching.
        """
        self.chatbot.storage.create_many([
            Statement(text='A', conversation='test_1'),
            Statement(text='A', conversation='test_2')
        ])

        statement = Statement(text='A')

        results = list(self.search_algorithm.search(
            statement, conversation='test_1'
        ))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'A')
        self.assertEqual(results[0].conversation, 'test_1')
    def __init__(self, name, **kwargs):
        self.name = name

        storage_adapter = kwargs.get('storage_adapter', 'chatterbot.storage.SQLStorageAdapter')

        logic_adapters = kwargs.get('logic_adapters', [
            'chatterbot.logic.BestMatch'
        ])

        # Check that each adapter is a valid subclass of it's respective parent
        utils.validate_adapter_class(storage_adapter, StorageAdapter)

        # Logic adapters used by the chat bot
        self.logic_adapters = []

        self.storage = utils.initialize_class(storage_adapter, **kwargs)

        primary_search_algorithm = IndexedTextSearch(self, **kwargs)
        text_search_algorithm = TextSearch(self, **kwargs)

        self.search_algorithms = {
            primary_search_algorithm.name: primary_search_algorithm,
            text_search_algorithm.name: text_search_algorithm
        }

        for adapter in logic_adapters:
            utils.validate_adapter_class(adapter, LogicAdapter)
            logic_adapter = utils.initialize_class(adapter, self, **kwargs)
            self.logic_adapters.append(logic_adapter)

        preprocessors = kwargs.get(
            'preprocessors', [
                'chatterbot.preprocessors.clean_whitespace'
            ]
        )

        self.preprocessors = []
        self.postprocessors = []

        for preprocessor in preprocessors:
            self.preprocessors.append(utils.import_module(preprocessor))

        postprocessors = kwargs.get(
            'postprocessors', [
                'chatterbot.postprocessors.joint_sentence'
            ]
        )

        for postprocessor in postprocessors:
            self.postprocessors.append(utils.import_module(postprocessor))

        self.logger = kwargs.get('logger', logging.getLogger(__name__))

        # Allow the bot to save input it receives so that it can learn
        self.read_only = kwargs.get('read_only', False)
Example #8
0
    def __init__(self, name, **kwargs):
        self.name = name
        self.logger = kwargs.get(
            'logger',
            log.Logger('chatterbot',
                       costum_format='[%Y-%m-%d %H:%M:%S] chatterbot',
                       debug=kwargs.get('debug', False)))

        storage_adapter = kwargs.get('storage_adapter',
                                     'chatterbot.storage.SQLStorageAdapter')

        logic_adapters = kwargs.get('logic_adapters',
                                    ['chatterbot.logic.BestMatch'])

        # Check that each adapter is a valid subclass of it's respective parent
        utils.validate_adapter_class(storage_adapter, StorageAdapter)

        # Logic adapters used by the chat bot
        self.logic_adapters = []

        self.storage = utils.initialize_class(storage_adapter, **kwargs)

        primary_search_algorithm = IndexedTextSearch(self, **kwargs)
        text_search_algorithm = TextSearch(self, **kwargs)

        self.search_algorithms = {
            primary_search_algorithm.name: primary_search_algorithm,
            text_search_algorithm.name: text_search_algorithm
        }

        for adapter in logic_adapters:
            utils.validate_adapter_class(adapter, LogicAdapter)
            logic_adapter = utils.initialize_class(adapter, self, **kwargs)
            self.logic_adapters.append(logic_adapter)

        preprocessors = kwargs.get(
            'preprocessors', ['chatterbot.preprocessors.clean_whitespace'])

        self.preprocessors = []

        for preprocessor in preprocessors:
            self.preprocessors.append(utils.import_module(preprocessor))
        self.trainer = ChatterBotCorpusTrainer(self)
        self.trainer.train("chatterbot.corpus.custom")
        log.add_logger('chatterbot', self.logger)
        self.this_file = os.path.dirname(__file__)
        self.learn_YAML = os.path.join(
            ''.join(os.path.split(self.this_file)[0]), 'chatterbot_corpus',
            'data', 'custom', 'myown.yml')
        # Allow the bot to save input it receives so that it can learn
        self.read_only = kwargs.get('read_only', False)
Example #9
0
class SearchTestCase(ChatBotTestCase):
    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(self.chatbot)

    def test_search_no_results(self):
        """
        An exception should be raised if there is no data to return.
        """
        statement = Statement(text='What is your quest?')

        with self.assertRaises(StopIteration):
            next(self.search_algorithm.search(statement))

    def test_search_cast_to_list_no_results(self):
        """
        An empty list should be returned when the generator is
        cast to a list and there are no results to return.
        """
        statement = Statement(text='What is your quest?')

        results = list(self.search_algorithm.search(statement))

        self.assertEqual(results, [])
Example #10
0
 def setUp(self):
     super().setUp()
     self.search_algorithm = IndexedTextSearch(
         self.chatbot,
         statement_comparison_function=comparisons.levenshtein_distance)
Example #11
0
class SearchComparisonFunctionLevenshteinDistanceComparisonTests(
        ChatBotTestCase):
    """
    Test that the search algorithm works correctly with the
    Levenshtein distance comparison function.
    """
    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(
            self.chatbot,
            statement_comparison_function=comparisons.levenshtein_distance)

    def test_get_closest_statement(self):
        """
        Note, the content of the in_response_to field for each of the
        test statements is only required because the logic adapter will
        filter out any statements that are not in response to a known statement.
        """
        self.chatbot.storage.create_many([
            Statement(text='Who do you love?',
                      in_response_to='I hear you are going on a quest?'),
            Statement(text='What is the meaning of life?',
                      in_response_to='Yuck, black licorice jelly beans.'),
            Statement(text='I am Iron Man.',
                      in_response_to='What... is your quest?'),
            Statement(text='What... is your quest?',
                      in_response_to='I am Iron Man.'),
            Statement(text='Yuck, black licorice jelly beans.',
                      in_response_to='What is the meaning of life?'),
            Statement(text='I hear you are going on a quest?',
                      in_response_to='Who do you love?'),
        ])

        statement = Statement(text='What is your quest?')

        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].text, 'What... is your quest?')

    def test_confidence_exact_match(self):
        self.chatbot.storage.create(text='What is your quest?',
                                    in_response_to='What is your quest?')

        statement = Statement(text='What is your quest?')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].confidence, 1)

    def test_confidence_half_match(self):
        from unittest.mock import MagicMock

        # Assume that the storage adapter returns a partial match
        self.chatbot.storage.filter = MagicMock(
            return_value=[Statement(text='xxyy')])

        statement = Statement(text='wwxx')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].confidence, 0.5)

    def test_confidence_no_match(self):
        from unittest.mock import MagicMock

        # Assume that the storage adapter returns a partial match
        self.search_algorithm.chatbot.storage.filter = MagicMock(
            return_value=[Statement(text='xxx', in_response_to='xxx')])

        statement = Statement(text='yyy')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 0)
Example #12
0
class SearchComparisonFunctionLevenshteinDistanceComparisonTests(ChatBotTestCase):
    """
    Test that the search algorithm works correctly with the
    Levenshtein distance comparison function.
    """

    def setUp(self):
        super().setUp()
        self.search_algorithm = IndexedTextSearch(
            self.chatbot,
            statement_comparison_function=comparisons.LevenshteinDistance
        )

    def test_get_closest_statement(self):
        """
        Note, the content of the in_response_to field for each of the
        test statements is only required because the search process will
        filter out any statements that are not in response to something.
        """
        self.chatbot.storage.create_many([
            Statement(text='What is the meaning of life?', in_response_to='...'),
            Statement(text='I am Iron Man.', in_response_to='...'),
            Statement(text='What... is your quest?', in_response_to='...'),
            Statement(text='Yuck, black licorice jelly beans.', in_response_to='...'),
            Statement(text='I hear you are going on a quest?', in_response_to='...'),
        ])

        statement = Statement(text='What is your quest?')

        results = list(self.search_algorithm.search(statement))

        self.assertEqual(len(results), 1, msg=[r.text for r in results])
        self.assertEqual(results[0].text, 'What... is your quest?')

    def test_confidence_exact_match(self):
        self.chatbot.storage.create(text='What is your quest?', in_response_to='What is your quest?')

        statement = Statement(text='What is your quest?')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].confidence, 1)

    def test_confidence_half_match(self):
        from unittest.mock import MagicMock

        # Assume that the storage adapter returns a partial match
        self.chatbot.storage.filter = MagicMock(return_value=[
            Statement(text='xxyy')
        ])

        statement = Statement(text='wwxx')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 1)
        self.assertEqual(results[0].confidence, 0.5)

    def test_confidence_no_match(self):
        from unittest.mock import MagicMock

        # Assume that the storage adapter returns a partial match
        self.search_algorithm.chatbot.storage.filter = MagicMock(return_value=[
            Statement(text='xxx', in_response_to='xxx')
        ])

        statement = Statement(text='yyy')
        results = list(self.search_algorithm.search(statement))

        self.assertIsLength(results, 0)
Example #13
0
 def setUp(self):
     super().setUp()
     self.search_algorithm = IndexedTextSearch(self.chatbot)
Example #14
0
 def setUp(self):
     super().setUp()
     self.search_algorithm = IndexedTextSearch(
         self.chatbot,
         statement_comparison_function=comparisons.SpacySimilarity
     )
Example #15
0
 def setUp(self):
     super().setUp()
     self.search_algorithm = IndexedTextSearch(
         self.chatbot,
         statement_comparison_function=comparisons.spacy_similarity)
Example #16
0
 def setUp(self):
     super().setUp()
     self.search_algorithm = IndexedTextSearch(self.chatbot)
Example #17
0
 def setUp(self):
     super().setUp()
     self.search_algorithm = IndexedTextSearch(
         self.chatbot,
         statement_comparison_function=comparisons.LevenshteinDistance
     )