From cbc194ed6e7e4b1ebe68cccb97349ea557dc5ec9 Mon Sep 17 00:00:00 2001 From: Gunther Cox Date: Fri, 19 Aug 2016 22:02:24 -0400 Subject: [PATCH 1/4] Added method to export statement data from an existing database. --- chatterbot/trainers.py | 19 +++++++++++++++++++ tests/training_tests/test_database_export.py | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/training_tests/test_database_export.py diff --git a/chatterbot/trainers.py b/chatterbot/trainers.py index dfcda26e0..f3c4466a7 100644 --- a/chatterbot/trainers.py +++ b/chatterbot/trainers.py @@ -11,6 +11,25 @@ def __init__(self, storage, **kwargs): def train(self): pass + def _generate_export_data(self): + result = [] + + for statement in self.storage.filter(): + for response in statement.in_response_to: + result.append([response.text, statement.text]) + + return result + + def export_for_training(self, file_path='./export.json'): + """ + Create a file from the database that can be used to + train other chat bots. + """ + from jsondb.db import Database + database = Database(file_path) + export = {'export': self._generate_export_data()} + database.data(dictionary=export) + class ListTrainer(Trainer): diff --git a/tests/training_tests/test_database_export.py b/tests/training_tests/test_database_export.py new file mode 100644 index 000000000..8fff92b81 --- /dev/null +++ b/tests/training_tests/test_database_export.py @@ -0,0 +1,20 @@ +from tests.base_case import ChatBotTestCase +from chatterbot.trainers import ListTrainer + + +class DatabaseExportTests(ChatBotTestCase): + + def setUp(self): + super(DatabaseExportTests, self).setUp() + self.chatbot.set_trainer(ListTrainer) + + def test_generate_export_data(self): + self.chatbot.trainer.train([ + 'Hello, how are you?', + 'I am good.' + ]) + data = self.chatbot.trainer._generate_export_data() + + self.assertEqual( + [['Hello, how are you?', 'I am good.']], data + ) From 37f3a9119f25e9f5754bb3ea5c218ca1410bb6bf Mon Sep 17 00:00:00 2001 From: Gunther Cox Date: Fri, 19 Aug 2016 22:21:56 -0400 Subject: [PATCH 2/4] Added docs and an example for database exports. --- docs/training.rst | 16 ++++++++++++++++ examples/export_example.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 examples/export_example.py diff --git a/docs/training.rst b/docs/training.rst index 3b46689da..bf30e643c 100644 --- a/docs/training.rst +++ b/docs/training.rst @@ -113,6 +113,22 @@ To explore what languages and sets of corpora are available, check out the `chat If you are interested in contributing a new language corpus, or adding a module to an existing language, please create a pull request. Contributions are welcomed! +Exporting your chat bot's database as a training corpus +======================================================= + +Now that you have created your chat bot and sent it out into the world, perhaps +you are looking for a way to share what it has learned with other chat bots? +ChatterBot's training module provides methods that allow you to export the +content of your chat bot's database as a training corpus that can be used to +train other chat bots. + +Here is an example: + +.. code-block:: python + + chatbot = ChatBot("Export Example Bot") + chatbot.trainer.export_for_training('./export.json') + .. glossary:: corpus diff --git a/examples/export_example.py b/examples/export_example.py new file mode 100644 index 000000000..044930a0f --- /dev/null +++ b/examples/export_example.py @@ -0,0 +1,16 @@ +from chatterbot import ChatBot +from chatterbot.trainers import ChatterBotCorpusTrainer + +''' +This is an example showing how to create an export file from +an existing chat bot that can then be used to train other bots. +''' + +chatbot = ChatBot("Export Example Bot") + +# First, lets train our bot with some data +chatbot.set_trainer(ChatterBotCorpusTrainer) +chatbot.train("chatterbot.corpus.english") + +# Now we can export the data to a file +chatbot.trainer.export_for_training('./myfile.json') From dcb115bf41b9e70d23103f79180a2d19b2e1be66 Mon Sep 17 00:00:00 2001 From: Gunther Cox Date: Fri, 19 Aug 2016 22:24:12 -0400 Subject: [PATCH 3/4] Use a default trainer instead of the value None This allows the database export method to be called. --- chatterbot/chatterbot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chatterbot/chatterbot.py b/chatterbot/chatterbot.py index 63bd37f37..f3ad4f02e 100644 --- a/chatterbot/chatterbot.py +++ b/chatterbot/chatterbot.py @@ -3,6 +3,7 @@ from .adapters.input import InputAdapter from .adapters.output import OutputAdapter from .conversation import Statement, Response +from .trainers import Trainer from .utils.queues import ResponseQueue from .utils.module_loading import import_module @@ -66,7 +67,7 @@ def __init__(self, name, **kwargs): self.input.set_context(self) self.output.set_context(self) - self.trainer = None + self.trainer = Trainer(self.storage) def add_adapter(self, adapter, **kwargs): self.validate_adapter_class(adapter, LogicAdapter) From a9f7aedeb6790b35856d702659547efbb6350f94 Mon Sep 17 00:00:00 2001 From: Gunther Cox Date: Sat, 20 Aug 2016 08:48:17 -0400 Subject: [PATCH 4/4] Move TrainerInitializationException to Trainer class. --- chatterbot/chatterbot.py | 10 ---------- chatterbot/trainers.py | 12 ++++++++++-- tests/training_tests/test_training.py | 3 +-- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/chatterbot/chatterbot.py b/chatterbot/chatterbot.py index f3ad4f02e..bb519e172 100644 --- a/chatterbot/chatterbot.py +++ b/chatterbot/chatterbot.py @@ -166,8 +166,6 @@ def set_trainer(self, training_class, **kwargs): @property def train(self): - if not self.trainer: - raise self.TrainerInitializationException() # Proxy method to the trainer return self.trainer.train @@ -178,11 +176,3 @@ def __init__(self, value='Recieved an unexpected adapter setting.'): def __str__(self): return repr(self.value) - - class TrainerInitializationException(Exception): - - def __init__(self, value='The `set_trainer` method must be called before calling `train`.'): - self.value = value - - def __str__(self): - return repr(self.value) diff --git a/chatterbot/trainers.py b/chatterbot/trainers.py index f3c4466a7..3c3364ce8 100644 --- a/chatterbot/trainers.py +++ b/chatterbot/trainers.py @@ -8,8 +8,16 @@ def __init__(self, storage, **kwargs): self.storage = storage self.corpus = Corpus() - def train(self): - pass + def train(self, *args, **kwargs): + raise self.TrainerInitializationException() + + class TrainerInitializationException(Exception): + + def __init__(self, value='A training class bust be set using the `set_trainer` method before calling `train()`.'): + self.value = value + + def __str__(self): + return repr(self.value) def _generate_export_data(self): result = [] diff --git a/tests/training_tests/test_training.py b/tests/training_tests/test_training.py index efd41b290..7e5dc1601 100644 --- a/tests/training_tests/test_training.py +++ b/tests/training_tests/test_training.py @@ -1,10 +1,9 @@ from tests.base_case import ChatBotTestCase -from chatterbot import ChatBot from chatterbot.trainers import ListTrainer class TrainingTests(ChatBotTestCase): def test_trainer_not_set(self): - with self.assertRaises(ChatBot.TrainerInitializationException): + with self.assertRaises(ListTrainer.TrainerInitializationException): self.chatbot.train()