Skip to content

Commit 4f2275e

Browse files
committed
Updated for raspberry pi and fixed some other issues
- updated spaCy requirements - included install script for raspi - made changes to spaCy loading save memory - by default, have best_match adapter allow repeated responses, with option to disable
1 parent 0c4e388 commit 4f2275e

File tree

11 files changed

+74
-22
lines changed

11 files changed

+74
-22
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ This package can be installed from [PyPi](https://pypi.python.org/pypi/ChatterBo
3636
pip install chatterbot
3737
```
3838

39+
For Raspberry Pi users: download or clone the repo and then run the install script:
40+
41+
```
42+
./install.sh
43+
```
44+
3945
## Basic Usage
4046

4147
```

chatterbot/chatterbot.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,11 @@ def get_response(self, statement=None, **kwargs):
127127
setattr(response, response_key, response_value)
128128

129129
if not self.read_only:
130-
self.learn_response(input_statement)
130+
# want to learn that response is valid for input statement
131+
self.learn_response(response, input_statement)
131132

132-
# Save the response generated for the input
133-
self.storage.create(**response.serialize())
133+
# also save the input statement
134+
self.storage.create(**input_statement.serialize())
134135

135136
return response
136137

@@ -211,6 +212,8 @@ def learn_response(self, statement, previous_statement=None):
211212
"""
212213
Learn that the statement provided is a valid response.
213214
"""
215+
if not statement.search_text:
216+
statement.search_text = self.storage.tagger.get_text_index_string(statement.text)
214217
if not previous_statement:
215218
previous_statement = statement.in_response_to
216219

@@ -223,15 +226,19 @@ def learn_response(self, statement, previous_statement=None):
223226

224227
if not isinstance(previous_statement, (str, type(None), )):
225228
statement.in_response_to = previous_statement.text
229+
if not statement.search_in_response_to:
230+
statement.search_in_response_to = previous_statement.search_text
226231
elif isinstance(previous_statement, str):
227232
statement.in_response_to = previous_statement
233+
if not statement.search_in_response_to:
234+
statement.search_in_response_to = self.storage.tagger.get_text_index_string(previous_statement)
228235

229236
self.logger.info('Adding "{}" as a response to "{}"'.format(
230237
statement.text,
231238
previous_statement_text
232239
))
233240

234-
# Save the input statement
241+
# Save the response
235242
return self.storage.create(**statement.serialize())
236243

237244
def get_latest_response(self, conversation):

chatterbot/comparisons.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
designed to compare one statement to another.
44
"""
55
from difflib import SequenceMatcher
6-
6+
from chatterbot import singleton_classes
77

88
class Comparator:
99

@@ -63,9 +63,8 @@ class SpacySimilarity(Comparator):
6363

6464
def __init__(self, language):
6565
super().__init__(language)
66-
import spacy
6766

68-
self.nlp = spacy.load(self.language.ISO_639_1)
67+
self.nlp = singleton_classes.singleSpacy.getInstance(language)
6968

7069
def compare(self, statement_a, statement_b):
7170
"""

chatterbot/logic/best_match.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def __init__(self, chatbot, **kwargs):
2121
super().__init__(chatbot, **kwargs)
2222

2323
self.excluded_words = kwargs.get('excluded_words')
24+
self.exclude_recent_repeated = kwargs.get('exclude_recent_repeated')
2425

2526
def process(self, input_statement, additional_response_selection_parameters=None):
2627
search_results = self.search_algorithm.search(input_statement)
@@ -40,15 +41,19 @@ def process(self, input_statement, additional_response_selection_parameters=None
4041
closest_match.text, input_statement.text, closest_match.confidence
4142
))
4243

43-
recent_repeated_responses = filters.get_recent_repeated_responses(
44-
self.chatbot,
45-
input_statement.conversation
46-
)
44+
recent_repeated_responses = None
4745

48-
for index, recent_repeated_response in enumerate(recent_repeated_responses):
49-
self.chatbot.logger.info('{}. Excluding recent repeated response of "{}"'.format(
50-
index, recent_repeated_response
51-
))
46+
# remove recently repeated only if user specifies
47+
if self.exclude_recent_repeated:
48+
recent_repeated_responses = filters.get_recent_repeated_responses(
49+
self.chatbot,
50+
input_statement.conversation
51+
)
52+
53+
for index, recent_repeated_response in enumerate(recent_repeated_responses):
54+
self.chatbot.logger.info('{}. Excluding recent repeated response of "{}"'.format(
55+
index, recent_repeated_response
56+
))
5257

5358
response_selection_parameters = {
5459
'search_in_response_to': closest_match.search_text,

chatterbot/singleton_classes.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from chatterbot import languages
2+
import spacy
3+
4+
# loading spacy more than once slows down everything and makes it consume a lot of extra memory
5+
# so having a single instance will save memory
6+
class singleSpacy:
7+
_instance = None
8+
@staticmethod
9+
def getInstance(language=None):
10+
if singleSpacy._instance is None:
11+
singleSpacy(language)
12+
return singleSpacy._instance
13+
14+
def __init__(self, language=None):
15+
language = language or languages.ENG
16+
singleSpacy._instance = spacy.load(language.ISO_639_1.lower())

chatterbot/storage/mongodb.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ def filter(self, **kwargs):
124124
or_regex = '|'.join([
125125
'{}'.format(re.escape(word)) for word in search_text_contains.split(' ')
126126
])
127+
# try matching whole words rather than part; for example 'hi' shouldn't match 'white'
128+
or_regex = '\\b' + or_regex + '\\b'
127129
kwargs['search_text'] = re.compile(or_regex)
128130

129131
mongo_ordering = []

chatterbot/tagging.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import string
22
from chatterbot import languages
3-
3+
from chatterbot import singleton_classes
44

55
class LowercaseTagger(object):
66
"""
@@ -17,13 +17,12 @@ def get_text_index_string(self, text):
1717
class PosLemmaTagger(object):
1818

1919
def __init__(self, language=None):
20-
import spacy
2120

2221
self.language = language or languages.ENG
2322

2423
self.punctuation_table = str.maketrans(dict.fromkeys(string.punctuation))
2524

26-
self.nlp = spacy.load(self.language.ISO_639_1.lower())
25+
self.nlp = singleton_classes.singleSpacy.getInstance(language)
2726

2827
def get_text_index_string(self, text):
2928
"""

install.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
# may need to install/ update Cython
4+
# python3 -m pip install -U Cython
5+
6+
if
7+
# for arm architecure, need to set BLIS to generic for install to work
8+
lscpu| head -n 1 | grep -q 'aarch\|arm'; then
9+
echo "Setting BLIS_ARCH to generic"
10+
export BLIS_ARCH='generic'
11+
fi
12+
echo "Installing Chatterbot"
13+
python3 -m pip install .
14+
15+
# change 'en' to any other language if desired; by default the small model is downloaded
16+
# but this can be changed; for example: change 'en' to 'en_core_web_lg' for the large model
17+
# then will need to create corresponding shortcut link; for example: python3 -m spacy link --force en_core_web_lg en
18+
echo "Downloading and linking spaCy en model"
19+
python3 -m spacy download en

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ nltk>=3.2,<4.0
44
pint>=0.8.1
55
python-dateutil>=2.7,<2.8
66
pyyaml>=5.1,<5.2
7-
spacy>=2.1,<2.2
7+
spacy>=2.2,<2.3
88
sqlalchemy>=1.3,<1.4
99
pytz

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ max_line_length = 175
2323
exclude = .eggs, .git, .tox, build,
2424

2525
[chatterbot]
26-
version = 1.1.0
26+
version = 1.1.1
2727
author = Gunther Cox
2828
email = gunthercx@gmail.com
2929
url = https://github.com/gunthercox/ChatterBot

0 commit comments

Comments
 (0)