Creating a LINE bot w/ Flask - Conversate with your Bot
In 1966, there was a bot named ELIZA, a psychotherapist who has the ability to communicate with a patient. She was written by Joseph Weizenbaum to mimic the rogerian physician, Carl Rodgers, well-known for rhetorically answering his patients. Here is an example of ELIZA in action:
ELIZA: Is something bothering you ?
YOU: Men are all alike.
ELIZA: What is the connection, do you suppose ?
YOU: They are always bugging us about something or other.
ELIZA: Can you hink of a specific example ?
YOU: Well, my boyfriend made me come here.
ELIZA: Is it important that your boyfriend made you came here ?
YOU: He says I'm depressed much of the time.
ELIZA: I'm sorry to hear that you are depressed.
YOU: It's true. I am unhappy.
ELIZA: Can you explain what made you unhappy ?
...
As you could see, this is quite phenomenal given that it was written in the '70s and it is capable of attempting the Turing Test. Now, shall we implement this in our bot? But first, dependencies.
# Install nltk package
pip install nltk
nltk.chat.eliza
ELIZA is built on pattern recognition. So each response is returned based on certain keywords within the user's input. There are two variables that need to be addressed: (1) a dict
of reflections for pronoun substitution (e.g. I <-> you etc.), and (2) a tuple
of response pairs, i.e. a regex matcher and a list of possible responses. This is already written in the nltk package, all we have to do is make some tweaks and implement it using the LINE Messaging API.
After installing the nltk package, we need to create a nltk.chat.util.Chat
object and override the converse()
method. The original method works as an infinite loop and outputs the response string to STDOUT
.
import nltk
class ElizaBot(nltk.chat.util.Chat):
"""
Inherit from `nltk.chat.eliza.eliza_chatbot` module and
override the converse method.
"""
def converse(
self,
user_input,
quit=["goodbye", "good bye", "bye", "see you"]
):
"""Override the original converse model of the nltk.util.Chat class
"""
# If user ends conversation, return one of escapes
if user_input.lower() in self._escapes:
return random.choice(self._escapes)
# Chat with ELIZA otherwise
while user_input[-1] in "!.":
user_input = user_input[:-1]
response = self.respond(user_input)
return response
Now we could add the bot object to our main function of our bot, and see the results. If you haven't got a LINE bot, create one following the steps here.
...
# Initialize chatbot instance
bot = chat.ElizaBot()
# Text message handler
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
# Retrieve user metadata
user_id = event.source.user_id
user_msg = event.message.text
# Log user metadata
print(f"\nUser: {user_id}")
print(f"Message: {user_msg}\n")
# Generate response
resp = bot.converse(user_msg)
# Reply user
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=resp)
)
There are also other "characters" in the nltk.chat
module such as SunTzu, Zen, and a teenage junky Iesha. By experimenting these different characters, you might notice that there is a lack of realism in some ways because these "models" actually have no understanding of languages. Of course, we could use neural conversational language models, but that's for another day.
References
- Wikipedia - ELIZA
- Natural Language ToolKit (NLTK)