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()
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?')
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)
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?')
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)
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)
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 setUp(self): super().setUp() self.search_algorithm = IndexedTextSearch( self.chatbot, statement_comparison_function=comparisons.levenshtein_distance)
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)
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)
def setUp(self): super().setUp() self.search_algorithm = IndexedTextSearch(self.chatbot)
def setUp(self): super().setUp() self.search_algorithm = IndexedTextSearch( self.chatbot, statement_comparison_function=comparisons.SpacySimilarity )
def setUp(self): super().setUp() self.search_algorithm = IndexedTextSearch( self.chatbot, statement_comparison_function=comparisons.spacy_similarity)
def setUp(self): super().setUp() self.search_algorithm = IndexedTextSearch( self.chatbot, statement_comparison_function=comparisons.LevenshteinDistance )