Iris Predicting Chatbot on Telegram powered by DialogFlow

Iris Predicting Chatbot on Telegram powered by DialogFlow

Build your first Machine Learning integrated chat bot on Google's DialogFlow!

Any Machine Learning model is pretty much useless unless you put it to some real life use. Running the model on Jupyter Notebook and bragging about 99.99% accuracy doesn't help. You need to make an end-to-end application out of it to present it to the outer world. And chatbots are one fun and easy way to do that.

Building chatbots has never been so easy. Googles's DialogFlow is an obvious choice as it's extremely simple, fast and free! Before proceeding, try out the app for yourself first here!

The Flow

Now that you've tried it, coming to building the complete application, we'd be going over below steps:

  1. Your Machine Learning Model (Iris predictor, in this case)
  2. The DialogFlow Chatbot which fetches inputs from user
  3. A Flask app deployed on any public host which renders the request and response
  4. A webhook call which your chatbot makes to the flask api to send the data and fetch the result
  5. Integrating DialogFlow with Telegram

We'll go over each step one by one. Let's first take a look how the architecture of our complete app will look like:

The architecture of our app

What is happening?

So the user has access to the Telegram chatbot which we will be built on DialogFlow and integrate with Telegram later. The conversation starts and the chatbot prompts the user to input the Data, which are the flower dimensions (Petal length, Petal width, Sepal length and Sepal width). Once the chatbot receives the last input, it will trigger a webhook call to the flask API which will be deployed on a public host. This flask API consists of our app which will retrieve the 4 data points and fit that to our Machine Learning model and then reply back to the chatbot with the prediction. You can find the complete code at my Github.

Now let's go over each step!

Building the components

The ML model

First let's build a basic ML model which take Iris dimensions and predicts the Iris type. No rocket science here. Just a very basic model which renders result with descent accuracy. Below is the bare bones code to that quickly.

#import all necessary libraries
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

#Load data
iris = load_iris() 
X = iris.data      
y = iris.target

#Train test split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42, test_size = 0.25)

#Define and fit to the model
clf = RandomForestClassifier(n_estimators=10)
clf.fit(X_train, y_train)
predicted = clf.predict(X_test)
print(accuracy_score(predicted, y_test))
print(clf.predict(X_test))

#Save the model as Pickle
import pickle
with open(r'rf.pkl','wb') as model_pkl:
    pickle.dump(clf, model_pkl, protocol=2)

We just load the data and fit it to Random Forest classifier. No need of cleaning the data as the dataset is already clean extremely small. I am not diving into any optimization here just to avoid complexity as our main aim is not the model accuracy but the complete application. Then just pickle the model and later this model, 'rf.pkl', will then be loaded in our flask app.

DialogFlow Chatbot

Now let's dive straight into DialogFlow to make our chatbot. You can use other APIs and frameworks as well to build a chatbot but Google's DialogFlow is an obvious choice as its easy, free and super quick to build! Go to DialogFlow and sign in with your Google account. Then click on 'Create Agent' to create your chatbot.

No alt text provided for this image

Next we need to create an intent which will ask the user for data and make a webhook call. Let's first edit the Default Welcome Intent to make it ask for a 'Yes' or 'No' from user.

No alt text provided for this image

Now as soon as the user types 'Yes', DialogFlow should call another intent which will ask the user for inputs and store the data points in 'Entities'. Here we are dealing with simple random numbers so we don't need to create our custom Entities. DialogFlow has default Entities in place to handle such data. So we need to create a 'Yes- FollowUp Intent' for this intent because that intent will be called after a positive reply from the user.

No alt text provided for this image

Click on 'Add follow-up intent' > 'Yes'. You can rename this intent to something else if you want. I will rename this to 'IrisData'. Now we need to add the entities, which will hold the data received from the user. We will just use the default @sys.number entity here for all the 4 inputs. Make 4 different parameters for the 4 data points needed from user - Petal Length, Petal Width, Sepal Length, Sepal Width. Make sure to add the prompts as well to ask the user for inputs separately.

No alt text provided for this image

Train the model with a few inputs so that it knows what to expect. You can test the chatbot now on the right panel to check if it is performing accordingly.

Once done, you'll need to enable fulfillment by 'Enable webhook call for this intent'. By doing this, this particular intent will make a webhook call to our app deployed on public host, which is Heroku. We now need to build the flask app and deploy it on Heroku and then put the URL in the 'Fulfillment' tab which is available on the left side.

Flask app on Heroku

We now need to build our flask app which gets the webhook call from our chatbot, retrieves the data, then fits to the ML model (rf.pkl) and returns back the fulfillment text to DialogFlow with the prediction. Below is the code:

# Importing necessary libraries
import numpy as np
from flask import Flask, request, make_response
import json
import pickle
from flask_cors import cross_origin

# Declaring the flask app
app = Flask(__name__)

#Loading the model from pickle file
model = pickle.load(open('rf.pkl', 'rb'))


# geting and sending response to dialogflow
@app.route('/webhook', methods=['POST'])
@cross_origin()
def webhook():


    req = request.get_json(silent=True, force=True)
    res = processRequest(req)
    res = json.dumps(res, indent=4)
    r = make_response(res)
    r.headers['Content-Type'] = 'application/json'
    return r

Once this is done, we need to process the fulfillment request from DialogFlow which is in JSON format to retrieve data. The fulfillment request looks something like this:

No alt text provided for this image

So we need to get into 'queryResult' >> 'parameters' >> 'number', 'number1', 'number2', 'number4'. Once retrieved, we will dump these data points into an array and slam it to our model and get the prediction.

# processing the request from dialogflow
def processRequest(req):


    result = req.get("queryResult")
    
    #Fetching the data points
    parameters = result.get("parameters")
    Petal_length=parameters.get("number")
    Petal_width = parameters.get("number1")
    Sepal_length=parameters.get("number2")
    Sepal_width=parameters.get("number3")
    int_features = [Petal_length,Petal_width,Sepal_length,Sepal_width]
    
    #Dumping the data into an array
    final_features = [np.array(int_features)]
    
    #Getting the intent which has fullfilment enabled
    intent = result.get("intent").get('displayName')
    
    #Fitting out model with the data points
    if (intent=='IrisData'):
        prediction = model.predict(final_features)
    
        output = round(prediction[0], 2)
    
    	
        if(output==0):
            flowr = 'Setosa'
    
        if(output==1):
            flowr = 'Versicolour'
        
        if(output==2):
            flowr = 'Virginica'
            
        #Returning back the fullfilment text back to DialogFlow
        fulfillmentText= "The Iris type seems to be..  {} !".format(flowr)
        #log.write_log(sessionID, "Bot Says: "+fulfillmentText)
        return {
            "fulfillmentText": fulfillmentText
        }


if __name__ == '__main__':
    app.run()

Once this is done, we just need to deploy the code on public host. I have chosen Heroku as again, it is easy, free and super quick! You just need to add below files to your new Github repository: the flask app, the model pickle file, a Procfile (this is very essential and helps Heroku locate the flask app), and a requirements text file which tells Heroku which all libraries and versions to pre-install to run the app correctly.

Just make a repository on your Github and go to Heroku. Create a 'New App' and 'Connect' your Github repository there. Once connected, just hit the deploy button and you are done!

No alt text provided for this image

The Webhook call

On to the final step now. We now need to connect our deployed app to our chat bot. Just enter the URL on which your app is deployed and add '/webhook' to it. Remember from the flask code above that the app is routed to '/webhook'. Just go to the 'Fulfillment' tab on the left panel in DialogFlow, enable 'Webhook' and just add the <your_app's_URL>/webhook.

No alt text provided for this image

And you are done! (Don't forget to click on save button!) You can test on the right panel by initiating a chat to test if the webhook request/response is working fine. You should get the fulfillment response back with the prediction.

Integrating with Telegram

Coming to final step. Nothing much to do here as integrating web apps with DialogFlow is very easy. We first need to go to Telegram to generate a dummy bot there and generate its token. Search for 'BotFather' and click on 'new bot'. It will ask you for the bot name. Enter any name as you wish. It will then prompt you to enter a username.

After you have done that, a token and a link for your bot will be generated there. Just copy that token and go to DialogFlow 'Integrations' panel on the left. Enable Telegram there, paste the token you just generated and click on start. That's it! Now just head on to the Telegram bot link and try out the app!

要查看或添加评论,请登录

社区洞察

其他会员也浏览了