I am trying to create a chatbot with rasa nlu that will help with hotel search. I created a small sqlite database containing the names and other description of a few restaurants. This is the structure of my database
Name Cuisine Price ambience location rating
Flower Drum chinese high 2 south 5
Little Italy italian high 2 south 2
Quattro mexican low 2 center 3
Domino's Pizza fast food mid 0 east 3
I trained the interpreter on some custom intents like this.
## intent:hotel_search
- I'm looking for a [Mexican](cuisine) restaurant in the [North](location) of town
- Which is the [best](rating) restaurant in the city
- Which restaurant has the most [rating](rating) in the city
- I am looking for a [burger](dish) joint in the [south](location) of the city
- I am trying to find an [expensive](price) [Indian](cuisine) restaurant in the [east](location) of the city
This is the code for training the interpreter
def train(data, config_file, model_dir):
training_data = load_data(data)
trainer = Trainer(config.load(config_file))
trainer.train(training_data)
model_directory = trainer.persist(model_dir, fixed_model_name = 'chat')
This is the code for finding hotels from the sqlite database
def find_hotels(params):
# Create the base query
query = 'SELECT * FROM hotels'
# Add filter clauses for each of the parameters
if len(params) > 0:
filters = ["{}=?".format(k) for k in params]
query += " WHERE " + " and ".join(filters)
# Create the tuple of values
t = tuple(params.values())
# Open connection to DB
conn = sqlite3.connect('hotels.sqlite')
# Create a cursor
c = conn.cursor()
# Execute the query
c.execute(query, t)
# Return the results
return c.fetchall()
This is the code for responding to the input message
# Define respond()
def respond(message):
# responses
responses = ["I'm sorry :( I couldn't find anything like that",
'{} is a great hotel!',
'{} or {} would work!',
'{} is one option, but I know others too :)']
# Extract the entities
entities = interpreter.parse(message)["entities"]
# Initialize an empty params dictionary
params = {}
# Fill the dictionary with entities
for ent in entities:
params[ent["entity"]] = str(ent["value"])
print("\n\nparams: {}\n\n".format(params))
# Find hotels that match the dictionary
results = find_hotels(params)
print("\n\nresults: {}\n\n".format(results))
# Get the names of the hotels and index of the response
names = [r[0] for r in results]
n = min(len(results),3)
# Select the nth element of the responses array
return responses[n].format(*names)
But when I test the interpreter with this example
I am looking for an expensive Chinese restaurant in the south of the city
This is the result I get
params: {'price': 'expensive', 'cuisine': 'chinese', 'location': 'south'}
results: []
I'm sorry :( I couldn't find anything like that
If I were to remove the expensive word from the input question I get a proper result such as this
I am looking for a Chinese restaurant in the south of the city
params: {'cuisine': 'chinese', 'location': 'south'}
results: [('Flower Drum', 'chinese', 'high', 2, 'south', 5)]
Flower Drum is a great hotel!
The bot is able to recognize all the entities but, it is not able to select the right data from the database as there is no data entry by the name expensive in the price colomn in the database. How do I train the bot to recognize the word expensive as high
You can add synonyms in your nlu.md. Add this to your file and 'expensive' gets mapped to high:
## synonym:high
- expensive