IBM

Watson Solutions

for

Machine Learning

Achieving Successful Results Across

Computer Vision, Natural Language

Processing and AI Projects

Using Watson Cognitive Tools

Arindam Ganguly

www.bpbonline.com

FIRST EDITION 2021

Copyright © BPB Publications, India

ISBN: 978-93-90684-700

All Rights Reserved. No part of this publication may be reproduced, distributed or transmitted in any form or by any means or stored in a database or retrieval system, without the prior written permission of the publisher with the exception to the program listings which may be entered, stored and executed in a computer system, but they can not be reproduced by the means of publication, photocopy, recording, or by any electronic and mechanical means.

LIMITS OF LIABILITY AND DISCLAIMER OF WARRANTY

The information contained in this book is true to correct and the best of author’s and publisher’s knowledge. The author has made every effort to ensure the accuracy of these publications, but publisher cannot be held responsible for any loss or damage arising from any information in this book.

All trademarks referred to in the book are acknowledged as properties of their respective owners but BPB Publications cannot guarantee the accuracy of this information.

Distributors:

BPB PUBLICATIONS

20, Ansari Road, Darya Ganj

New Delhi-110002

Ph: 23254990/23254991

MICRO MEDIA

Shop No. 5, Mahendra Chambers,

150 DN Rd. Next to Capital Cinema,

V.T. (C.S.T.) Station, MUMBAI-400 001

Ph: 22078296/22078297

DECCAN AGENCIES

4-3-329, Bank Street,

Hyderabad-500195

Ph: 24756967/24756400

BPB BOOK CENTRE

376 Old Lajpat Rai Market,

Delhi-110006

Ph: 23861747

Published by Manish Jain for BPB Publications, 20 Ansari Road, Darya Ganj, New Delhi-110002 and Printed by him at Repro India Ltd, Mumbai

www.bpbonline.com

Dedicated to

My Mother Moli Ganguly,

My Partner in life Sugandha Ghosh

&

My True Friend Dipanjan Bosu

About the Author

The author has being working in one of the top Multinational Companies in India for several years. He has been proven his expertise in the field of Web Application Development and Machine Learning for quite some time. He is a dedicated Machine Learning Engineer now and has proven his knowledge in several domains. He has consulted with various clients full time and freelance for over a decade. He has done Masters in Computer Applications and also teaches in several tech forums.

About the Reviewer

Alan Bluck is a systems architect providing a broad range of services, with over 45 years IT experience. He has been a Solutions Architect for IBM for over 10 years. His experience includes high level technical design, through mentoring for code development and installation and configuration of IBM’s core products. He is responsible for high-level analysis and configuration on existing and new IBM systems He is also responsible for mentoring and troubleshooting high-level systems and issues, ensuring that scheduled timelines are maintained and deadlines are met. He has over 45 years Software Development experience in both Business and Scientific systems; 5 years’ experience as a Project Manager / Analyst Developer, 11 years as a Software Development Manager for a team of 12 Software Engineers, 11 years as a Technical Consultant, 16 years as a Systems Architect and 3 years as the founding Director of ASB Software Development Limited. He has two recent IBM Certifications for "The IBM DataFirst Method" and "Hybrid Cloud 2016" courses. He has a B.Sc. in Biochemistry from the University of Kent, Canterbury, United Kingdom. He is a Member of the British Computer Soxciety (MBCS) and is a Chartered Information Technology Professional (CITP).He is also a British Computer Society, (BCS) Digital IT Apprentice End Point Assessor (for Software Development).

Acknowledgement

I would like to thank my mother for being my motivation and her continued support. I would also like to thank my best friends for their continued support and pushing me to go forward with this project.

I am grateful to my mentors and teachers and all the open source online content creator for sharing such wonderful tutorials for all of us. I would also like to thank all the computer researchers who has published such wonderful papers and has brought wonderful advancements into the world of Machine Learning and AI.

Finally, I would like to thank all the members of BPB, especially Manish Jain, for guiding and staying with me for so long to bring out the best from me.

Preface

This book educates the reader to not only build their machine learning skills, but also to take it to the next level by showing how to deploy an end to end project. The book takes the reader through a refresher to the basic concepts of machine learning including the basic mathematical details and then introduces the reader to some wonderful platform to build and deploy these concepts. This book also shows how some of the complex machine learning problems can be tackled with less to no code at all. Finally, the book guides the user step by step to deploy the machine learning projects and how to expose them as web application.

This book focuses on understanding and building concepts through hands on approach and is pushed to the next level by extending the project that has been built while learning the previous concepts. The reader learns the theoretical concepts and starts implementing them in Python. Once the user is conversant in implementing these concepts in Python, the user is taken to a platform to deploy these codes. Once the reader has deployed the codes, a web application is built to use them. At each step the reader is also shown how Watson provides some wonderful tools to all of these without having to code.

The primary target of this book is not to teach machine learning concepts but to show a professional how the programming skills can be harnessed to deploy an end to end project into production and maintain an industry standard.

The book follows the following steps in a hands on approach:

Chapter 1 refreshes the reader with the history and background of Machine Learning and the various mathematical concepts required to understand the machine learning concepts. Using which we will build a very small machine learning solution.

Chapter 2 introduces the reader to deep learning and it’s concept. Deep learning is one of the advanced machine learning mechanisms that are used in the current times. The reader will be able to understand how Artificial Neural Networks are built and built a small project here as well.

Chapter 3 refreshes the reader with some feature engineering concepts and metrics to evaluate the machine learning performance model. Here the reader will also be given some Python refresher which might be able to help the user to revise some of the Python Programming concepts.

Chapter 4 introduces the reader to IBM Watson and IBM Cloud environment. Here the reader will create an IBM Cloud account and create a chatbot which will be able to interact with the reader like a human and solve a real life business problem with no code at all.

Chapter 5 will show the user how to use Python programming skills to deploy the machine learning solutions to IBM Cloud in production and expose API. The reader will be able to test out the APIs developed for the machine learning solution built.

Chapter 6 will enable the reader to optimize the solutions built. The reader will try out different model as well as tweak the hyper parameters to obtain a better model in Python. Finally, the reader will be introduced to Auto AI which will do all the heavy lifting that the reader has gone through till now while building and optimizing a machine learning model with not even a sinle line of code.

Chapter 7 will introduce the reader to another great IBM Watson tool pertaining to image recognition.

Chapter 8 will introduce the reader to Natural Language Processing concepts and will show the user how to use these concepts to solve a Natural language processing problem using another wonderful tool provided by IBM Watson specific to Natural Language Processing.

Chapter 9 will focus specifically on deploying and exposing the machine learning models to web application interface by building Python server. This chapter will also introduce the user to two of the best tools of IBM Watson – Tone Analyzer and Text to Speech. The user will learn how to use them into production and deploy them in web application.

Chapter 10 will guide the reader step by step to deploy the chatbot built earlier by the reader and will be confident enough to expose any machine learning solution through IBM Watson tools.

Downloading the coloured images:

Please follow the link to download the

Coloured Images of the book:

https://rebrand.ly/nc1oc4c

Errata

We take immense pride in our work at BPB Publications and follow best practices to ensure the accuracy of our content to provide with an indulging reading experience to our subscribers. Our readers are our mirrors, and we use their inputs to reflect and improve upon human errors, if any, that may have occurred during the publishing processes involved. To let us maintain the quality and help us reach out to any readers who might be having difficulties due to any unforeseen errors, please write to us at :

errata@bpbonline.com

Your support, suggestions and feedbacks are highly appreciated by the BPB Publications’ Family.

Did you know that BPB offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.bpbonline.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at business@bpbonline.com for more details.

At www.bpbonline.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on BPB books and eBooks.

BPB is searching for authors like you

If you're interested in becoming an author for BPB, please visit www.bpbonline.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

The code bundle for the book is also hosted on GitHub at https://github.com/bpbpublications/IBM-Watson-Solutions-for-Machine-Learning. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/bpbpublications. Check them out!

PIRACY

If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at business@bpbonline.com with a link to the material.

If you are interested in becoming an author

If there is a topic that you have expertise in, and you are interested in either writing or contributing to a book, please visit www.bpbonline.com.

REVIEWS

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at BPB can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about BPB, please visit www.bpbonline.com.

Table of Contents

1. Introduction to Machine Learning

Structure

Objectives

Artificial intelligence and machine learning

Types of machine learning

Supervised machine learning

Unsupervised machine learning

Linear regression

Python code for linear regression

Support vector machine

K-nearest neighbour classifier

Conclusion

2. Deep Learning

Structure

Objectives

A brief history of deep learning

Biological neuron

Artificial neuron

Perceptron

Sigmoid neuron

Gradient descent and backpropagation

Gradient descent

Feed forward neural network

Backpropagation

TensorFlow and Keras

Conclusion

3. Features and Metrics

Structure

Objectives

Python refresher

Data analysis with pandas

Metrics

Conclusion

4. Build Your Own Chatbot

Structure

Objectives

What is Watson Assistant?

Intents

Entities

Dialogs

First ever project - the chatbot

Create an IBM ID

Create a resource

The use case

Create your intents

Create your entities

Create the dialogs

Conclusion

5. First Complete Machine Learning Project

Structure

Objectives

Downloading the data

Setting up our environment

Data analysis

Data preparation

Model training

Storing and deploying the model in your Watson Machine Learning repository

Conclusion

6. Perfecting Our Model

Structure

Objectives

Decision tree

Random forest

Grid search cross validation

Auto AI

Prepare dataset

Conclusion

7. Visual Recognition

Structure

Objectives

Setting up the environment for Watson visual recognition

Identify the visual recognition problem

Create custom model

Adding image data

Training

Conclusion

8. Watson Discovery

Structure

Objectives

Natural Language Processing

Scrape and find the right resources

Analyse your documents

Convert document data into raw formats

Filter out junk data

Convert the text to a number using pre-trained embedding

Apply your model

NLP with IBM Watson Discovery

Setting up the environment

Watson discovery news collection

Querying Watson discovery collection

Working with new collections

Annotating

Conclusion

9. Deployment and Others

Structure

Objectives

Building a Python server

Deploying your web application to IBM Cloud

IBM Watson Tone Analyser

IBM Watson Text to Speech

Conclusion

10. Deploy the Food Ordering Bot

Structure

Objectives

Link your dialog skill to your assistant

Other ways to deploy a Watson Assistant

Create a Python application to use the Watson Assistant API

Conclusion

Index

CHAPTER 1

Introduction to Machine Learning

Artificial intelligence (or AI) is a term in today’s world that lights up the eyes of not only people in the IT or technology industry, but also people without any connection to IT. AI is now not only a demand in the industry but also a necessary item in the toolkit to keep the pace up in the growing market. Unfortunately, to find the correct resource to possess the knowledge of AI is no less than a treasure hunt.

Before we begin, you should know that this book does not teach you web development and it does not teach you how to be a machine learning expert either. This book is about harnessing the power of IBM Watson cognitive tools into production using the machine learning and web development skills that you may already possess. Machine Learning and web development are completely different subjects and there are thousands of books just on these topics. Although there is a brief introduction to machine learning and deep learning, I will urge you to go ahead and hone your web development and machine learning skills after you complete the book and then come back to enhance all the solutions that you build here.

Now, let us try to unravel the mystery behind artificial intelligence and machine learning.

Structure

The following topics will be covered in this chapter:

- Artificial intelligence and machine learning

- Types of machine learning

- Linear regression

- Support vector machine

- K-nearest neighbor classifier

Objectives

- To get introduced to artificial intelligence and machine learning and understand their differences and misconceptions that float around them.

- To understand the basic classification and difference between supervised and unsupervised machine learning.

- To get introduced to some supervised machine learning algorithms such as linear regression and SVM, and implement them in Python

- To get introduced to one of the most popular unsupervised machine learning algorithms—K-nearest neighbor and implement it in Python

Artificial intelligence and machine learning

Let us try to break the ice by first removing some popular misconceptions. People tend to think that artificial intelligence and machine learning are synonymous but they are actually not. Artificial intelligence is a broader umbrella covering machine learning. According to Wikipedia, “In computer science, artificial intelligence (AI), sometimes called machine intelligence, is intelligence demonstrated by machines, in contrast to the natural intelligence displayed by humans and animals.” This implies that any machine demonstrating human-like intelligence can be said to be artificially intelligent. Let us understand with an example.

Suppose we create a set of logical conditions which contain all possible combinations of moves in a 3x3 tic-tac-toe game against all possible moves of the opponent as shown in the figure 1.1.

Figure 1.1: A basic breakdown of the Tic-Tac-Toe game by some of its possible moves

We program this set of logical conditions into a computer to play the game against a human. Then, it might be possible that the computer wins in most of the games. The computer is intelligent enough to determine which move to make for every move that the opponent makes in a game using the set of logical conditions fed to it. Here, we can say that we have created an artificially intelligent program to play tic-tac-toe with any opponent by itself.

Now, let us understand what machine learning is. Machine learning is a subset of AI. According to Wikipedia, “Machine learning (ML) is the study of computer algorithms that improve automatically through experience. It is seen as a subset of artificial intelligence. Machine learning algorithms build a mathematical model based on sample data, known as "training data", in order to make predictions or decisions without being explicitly programmed to do so.” This means that instead of feeding the computer a predefined logic or a set of conditions, we show the computer some data—more specifically—some input data and their corresponding output data. Based on this datam the computer tries to discern a pattern (or an equation which in Wikipedia is described as a mathematical model). Now, the computer is said to be trained and the data shown to the computer is generally called training data. The computer then gives the output to a new set of input data for which the output data is unknown using the pattern (or equation) that the computer built during the training exercise.

Coming back to the tic-tac-toe example, in machine learning algorithms, the computer can be fed with a set of game recordings (like a lot of recordings). The computer then, based on these recordings, builds its own set of conditions (some of which might even lead it to lose the game) which allows it to play tic-tac-toe with any opponent.

At this point of time, you might be thinking as to why should one opt for training a computer with machine learning algorithms when there is a sure chance of winning if we feed it with artificial intelligent conditions as opposed to machine learning algorithms?

The number of conditions to be built and fed for a 3x3 tic-tac-toe are finite, but think about a 9x9 tic-tac-toe game. It almost becomes impossible for a person to keep track of and build all the possible moves. One would rather keep a recording of all the moves and feed it to the computer. Of course, our aim is not to build a tic-tact-toe game but to solve real-world problems like credit-card fraud detection or stock price prediction where we don’t even know what might be the next move. Most real-world problems tend to have infinite and mostly unpredictable set of possible outcomes. Hence, machine learning algorithms are a go-to solution for any big industries in today’s time.

Now that we have entered the territory of machine learning, let us start scratching the surface with the types of machine learning.

Types of machine learning

“The term machine learning was coined in 1959 by Arthur Samuel, an American IBMer and pioneer in the field of computer gaming and artificial intelligence.” – Wikipedia

In general, all machine learning algorithms are mainly classified into two categories:

- Supervised machine learning algorithms

- Unsupervised machine learning algorithms

Supervised machine learning

Imagine you are teaching a child how to recognize a cat from a dog (imagine he/she has never seen a cat or a dog). You might show him/her different pictures of cats and tell him/her that these are what you call cats. Then, you show him/her different pictures of dogs and you say that these are what we call dogs. The child will try to find out some characteristics (what we call in ML terms “features”) which will cause the distinction and the recognition of cats and dogs. For example, dogs generally have a nose and mouth outward from the face whereas cats don’t, dogs have longer ears than cats, and so on. Now, the next time you show a picture of a cat or a dog, the child will be able to determine what the picture is of based on those characteristics.

This is exactly how supervised machine learning algorithms work. We feed some data into the computer and annotate them to let them know what each data output signifies. Based on their features, the computer decides to form a mathematical model so that it can predict the output of some unknown data. We will delve deeper into some of the algorithms to make things clearer.

Unsupervised machine learning

Unsupervised machine learning algorithms are mainly used for classification purposes where we don’t quite know the class of each data sample. Similar to supervised machine learning algorithms, we feed the data into the computer, but we don’t tell the computer what output each data signifies; or in other words, we don’t annotate the data to its proper classes. Instead, we let the computer decide what each data sample signifies. The computer itself labels an output to each data sample based on some features and that also the computer itself decides.

Now to make things clearer, let us take a look at one of the most important supervised learning algorithms.

Linear regression

One of the most important, basic, and frequently-used algorithms in machine learning is linear regression. Machine learning tries to form a functional equation from a problem which can be solved by passing in the required parameters. For example, if there is a problem of predicting the number of screws to be bought for manufacturing a keyboard and it can be seen from the data that to manufacture a keyboard, 8 screws are needed, then the equation simply becomes f(x) = 8x where x is the number of keyboards to be manufactured or the number of orders of keyboards.

In real-life scenarios, the problems won’t be that simple and it would be next to impossible to derive a fixed equation from the problem statement. So, the next best idea is to plot the points (x and f(x) of the problems, i.e., the parameters and the result) and find the nearest straight line that might fit the points. This method of fitting a line is called linear regression and this approach is the basis of most of the machine learning algorithms.

Let us try to understand the algorithm by starting with the basics that we learnt in school.

Recall that one of the most useful and famous equations that we learned in high school was as follows:

y=mx+c

If you joggle your head, this is the famous equation of a line where

- x is the co-ordinate value of x-axis

- y is the co-ordinate value of y-axis

- m refers to the slope of the line

- c is the y-intercept

The following figure shows a visual representation of the equation.

Figure 1.2: Graphical representation of equation of a line, y=mx+c

If you remember, we learned how to solve a system of simultaneous linear equations in high school. We can say that in the equation, with the given two sets of x and y values, we can come up with values of m and c. Now, once we know the line (values of m and c), we can find out the value of any y given the x value. This is the concept used in the linear regression algorithm of machine learning. In real-world problems, the x is not a single value but a set of values, i.e., a matrix. So, the line that we try to draw becomes a hyper-plane when one y value corresponds to a set of x values. The equation then becomes as follows:

y = a0 + a1x1 + a2x2 + a3x3 + … + anxn

People from the Statistics world might recognize this as curve fitting and that’s exactly what it is. So, we gather values for each of x1, x2, x3,…, xn and their corresponding y values. This will give us a set of equations as follows:

y1 = a0 + a1x11 + a2x12 + …. + anx1n

y2 = a0 + a1x21 + a2x22 + …. + anx2n

y3 = a0 + a1x31 + a2x32 + …. + anx3n

…..

yn = a0 + a1xn1 + a2xn2 + …. + anxnn

Hence, we have a set of values for all the x and their corresponding y and we have to calculate the values of all the coefficients a.

If the math has already bored you, let us take an example and understand. Suppose we are given the task of calculating the median house value from a set of features such as population, total rooms, total bedrooms, latitude, longitude, etc. You can download the dataset from here:

https://www.kaggle.com/camnugent/california-housing-prices

If you open the dataset, you will see the following:

Figure 1.3: California Housing Dataset from Kaggle

The first column is the desired output, i.e., the median house value (the y values) and the rest can be thought of as each values of x (like latitude is x1, longitude is x2, and so on)

People with a knowledge of matrix and linear algebra can imagine the x values as matrix (X) and coefficient values, and y values as vectors (or, single column matrix, Y and A) and can form the equation as follows:

Y = ATX

Now, there is something called the normal equation which gives you the direct formula to calculate the coefficient matrix. This is as follows:

A = (XTX)-1XTY

But we can also ask the computer to learn the values of the coefficients. Now, here comes the most interesting part. Let us understand what we mean by learning. How can a machine learn?

LEARNING

“Failures are the pillars of success”

To understand how a computer learns, let us go back to our childhood when we learned how to walk and how to ride a bicycle. If you remember your good old childhood days, we did not get straight away get a formula to walk or ride a bicycle. We started off by making mistakes when we first got on our bicycle or started to walk and our parents used to point out what the mistake was. Based on that, we corrected ourselves and finally one fine day, we were perfect. We could walk or take a bicycle out on our own.

We will use a similar procedure to make the computer learn. We will first let the computer take random values for the coefficients. Then, we will define something known as the loss function. This function will point out to the computer how many mistakes it is making. The computer will correct its path based on the mistakes.

The loss function that we will define is the mean squared error loss function:

Here, Y’ is the value that we get when we calculate the output value using the coefficients we derive at each step and Y is the true value of Y. Also, m is the number of samples of data. Let me explain what we mean by true value and derived value.

When we receive a sample of data for learning, we keep aside a set of data (generally 25%) for testing later on and the rest of the data for training. Now, for any supervised algorithm, we already have the Y values in the dataset (for example, the median house value in the dataset you downloaded). This is the true value. Now during learning, we first set random values of coefficients (ai values). We calculate the values of Y for each equation using these random coefficient values and X values. These values of Y that we get are the predicted values or derived values.

We then calculate the error done by using the loss function. We correct the values of the coefficient matrix based on the error and again calculate the predicted Y values for this new set of coefficient values.

Each such iteration is called an epoch. We set the maximum epoch value before starting the learning algorithm. After the maximum iteration (or epoch), we stop and take the test data that we had set aside and predict the values of Y using the final values of coefficients we got at the end of the maximum epoch.

We can then say that the computer has finally learnt the values of the coefficient.

But after we are done with the testing data, we can try to estimate how well our computer has learned. One such important estimate is given by cross-validation scores.

That seems like enough of math to get confused. The next section of this chapter is for the people from the world of computer programming.

Python code for linear regression

We are going to use the favourite programming language of data scientists, Python. If you are already familiar with Python and have it set up in your system, you are free to skip the installation part. The code for this chapter is present in the GitHub link as follows:

https://github.com/gangulyarin/codes

To set up our work environment, we need to make sure that we have Python. We will be using Python 3 for this. Go to python.org and follow the installation instructions to install the latest version of Python 3 into your system. At the time of writing this book, the Python version is Python 3.7.7.

Now, we need to have pip installed in our system. This is supposed to be installed along with Python. To check your pip installation type, the following is your command prompt

$ python3 -m pip –version

Now, we need an editor to write our code. There are a lot of useful editors for Python:

- Jupyter

- Pycharm

- Python IDE

There are many more. You can try to check them out. But even if you don’t, that is alright. You can even write this in Notepad, but it is always encouraged to have a good editor that you are comfortable with.

Next, let us set up our directory. It’s good to be well organized. We are going to have everything under a folder named ML_Project.

$ mkdir ML_Project

$ cd ML_Project

Now, place the dataset that we had downloaded in this folder. Next, let us install four of the most important Python packages using pip.

pip install matplotlib numpy pandas scikit-learn

Once these are installed, you are ready to start. Let us understand what the significance of these packages are:

- Matplotlib: This package is used to visualize data in plots and graphs.

- NumPy: This package is used for numerical calculations..

- Pandas: This package contains a lot of a data analytical tools

- Scikit-learn: This is the package which has all the machine learning algorithm implementations.

Now pull up your favourite editor and let’s start coding.

Firstly, let’s import all the packages.

import pandas as pd

import numpy as np

from sklearn import linear_model

from sklearn.model_selection import train_test_split

test_train_split is used to divide data into training and test set that we will look at just now and the linear_model module contains the linear regression algorithm.

Now, let’s read the data with the help of pandas. Here, we are going to use a dataset that has been already provided by scikit-learn to predict the price of a house in Boston (similar to the dataset we saw previously).

from sklearn.datasets import load_boston

boston_data = load_boston()

Now, we have to convert the data into something called as DataFrame. It is one of the convenient containers in Pandas package to hold a dataset. We will also divide the data into X (features) and Y (output values).

X = pd.DataFrame(boston_data.data, columns = boston_data.feature_names)

Y = pd.DataFrame(boston_data.target)

Scikit-learn actually simplifies this by having them in separate units—data and targets.

Now, the first step of any machine learning problem is to feature engineering. We first examine the data and find out the features which are necessary by finding the ones which have high correlation with the output. Then, we examine those features individually and make them in an appropriate format for the algorithm to ingest. Fortunately, the dataset that scikit-learn provides doesn’t need any such feature engineering.

Next, we take the data and divide it into test and training set. To value our machine learning algorithm in the end, we must make sure first that the test and training data never overlap. We do this using the function train_test_split. This function takes random samples of data and places a percentage of dataset into the test set and the rest in the train set.

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.25, random_state=42)

Here, 0.25 is the percentage of data that we want in the test data and the rest in the train data. We keep the testing set (x_test, y_test) aside for us to test later.

Now, all the machine learning algorithm will work on is the training set (x_train, y_train) only. So, let us now ask our computer to run the linear regression machine learning algorithm on our train dataset. To do this, let us create a linear regression model instance and train our dataset by fitting into the linear regression model instance.

lin_reg = linear_model.LinearRegression()

lin_reg.fit(x_train, y_train)

This will run the linear regression algorithm on the training set and form the coefficient matrix for the equation to fit. You can view the coefficients using the following line:

print(lin_reg.coef_)

So now that the equations are ready, you can print and see the Y values that it calculates for the test set.

y_pred = lin_reg.predict(x_test)

print(y_pred)

Figure 1.4: Output of y_pred

Figure 1.5 shows some of the y_pred values. You can check the values by printing y_test values. But why take the pain ourselves? Let us estimate the error by having some kind of metric and let us choose the same error metric that we saw for linear regression calculation, i.e., mean square error.

from sklearn.metrics import mean_squared_error

print(mean_squared_error(y_test, y_pred))

This is what we’ll get:

Figure 1.5: Output of mean squared error

Congratulations! You have successfully programmed your first linear regression model. That wasn’t so hard! All thanks to the wonderful package scikit-learn.

Linear regression is not only used for predicting unknown values. They can also be used for classification problems. Classification problems are mainly used to discern whether a feature set value leads to a certain class (for example, credit card fraud or not, tumour malignant, or benign etc.)

There are also multi-class problems where linear regression decides which class the feature set value leads to (for example, picture is of a dog, cat, or cow).

There is a good example of a code in the scikit-learn documentation which you can find here: https://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html

Before moving on to unsupervised algorithm, we will briefly take a look at another supervised learning algorithm which is very popular. We will not go in as deep as linear regression but you can consider it an exercise to explore and implement it after you get the idea.

Support vector machine

Support vector machine is another very powerful supervised learning algorithm mainly used for classification problems. Linear regression models generally fail in case of non-linearity but this is where support vector machines shine. It can also perform outlier detection.

The fundamental idea behind support vector machine is that it tries to draw a soft margin boundary to separate one class from another. Consider the following figure.

Figure 1.6: Outlier in a plot

The red line is the decision boundary (not the line that the linear regression model equates to) which separates the data points into two classes. We have coloured the data points in blue and green to differentiate the true class of the data. As you can see, a few data points are on the wrong side of their respective classes. These are called outliers. But that is the best linear regression can come up with.

Support vector machine on the other hand creates a soft margin based on the hyper-parameter C that we provide. If we set it to a low value, we end up with the model on the left of figure 1.8.

Figure 1.7: Different values of C for SVM

With a high value, we get the model on the right. Margin violations are bad. It’s usually better to have few of them. However, in this case, the model on the left has a lot of margin violations but will probably generalize better.

It’s up to you to explore and experiment with this model as an exercise.

Let us move on to an unsupervised machine learning algorithm in the next section.

K-nearest neighbour classifier

As you might have guessed, this is an unsupervised machine learning algorithm used for classification problems. Look at figure 1.9.

Figure 1.8: A clear classification plot to the human eye

By looking at it, any human can say that the data points can be divided into two classes, even if we do not say which data point belong to which class. The data points on the upper right can be considered to be of one class (say, Class A) and the lower left data points of another class (say, Class B). But is it so obvious for a computer?

Let us analyse our own observations. How did we classify the data points? From plain sight, we can say that any point at the top right is very far from the ones at the bottom right. Also, select any point at the top right. It is relatively closer to any point in Class-A than any point on Class-B as seen in the next figure. Hence our deduction.

Figure 1.9: Deduction of the plain sight classification of a plot

It turns out that we can make our computer follow the same procedure to classify data points into separate classes. And the fun part is we don’t need any annotation or label as output for the true (or correct) class as we needed in the case of a supervised learning algorithm.

We will only need two hyperparameters – distance function and neighbourhood.

There are several methods to calculate the distance between two points in a graph plot such as Euclidean distance, Manhattan distance, Minkowski Distance, etc.

We can simply use Euclidean distance to calculate the distance between the two points as follows:

Distance =

The other hyperparameter that we need is neighbourhood. We have to tell our algorithm to compare the distance between a certain number of data points around it to discern the class. For example, if we set this value to 3, then it will take the distance of three of its nearest data points and see which class they belong to and put it to a vote. Based on this, it will decide which class it will belong to.

Let us again try to code and solve a machine learning problem using the k-nearest neighbour classifier.

We will use the famous iris dataset in this example. This is a famous dataset that contains the sepal and petal length and width of 150 iris flowers of three different species: iris setosa, iris versicolor, and iris virginica.

The code is as follows:

Figure 1.10: Iris Classification code using KNN

The only thing one needs to know about the code is the function k-neighbor classifier which does the classification. It takes two hyper parameters. These are as follows:

- n_neighbors which is the count of neighbourhood data points to consider.

- The distance hyperparameter which is default to Minkowski but we have set it to Euclidean.

Conclusion

So, we now have a basic decent idea of machine learning. We now know how it is not traditional artificial intelligence and how it grew out to become a larger branch. We do not only explore concrete the countable possibilities that a solution to a problem might have, but we can also map an equation to a solution using methods such as linear regression relating to the same way that our brain works.

We also saw that machine learning problems can be of two types – classification and regression.

Also, machine learning algorithms are of two types broadly - supervised and unsupervised machine learning algorithms. Supervised machine learning algorithms take into consideration historical data (solutions) and try to align an equation to the data trend. Unsupervised algorithms on the other hand try to cluster data points in a n-dimensional plane.

We learnt two supervised learning approaches – linear regression and support vector machines and an unsupervised algorithm – k-nearest neighbour classifier. We are also confident in coding these algorithms in Python using scikit-learn, one of the foremost packages in Python used for machine learning algorithms.

In the next chapter, we will explore deep learning, an advancement of machine learning which has slowly developed to be an independent branch of artificial intelligence in the recent times. We will also learn some deep learning algorithms and learn to code them in Python.

CHAPTER 2

Deep Learning

We have seen that machine learning allows computers to almost learn the same way a human would. We have seen how to tackle real-world problems with mathematical equations which represent common problems and align the solution to the equation. We have also seen how to use Python and its machine learning package Scikit-Learn to avoid building these equations and algorithms from scratch and just make a few calls to some predefined functions to use these equations.

We now feel confident enough to use the power of machine learning to solve some of the most complex problems in the real world. But the traditional machine learning could only solve problems which can be thought of in terms of the equations, or at least closely aligned to these equations. Hence, some problems were very far from being solved (for example, language translation had a very bad performance when traditional machine learning approaches were advocated). In such cases, it is necessary to understand how the human brain works.

In this chapter, we will learn about deep learning which is a branch of artificial intelligence that tries to mimic how human brain cells work and tries to solve a problem in a way that the human brain would instead of applying stringent mathematical equations.

Structure

The following topics will be covered in this chapter:

- A brief history of deep learning

- Biological neuron

- Artificial neuron

- Gradient descent and backpropagation

- TensorFlow and Keras

Objectives

- Understanding the advent of deep learning and a quick walk through how our brain cells (neurons) function.

- To try to build a basic logical and mathematical model based on our knowledge of neurons called perceptron. We will then move on to formalizing this model into a more practical and current model called sigmoid neuron.

- Start understanding how we can make them functional using some popular concepts and algorithms such as gradient descent and back propagation respectively.

- Check out the famous Python packages - TensorFlow and Keras to harness our understanding of computer programming.

A brief history of deep learning

Everything about deep learning did not begin with complex computer programs or equations. To mimic the brain, scientists had to first understand how the brain worked. Understanding the working of our brain was not a new thing. It dates back to the 19th century when Joseph von Gerlach first proposed that the nervous system works as a single network of discrete cells. Camillo Golgi studied this in much detail and examined the brain tissue. This was the first time that anyone got an idea of how the brain tissue might look like. It was still in the late 1890s when Santiago Ramón y Cajal proposed that the nervous system is actually made up of discrete individual cells forming a network. Then, the term "neuron" was coined by Heinrich Wilhelm Gottfried von Waldeyer-Hartz around 1891.

After 1950, with the invention of the electron microscope, it was confirmed that nerve cells were individual interconnected cells. Finally, in the 1900s, McCulloch and Pitts proposed a simplified model of a neuron.

So although deep learning has made its mark in the recent times, it was the 19th century that started it all.

Biological neuron

We are not going to go deep into biology but an understanding of the components of our brain can help you relate with artificial neurons that we will build. Figure 2.1 is an image of the neuron taken from Wikipedia.

Figure 2.1: Biological Neuron (The image is taken from Wikipedia)

As you can see from, figure 2.1 above, the various components of a neuron are as follows:

- Dendrite

- Synapse

- Soma (labelled as cell body)

- Axon

To understand how these components work, you must keep in mind that neurons work by receiving signals from various parts of our body (like skin, eyes, etc.) or another neuron from its network, processes the signal, and outputs a response to another neuron in its network.

Now, let’s fit the components together in the following story.

- Dendrite is the one that receives the signal either from the other neuron or a body part.

- Synapse is the connection between various neurons that hold them together.

- Soma does the complex processing that determines our response.

- Axon is the part that outputs the signal.

We are not going to go any deeper than this, but we will keep this in mind to connect our artificial neuron with the biological neuron.

Artificial neuron

The first artificial neuron design was a very simple one designed by McCulloch and Pitts and we call it the McCulloch Pitts neuron.

Figure 2.2: McCulloch Pitts neuron

With reference to Figure 2.2 above, all the xi are the input signals. g is known as the aggregate function which aggregates all the inputs into one and takes it to the next function f which takes the decision. As you can see from the figure, the inputs are defined binary (either 0 or 1). The definition of the functions is as follows:

g(x1, x2,….,xn) = g(x) = ∑xi

y = f(g(x)) = 1, if g(x)>=θ

= 0, if g(x)<θ

where θ is the thresholding parameter.

The significance of this design is that it can represent a lot of Boolean functions (Refer to figure 2.3 which is as follows)

Figure 2.3: AND, OR, and NOR gates represented by the McCulloch Pitts neuron

Let us understand one of the preceding Boolean functions—AND gate.

We know that the truth table of AND and OR gate is as follows:

A

B

A & B

A or B

0

0

0

0

0

1

0

1

1

0

0

1

1

1

1

1

Table 2.1: And gate and Or gate truth table

In short, we can say that the output is 1 only when all the inputs are 1 for an AND gate.

So, f(g(x)) = 1 when all xi are 1. So for a 2 input gate x1+x2>=2, only then the f(g(x)) = 1. Hence, our threshold θ is 3.

Similarly, for a 3 input AND gate, it should be 3 and so on.

For an OR gate, we know that the output is 1 if any of the input is 1 and 0 otherwise. Hence, x1+x2>=1, only then will f(g(x)) = 1. Hence, threshold for an OR gate is 1.

Try to work out for other Boolean functions. If you do so, you will find that it is not possible to build such a function for the XOR gate. Let us try to understand why.

If we think about our output f(g(x)) geometrically in a 2D co-ordinate system and plot the truth table for an OR gate, we will get the following figure 2.4.

Figure 2.4: Geometrical representation of an OR gate

As you can see, the line gives us a decision boundary. Anything above that line gives us a 1 output and the ones below are 0.

But if you notice, we can do this only for linear decision boundaries which makes it impossible to plot an XOR gate.

Perceptron

Something similar but more formal was brought forward by Frank Rosenblatt. The next figure 2.5 is a representation of a perceptron which might be relatable to you with respect to the McCulloch Pitts neuron.

Figure 2.5: A perceptron

This represents a more general computational model. The main differences are the weights that are attached to the input connections and a default input called bias is added. Hence, the equation now becomes as follows:

y = 1 if ∑wixi>=θ where i ranges from 1 to n, n being the number of inputs.

= 0 otherwise

We can rearrange the previous equation considering the terms only when y = 1.

y = ∑wixi – θ

Let’s assume x0 = 1 and w0 = -θ, then

y = ∑wixi where i ranges from 0 to n.

Now, the inputs can be non-Boolean as well and we can predict the output by adjusting the weights. Thus, to model an OR gate, we can have the following truth table:

x1

x1

x1 OR x2

0

0

0

∑wixi<0

0

1

1

∑wixi>=0

1

0

1

∑wixi>=0

1

1

1

∑wixi>=0

Table 2.2: Inequalities derived from OR Gate

Solving the set of inequalities, we can get the values of weights wi. One possible solution to this set of inequalities is w_0 = -1; w_1 = 1.1; w_2 = 1.1 (since solving inequalities gives multiple possible values)

Similarly, it is possible to get values of weights even if the input values are non-Boolean. But it is still not possible to get values for weights if the gate is an XOR gate.

x_1

x_1

x_1 XOR x_2

0

0

0

∑wixi<0

0

1

1

∑wixi>=0

1

0

1

∑wixi>=0

1

1

0

∑wixi<0

Table 2.3: Inequalities derived from an XOR Gate

The last and second last line in the table would contradict each other while solving the inequality. But still, it is possible to model an XOR gate if we stack another layer of perceptron before reaching the output (Figure 2.6). This is called a multilayer perceptron.

Figure 2.6: Multilayer perceptron

This was all good, but where is the machine learning?

The following section presents to you the perceptron learning algorithm.

It is very obvious that in the perceptron model, all we need is to get the right values for the weights and we are done. So, what we are going to do is initialize weights to random values and try adjusting them until they find the correct place. Keep in mind that since we are learning and hence training, we already know what the output is. We traverse the weight values until we reach the correct output and that is when we say we have reached convergence.

Let us put all the weight values into a vector and all the input and output values into vectors as well.

X = [x_1, x_2,…….xn], W = [w_1, w_2,…….wn], Y = [y_1, y_2,…….yn]

The mathematical details and proof for the algorithm are beyond the scope of this book. But the idea is that the weight vector W keeps turning until it reaches a position with adjusted weight values.

Sigmoid neuron

Let us consider a use case. We are trying to predict the quality of an article to be published in a journal. For this use case, let us consider a single parameter views. This parameter will be the number of views of the article in question.

Now, we have to fix a threshold to determine the output y which will be 1 if the article is to be published and 0 otherwise. Before that, for any neural network architecture, we have to normalize the input values so that the values range between 0 and 1 for ease of computation. Although normalization is a complex process, we will do this by calculating the maximum of the views (lets call it Vmax). For each view (let's call it Vi), the normalized view value will be:

Vi = Vi/ Vmax

Now let us fix a threshold θ = 0.5

So

Y = 1 if ∑Vi>θ (considering all weights are 1)

= 0 otherwise

But consider an article having the view value Vi = 0.4999. Is it favourable to reject the article with the view 0.4999?

To overcome this, computer scientists came up with sigmoid neurons where instead of having a thresholding function, a sigmoid function is used. Check figure 2.7 to understand the difference (the equation for sigmoid function is also given in the figure). Sigmoid function gives a smooth value and is also differentiable at all points (why differentiability is important is a question that we will address very soon).

Figure 2.7: Threshold and Sigmoid Function

Gradient descent and backpropagation

Now that we have a fair idea of what a neuron is, we must now ask ourselves the most important question – Where is the learning?

In artificial neural network, everyday new research brings forward a new learning algorithm. But here, we are going to stick to the basics which are the basis of all modern algorithms - gradient descent.

Now for any learning algorithm, we must have the following set up:

- Data: Here, we must ask ourselves what the data dimension is (both input and output).

- Model: The equation that we think would be suitable to relate the input with the output.

- Parameters: In the case of sigmoid neuron, the learnable parameters are the values of wi.

- Learning Algorithm: A way to learn the previously mentioned parameters.

- Objective function: The measure which tells us how good or bad our learning is going at each step by calculating the error.

Now, let us first take care of the easy ones.

Data will generally be an n dimensional input in Real space.

Model will be the suitable equation, and in the case of a sigmoid neuron, the sigmoid function is the suitable relation between the input and output.

Y = σ(W,X) =, where Y is the output vector, W is the weight vector and X is the input vector.

Now in the case of multilayer neural network, each layer will have several sigmoid neurons and their corresponding XL, WL and YL values at layer L.

Parameters are the WL values at layer L.

We can have a suitable objective function. We will see how to choose a suitable objective function later in this chapter. For the time being, let us take one very popular objective function to know the extent of the error made by the algorithm at each step – MSE (mean square error)

L(w) = (Ytrue – Y), where Ytrue is the expected Y value and Y is the output that we got from the algorithm.

The most important part that we are left with is the learning algorithm. The learning algorithm which we are going to see is gradient descent.

Please keep in mind that all the notations (X, Y, W) are vectors, i.e. they are not single values but a collection of multiple values. We will come to its dimension very shortly.

Gradient descent

Gradient descent is the foundation stone of any neural network algorithm. The main idea behind gradient descent is in its name.

At first, we fix an epoch value which is the maximum number of iterations. At each iteration, we calculate the loss using the loss function and update the parameters (W) by the gradient of the loss.

Gradient is the change of a vector (collection of values) with respect to a parameter. So in this case:

where W is the weight vector and L is the loss value.

But keep in mind that W is different at each layer and for each input in a neuron.

The mathematical details of a gradient are beyond the scope of this book.

Let us formally see the gradient descent algorithm now.

1. Let the input data be X and output data be Y (all vectors of a certain dimension)

2. We initialize the parameter vector W by random values

3. Let epochs be t

4. For each step t

1. Calculate Y = σ(W,X)

2. Calculate L = Ytrue – Y

3. Calculate Gradient

4. Update parameter W = W –

Now, there are a few noteworthy points about gradient descent.

Firstly, the update that we are doing for our parameter is based on the gradient that we calculated on loss, i.e., how much of W should we change based on the the loss function value. Hence, this should point us in the right direction so as to minimize the loss (hence you can reason that we are subtracting instead of adding). But should this always lead us to the correct direction? As it turns out, it does, and plotting the loss function value at each epoch will always give a convex function which can lead the loss to eventually converge. This intuition is also proven mathematically by several computer scientists.

Secondly, there are a number of variants of gradient descent that computer scientists have come up with such as Stochastic Gradient Descent and Nesterov Gradient Descent. Over time, computer scientists have also added new elements to gradient descent to make computations less painful for the computer, such as optimizers and drop-out.

Feed forward neural network

Now that we have a basic idea of gradient descent, we can move on with this idea to understand what a feed forward neural network is. Let us consider an input vector of size n. Similar to a multi-layer perceptron, we consider L-1 layers. These are called hidden layers. Each layer has n neurons. There is also a last output layer which has k neurons where k is the number of output classes. This is a deep neural network since at each layer; all the n neurons are connected to the next layer’s n neurons. Hence in between each layer, there are n×n weights (refer to figure 2.8 given below).

Figure 2.8: Feed Forward Neural Network

The figure also shows biases which are nothing but simple input weights with no output attached to them.

But remember that each neuron is a sigmoid neuron, having an aggregation function and a sigmoid function. It is important to understand that there is a plethora of activation functions that can be used for a deep neural network. But the most widely used and the simplest is the Rectified Linear Unit (ReLU) function. Figure 2.9 given below will help you understand the ReLU function. This function is differentiable and is used widely due to its non-negative nature (as you can see y values do not go below 0).

Figure 2.9: ReLU function

The activation function of the output layer is dependent on the problem use case. This function is either a softmax function or a liner function based on whether the use case is a classification problem or a regression problem. A softmax function gives a probabilistic perception of all the classes (the detailed math is beyond the scope of this book).

Backpropagation

You must have realized that although we have weights and neurons, we only have the inputs and outputs as known values. We still don’t know the weights. Knowing the correct values of weights is the key to learning. And unless we are learning using the neural network, we are effectively not achieving our goal. Hence, to learn, we need to find the correct values of the weights which will give the approximation of the input and output relation.

To do this, we will first initialize the weights randomly. There are several ways to initialize weights randomly. For example, we can take weight values from a normal distribution. Once that is done, we make a forward pass from input to output of the deep neural network. This will give us certain output values based on the weight values, and so to correct them, we calculate the loss of the output value based on the true output values. Choosing a loss function is as critical as choosing an output activation function. The following is a simple table which will be effective in choosing the correct loss function and the output activation function based on the use case.

Outputs

Real Values

Probabilities

Output Activation

Linear

Softmax

Loss Function

Squared error

Cross entropy

Table 2.4: Loss Function Selection based on Use Case

Once the loss is calculated, we take the gradient of the loss function with respect to weights at each layer and we correct the weight values and biases at all the layers for all the weights. Now we make a second pass and repeat the same.

Like a multilayer perceptron problem, we fix an epoch (maximum number of iterations) and repeat the above process. This method of correcting weights based on gradients is called backpropagation.

TensorFlow and Keras

Now that we have been through so many pages of theories covering the basics of neural network, let us be brave enough to join the battalion of deep neural network engineers and take our first step in implementing a deep neural network in Python.

So as a first step, let us install our Python packages. We are going to use Keras (https://www.keras.io). Keras gives us a simple API to implement complex neural networks. It works on top of TensorFlow and so we will need to install TensorFlow to have a Keras backend.

Open up terminal (command prompt for windows users) and install TensorFlow:

pip install tensorflow

It might be a relief for you to know that installing TensorFlow also installs Keras. At the time of writing this book, the latest version of TensorFlow is 2 and TensorFlow 2 is a big leap from TensorFlow 1. This version provides us a simpler API then the earlier version.

Once you are done with installing, pull up your favourite Python IDE and let’s start coding.

We are going to address a simple classification problem. The dataset we will use is the Fashion MNIST dataset. Just like Scikit-Learn, Keras gives you a set of free datasets to use and MNIST and Fashion MNIST are a few of them. Fashon MNIST dataset contains a huge number of items related to fashion such as suits, shirts, shoes, etc.

We are going to learn what the images represent and predict what a new image represents.

So as a first step, let us include the TensorFlow and Keras package into our script.

import tensorflow as tf

from tensorflow import keras

We are also going to need NumPy and pandas for calculation. Let us go ahead and include them as well.

import numpy as np

import pandas as pd

Now let us load the dataset from Keras. Keep in mind that the dataset contains image data, or in other words, pixel data. So each dataset can be considered as an array (or matrix) of pixels. When loading MNIST or Fashion MNIST using Keras rather than Scikit-Learn, one important difference is that every image is represented as a 28 × 28 array rather than a 1D array of size 784. Moreover, the pixel intensities are represented as integers (from 0 to 255) rather than floats (from 0.0 to 255.0).

fashion_mnist = keras.datasets.fashion_mnist

(x_train_full, y_train_full), (x_test, y_test) = fashion_mnist.load_data()

You can check the shape of the train set by x_train_full.shape. One good thing about this dataset is that Keras already has given you the dataset split into the train and test set. This train set will be used to train the neural network but we also need a validation set to calculate how our model has performed. So let us keep aside a few datasets as validation sets for the neural network to calculate the score of the model after training. We will use some values from the test set to see for ourselves how our model predicts. Also, as we know, we need to normalize the dataset in the same way we did earlier by dividing the values by the maximum value. Here, the maximum intensity of a pixel is 255 so we will divide all numbers by 255.

X_valid, X_train = x_train_full[:5000]/255.0, x_train_full[5000:]/255.0

y_valid, y_train = y_train_full[:5000], y_train_full[5000:]

X_test = x_test / 255.0

Now let us come to the fun part – building the model. Type the following code:

model = keras.models.Sequential()

model.add(keras.layers.Flatten(input_shape=[28,28]))

model.add(keras.layers.Dense(300, activation="relu"))

model.add(keras.layers.Dense(100, activation="relu"))

model.add(keras.layers.Dense(10, activation="softmax"))

Let us see what is going on here.

We first initialize a sequential model. A sequential model is used to define a neural network in Keras. Then, we add an input layer.

Now as you know, output dimension is a matrix; we need to change it to a vector (or simply called an array) to provide the input. Hence, we tell Keras the shape of the input dimension and ask it to flatten the matrix from a (28,28) dimension to a 748 dimension vector.

Next we add a dense hidden layer with 300 neurons. It will use the ReLU activation function. Each dense layer manages its own weight matrix, containing all the connection weights between the neurons and their inputs. It also manages a vector of bias terms (one per neuron).

We add another dense hidden layer of 100 neurons. And finally, we have our output layer with 10 neurons (as we have to predict 1 of 10 classes) and keep the activation function as softmax function (as this is a classification problem).

Now before fitting the mode to the dataset, we need to compile the model by assigning the proper loss function and the optimizer. Optionally, you can specify a list of extra metrics to compute during training and evaluation:

model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])

We have used sparse_categorical_crossentropy because we know that the output may be inclusive and sparse. By inclusive, it means one output vector may have several classes having high probabilities. It is sparse because each output vector is supposed to have more false classes than true classes. The other options would have been categorical_corssentropy (if the output vectors would not have been sparse and inclusive) and binary_crossentropy (if there were only two classes to predict).

Now that the model is compiled, let us fit it to our dataset and train.

history = model.fit(X_train, y_train, epochs=30, validation_data=(X_valid, y_valid))

You will see each epoch running and giving us the loss and accuracy at each epoch.

After training, we will see how our model has performed by evaluating the model. The model evaluation will be done based on the validation set that we set.

print(model.evaluate(X_test, y_test))

You should be happy if your first model gives a score of more than 80% as accuracy.

Conclusion

Now we are fairly confident in understanding and building a deep learning model using artificial neural network. We also saw the mathematics behind an artificial neural network and how to get a mathematical model from a basic Boolean truth table to a multilayer perceptron (MLP). We now also understand that a threshold logic has disadvantages as compared to a smooth function such as a sigmoid function. This sigmoid function can also be used in a neuron to build a sigmoid neuron and build a layer of such neurons to give a feed forward neural network. But don’t just stop here! I urge you to look at other deep learning models such as convolutional neural network and recurrent neural networks.

We have also seen a Python package – TensorFlow and its user friendly wrapper Keras that is used worldwide to create deep learning networks and we have also built a basic deep learning model using them.

Although it suffices to build a model from a good dataset having a clear set of X values and Y values, you won’t get such a good dataset in the real world. You will have to create a dataset from a use case and some of this data might even be noisy enough to create a separate system to build a clear dataset. In the next chapter, we will see some techniques to get a clear set of X and Y values from a noisy dataset.

CHAPTER 3

Features and Metrics

We have seen how machine learning models work. We have even built a couple of machine learning models to solve some unique use cases. We saw that these kinds of problems can be solved by just a couple of lines of code. But the world is not that fair. Let me reveal a big secret to you. Coding a model is easier than preparing the data. This chapter will show you why and how you should be ready to face the challenges of data preparation.

We will have some basic mathematics and some basic Python code in this chapter. But fret not; we will have a good amount of prelude to them before going into the details.

Structure

The topics that will be covered in this chapter are as follows:

- Python refresher

- Data analysis with Pandas

- Metrics

Objectives

Get hands-on experience in programming with Python and its basic syntax.

Get hands-on experience in data handling and data analysis using the features of Pandas.

Learn about the various metrics that you can use to understand and evaluate your machine learning performance.

Python refresher

This is not a nightmare for non-programmers. We will go through some basics of Python over here and not take a roller coaster ride. We will look at only those elements which will be needed for our learning. You must have seen at least some programming languages.

Firstly, some trivial operators (arithmetic and logical) which do not need any explanation are as follows:

- + (add)

- - (subtract)

- * (multiplication)

- / (division)

- and (logical and)

- or (logical or)

- not (logical not)

For a full list, you can go to the famous W3schools site:

https://www.w3schools.com/python/python_operators.asp

Some trivial data types are int (integer), float (real numbers), and str (string). But we need to know some non-trivial data types as well. These are as follows:

- Array: Arrays are a collection of values of a similar data type. For example, [5,8,64,47854,12,555] is an int array (denoted by square brackets).

- List: Lists are a collection of values not necessarily of the same data type. For example, [“Five”,8.225,64,47854,”Twelve”,555] is a list (denoted by square brackets as well).

- Tuple: Tuples are the same as lists with a small difference which is that the values in tuples cannot be changed. Tuples are denoted by round brackets such as (“Five”,8.225,64,47854,”Twelve”,555)

- Dictionary: Dictionaries are a collection of key value pairs where the keys are of a data type and the values are of a different data type. They are denoted by braces such as {"name" : "John", "age" : 36}.

Other than these, there are some trivial program elements such as if-then-else, for loops, and functions. The only difference in Python when compared to any other programming language is that there is no concept of braces ({}) to enclose a scope. Rather, the scope is determined by indentation.

- If-else:

if num>0:

abs_num = num

else:

abs_num = num*-1

- For loop:

for num in range(0,5)

print(num*2)

- Function:

def add(a,b):

c = a + b

return c

The preceding bullet points are self-explanatory, except the for loop part where we are using range. The range function returns a list of numbers from the first number (0 here) to one less than the second number (5 here). So, the for loop iterates from 0 to 4. We can mention a third argument which will specify the step. By default, it is 1. The indentation can go deeper if there are nested scopes.

One last important element that we will talk about is the packages and the import statement. Just like in the previous chapters, we need a number of packages pre-built with a huge number of features to help us with our code. One such package we used in the previous chapters is the sklearn package. Another very important package is the pandas package which we will discuss here very soon. All these packages are imported into the code using the statement import <package name> so that we can use their functions in our code. The different ways we use import statement are as follows:

- import numpy

- import pandas as pd

- from sklearn import linear_models

In the first bullet, we need to use the full package name in order to avoid name collisions, such as numpy.ndarray(). In the second bullet, we can use an abbreviation we created so that it’s easy to use the short names instead of using the full name, such as pd.DataFrame(history). In the third bullet point, we imported the specific element we want to use. Now that we have a fair amount of clarity of the Python syntax, we will move to one of the main packages in data science – Pandas.

Data analysis with pandas

Pandas is the major tool used in data analysis. As it was mentioned before, the maximum effort required to solve a machine learning problem is given to data preparation and this is where Pandas comes into the picture. Pandas provides some simple data structures which can be used to analyse and manipulate data so as to best fit our problem and align our thoughts to the machine learning models that we know of.

We have kept the data file ready in GitHub in case you want to follow along in your favourite Python editor.

By using pandas, we can read any data file such as a csv in just a single line of code.

import pandas as pd

df = pd.read_csv("housing.csv")

In the read_csv function, we can also mention a list of columns that we want it to read, the number of rows to read, etc. But the main thing to note here is what the function returns. The Pandas read_csv returns a Pandas data structure called a DataFrame. Considering a data file containing a table of data, the DataFrame automatically assigns an index to each row and stores it in an object called index and stores the set of columns in an object called columns. We can check the index and columns as follows:

print(df.index)

print(df.columns)

In a machine learning problem, these columns are the features that we will assume to form our own model. Hence, it is very important to know how to manipulate and use these features as columns in Pandas.

The Pandas DataFrame also provides a set of functions to get an initial idea of the data. We can use df.head() to view the first 5 data rows and df.info() to view the number of rows and the object type of each columns. This is what we got after using df.info():

<class 'pandas.core.frame.DataFrame'>

RangeIndex: 20640 entries, 0 to 20639

Data columns (total 10 columns):

#   Column              Non-Null Count  Dtype

---  ------              --------------  -----

0   longitude           20640 non-null  float64

1   latitude            20640 non-null  float64

2   housing_median_age  20640 non-null  float64

3   total_rooms         20640 non-null  float64

4   total_bedrooms      20433 non-null  float64

5   population          20640 non-null  float64

6   households          20640 non-null  float64

7   median_income       20640 non-null  float64

8   median_house_value  20640 non-null  float64

9   ocean_proximity     20640 non-null  object

dtypes: float64(9), object(1)

memory usage: 1.6+ MB

Now, we can see very clearly that there are a few missing pieces in the data since the total_bedrooms column has 20433 data. To resolve this, Pandas provides us with a simple function fillna. By using fillna, Pandas fills up all the missing values with a value of our choice. We can provide a large negative number or the mean of all the other values in the column. The simple one-liner to do this is as follows:

df.total_bedrooms = df.total_bedrooms.fillna(-999)

print(df.info())

<class 'pandas.core.frame.DataFrame'>

RangeIndex: 20640 entries, 0 to 20639

Data columns (total 10 columns):

#   Column              Non-Null Count  Dtype

---  ------              --------------  -----

0   longitude           20640 non-null  float64

1   latitude            20640 non-null  float64

2   housing_median_age  20640 non-null  float64

3   total_rooms         20640 non-null  float64

4   total_bedrooms      20640 non-null  float64

5   population          20640 non-null  float64

6   households          20640 non-null  float64

7   median_income       20640 non-null  float64

8   median_house_value  20640 non-null  float64

9   ocean_proximity     20640 non-null  object

dtypes: float64(9), object(1)

memory usage: 1.6+ MB

This line of code also introduces us to another important element of the Pandas DataFrame which is accessing the values of a column of a DataFrame. As you can see, we have accessed the column values by simply using df.total_bedrooms. Pandas allows us to use column names as properties of the DataFrame. We can also access the columns using two-dimentional array notation.

features = [

f for f in df.columns

]

df_original = df.copy()

for col in features:

df.loc[:, col] = df[col].astype(str).fillna("NONE")

The above line of code converts all columns to string using astype() and fills all the missing values of the columns to NONE. But before everything, we are keeping a copy of the original DataFrame using the copy() function. Notice how we have accessed the column values in the second line of the code using loc. By using loc, we can access the DataFrame in the same way we will access a two-dimensional array. The : in the first index implies all values. So df.loc[:,col] implies all the values of col column. We also see the same columns being manipulated in the right-hand side of the = but by simply using the column index as df[col]. Keep in mind that col is the name of the column in string. For example, to access a column, just write df["population"] where population is the column name. Another important point to notice in the code is the loop in the first line. This is a short-hand form of using a loop and assigning to a variable. To break it down, the code should be as follows:

features = []

for f in df.columns:

features.append(f)

print(features)

There is another way of accessing data in Pandas which is worth mentioning, that is, using iloc. iloc is similar to loc except that we can even use the column numbers instead of the exact column names. So, if we want to access all the data of column RM, we can simply write df.iloc[:,4] as total_bedrooms is the fifth column according to the indices shown in the output of df.info().

Pandas also allows us to operate on multiple columns and gives us a new column by simply using the operator with the column index as follows:

df[new_column] = df[column1]+df[column2]

Sometimes, we might also want to remove a column or filter some specific values of the column. For example, if we want to remove the RM column, we simply write:

df2 = df.drop(["ocean_proximity"], axis="columns")

Here the first argument of the drop function is the column name. The second argument is the axis, which tells whether we remove the column or row. Instead of row and column as the axis, we can also give 0 and 1 respectively.

If we want to filter some values off the AGE column so that only data containing AGE>30 is present, we write:

df_original["housing_median_age"] = df_original[df_original["housing_median_age"]>30]

Pandas also offers us a way to view the data in a histogram form with the help of another package called matplotlib. Suppose we want to visualize how the AGE feature is spread out. We first import the matplotlib package and call the hist function on the DataFrame column. Finally, to view the histogram, we show the visualization using the show() function of matplotlib. The code for this is as follows:

import matplotlib.pyplot as plt

df.housing_median_age.hist()

plt.show()

The output is as given in figure 3.1.

Figure 3.1: Histogram generated using Pandas]

We can also view all the histograms by omitting the column name and using df.hist().

You need to know one last thing about feature manipulation before moving on to the next section which is handling categorical columns. For this, we will use another dataset catdat.csv.

import pandas as pd

df = pd.read_csv("catdat.csv")

print(df.info())

This will give us the following:

<class 'pandas.core.frame.DataFrame'>

RangeIndex: 600000 entries, 0 to 599999

Data columns (total 25 columns):

#   Column  Non-Null Count   Dtype

---  ------  --------------   -----

0   id      600000 non-null  int64

1   bin_0   582106 non-null  float64

2   bin_1   581997 non-null  float64

3   bin_2   582070 non-null  float64

4   bin_3   581986 non-null  object

5   bin_4   581953 non-null  object

6   nom_0   581748 non-null  object

......

20  ord_4   582070 non-null  object

21  ord_5   582287 non-null  object

22  day     582048 non-null  float64

23  month   582012 non-null  float64

24  target  600000 non-null  int64

dtypes: float64(6), int64(2), object(17)

memory usage: 114.4+ MB

As you can see, there are a lot of columns having the data type as object. If we want to see the first five rows, we can use the head() function of Pandas as discussed previously. This will give us the output as shown in figure 3.2.

Figure 3.2: Using head() to get the first five rows of the table]

As you can see, most of the data is in the form of a category. For example, the column bin_4 is either Y or N. Let us check a few of the column values. To get the number of rows grouped by each category, we can use the value_counts() function. To make this clearer, note the output of value_counts when applied to nom_0:

print(df2.nom_0.value_counts())

This will give us the following:

Red      323286

Blue     205861

Green     52601

Name: nom_0, dtype: int64

This output tells us that the column nom_o contains 323286 values “Red”, 205861 as “Blue” and 52601 as “Green”. Now to handle such columns, we need to convert them into some numerical value. To convert them into some numerical value, we need to encode them. One very important encoding mechanism which is used in almost all machine learning problems is the “one hot” encoding. Let us first understand the concept of “one hot” encoding.

Let us consider the following column values:

nom_0

Red

Blue

Red

Red

Green

Blue

Blue

Red

Green

Red

When converted to “one hot” representations, we get the following:

norm_0_1

norm_0_2

norm_0_3

1

0

0

0

1

0

1

0

0

1

0

0

0

0

1

0

1

0

0

1

0

1

0

0

0

0

1

1

0

0

Table 3.1

As you might have realized from the above column values, the column value is broken down into three values: norm_0_1, norm_0_2, and norm_0_3 as there are three categorical values – Red, Blue, Green. Red value is represented by keeping norm_0_1 to 1, norm_0_2 to 0 and norm_0_3 to 0. Similarly, the Blue value is represented by keeping norm_0_1 to 0, norm_0_2 to 1, and norm_0_3 to 0. Lastly, the Green value is represented by keeping norm_0_3 to 1 and the others to 0. This is what the “one hot” vector encoder does. Now to code this, we first need to make sure that we have gotten rid of all the missing values, or else they will also be a category. The Python code after removal of missing values is as follows:

from sklearn import preprocessing

ohe = preprocessing.OneHotEncoder()

df["nom_0_ohe"] = ohe.fit_transform(df["nom_0"])

To check the contents, convert the column into array and print:

print(df["norm_0_ohe"].toarray())

These feature engineering techniques are the starting point of our machine learning solutions. Now that we have a fair amount of idea how the features should be engineered to fit our models better, we can move to the last part of the machine learning solution which is evaluation using metrics.

Metrics

To get an idea of how our model performed, we need to evaluate our model using some kind of metric. Now we already have an intuition of accuracy. But accuracy is not the best fit in all kinds of use cases. So, we introduce you to some other metrics required for the evaluation of machine learning models.

First, let us understand what is accuracy and why it is not the best fit for all problems.

Consider a classification task where we have a training dataset containing 100 samples of class A and 100 samples of class B. After training using some model, if we get an accuracy of 90% (or a score of 0.90), then we can safely say that the model has recognized 180 samples correctly and 20 samples wrongly. Now let us modify our dataset a bit. We now have 150 samples of class A and 50 samples of class B. We train again and get an accuracy of 90%. But can we say that the sample has recognized 90% of 150 samples (135 samples) of class A correctly and 45 samples (90% of 50) of class B correctly? Since the total accuracy of the model is 90%, it is possible that it classified all samples of class B as class B but correctly classified only 80% of 150 samples (120 samples) of class A correctly (90+10 percent of class B and 90-10 percent of class B which comes to a total of 90 percent of the total sample). The reason for this is the dataset is skewed.

In such cases, we need something called precision. But before understanding precision, we need to know a few concepts. Suppose we have a problem to predict whether a set of data values implies that it belongs to class A or not. Then:

- True Positives: True positives (TP) are predictions where the model predicts that the dataset implies it belongs to class A and the actual dataset also says that it belongs to class A.

- True Negatives: True negatives (TN) are predictions where the model predicts that the dataset implies it does not belong to class A and the actual dataset also says that it doesn’t belong to class A.

- False Positives: False Positives (FP) are predictions where the model predicts that the dataset implies it belongs to class A but the actual dataset says that it doesn’t belong to class A.

- False Negatives: False Negatives (FN) are predictions where the model predicts that the dataset implies it does not belong to class A but the actual dataset says that it does belong to class A

Now, precision is the accuracy of the positive predictions. Mathematically,

Precision = TP / TP + FP

This will help us resolve the problem that we were facing while calculating accuracy if the data set is skewed. Suppose we have a dataset of 80 samples of class A and 20 samples of another class (not class A), and our model predicts 60 (out of 80) samples correctly as belonging to class A and 10 samples (out of the 20 negative samples) wrongly as belonging to class A, then our precision is 60/(60+10) ≈ 0.86 as it has correctly identified 60 samples belonging to class A out of the 70 samples it predicted to belong to class A.

Similarly, there is another very important metric called recall, sometimes also called sensitivity or True Positive Rate (TPR). Recall can mathematically be defined as

Recall = TP / TP + FN

Assuming the previous example of the dataset having 80 samples of class A and 20 samples of another class (not class A), and that our model predicts 60 (out of 80) samples correctly as belonging to class A and the rest 20 (out of 80) samples not belonging to class A, then our recall is 60/(60+20) = 0.75 as it has correctly identified 60 positive samples out of 80.

Another similar metric for evaluation which is widely used is F1 score which is the harmonic mean of precision and recall.

All the three metrics precision, recall and F1 score are available in Scikit-learn. You just need to import them as follows:

from sklearn.metrics import precision_score, recall_score, f1_score

To use these functions, you need to pass the true value as the first parameter and the value predicted by your model as the second parameter. For example:

precision_score(y_train, y_train_predicted)

Now you need to understand that you cannot have the cake and eat it too. You need to make a trade-off between precision and recall. To understand the reason, consider two use cases which are as follows:

1. Suppose we are given a problem to predict a tumour malignant or not based on the x-ray image provided. Here, we need a good precision score as we do not want to have any false positive because telling a patient that the person’s tumour is malignant even though it actually is not can be disastrous! But we can afford to have a few false negatives where the model might predict that it is not malignant although it actually is. We can move on to other tests to confirm the model’s predictions. So recall can be low but precision must be high.

2. Suppose we are given a problem to identify shoplifting from CCTV footage of a shopping mall. Here we need a good recall score because we cannot afford to have a false negative. Imagine having high false positives instead (high precision instead of recall) and predict some honest customers performing shoplifting even though they were not! Instead, we can afford to have a few false negatives where we predict that the customer is not a shoplifter even though he/she is.

To have a good balance between them, we need to have a threshold between negative predictions and positive predictions so that the more we move the threshold towards positive predictions, we allow more false positives (more precision score) and if we move it other way, we allow more false negatives (more recall score). To get a set of thresholds and their corresponding precision score and recall score, Scikit-learn provides us with a handy function called precision_recall_curve.

from sklearn.metrics import precision_recall_curve

precisions, recalls, thresholds = precision_recall_curve(y_train, valid_preds)

Here, y_train is the target (y) values or class labels of the training data and valid_preds is the set of predictions the model made as true positives.

We need to find a sweet spot in the precision recall curve where the threshold is fair enough to give a good precision score as well as recall score. Of course, this will depend on the use case that was mentioned earlier.

The receiver operating characteristic (ROC) curve is another common tool used with binary classifiers. It is very similar to the precision/recall curve, but instead of plotting precision versus recall, the ROC curve plots the true positive rate (another name for recall) against the false positive rate (FPR). The FPR is the ratio of negative instances that are incorrectly classified as a positive. It is equal to 1 – the true negative rate (TNR).

from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(y_train, valid_preds)

One way to compare classifiers is to measure the area under the curve (AUC). A perfect classifier will have a ROC AUC equal to 1 (the lesser, the worse) which ranges from 0 to 1.

from sklearn.metrics import roc_auc_score

roc_auc_score(y_train, valid_preds)

So to summarize, we can conclude that any machine learning problem has the following sections:

- Engineering your features to best fit your model by removing missing values and mapping your categorical values to numbers, etc. (all the tricks we learnt in the first section of this chapter)

- Building your model

- Evaluateing your model

Conclusion

We have gained an idea of working with Python. People with a prior idea of programming will find it a piece of cake to go through the Python refresher. People newer to the idea of programming might have to refer to the documentation and tutorials available to get their hands a bit more comfortable in writing Python code.

Once we have a fair amount of ease into the Python landscape, we can rightly jump into data analysis with Python as this is the part where Python beats all its peer programming languages. We have been introduced into the basics of data analysis using Pandas, the best data analytics package. We have seen how to get data from CSV files, gather, and analyse its summary and if needed encode some categorical columns for our machine learning code.

Once we are done with data analysis and building our machine learning algorithms, we have to evaluate our algorithm’s performance using some metrics. We have learnt some of these metrics in the last part of this chapter.

In the next chapter, we will start with a wonderful machine learning project but with minimal or no code.

CHAPTER 4

Build Your Own Chatbot

Whenever we consume a product as a customer in any sector such as telecom, banking services, etc., we are provided with a platform where we can reach out to in case we need any assistance regarding the product. This platform is generally known as a customer care service. We are provided with an email or a telephone number where we can reach out and the concerned person assists us with the common problems that a customer can face.

As automation is taking over the world, businesses are also looking to automate this customer care service so that there can be less human intervention. But the problem with automating this is understanding the problem that the customer faces. We as customers can converse with the customer care executive, and may be with a series of questions, we can explain our problem.

In this modern era of AI, we can see that whenever we visit a commercial website, we are greeted by a chatbot popup. This chatbot does exactly the same as a customer care executive does. We can converse with the bot and explain our problem with the product. The chatbot can even suggest us an appropriate product based on our needs after a conversation.

In this chapter, we will build one such chatbot which can suggest an appropriate product based on a conversation with us.

IBM Watson has a number of cognitive solutions which can cater to a huge plethora of use cases. One such solution is the IBM Watson Assistant.

IBM Watson Assistant provides us with a wonderful toolset to build a chatbot based on any business need. We can even take the chatbot and share it or deploy it in a web application.

Before jumping right into building the bot, let us first understand the building blocks that we will use to create a complete chatbot.

Structure

The following topics will be covered in this chapter:

- What is Watson Assistant

- Intents

- Entities

- Dialogs

- First Ever Project – The Chatbot

Objectives

- Get an idea of what Watson Assistant provides as a way to develop chatbots

- Get to know the basic building blocks of any chatbot, i.e., the intents, entities, and dialogs. Understand how they work together and how to create custom intents, entities, and dialogs to build an amazing chatbot for a real-life use case.

- Finally, create an IBM cloud account and get hands-on training to create a real-life chatbot.

What is Watson Assistant?

Watson Assistant is one of the several services provided by IBM Watson to create a Chatbot specific to any range of business requirements. This tool does not require any sort of programming; rather we can set up logic using its building blocks to suit our needs. The chatbot we will create is known as an assistant.

IBM Watson Assistant also allows our assistant to publish in social media such as Facebook, publish as an independent web application, or integrate with our own web resources using the wonderful API it provides.

An assistant is built with the following building blocks:

- Intents

- Entities

- Dialogs

Let us look at each of them one by one.

Intents

Intents are the objectives or goals that your users will want to accomplish at any given time. In other words, intents are what the chatbot can do or address. You can make a list of all the goals that you anticipate your user would want the chat to address for them and they become the intents of the assistant. For example, if one of the intents of a weather assistant is to answer what the humidity percentage is, then ask_humidity can be kept as an intent and the intent should contain some sample utterances. Utterances are some of the ways in which the user can ask the assistant, for example “What is the humidity percentage value today?” or “Can you please tell me how much the humidity percentage is today?”

Entities

Entities are terms which are used in the context of a particular intent to differentiate the flow of an intent. For example, a town can be an entity which can be used to identify which town’s humidity a user enquires about.

Dialogs

A dialog can be thought of as a container which captures the intents and entities and directs them to another dialog based on the condition defined in them. A set of dialogs are connected in the form of a tree and forms a dialog skill. A dialog skill contains the training data and logic that enables an assistant to help your customers.

Now, let us get hands-on experience building a nice chatbot.

First ever project - the chatbot

As this is the first time you will be doing something in IBM Watson, let us first prepare ourselves to get into the jungle of IBM Watson.

Let us first get comfortable with this awesome tool IBM Watson Assistant. So, open your favourite browser and get started.

Create an IBM ID

As the first step, we need to set up an account in IBM Cloud. This one is pretty easy. Go to https://cloud.ibm.com/registration and set up your account by providing your email ID and a password and verifying the email address and entering your personal account information as shown in Figure 4.1:

Figure 4.1: IBM Cloud Registration Page

Once done with setting up an IBM ID, go to https://cloud.ibm.com/login and provide the email ID used to create the previous credentials just created. Your registered email ID is your IBM ID. Go ahead and log in to your IBM ID in the IBM Cloud login screen as shown in Figure 4.2:

Figure 4.2: IBM Cloud Login Page

Next, enter the password and you are in.

Let us look at how an IBM Cloud account looks like. This is the place where all your IBM Cloud resources are summarized. It will look like the following screenshot:

Figure 4.3: IBM Cloud home page

As you can see, my account has 12 resources. I have one Cloud Foundry app, nine services, one storage, and one developer tool. A new account would not have any of them. As you might have noticed, the left-hand side bar contains the icons of all the resource categories where you can go directly to your resource type.

Next, click on View all in the Resource Summary panel and all your resources will appear on a new page as shown in Figure 4.4:

Figure 4.4: IBM cloud resource list

This is my resource list. I have a few services but a new account may have none. This page will enlist all your resources categorically.

Create a resource

The agenda of this chapter is to create a chatbot. So, let us create an Assistant.

Click on the Create resource button on the top right-hand corner of the page as shown in Figure 4.4.

This page initially shows some recommended and featured services as you can see on the left-hand side bar. As you can see, it already shows the Watson Assistant Resources as shown in Figure 4.5:

Figure 4.5: IBM Cloud Products Catalog

If you want an extensive list, click on Services on the left-hand side bar. This will show a categorical list of all the resources one can use as shown in Figure 4.6:

Figure 4.6: IBM Cloud Services Catalog

If you click on the check box next to AI/Machine Learning in the category group on the left-hand side bar, it will show you only the list of AI/Machine Learning resources. Watson Assistant is an AI/Machine Learning resource (supposed to be the first resource on the AI/Machine Learning List). So, you can click on the Watson Assistant card either here or on the Featured Resources (if it comes up) to create your Watson Assistant resource.

Also, at any point in time, you can type ‘assistant’ on the search bar that appears on every page and the Watson Assistant card shows up.

Once you click on the Watson Assistant card from any of the resource lists, you will be taken to the Create Watson Assistant page as shown in figure 4.7:

Figure 4.7: Watson Assistant Creation Page

On this page, you get a list of pricing for resource creation. Now, as default, a user is kept in a Lite account. All services that you can create in the Lite account are offered free which is pretty good for research and development. But if you want to go for the ones which are not free, you will be prompted to upgrade your account and you will be asked to provide the payment information. Once you upgrade your account, you can use those.

Although, one downside of having a free offering is that you can have only one instance of the service. As you can see from Figure 4.7, since I already have an assistant created from my Lite account, I get a warning stating this:

In this book, we will use everything from a Lite account.

So, select the Lite offering for the Watson Assistant Service, and you can scroll down to change the name of your service. For a Lite account, the resource group would be Default. (If you are interested, you could look at the help on Group resources at:

https://cloud.ibm.com/docs/account?topic=account-account_setup#bp_resourcegroups).

Also, at the top of the page, you might have noticed the Select a Region field. Every Watson Service is taken from the IBM Cloud, and these are a few of the cloud regions. As of now, it won’t matter much but we will look at this later. Let us keep it as is for now.

Click on the Create button on the right-hand side bar at the bottom, and your Watson Assistant resource will be created in about 30 seconds.

Once your Watson Assistant is created, you will be directed to the Manage page. You will be able to see the API key and URL for web integration. We will come to this later. You will also see a Getting Started tutorial link which is a great documentation for beginners. You will get an idea if you take a look at figure 4.8:

Figure 4.8: Watson Assistant launch page

Click on the Launch Watson Assistant button and your first Watson Assistant will open in a new browser tab.

The Watson assistant page shows the start tour pop up where you can take a tour to understand the basics of Watson Assistant as shown in figure 4.9:

Figure 4.9: Watson Assistant Homepage

But we already know what are intents, entities, etc. So, let us start and cancel this and skip to create the assistant.

The Watson Assistant gives us the default skill – My first skill and tells us to create the intent. But first let us look around a bit and get a feel of the environment.

Figure 4.10: Intents Section

As you can see we have different tabs for creating and managing intents, entities, and dialogs. If you hover on the left-most bar, you will see two tabs – Skills and Assistants. Currently, we are on the Skills page. An Assistant is the chatbot that we will deploy and each assistant can have a skill set. So we can prepare different skills like Airport_Customer_care, Restaurant_Customer_care and we can attach each of them to an Assistant and deploy. For the Lite version, we can only attach a single skill to an assistant.

If you click on the Assistant tab, you will see that it already has a default assistant for you – My first assistant. It also has attached the default skill, i.e., My first skill to this assistant and it does not have any integrations as of yet. Integrations are needed for deployment. We will come to this later.

Figure 4.11: Assistants Page

On the right-hand side of this assistant, you can click on the three dots to see the settings. The settings will show the name, API details, and Inactivity timeout. We will need this when we move for deployment.

You can click on the assistant to see the assistant details. On the details page, it shows the Skill details attached to it with the number of dialogs, Integrations, and web chat deployment, as shown in figure 4.12:

Figure 4.12: Skill linked to Assistant

Now before proceeding, let us frame a business problem and understand it.

The use case

In the situation of a pandemic such as COVID-19, we have to stay indoors. Let us build a customer care assistant for a restaurant which can take your order for a meal and your address and be able to deliver the order to your home. The food can be customized based on the user’s taste and the chatbot needs to understand all this without any human intervention.

For any software development problem, the first step is a proper plan. So before doing anything on the computer, let us plan everything.

Let us consider that our chatbot can accept food orders, specifically burger and chicken preparations. We will ask the user which of the two they want and then based on that, we will ask more specific questions about the item. For this use case, let us assume our kitchen can prepare the following burgers - veg burger, chicken burger, and the following chicken preparations – chicken wings, chilli chicken, spicy grilled.

For any Watson Assistant to come into being, we need to properly define the intents, entities, and dialogs. So let us build our intents, entities, and dialogs.

Create your intents

Remember that intents are the goals that the chatbot expects to address. When you are planning, you can have as many intents as you want and never end. But we must have some finite number of objectives for the chatbot and tell the user to contact a human for anything else. Also keep in mind that the user might think that it is a human. So you must also have some casual conversation objectives as well. All intent names start with #. Let us have the following intents:

- #greet: We expect our users to greet when they start their conversations. The IBM Watson provides a welcome dialog node when the chat begins by default. But we also need our assistant to understand when the user greets back. Or else the response to greet would fall into an unknown category and Watson also has a response node for any fallbacks or unknown categories.

- #order: This is the main intent of our assistant. We would definitely want our customer to order food. This intent would capture such user requests.

- #exit: Just like #greet, we also want our assistant to understand when the customer bids adieu.

Let us go ahead and create the intents.

On the left-hand side bar, click on Skills and all your skills will be listed. As of now, you will only have the default skill – My first skill. You can go ahead and create your own food ordering skill here as a new skill or edit the present skill. I have created a new skill by the name Food_Order. You can create a skill by clicking on the Create Skill button, as shown in figure 4.13:

Figure 4.13: Skills page

Once this is done, click on the skill to edit and you will be taken to the Intents tab. Here, you can create the intent by clicking on the Create intent button. You can also create intents by importing a CSV list of intents using the Import intents button:

Figure 4.14: Intents Page

After clicking on the Create intent button, you will be asked to enter a name for the intent and an optional description. So, let us create the most important intent which pertains to our business use case, i.e., #order.

Enter the name as order (# is prefixed already) and click on Create and you will be asked to enter some user examples. In order for the Watson Assistant to understand the intent, we must enter as many user examples as possible. These user examples are actually the training data for Watson to understand the intent.

We can think of several ways in which a customer can ask for an order. For example, the user may ask “Can I get a burger” or he can say “I’d like to order a burger”. As we are dealing with burgers and chicken, it would be better if we enter examples for each case having both burger and chicken such as “Can I get a burger” and “Can I get chicken”. You can go ahead and enter as many user examples as you want. The more the better.

I have compiled the following list of user examples which I feel will suffice for our assistant. If you find it difficult to create your own, feel free to use the following from figure 4.15:

Figure 4.15: Creating Intent

Once done, you can go back to the skill details page by clicking on the left arrow button on the top left-hand corner. You will see your intent has been created. To create the next intent, click on the Create intent + button on the top right-hand corner.

Similarly, you can create the #greet intent now. This intent will understand the user greetings such as “Hello”, “Good Morning”, etc. You can enter as many greeting examples as possible. The following is a list of user examples for #greet that I had given for this use case:

- Good Afternoon

- Good Evening

- Good Morning

- Hello

- How are you

The last intent we are left with is the #exit intent. This is the intent we will define for the Assistant to understand when the customer bids adieu. I had given the following list of user examples for this:

- Bye

- Great

- Thank you

- Thanks

Now we are done with intents. Let us go ahead and define our entities.

Create your entities

To move on to entities, click on the Entities link just below Intents on the skill page. You will be able to see that the link expands showing two sub links – My entities, System entities.

Watson already provides you with a set of system entities for the assistant to understand such as the number, percentage, date, etc. and they are prefixed with sys, such as sys_date. Click on System entities to view them as shown in Figure 4.16:

Figure 4.16: Entities Section

If we want to use any of them, we have to set the status to on by toggling the on button on the right-hand side of any row next to the entities in the Status column.

In our use case, we won’t need any of them.

As entities are the specifics that the intent will act upon, we can have the following entities (entities start with @):

- @food_type: This entity will hold the food type, i.e., burger or chicken.

- @burger_type: This entity will capture the type of burger. Let us assume our kitchen can prepare a Veg Burger and Mexican Burger.

- @chicken_type: Similar to the preceding one, this will capture the chicken preparation. Let us assume our kitchen can prepare chilli chicken, chicken wings, and spicy grilled chicken.

Now that we have decided our entities, let us create them.

Click on the My entities sub link on the left-hand side to create your entities which will be needed for our use case. Similar to intents, there will be no user--defined entities in the beginning and we can create them by clicking on the Create entity button.

To create our first entity, enter the name food_type (as @ is already prefixed) and you will be asked to enter values and their corresponding synonyms. Our @food_type entity can understand the following values as we decided - burger, chicken.

Synonyms are added so as to make the assistant understand that something similar can also be entered by the user. For these entity values, we won’t need to enter synonyms. So enter each of the value in the text field below the Value one by one and click on the Add value button. Also, make sure Fuzzy Matching on the top right-hand corner is set to on. Fuzzy matching matches your values even if the user entry does not match exactly with the value but means the same, as shown in the following screenshot:

Figure 4.17: Creating Entity @food_type

To go to the previous page, click on the right arrow on the top-left corner of the page.

Let us create the next entity - @burger_type.

Click on the Create Entity button from the entity list page and type the name as burger_type. We will have the values – Mexican Burger, Veg Burger for our use case as shown in the following screenshot:

Figure 4.18: Creating Entity @burger_type

Similarly, we will create the @chicken_type entity to capture the chicken preparation. We will have the values - Wings, Chilli Chicken, Spicy Grilled. Here, we can add a synonym to the Wings value – Chicken Wings. You can add synonyms for the other values as well:

Figure 4.19: Creating Entity @chicken_type

Now that we are done with intents and entities, we are left with the most important building block of any assistant – Dialog.

Dialogs define the conversation flow in the chatbot. So before proceeding, we need to plan out the conversation flow.

Any conversation flow is like a set of conditional flow of conversations. For example, when we go out to buy an ice cream, the ice cream seller first asks us whether we need a cone or not, then the flavour, and then any other specifics, and so on. We need to model our conversation flow in a similar manner. Also, keep in mind that if we ask the ice cream seller to give us one big cone ice cream of a mango flavour topped with a cherry, the ice cream seller should not ask us anything else such as the flavour, or cone, etc. as he already has all the information.

People with a background of programming have seen how a conditional flow works. It constitutes an if-else-if ladder. If you have no knowledge of conditional programming, imagine a set of conditions being asked one after the other, one being dependent on the previous condition.

Our conditional flow can be something as follows:

1. Greet the user.

2. Respond if the user wants to order in the next step.

3. If the user already asked for an order, then ask to choose between – Burger or Chicken.

4. If the user has asked for an order and has mentioned Burger either in step 2 or 3 then ask to choose between – Mexican Burger or Veg Burger.

5. Similarly, if the user has asked for an order and has mentioned Burger either in step 2 or 3 then ask to choose between - Wings, Chilli Chicken, Spicy Grilled.

6. Once the user has asked for an order (step 2) and has mentioned whether chicken or burger (step 3) and has also mentioned what kind of preparation (step 4 or 5 based on the choice of step 3) then go ahead and place the order by asking the address and respond with the time to reach it.

7. Check if the user responds with a thanks or bids adieu, then respond accordingly with a warm welcome.

8. Keep a check mentioning that it didn’t understand in case the user enters something out of the training data.

Let us model our conditions more formally in terms of intents and entities based on the above conditional flow:

1. Greet the user. - #greet.

2. Respond if the user wants to order in the next step. - #order.

3. If the user has already asked for an order, then ask the user to choose between – Burger or Chicken. - #order AND @food_type.

4. If the user has asked for an order and has mentioned Burger either in step 2 or 3, then ask the user to choose between – Mexican Burger or Veg Burger. - @food_type = burger.

5. Similarly, if the user has asked for an order and has mentioned Burger either in step 2 or 3, then ask the user to choose between - Wings, Chilli Chicken, Spicy Grilled. - @food_type = chicken.

6. Once the user has asked for an order (step 2) and has mentioned whether chicken or burger (step 3) and has also mentioned what kind of preparation (step 4 or 5 based on the choice of step 3), then go ahead and place the order by asking the address and respond with the time to reach it. - @chicken_type OR @burger_type

7. Check whether the user responds with a thanks or bids adieu, and then respond accordingly with a warm welcome. - #exit

8. Keep a check mentioning that it didn’t understand in case the user enters something out of the training data.

One should clearly understand the difference between a AND and OR boolean logic. AND requires both of the two conditions to be satisfied to fulfil the request and OR requires any one of them to be satisfied to fulfil the request.

But there is a flaw in these conditions. And that is because a computer processes conditions sequentially. The problem is with the sequencing of the steps. If the user asks for an order first, and then specifies whether it is burger and chicken and then which preparation of chicken, then this sequence would run fine. The assistant will run through the steps one by one and will respond based on the condition. But what if the user directly orders a Mexican Burger? The assistant will move to step 2 and find a match because his #order entity matches. Although the perfect match would be the one in step 6. Hence, the assistant will respond asking which type of order would the user prefer – burger or chicken. But the user has already mentioned what kind of burger, this could lead to poor user feedback as he would be faced with all the queries that he has already mentioned in his first request.

To avoid this from happening, we need to re-order the conversation flow. We need to put the most specific request first and then the next less specific one, until we reach the dialog checking only #order.

1. Greet the user. - #greet

2. Once the user has asked for an order (step 2) and has mentioned whether chicken or burger (step 3) and has also mentioned what kind of preparation (step 4 or 5 based on the choice of step 3), then go ahead and place the order by asking the address and respond with the time to reach it. - @chicken_type OR @burger_type

3. If the user has asked for an order and has mentioned Burger either in step 2 or 3, then ask the user to choose between – Mexican Burger or Veg Burger. - @food_type = burger

4. Similarly, if the user has asked for an order and has mentioned Burger either in step 2 or 3, then ask the user to choose between - Wings, Chilli Chicken, Spicy Grilled. - @food_type = chicken

5. If the user already asked for an order, then ask to choose between – Burger or Chicken. - #order AND @food_type

6. Respond if the user wants to order in the next step. - #order

7. Check whether the user responds with a thanks or bids adieu, and then respond accordingly with a warm welcome. - #exit

8. Keep a check mentioning that it didn’t understand in case the user enters something out of the training data.

But there is still a flaw. If the assistant works in a sequence, won’t step 2 lead to step 3. Hence, after knowing Mexican Burger, it is going to ask which type of burger, and then either burger or chicken. To fix this, we will also need to add a jump statement, so that after step 2, it can directly move on to step 7. Similarly, after step 3, the assistant should jump to step 2 and then to step 7. Let us add these jump statements and reorder a bit.

1. Greet the user. - #greet

2. If the user has asked for an order and has mentioned whether chicken or burger and has also mentioned what kind of preparation, then go ahead and place the order by asking the address and respond with the time to reach it. - @chicken_type OR @burger_type

3. If the user already asked for an order, then ask the user to choose between – Burger or Chicken. Jump to Step 5. - #order AND @food_type

4. Respond if the user wants to order in the next step. Jump to step 3. - #order

5. If the user has asked for an order and has mentioned Burger either in step 2 or 3, then ask the user to choose between – Mexican Burger or Veg Burger. Jump to step 2. - @food_type = burger

6. Similarly, if the user has asked for an order and has mentioned Burger either in step 2 or 3, then ask the user to choose between - Wings, Chilli Chicken, Spicy Grilled. Jump to step 2. - @food_type = chicken

7. Check whether the user responds with a thanks or bids adieu, and then respond accordingly with a warm welcome. - #exit

8. Keep a check mentioning that it didn’t understand in case the user enters something out of the training data.

Please note that after step 3, we are moving to step 5 even if we don’t know whether the user entered Burger or Chicken because even if the user chose Chicken but jumping to burger would now move to the next condition sequentially and would land to step 6.

Now we are in order. Try to run this in your mind and you will see that this will preserve the natural sequence of ordering food. We will refer to these steps as our conversation model.

Let us start building this sequence of dialogs in our Watson Assistant.

Create the dialogs

Similar to intents and entities, click on the Dialog link on the left-hand side, and you will be able to see that Watson has already built a very basic conversation model. Each of the boxes are called dialog nodes and they are linked with lines. These dialog nodes are each of the conversation steps that we chalked out earlier. Now, one of the nodes is the Welcome node, which greets the user with “Hello. How can I help you?” and the other one is the Anything else node which responds when the assistant can’t understand the user words (step 8).

Now we have already defined a #greet intent. So we will edit the welcome node and add our greeting message as well.

Now to edit the node, you need to click on it and by clicking on it, you will be able to see the following appear on the right-hand side of the page:

Figure 4.20: Create Dialog Node

Now, let’s look at each of the components of a dialog.

The first text field at the top specifies the name of the node. This is optional.

The text field below If assistant recognizes is the field where we need to mention the conditions as intents and entities. In this case, since welcome is neither an intent or an entity, it is a literal.

The text field below Assistant responds is the response type and value. If you click on the drop down mentioned Text, you will see that Watson offers a range of ways to respond other than the simple text such as Option (if we need to provide options to users, mainly used in case of lists), Pause (in case you want the assistant to wait for a certain amount of time), or an Image. We will in general use only the Text type.

We can also add multiple responses and display them sequentially or randomly by clicking on the Add response type + link. We will see this in action for the next node.

Lastly, the text field below Then assistant should is how the conversation should move to the next node. There are two options for this – Wait for reply and Jump to. We can either wait for the user to respond and then move to the next sequential node, or we can jump to a specific node based on a condition (which we needed to do in poor conversation flow).

Now, we already have a greeting intent in our assistant - #greet.

In the condition field, we will add this condition as well so that the assistant also recognizes when the user greets and responds on this node.

Click on the + sign next to welcome and Watson creates another condition field and a and drop down. If you click on the drop-down menu, you will see it also gives an option to conjugate the conditions using or. This is the Operator field, which is used to conjugate multiple conditions.

We will use the or operator to conjugate welcome with our own intent #greet. So, go ahead and select or from the operator field and type #greet in the next condition field. You will even see an auto complete when you type # in the condition field, which is really helpful.

Now, let us change the response text as well by asking the user to order. So, enter the following in the Response Text field:

Hello! What would you like to order today?

When you are done, your node should look like this:

Figure 4.21: Entering Response of a Dialog Node

Our first dialog node is ready.

Now, we already have an Anything else dialog node by default. Let’s keep it as is and click on it to see what it contains.

Figure 4.22: Anything Else Dialog Node

This dialog node is almost the same as the default welcome node except that in the response field, it has multiple text responses with responses set to sequential mentioned as follows. So the first time the dialog node is reached, it will respond with the response on the first line. The next time, with the one on the second line. Then, the next time with the one on the third line. And again if the node is reached the fourth time, it will respond with the response on the one on the first line (rolls back up) and it continues. We can also set it to multiline, in which case the response will show all the lines every time. If the response is set to random, then it will randomly pick up one line from those multiple lines each time.

Also if you notice the dialog flow diagram, you will see that each dialog node box shows the summary. For example, the welcome dialog node box shows the following:

Figure 4.23: Welcome Dialog Node

It shows the name of the node Welcome, the condition below welcome||#greet (in programming terms || symbolizes OR and && symbolizes AND), and a small summary showing the number of responses, context variables set (we will see this soon) and whether it waits for the user (Does not return) or jumps to another node.

Let us start adding our own dialog nodes based on the conversation flow we decided.

Let’s add step 4 first, i.e., #order.

Click on the three vertical dots at the end of the Welcome dialog node and you will see the following drop-down menu in figure 4.24:

Figure 4.24: Add/Remove Dialog Node Options

Select Add node below from the options in the drop-down menu and a new node will be added in a sequence just beneath it. The other possible options to add a node as seen from the drop down are as follows:

- Add node above: To add a node as a previous step.

- Add child node: This allows us to add a node as a child node in a sequence which is generally needed if we want a sequence condition check to occur if and after the condition in the parent node is satisfied.

- Add folder: This is needed when we want to group together a set of nodes. This is needed when there are a large number of nodes. The sequence or activity is not affected by this.

- Move: In case we want to re-order the sequence of a node.

- Duplicate: In case we want to make a copy of the node.

- Jump to: If we want to set jump to a specific node after completion of this node activity (like we added jump statements in our conditional steps).

- Delete: If we want to remove the node.

In this node, we will ask for an order and then let the user choose between Burger and Chicken.

In the condition field (the field below the label If assistant recognizes), add our order intent. Type # and you will be able to select #order from the autocomplete options.

Now, we will not add a Text response, nor will we add an option response because adding an option response allows the user to choose but does not store the value chosen. To store the value chosen, we need to know two new concepts – slots and context variables.

Slots allow you to prompt the user for a certain entity until the user enters a value for it and stores the value in a context variable.

Context variables can store a value for the whole life cycle of the assistant until the user quits the Watson assistant so that we can use the value later (in case we want to display it).

Now, to enable slots, click on the Customize link on the top-left corner of the dialog details pane just next to the dialog node name. Under the Customize Node tab, turn on the toggle button at the top-right corner and make sure to check the box – Prompt for everything and click on Apply:

Figure 4.25: Enabling Slots

Once you switch on the Slots, you will get a slot field set after condition field – Then check for. We need to prompt the user to enter the food type (i.e. burger or chicken) here. So, enter our entity @food_type beneath Check for. Beneath the label Save it as, we need to enter a context variable. A context variable starts with $. Let’s name the context variable the same as our entity (to avoid confusion) - $food_type, as this context variable will store the value of the entity @food_type. Let Type be Required, as shown in the following screenshot:

Figure 4.26: Adding Slots

Click on the button just next to Required to configure the slot.

In the Configure Slot pop up, select Option from the drop-down menu below If slot context variable is not present ask:. Let’s leave Title and Description blank as it is optional and click on the Add option to have two options. Fill the list label and value as Burger and Chicken as shown in Figure 4.27:

Figure 4.27: Adding Slot Label and Value

Click on Save and you have your slots ready.

You can optionally add a response type after If no slots are pre-filled; ask this first, if you want to ask before you prompt.

Leave everything else as it is. Watson automatically saves whatever changes you make to a dialog on runtime dynamically.

Later, we will add a jump statement to jump to step 3 to ask the user to choose which preparation of Chicken or Burger is required based on the choice the user made on the Slot here (as decided in our conversation model). But for that, first we need to create the dialog node corresponding to step 3.

So, either add a node above #order node or add a node below the Welcome node by clicking on the three dots of #order node or Welcome node.

We will not add any slot here, as the user has already chosen between Chicken and Burger in the #order node.

Add the condition in the condition field as decided #order and @food_type. Here, and is the operator. But remember that we have stored the @food_type value in the context variable $food_type. So add another or operator and another condition $food_type. But then why do we even need @food_type. It is because if the user directly asks for an order along with the @food_type, we will need to capture that here as well. Finally, add a Text response asking the user to choose the particular preparation as shown in figure 4.28:

Figure 4.28: Add Dialog Node to choose

Now that we have our step 3 ready, let us add a Jump from the #order node (step 4) as discussed.

So click on #order dialog node and on the details pane on the left-hand side, scroll down to Then, the assistant should go to the drop-down menu and select Jump to. As soon as you click on this, it will ask you to select a Destination node as shown in figure 4.29:

Figure 4.29: Add End Action of Node

Click on the #order && @food_type || $food_type node and it will prompt you with a drop-down menu to select from – Wait for user input, If assistant recognizes (condition), and Respond:

Figure 4.30: Add Jump to Option

Select the option If assistant recognizes (condition) as we want our jump to take place once the condition for this node is satisfied. As soon as you select this, a jump statement will be added to the #order node as shown in figure 4.31:

Figure 4.31: Final #order Node

Let us now create the nodes for steps 5 and 6 to ask the user to enter the specific preparation for Burger or Chicken based on the user input.

Let us first create Step 5 for choosing the burger preparation.

Create a node just below #order node. Here, we will give the condition @food_type:burger so that the entity @food_type is burger. So any mention of this entity would lead to this node. Since we are going to ask for the choice and for convenience store it in a context variable to be used later, we will add slots like we did previously.

So enable the slot by clicking on customize and enable Slot with Prompt every time the option is checked as shown in figure 4.25. Next, we will add Then check for the following values:

- Check for - @burger_type

- Save it as - $burger_type

Figure 4.32: Dialog Node for @food_type is ‘burger’

Click on the button next to Required to add the slot options as shown in figure 4.33:

Figure 4.33: Add options for type of burger

Click on Save and your node is ready.

Now that we have our dialog node corresponding to Step 5 ready, let us add the jump statement to node #order && @food_type || $food_type which corresponds to step 3 in our conversation model. So click on the #order && @food_type || $food_type node and scroll down to Then assistant should at the very bottom. Select Jump to and select the node @food_type:burger as the destination (keeping If assistant recognizes condition as shown in Figure 4.30) by clicking on it. Finally, the node should be displayed as shown in Figure 4.34 in the flow diagram:

Figure 4.34: Final Node after adding Jump to option

Similarly, let us create a similar node for Chicken.

Create a node just below @food_type:burger. Here, we will give the condition @food_type:chicken so that the entity @food_type is chicken. We will enable the slot by clicking on the Customize and toggling Enable Slot button and keeping Prompt for everything as shown in Figure 4.25.

Add the condition for slots in Then check for as follows (as shown in figure 4.35):

- Check for - @chicken_type

- Save it as - $chicken_type

Figure 4.35: Dialog Node for @food_type is ‘chicken’

Now, click on the settings button next to Required and add the slots as shown in Figure 4.36:

Figure 4.36: Adding slots for choosing Chicken type

Now, we need to create Step 2 of our conversation model to add a jump statement to both the nodes @food_type:burger and @food_type:chicken.

Create a new node below the Welcome node. Here, we need to check whether the user has already provided any of the two entities - @burger_type or @chicken_type to specify which preparation of burger or chicken does the user desire to order. So in the condition, add @burger_type and @chicken_type conjugating using the or operator in between as shown in Figure 4.37:

Figure 4.37: Node after Welcome Node

Now here, we do not need any slots but we need to set a context variable to allow the assistant know that the user has already provided the specific preparation of the food item and so that we can go ahead and ask for the address. Let this context variable be the address and we will set it to true if this dialog node is reached.

To set a new context variable, we need to open the context editor. To open the context editor, click on the three vertical dots next to the Assistant responds label as shown in Figure 4.38 and click on Open context editor:

Figure 4.38: Open JSON editor for adding context variable

For a programmer who feels more comfortable in JSON can also edit or create context editors in JSON by clicking on the Open JSON editor.

Once you click on Open context editor, then the set context section will open, where you can set a new context variable or add an existing variable and value. Add the variable as address and value to true (Figure 4.39).

Since we need to ask for the address, let us add a text response as shown in Figure 4.39:

Figure 4.39: Adding context variable

Next, let us accept the order after getting the address and acknowledge the user. We will create a new dialog node for this.

Add a child node of the node we just created, i.e., @burger_type || @chicken_type. Click on the three vertical dots and click on the Add child node option from the drop-down menu (from Figure 4.24). A new child node will be created beneath the @burger_type || @chicken_type node.

Set the condition as $address as we want to only check whether the user has provided the address and set a test response such as “We are sending your order to your mentioned address in 30 minutes.” as shown in Figure 4.40:

Figure 4.40: Set response for $address node

We haven’t yet set the jump statements for @food_type:burger and @food_type:chicken nodes (Steps 5 and 6 of our conversation model). So add the jump statements to these nodes to jump to the @burger_type || @chicken_type node as the destination with If assistant recognizes (condition).

Figure 4.41: Adding jump statements to @food_type: chicken node

Now, we are left with the last node to set, which is our last step in the conversation model.

So create a node just above the Anything else node. Set the condition as #exit intent and keep a text response “I am very Happy to serve you. Please visit again. Thank you.” As shown in Figure 4.44:

Figure 4.42: #exit intent node

Congratulations!! You have a complete chatbot for food ordering.

Go ahead and test by clicking on the Try it button on the top-left corner of the page. Go ahead and ask the assistant “I want to order” or “I want to order a burger”. Some of the tests I conducted are given in figures 4.43 and 4.44. At times, Watson might be training while you are going to try out and might ask you to wait for some time.

Figure 4.43: Trying out the bot

Notice that each conversation tells us what intents and entities are found. You can click on the conversations to see which node it corresponds in the diagram.

Moreover, you can click on the Manage Context on the top-left corner to check what context variables it has stored.

Figure 4.44: Checking out the context variables

As you can see it already has a few system variables (like $timezone) along with the context variables we defined.

Test out a bit more of the chatbot you just created and in the next chapter, we will see how to deploy this into production.

Conclusion

Let us take a pause and review the huge accomplishment we have achieved in this chapter.

In the beginning, we learned about the building blocks of a chatbot. We learned what do we mean by intents, entities, and dialogs with regards to a chatbot. We then created our own IBM Cloud account and IBM ID and created an instance of a Watson Assistant Service.

We explored the Watson Assistant Page to understand the Watson Assistant structure and created our very own assistant and its associated skills which can serve as a bot to understand humans in their colloquial terms and appropriately place an order in the restaurant.

We created intents and entities. We also understood the necessity of storing values in a conversation flow to follow the context of the conversation, in which case Watson Assistant provided us with context variables. We learned complex dialog structures and got an understanding of the options and slots needed for a complex dialog.

Once we completed the structuring of our chatbot, we saw where we can try it out to see if our chatbot is working properly and also checked all the context variables and values.

This was quite an achievement without a single line of code. Let us now take our coding skills we learned in the previous chapters to build something cool in the next chapter.

CHAPTER 5

First Complete Machine Learning Project

In the previous chapter, we built our first project, but we did not use any of our Python skills or machine learning algorithm concepts that we learned previously. IBM Watson Assistant gracefully handled all our concepts and articulated them to produce a wonderful chatbot.

But we have a fair amount of idea about what machine learning is and how to approach a machine learning problem along with some theoretical (mathematical) knowledge in the first three chapters. I think it’s time to set the groundwork and do some actual machine learning projects. But to start building a machine learning solution, we need to keep in mind that the machine learning algorithm is just a small part of the solution. We need to gather data, analyse it, prepare it and in the end, deploy it. There are a lot of resources required for the pre-processing of a machine learning algorithm over the Internet, but very few on the post processing for deployment.

But first we must put to test all the knowledge we have gathered till now. We saw several datasets in the past few chapters such as the housing dataset in the first chapter and the mnist fashion dataset to classify an image such as a t-shirt or shoe, etc. We will use the original housing price prediction dataset. You will get a new flavour of IBM Watson in this chapter, when we will deploy our machine learning model for production use. Excited! Let’s begin!

Structure

The following topics will be covered in this chapter:

- Downloading the data

- Setting up our environment

- Data analysis

- Data preparation

- Model training

- Storing and deploying the model in your Watson Machine Learning repository

Objectives

- Get hands-on experience of a real-life machine learning problem.

- Gather and understand the data.

- Getting comfortable with Watson Machine Learning Studio by setting up a new environment for Watson Studio in Watson Cloud Pak for Data.

- Use the skills developed in the previous chapters to analyze the data, check the feature columns, and prepare them for model training which includes separating the dataset into training and testing data.

- Understand how to use the Python package to apply the appropriate machine learning model to address a real-life machine learning problem and deploy it in IBM Cloud to be used by any third-party application though API calls.

Downloading the data

Let’s begin by downloading the data. The data we will be using can be found on the following URL:

https://www.kaggle.com/vikrishnan/boston-house-prices

Download the complete dataset containing both the training and testing data by clicking on the download button (top-right corner). We can also check the data before downloading. If you have difficulty downloading from Kaggle, I have uploaded the dataset in my GitHub repository. The content section in the webpage gives an overview of the dataset contents as shown in Figure 5.1:

Figure 5.1: Kaggle Dataset

As shown in the content section, The Boston Housing Dataset is a derived from the information collected by the U.S. Census Service concerning housing in the area of Boston, MA. The following describes the dataset columns:

- CRIM: Per capita crime rate by town

- ZN: Proportion of residential land zoned for a lot over 25,000 sq. ft

- INDUS: Proportion of non-retail business acres per town

- CHAS: Charles River dummy variable (1 if tract bounds river; 0 otherwise)

- NOX: Nitric oxides concentration (parts per 10 million)

- RM: Average number of rooms per dwelling

- AGE: Proportion of owner-occupied units built prior to 1940

- DIS: Weighted distances to five Boston employment centres

- RAD: Index of accessibility to radial highways

- TAX: Full-value property-tax rate per $10,000

- PTRATIO: Pupil-teacher ratio by town

- B: 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town

- LSTAT: % lower status of the population

- MEDV: Median value of owner-occupied homes in $1000's

Our task is to predict the median value of the home prices, i.e., MEDV. There are 506 rows and 13 attributes (features) with a target column (price). If you download the dataset and open it in a text editor, you will see that there are no column headers. So we have to manually assign column headers to the dataset in order as mentioned in the Kaggle data description.

Setting up our environment

We will use a Watson service called Watson Studio to build our model instead of our local Python editor so that we can deploy it in production. So log in to your IBM Cloud account from https://cloud.ibm.com. Browse the catalog and select Watson Studio and create an instance of Watson Studio. The Watson Studio Creation page is shown in Figure 5.2:

Figure 5.2: Creating Watson Studio

Once your Watson Studio instance is provisioned, you can open the Watson Studio Resource page:

Figure 5.3: Watson Studio Resource Home Page

Click on the Get Started button to launch your Watson studio instance. Once you launch Watson Studio, you will have to wait until your IBM Cloud Pak for Data as a Service account is provisioned, and you will be directed to the Watson Studio home page. IBM Watson takes all your resources and links them to a Cloud Pak for Data as a Service account. You can assume that it is a composite package consisting of all your IBM Watson resources (Figure 5.4):

Figure 5.4: Cloud Pak for Data

You will be able to see all your resources on the right panel and your Watson Studio projects as well:

Figure 5.5: Cloud Pak for Data Home page

Now, you will need to create a project by clicking on the Projects link on the left panel. You will be directed to the page which lists your projects. At this point of time, it will be empty (assuming you have not created any project earlier). On the top-right corner of the page, you will find a New Project button, which you can click on to create a new project. Once you click on the button, you will be asked to choose between creating an empty project or creating a project from a sample file as shown in Figure 5.6:

Figure 5.6: Creating a Project in Cloud Pak for Data

Let’s go ahead and create an empty project. You will be prompted to create a new cloud storage if you don’t already have one. If you want to create the cloud storage beforehand, you can go to catalog and search Object Storage:

Figure 5.7: Selecting an Object Storage to store the Machine Learning assets

The Object Storage resource creates a Cloud Object Storage:

Figure 5.8: Creating a Cloud Object Storage

Once you have your cloud storage, your Watson Studio Project creation page will show the cloud storage as default as shown in Figure 5.9:

Figure 5.9: Creating a new Project

Once you have created a project, you will be redirected to the project overview page which will show your number of assets and collaborators as shown in Figure 5.10:

Figure 5.10: Cloud Pak for Data Project Home Page

You can add collaborators to this project when you will be working in a team.

Now, we will add our housing csv file that we downloaded. Click on the Add to Project button on the top-right corner of the page, and you will be asked to choose between the asset types. You will realize that Watson Studio allows us to choose from a number of asset types which are needed for a machine learning project.

Since we are going to upload a CSV data file, let us select the first option Data from the page as shown in Figure 5.11:

Figure 5.11: Choosing asset type for our project

You will see that a left panel pops up which offers us to browse from our local file system as shown in Figure 5.12:

Figure 5.12: Section to load assets

You can click on browse and upload the housing.csv file from your local file system. Once your csv is uploaded, you will see that the asset count is increased by 1, and you can click on the Files tab on the left pane to view your uploaded file:

Figure 5.13: Loading file assets

Now, we need a place to write our Python script. IBM Watson Studio offers us the Jupyter Editor where we can build our model using Python and deploy it. So, let us click on the Add to project button once more and from the list of assets, select Notebook.

Once you select Notebook, you will be asked to name your notebook and check the Python runtime version. If you click on the Select runtime drop-down menu, you will see that Watson Studio offers us with a number of runtime options. Let’s keep the current Python version runtime that it offers. You can also upload any Jupyter notebook that you already have from the From file tab or take a file from a deployed URL from the From URL tab. Since we are building our model from scratch, we will provide the notebook name under the Blank tab and click on the Create button at the bottom-right corner of the page as shown in Figure 5.14:

Figure 5.14: Creating New Jupyter Notebook

Once you click on the Create button, Watson will instantiate your Python runtime and prepare your Jupyter Notebook. As soon as you instantiate, you will see a very familiar page (for people who have been using the Jupyter notebook for the previous chapters or earlier).

Figure 5.15: Jupyter Notebook Opened in Watson Studio

Yes, this is the same Jupyter notebook that is used in local systems and it works in the same way.

So, now that we have our environment set up. Let us move on with Data analysis.

Data analysis

Now, we need to read the data from the CSV we uploaded using Pandas. But it won’t be imported into a dataframe by a simple read_csv. We have to import it from the cloud storage. To do that, click on the second button from top-right banner and a right panel will pop up. Click on the drop-down menu of Insert to code below the housing.csv file name under the Files tab as shown in Figure 5.16 and select pandas Dataframe:

Figure 5.16: Inserting Pandas Dataframe

Like a magic spell, you will have your data asset imported into a pandas dataframe.

You can run this cell (using the Run button at the top) to check the first 5 data samples using the pandas dataframe head() function:

Figure 5.17: head() of Pandas ran from Watson Studio

You might have got an idea now that the data is stored in the df_data dataframe. But as you can see the headers are wrong. It has taken the first row as the header names (which is the default setting of read_csv). So, we have to manually provide the column names.

Add the following lines just before the read_csv function call:

column_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']

Edit the read_csv function call as shown in the following code so as to specify not to use the header from the file and use a delimiter as a space:

df_data_1 = pd.read_csv(body, header=None, delimiter=r"\s+", names=column_names)

Once you do these changes, you can run to check the correct dataframe:

Figure 5.18: Producing Dataframe head from csv in Watson Studio

Now that our dataframe is ready, let us go ahead with the analysis.

Let us ensure to check the data types of all the columns using the following lines of code in

df_data_1.info() as shown in Figure 5.19:

Figure 5.19: info() of our CSV Dataset

It looks like we won’t have to be concerned with missing values, as all the columns have 506 non-null values. We also won’t have to be concerned with categorical values, as all data types are numeric.

To get more insights, we can use the describe method of pandas to have a statistical summary of the datasets as shown in Figure 5.20:

Figure 5.20: using describe()

Looking at the last column, it is safe to assume that the median price is scaled and normalized to values in the range 0 to 50. We can assume that the actual range is from $1000 to $50000.

Now to make the best use of a model and predictions, we must use only the columns which are necessary and sufficient for prediction. Any column which is not required might have two main adverse effects:

- It can skew the prediction algorithm.

- It can unnecessarily decrease the processing speed.

Since our target is the MEDV column, let us check the columns which have a high correlation coefficient with the MEDV column. The Pandas Dataframe has a function called corr(). The function uses the standard correlation coefficient (also called Pearson’s r) between every pair of attributes. Pearson’s r values range from -1 to 1. Values tending to 1 or -1 can be assumed to be highly correlated, and values close to 0 are least correlated. Run the following lines to get the coefficient matrix and then check how our target column MEDV correlates with each of the attributes. Figure 5.21 will get you a clearer idea:

Figure 5.21: Correlation Matrix

We can have our own threshold assumption to remove some of the unnecessary attributes from the dataset. I feel it is safe to say that we can have attributes which have the correlation coefficient from 1 to 0.35 in the positive side and -0.45 to -1 in the negative side. Based on this assumption, we can remove the following columns:

- B: 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town

- DIS: Weighted distances to five Boston employment centres

- CHAS: Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)

- RAD: Index of accessibility to radial highways

- CRIM: Per capita crime rate by town

- NOX: Nitric oxides concentration (parts per 10 million)

Let’s keep the AGE attribute for now.

Although, some of the attributes intuitively seem to be more related to the median house value, but this is the harsh reality!

Data preparation

Let us prepare our X and Y datasets based on our previous analysis:

column_sets = ['LSTAT', 'PTRATIO', 'INDUS', 'TAX', 'AGE', 'ZN', 'RM']

X = df_data_1.loc[:,column_sets]

y = df_data_1['MEDV']

Now, let us divide the data into test set and train set:

import sklearn.model_selection as model_selection

X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, train_size=0.65,test_size=0.35, random_state=45)

We have taken 65% of the dataset for training and 35% of the dataset for testing.

Model training

Now, we are ready to apply a model which we might think is the best fit for our problem. Since the correlation coefficients seem close to 1 for our selected attribute, we can go for linear regression. We can create a pipeline which can contain the steps to train the model as follows:

Figure 5.22: SKLearn Pipeline

We need to save our model now. A model is saved in a format known as Pickle. The statement import pickle is used for this. The Pipeline object is saved to a pickle file and a tar.gz file in the following lines of code:

Figure 5.23: Pickle file creation

Let’s check how our model has performed. We are going to use the Root Mean Squared Error discussed in the first chapter – Introduction to Machine Learning, to evaluate our predictions. To get the evaluation, let us do the following:

1. Import the required packages.

2. Predict our test values (X_test), i.e., the 35% of our sample data we kept for testing.

3. Calculate the root mean squared error of the predictions obtained in the previous step against y_test (target values of the 35% test data).

Figure 5.24: Evaluating ML model

Not too good. You can change your model to support vector machines, decision trees or tweak any hyper parameter to increase your RMSE and that is a continuous process. I leave that as an exercise for you. But our focus is to deploy the model for production as of now.

Storing and deploying the model in your Watson Machine Learning repository

Now, we will store our model in the Watson Machine Learning Repository. We will need to create a Watson Machine Learning Service in our account.

Go to your IBM Cloud home page and search for the Machine Learning service from the catalog and create as shown in Figure 5.25:

Figure 5.25: Watson Machine Learning Service

Once you have created your Watson Machine Learning instance, you need to generate the IAM API Key. So go to your IBM Cloud home page and click on the Manage menu option on the top-right pane at the right. From the Manage drop-down menu, click on the Access (IAM). On the Access (IAM) page, click on API Keys on the left pane, and you will see the page as shown in Figure 5.26:

Figure 5.26: Service Credential of Watson Machine Learning

Here, click on the Create an IBM Cloud API Key button, and you will be prompted to enter a name and description for an API key as shown in Figure 5.27:

Figure 5.27: Creating the Credential

Give a name and click on the Create button. A dialog box will pop up with the API Key value.

Click on the Copy button to copy the API Key and save it somewhere in your local system.

Go back to your Jupyter notebook in Watson Studio and install the Python package – watson_mchine_learning_client using the following command:

!pip install watson_machine_client

Once this is installed, instantiate your Watson machine learning client by providing your machine learning credentials:

from watson_machine_learning_client import WatsonMachineLearningAPIClient

api_key = 'KuHIixPi_ -US-kxcmB9xHKxaT1k'

location = 'https://eu-de.ml.cloud.ibm.com'

wml_credentials = {

"apikey": api_key,

"url": location

}

client = WatsonMachineLearningAPIClient(wml_credentials)

As you might have noticed, you need to enter the API key value that you just copied as the value of the api_key. You will also need the location which can be found from the following URL based on the location of your service instance that you created:

https://cloud.ibm.com/apidocs/machine-learning

Now, we will need to create a deployment space. For that, go to the IBM Watson Studio home page by clicking on the IBM Watson Studio title on the menu at the top-left corner of the page. Once you are on the home page, locate the Deployment Spaces tab on the right, just below the banner, and click on the New deployment space button. You will prompted to enter the details as shown in Figure 5.28:

Figure 5.28: Creating Deployment Space

Select the proper cloud object storage as well as the proper Watson Machine Learning Service as shown in the preceding figure and click on the Create button. Once you are on the deployment space page, copy the Space GUID and save it somewhere in your local system from the manage page as shown in Figure 5.29:

Figure 5.29: Save Space GUID

Once this is done, go back to your Jupyter notebook by going to the project asset and typing the following code to set the default deployment space (Here, you will need to provide the space GUID that you just copied.):

space_id = '11392c54-0523-901faf315a87'

client.spaces.list(limit=10)

client.set.default_space(space_id)

You will see a SUCCESS message if everything goes fine.

Now, it’s time to store the model in your Watson repository.

Use the following lines of code to store the metadata of your model:

import json

sofware_spec_uid = client.software_specifications.get_id_by_name("default_py3.7")

metadata = {

client.repository.ModelMetaNames.NAME: "housing-LinReg",

client.repository.ModelMetaNames.TYPE: 'scikit-learn_0.23',

client.repository.ModelMetaNames.SOFTWARE_SPEC_UID: sofware_spec_uid

}

model_details_pkl = client.repository.store_model(model="model-dir", meta_props=metadata)

published_model_uid = client.repository.get_model_uid(model_details_pkl)

model_details = client.repository.get_details(published_model_uid)

print(json.dumps(model_details, indent=2))

You will see the model details in a JSON format as follows:

{

"entity": {

"software_spec": {

"id": "e4429883-c883-42b6-87a8-f419d64088cd",

"name": "default_py3.7"

},

"type": "scikit-learn_0.23"

},

"metadata": {

"created_at": "2021-03-07T13:11:37.620Z",

"id": "c1d79352-42b6-4bdb-abfb-60741049984a",

"modified_at": "2021-03-07T13:11:40.311Z",

"name": "housing-LinReg",

"owner": "IBMid-550005A6UW",

"space_id": "11392c54-0523-44c1-a972-901faf315a87"

},

"system": {

"warnings": []

}

}

Now, you will need to deploy your model in the deployment space using the following lines of code:

metadata = {

client.deployments.ConfigurationMetaNames.NAME: "Deployment of housing model",

client.deployments.ConfigurationMetaNames.ONLINE: {}

}

created_deployment = client.deployments.create(published_model_uid, meta_props=metadata)

Once you run the code, you will see the following output if everything goes fine:

#######################################################################################

Synchronous deployment creation for uid: 'c1d79352-42b6-4bdb-abfb-60741049984a' started

#######################################################################################

initializing

ready

------------------------------------------------------------------------------------------------

Successfully finished deployment creation, deployment_uid='cb42e408-a75f-1188e0d737b3'

------------------------------------------------------------------------------------------------

You have successfully deployed your machine learning model in the Watson repository.

But wait! How do you use it in an application? To use your model, Watson provides you with an endpoint URL. You can use this URL to send data to your model to predict values. You can get your endpoint URL using the following line of code:

model_endpoint_url = client.deployments.get_scoring_url(deployment_details)

Figure 5.30: Endpoint URL of model

Now that we have everything ready, let us try to use this URL to send some data and predict. But for that, we need to know the implementation details. To get to know the implementation details, go to the IBM Watson Studio homepage and from the Deployment spaces tab (right from where you created your deployment space), click on your deployment space to go to the Deployment space. Click on the Deployments tab on the Deployments page and you will be able to see your deployment that you just created using the Python code as shown in the following table. Click on the deployment (Deployment of housing model in your case), and you will be able to see all sorts of deployment options as shown in Figure 5.31:

Figure 5.31: Implementation details

Copy the endpoint URL and save it in your local system. As you can see, there are a lot of different options for you to try out such as Java, Python, JavaScript, and Scala. You can also go ahead and go to the Test tab to enter the input data directly to test. You can use the input data as shown in Figure 5.32 and click on the Predict button to see the predictions:

Figure 5.32: Testing the mode]

The easiest way to test an URL is using cURL. If you are into web development, then you can find out a way to implement a web app for this or use Postman for this as well. If you are unaware of cURL, then please download cURL from the following URL:

https://curl.haxx.se/download.html

Once you have set up cURL, open your terminal. The first step is to get an access token. For that, you need to provide your Watson Machine learning API key in the following format:

curl -k -X POST \

--header "Content-Type: application/x-www-form-urlencoded" \

--header "Accept: application/json" \

--data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" \

--data-urlencode "apikey=oPnyC59_yXwJ37X6MNfNF5pxOGJ3iY8FOJHLa" \

https://iam.bluemix.net/identity/token

This will give you a JSON response. Make sure to just copy the value from the access_token field in the response and not the other fields. Once you have the access token, you can use another cURL to get a prediction from a sample data in the following format:

curl -X POST --header 'Content-Type: application/json'--header 'Accept: application/json' --header "Authorization: Bearer $IAM_TOKEN" --header "ML-Instance-ID: $ML_INSTANCE_ID" -d '{"input_data":[{"fields": [$ARRAY_OF_FEATURE_COLUMNS],"values": [$ARRAY_OF_VALUES_TO_BE_SCORED, $ANOTHER_ARRAY_OF_VALUES_TO_BE_SCORED]}]}' $ENDPOINT_URL

Here is a sample cURL command I used:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json'--header "Authorization: Bearer eyJ raWQiOiIy MDIxMDIxOTE4MzUiLCJhbGciOiJSUzI1NiJ9.eyJpY W1faWQiOiJJQk1 pZC01NTAwMDVBNlVXIiwiaWQiOiJJQ k1pZC01NTAwMDVBNlVXIiwicmVhbG1pZCI6Ikl CTWlkIiwianRpIjoiOTI3YzM1ZDYtNjh lMy00MzI0LTljYTQtNW1lIjoiRyIsIm5hbWUiOiJBIEciLCJlbWFpbCI6I mFndHJ1c3R3b3J0aHlAZ21haWwuY29tIiwic3ViIjoiYWd0cnVzdHd vcnRoeUBnbWFpbC5jb20iLCJhdXRobiI6eyJzdWIiOiJhZ3RydXN0 d29ydGh5QGdtYWlsLmNvbCJic3MiOiI2ZmFhMjlmZGNmMTI0NTQ0 OGQ3MzFiMDBkMmJhNjIwMSIsImZyb3plbiI6dHJ1ZX0sImlhMTYx NTEyMzM2M SwiZXhwIjoxNjE1 MTI2OTYxLCJpc3MiOiJodHRwczovL2 lhbS5ibHVlbWl4Lm5ldC9p ZGVudGl0eSIsImdyYW50X3R5cGUiO iJ1cm46aW JtOnBhcmFtczpvYXV0aDpncmFudC10eXBlO mFwaWtleSIsInNjb3BlIjoiaWJt IG9wZW5pZCIsImNsaWVud F9pZCI6ImRlZm F1bHQiLCJhY3IiOjEsImFtciI6WyJwd2QiXX0.U5oNNJc8NIRTbLhetO7hjchWtKg5r 5awGZMs0KDrLHmwmCWFnzFWqY_j-8 SzMp8U_ jIBrJBcCKtZALt6Lv_PmLfTbmEezQCRWHF7R GPfJRSHGNxSO5m28mPcwPhr7z-tfvlm3LlK9TI6bMbNhRU6H7ET Fux_L8iSmoBh8OShQZgh CdFr0tAH4IbEowZNOMUURPCu 00pOxD5bngIb4 ay2NcwIBEdaHGRArg5nGrQU9oquinudnVM2wEnqAO1PchT7ZJhf9gcU 886l4Ikx_SB9-6Td3NS4pbSRlD-Oqf_wsy2 uYRaZf-jUempLHonYVoX1bV3m519k-yeGEWJJ6YWLag" --header "X-WML-User-Id:agtrustworthy@gmail. com" -d '{"input_data":[{"fields": ["LSTAT", "PTRATIO", "INDUS", "TAX", "AGE", "ZN", "RM"],"values" : [[8.05,18.6,1. 38,216.0,59.5,17.5,7.104]]}]}' https://eu-de.ml.cloud.ibm.com/ml/v4/deployments/cb42e408-84ee-43a0-a75f-1188 e0d737b3/predic tions?version=2021-03-07

Here, you will need to put the endpoint URL and the data that we used to test above.

Conclusion

Similar to the previous chapter, we successfully built a machine learning project to solve a real-life problem using a real-life dataset. But unlike the previous chapter, this was mostly code-driven and you should have gained confidence after completing this chapter.

We set up an IBM Cloud instance to build our model, gathered real-life data and leveraged all our coding skills and machine learning concepts to analyse, prepare, and build a perfect model to solve our problem.

Although, solving a machine learning problem is a common task, we walked further down the road to deploy it into a production cloud environment and exposed APIs for third-party applications to use our model.

In our next chapter, we will improve this machine learning model to see if we can get better precision and accuracy with some other algorithm. We will try to optimize our machine learning algorithm by leveraging the hyper parameters and use some other Watson’s services to automate the optimization.

CHAPTER 6

Perfecting Our Model

In the previous chapter, we built a model to predict the median housing price from a dataset. We had built a linear regression for prediction but we did not get a good score. Our main focus was to build a complete machine learning model from scratch and deploy for production use.

Let us concentrate on increasing our accuracy score in this chapter because it is not much of a production use if it cannot predict properly. But increasing the score is not just in the hands of the machine learning algorithm. Instead, we must look out for ways to optimize our solutions.

In this chapter, we are going to try to optimize our solution by several approaches. We will try changing the model, we will try changing the parameters, and then automate it.

Structure

- Decision tree

- Random forest

- Grid search cross validation

- Auto AI

Objectives

- Learning the concepts of decision tree and how to use it in a machine learning problem.

- Getting the concepts of forests and how to use random forest as a regression model to solve complex machine learning problems

- Understanding how to approach optimizing your machine learning models. Start optimizing your machine learning models by tuning your hyper parameters using grid search and levelling up your Python skills.

- After understanding the concepts of optimizing the machine learning algorithm, leverage the Auto AI tool of IBM Watson to do the same for you.

Decision tree

One very good machine learning regressor is the decision tree regressor. The algorithm divides the dataset into common features and builds a decision tree based on the features. The next image might give you a rough idea.

Figure 6.1: Decision Tree

Scikit offers a simple class to predict using the decision tree called DecisionTreeRegressor. Let’s try to implement a DecisionTreeRegressor on our dataset.

Go ahead and open your Watson Studio project that you have created. Scroll down in the Notebook section and open your notebook in edit mode by clicking the edit button at the end of the row containing your notebook name as highlighted in the image below.

Figure 6.2: Edit Notebook

Once your notebook is ready, go to the cell where you defined your pipeline and added a linear regression model (Figure 5.23 from previous chapter). Click on the Insert drop down on the notebook menu and click on Insert Cell Below.

Figure 6.3: Inserting Cell]

A new blank cell will be added below where we can test our decision tree regressor. Let us not build a pipeline right away this time. Instead, let us test first and then we can put it into a pipeline any time.

Add the following code to fit a DecisionTreeRegressor from Scikit-Learn.

Figure 6.4: Adding Decision Tree

Add another cell below it and evaluate your model using the test sets:

Figure 6.5: Evaluate Decision Tree

It went down!

Our new model performed worse! But we can go on with another model or change the hyper-parameters (we can tune the depth of tree as a hyper-parameter). But this can’t go on and on. One solution to this problem is using an ensemble method.

Random forest

Ensemble learning methods use hyper-parameter tuning to evaluate a model with several hyper-parameters and then extracting the one with highest accuracy score. Random forests train many decision trees on random subsets of the features, then averages out their predictions to achieve best results. We can use Scikit-Learn’s RandomForestRegressor for this purpose.

Open up your notepad again in edit mode and add a cell below the one you just modelled DecisionTreeRegressor. Add the following code and run to fit a RandomForestRegressor on your dataset.

Figure 6.6: Random Forest Regressor

The code is almost similar to DecisionTreeRegressor, except that it is imported from the ensemble module of Scikit-Learn. We have also added some parameters in the regressor as follows:

- n_estimators: The number of trees in the forest.

- max_depth: The maximum depth of the tree.

You can read about all the parameters from Scikit-Learn’s official documentation here:

https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html

Next, let us evaluate our model as we did for the earlier models by adding another cell below it.

Figure 6.7: Evaluating Random Forest Regressor

A little improvement as compared to DecisionTreeRegressor!

We can fiddle with some of the hyper-parameters of RandomForestRegressor (such as n_estimators, max_depth, etc.) and try to obtain the best results. But there is no end to this and it will take a lot of time to come up with a good set of hyper-parameters.

Grid search cross validation

Instead, we can use Scikit-Learn’s GridSearchCV to search for us. All you need to do is tell it which hyperparameters you want it to experiment with and what values to try out, and it will use cross-validation to evaluate all the possible combinations of hyperparameter values.

Add another cell below the evaluation of RandomForestRegressor and add the following code to implement GridSearchCV:

from sklearn.model_selection import GridSearchCV

param_grid = [

{'n_estimators': [4, 12, 32], 'max_depth': [2, 4, 6, 8]},

{'bootstrap': [False], 'n_estimators': [5, 10], 'max_depth': [2, 3, 4]},

]

forest_reg = RandomForestRegressor()

grid_search = GridSearchCV(forest_reg, param_grid, cv=5, scoring='neg_mean_squared_error', return_train_score=True)

grid_search.fit(X_train, y_train)

Let us understand the code.

In the param_grid, we have defined two dictionary elements. It first fits the dataset 12 times (3 n_estimator values with 4 max_depth values). Next, it fits the dataset 6 times (2 n_estimator values with 3 max_depth values) but with bootstrap set as false this time. The bootstrap parameter uses the whole dataset to build a tree if set to false. So, in total, it fits the dataset 18 times to RandomForestRegressor and it will train each model 5 times (since we are using five-fold cross validation using the cv parameter in gridSearchCV function). So in all, it will run 90 times and it is going to take some time.

But when it is done, it reserves the best hyper-parameter set for prediction. We can check the best parameters using the following code:

grid_search.best_params_

The output as the best parameters was as follows:

{'max_depth': 6, 'n_estimators': 12}

We can check all the results of all the parameters using the following code.

Figure 6.8: Grid Search Results

The scores are almost near to linear regression. Hence, we can conclude that linear regression can be the best fit as of now. But there are so many models out there and so many hyper-parameter combinations that can be tuned. What if you were to know that IBM Watson offers a simple solution to pick up the best model from a range of models without writing a single line of code?!

Auto AI

Welcome to Auto AI! One of the reasons IBM Watson is popular is Auto AI. Whatever you did in the previous sections, you can do more without writing a single line of code. Auto AI analyses your dataset and fits the data into a number of machine learning models. It uses hyper-parameter tuning to find the best parameter and optimizes the model using hyper-parameter optimization. Let us start implementing without getting too much into the theory.

Prepare dataset

Life is not a bed of roses! I believe this is the perfect proverb that a person can fit into anything in life. It similarly fits here as well. Your eyes must’ve shone when I mentioned that there is not a requirement for a single line of code. But do you remember that we had to modify the code that Watson Studio used to import your dataset from your repository? We had to add the column names manually or else it takes the first line as the header and our CSV file does not have a header. Since we cannot do this using code here, we have to take pains to add the columns manually and convert it to CSV.

So, open up your CSV in any notebook and the following values as column header in the first line to let Auto AI understand the headers and save as comma-delimited value.

'CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO' 'B' 'LSTAT' 'MEDV'

I have the file uploaded in my GitHub link of the book for you to use.

Fun fact - If you open the file in Notepad, you will see that the file is actually delimited by space even though it is saved as comma-separated-value file. This is the reason we gave +’\s’ as a delimiter when importing in pandas. So we needed to convert the file to a CSV as this is the only format that AutoAI understands.

Now let us open our Watson Studio Project and add this dataset in the assets like we did in our previous chapter.

Figure 6.9: Open Project

Click on Add to project button and choose Auto AI Experiment from the catalog.

You will be redirected to the New Auto AI Experiment page and you will be prompted to enter a name. On the right, you will also be asked to associate a machine learning service with this as shown below in figure 6.11 (There can be multiple locations and resource groups which might be available due to which some services might be hidden until the correct location and/or resource group is selected).

Figure 6.10: Associate Machine Learning Instance

Once you are done associating a machine learning instance, click on Create to create the Auto AI instance.

Figure 6.11: Creating Auto AI Experiment

Once your Auto AI instance is created, you will be taken to the Auto AI project page where you will need to add the dataset. You can directly add the CSV here or you can add it from the project which you have just added as housing_labeled.csv.

Figure 6.12: Auto AI Project Home page

Select the file you just uploaded with the header names and click on Select asset button in the bottom as shown in the next image.

Figure 6.13: Select CSV as data asset

Once the file is imported, Auto AI analyses the file and asks you the prediction column. You can go ahead and select MEDV from the dropdown.

There is no need to remove less correlated attributes. Auto AI does this for you.

As soon as you select the target column, Auto AI prompts you with what it thinks is the model that it will start with. The next image should give you an idea of where you need to select the output column and where it shows the best model.

Figure 6.14: Configure details page

Now you can check all the settings it uses and change it from Experiment settings button. The Experiment settings page first shows you the Data source settings. Here, you can check the percentage split between train and test datasets as shown as follows.

Figure 6.15: Experiment settings

By default, it is 85% of train set which you can increase up to 95%.

You can then go to Prediction settings from the left pane where you can see what kind of problem it has assumed, i.e. Binary Classification, Multiclass Classification or Regression and the metric that it is assuming to evaluate. You can change these settings as well.

Figure 6.16: Setting prediction type

The Runtime settings shows the machine learning service you associated it to and other configurations which cannot be altered.

Let’s keep it as it is and click on Cancel to return to the Auto AI project page. Since we have everything set up, click on Run experiment button at the bottom and watch Auto AI do its magic!

You will be able to visualize the algorithm working which is really fun to watch as shown in the next image!

Figure 6.17: Auto AI running

Once the algorithm finishes running, you can view the summary.

You can also check the evaluation comparison by clicking on the Pipeline comparison tab as shown in the next image.

Figure 6.18: Auto AI Pipeline comparison

As you can see, the algorithm has used cross validation. It can also use holdout set mechanism which is out of scope of this book. You can go ahead and check it out.

You can also check all the models it has fitted ranked in order of evaluation metrics as shown in the next image.

Figure 6.19: Ranked pipeline comparison

You can change the ranking by changing the evaluation metrics in the drop down beside Rank by. You can also expand any of the pipelines to check its details.

Let’s deploy the model now. If you go to the right end of any pipeline row, you will get a dropdown to save it either as a model or a notebook.

Figure 6.20: Save as Notebook/Model

Let’s select model. It will ask for the model name as shown below:

Figure 6.21: Saving as Model

Once it is saved, we can return to our main project page and scroll down under Assets tab to check the model. We can click on Deploy from the right as shown in figure 6.22 to deploy the model.

Figure 6.22: Deploy model

Once it is deployed, we can click on the model name and check the Deployments tab to check its deployment details like we did for Scikit-Learn models.

Conclusion

In this chapter, we have learnt a new machine learning algorithms which is one of the most frequently-used algorithm—decision tree regressor. We learnt how to use scikit-learn to implement decision tree regressor. We also understood the concept of forest and implemented random forest regressor in scikit-learn. All of these models have a similar version for classifier, namely decision tree classifier and random forest classifier.

After we finished exploring and implementing models, we took a step further into optimizing our models. We saw how we can leverage the various hyper parameters to optimize our machine learning models. We also used grid search to implement optimization in Python.

After such advanced coding concepts, we took some help from Watson’s tool Auto AI to do all the above for us in one go.

Now that we are comfortable handling any kind of structured datasets with ease, let us get our hands dirty with some unstructured datasets in the next few chapters.

CHAPTER 7

Visual Recognition

In the last chapter, we perfected our model and deployed it to be used in production by any third party application. But we must ask ourselves this: Will real life problems be so kind as to provide us with such a beautiful tabular data? Most of the data in real life will be unstructured!

But as soon as we hear artificial intelligence, some of the things that come to our mind (or anyone’s mind) are some of the top end applications that the world is pulling off using AI. Every data scientist dreams of building a completely automated system which achieves human behaviour. This idea led to some far-fetched dreams from Iron Man’s Jarvis, identifying the target to shoot at, to killing machines used by Humanoid robots such as terminator. All of these require that the machines identify and recognize objects by visualization.

In fact, the first thing taught to an infant is recognizing colors and objects through images. If you were to teach your child about colors and shapes, you would first show him colors and objects in a book and then ask him to identify objects in the real world.

Machine learning is no different. We give the machine some labelled images and then train it through some image recognition model.

Finally, to test we give it some test set from an unseen sample.

Visual Recognition has a wide range of application in the real world from reading and understanding invoices to catching intruders through security cameras.

Here, we will see how to tackle one of the most common unstructured data formats, i.e. image.

IBM Watson Visual Recognition service is the tool you need if you want your application to identify objects from images. It uses deep learning algorithms to analyze images for scenes, objects, and other content. This is going to be interesting!

Structure

The following topics will be covered in this chapter:

- Setting up the environment for Watson Visual Recognition

- Identifying the Visual Recognition problem

- Creating the custom model

- Adding image data

- Training

Objectives

- Setting up the environment for a visual recognition problem using Watson Visual Recognition Service.

- Understanding the Visual Recognition task and how to approach it.

- Learning how to create a model by leveraging the Watson Visual Recognition Service

- Knowing how to add the unstructured images

- Finally, training and evaluating

Setting up the environment for Watson visual recognition

Let us set up our environment first before diving into our Visual Recognition project.

Open your Watson Studio Service and create or open a project. Click on the Add to project button at the top right and select Visual Recognition from the list. It will ask you to associate a Visual Recognition service with this as shown in the next figure:

Figure 7.1: Associate Watson Visual Recognition Service

This will open up a page which will list your services and has a New service button to create one as shown in the next image.

Click on the New service button and it will open up a list of services (similar to the one when you create a new resource when you login). Select Visual Recognition from the list as shown in the next image.

Figure 7.2: Visual Recognition Service

On the Visual Recognition page, fill up the appropriate fields (name of service, region, etc.) and click on Create to create a Visual Recognition service.

Once your service is created, you will be able to see your Visual Recognition service in the list of services (if needed, select the regions from the top of the dropdown). Select the Visual Recognition service you just created and click on Associate service beside Cancel at the top of the list.

In case your version of IBM Watson and IBM Cloud Pak for Data does not allow you to add and associate the service as given in the previous step, you can go to the home page of your IBM Cloud and add the service from there by clicking on Create a Service from there (like you had created Watson Assistant).

Figure 7.3: Visual Recognition Service Created

Once your service is up and associated, you will be redirected to the Create visual recognition model page.

Identify the visual recognition problem

Now any Visual Recognition application can be broadly classified into two types:

- Image classification: In this type of application, you train your model to classify one type of image from another. For example, you might train a model to classify between dogs and hyenas, or build a model to watch a CCTV footage and classify between people wearing helmets and those not wearing them.

- Object detection: In this type of machine learning problem, you try to identify an object in an image. For example, you can build a model to identify how many people there are in a park from a CCTV footage.

Create custom model

We are going to build a model for image classification and we leave it you to try out an object detection model. So, click on Create model + in the Classify images box. You will need to create a project by entering a project name and clicking on the Create button.

Once you are in the Default Custom Model page, you have to do two things – upload images for train and test and define the classes of your images. As you can see in the next image, it tells you that the maximum size of the data is 250 MB.

Figure 7.4: Default Custom Model Page

The task that we are going to address is to classify images of dogs based on their breeds. We will have two classes of breeds – Husky and Beagle. We have provided the link to download the zip files for each below to get the sample images to train and test. All these images are taken from Watson’s GitHub link for tutorial.

- Beagle:

https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/beagle.zip

- Husky:

https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/husky.zip

Before you proceed, you need to keep in mind two things:

- Watson recommends you to organize your images in a zip format – one zip per class where each zip file can have a minimum of 10 images and a maximum of 10000 images or a maximum of 100 MB per zip size.

- The supported image file formats are JPEG or PNG and the maximum image size is 32×32 pixels.

So let us unzip and extract the images and keep 20 images in each zip file for each class. The rest we will use for testing.

Adding image data

Now to add the images, you will need to upload the zip files in the data panel on the right. So click on the Browse button on the right and select your zip files. Once you have uploaded, you will be able to see the zip files in the data panel on the right. You will also be able to see them on the dashboard, each zip file representing one class. You can edit the names of the classes (obviously, you don’t want your classes to be named something like Beagle_data.zip).

Figure 7.5: Rename class name

Training

Once your data is ready, you can click on Train model button at the top right as shown in the next image.

Figure 7.6: Visual Recognition Model Training

Once your training is complete, you can test your custom model in the Test area of the Visual Recognition model builder. You can test individual image files by dragging them from your computer onto the test area. You can also test all the images in a .zip file from the data panel. (If the data panel isn’t open, you can open it by clicking the Find and add data icon, that is, the find data icon).

Deploying this model is similar to deploying an Auto AI model. We will leave that as an exercise for you.

Conclusion

Visual Recognition is one of the subsets of a huge area of machine learning namely Computer Vision. In this chapter, we have leveraged IBM Watson’s Visual Recognition tool to classify images. We have seen how to create an instance of the Visual Recognition Service and train it for a classification task.

Although Watson Visual Recognition is a great way to start with unstructured data, there are a lot of fields untouched when it comes to unstructured data such as documents and natural languages. We will take a look at how to deal with them in the next chapters.

CHAPTER 8

Watson Discovery

We now have a fair idea of how to leverage our Data Science and Python skills to deploy a machine learning model into production using IBM Watson. We saw how we can go about solving any structured dataset gracefully and deploy it into production as well. We also saw how to deal with one of the most common unstructured data assets – images. But while working in an industry, you will also face another common unstructured data type such as documents of various kinds such as legal documents, contracts, etc. To approach these types of data, you will need to know how to deal with natural human languages, keeping in mind that computers only understand numbers. These kinds of machine learning problems are so common that they have found a separate place in the class of machine learning problems – Natural Language Processing.

Let me show you how IBM Watson can take some of the burden off your shoulders. You can use your analytical skills to solve some of the best NLP (Natural Language Processing) problems without any Python code using Watson Discovery and Knowledge Studio.

Structure

- Natural Language Processing

- Scrape and find the right resources (PDFs or Docx, etc.)

- Analyse your documents

- Convert document data into raw formats

- Filter out junk data (for example, special characters, unless it is what you need to identify)

- Convert text to a number using trained pre-embedding.

- Apply your model

- NLP with IBM Watson Discovery

- Setting up the environment

- Watson Discovery News collection

- Querying Watson Discovery collections

- Working with new Collections

- Annotating

Objectives

- Understand the methods and building blocks of Natural Language Processing.

- Understand the different methods to convert raw documents into formats and structures that can be used for machine learning algorithms.

- Learn how to analyse these data structures and use the data preparation methods for machine learning algorithms to work.

- Learn how IBM Watson Discovery is useful to solve NLP problems.

- Learn the various steps to work with the IBM Watson Discovery Service, including setting up, creating collections, annotating, and finally querying them.

Natural Language Processing

One of the broader classifications of machine learning applications is Natural Language Processing (or NLP). NLP tasks consist of the following steps:

1. Scrape and find the right resources (Pdfs or Docx, etc.).

2. Analyse your documents.

3. Convert document data into raw formats.

4. Filter out junk data (for example, special characters, unless it is what you need to identify).

5. Convert the text to a number using trained pre-embedding.

6. Apply your model.

The next steps are similar to any other machine learning problem. But the steps of pre-processing are the ones which are heavy for any NLP task. So, let us look into each of the tasks one by one.

Scrape and find the right resources

Data is the driver for any machine learning problem. So to be successful in any machine learning task, you have to look for the correct data which suits your needs. This step focuses on finding the right data from a heap.

Generally, in real-world problems, you will be provided with client data (document). You will usually be overwhelmed by the number of documents you are provided with when you ask for data to be trained. Also, you will probably be stating that the more data you have, the more will be your model’s accuracy. But this is where the catch is – the more data you have, the more you have to scrape from that huge chunk and find the correct data that suites your problem. Also, the more data you have, the more pre-processing you need to do. But that is a price you need to pay to achieve good accuracy.

Analyse your documents

In this step, you have to continue with what you started doing in the previous step. You have to go through all the documents you received and analyse them to find patterns and keywords which you will use in your NLP tasks. As there is a principle in software engineering, plan before you start. This step essentially does so.

For example, if you were assigned a NLP task to prepare a model to take a document and classify into security contracts and other contracts, you would generally look for keywords such as “Law”, “Contract”, etc. Now, from that huge chunk of documents, you might have already filtered out invoices, P/L statements, etc. Now, in this step, from the rest of the documents, you have to identify which are security contracts and which are not. Often, this step requires a domain expert who will sit with you and help you classify the documents. You, in turn, might have to get inside his head to understand how he is classifying, which essentially means finding out the keywords he is looking for, clauses he is identifying, etc.

Convert document data into raw formats

Now, you will start with your programming/tooling skills in this step. If you have already started thinking about how you are going to approach a classification or regression problem in NLP, you must have realized that all the data you have been provided are in a format, your code won’t understand.

Your data will be in several formats. You might even have to manually scan some documents if they are in the hard-copy format (I hope you don’t have to go through this at least!). Finally, what you will have are PDFs, images in JPG/PNG (the list goes on), MS Word documents, spreadsheets, or even some custom formats. But how will your code understand the characters from so many different file formats.

Actually, this step requires some special tools/skills. To extract text from each of those formats, you will need tools for each of them. For example, you might need an OCR (Optical Character Recognizer) such as Tesseract if you are extracting text from images or PDF, or PyMuPDf to extract text from pdf in Python, a Word file to XML, or a JSON converter to convert Word documents to XML or JSON, and then write your custom code to extract the text, and so on.

All such tools should give you the extracted text and you can store them in some files.

Filter out junk data

Once you have the raw text, you will look out for keywords and patterns. Suppose you are assigned a task to extract all lenders from a contract. You realise that you have to extract portions of document containing the word ‘lend’ or any of its forms. But this word might come in a wide variety of forms such as lenders, lending, lends, etc. So you have to convert all such forms into lend. This is called lemmatization.

Your documents might also contain Unicode characters and special characters which you will need to convert into plain text. For example, 0x0084 is a Unicode representation of a closing double quotation. You will need to remove such characters or convert the needed ones to plain text.

If your documents are in the HTML format, you would need to remove all tags.

Stop-words are commonly occurring words such as a, the, etc. which can cloud your model’s judgement, thinking that these are the keywords which define a particular class of document as they occur most frequently. You will need to remove them as well.

The preceding scenarios have been presented to make you aware of some of the situations you need to deal with before presenting even the raw data to your machine learning model. It would be a good idea to compile a script or have a tool ready to achieve some of the tasks.

Convert the text to a number using pre-trained embedding

If you can recall, all our input data to any machine learning models that we created using Python are numbers. Our machine learning model will need numbers to put into the linear regression equations or to assign to your X values in your neural network neuron inputs. But we just converted everything we got from the client to text. Now, we need to convert them to numbers.

But converting words to numbers blindly will bring in more problems. This is where the concept of word embedding arrives. Word embedding converts each word into numbers so as to give a meaningful representation of numbers such that related words can have a small gap in the number line. For example, when word embedding converts the words such as Man, King, Woman, Queen into numbers, Man – King >> Man – Queen as they are close in relation to gender. Also, the difference between Woman – King and Man – Queen should be very less.

These types of embeddings are generally achieved by training a model to a large dataset. There are a lot of pre-trained word embeddings. Google’s BERT being the most popular at the time of writing this book.

Apply your model

After all this hassle, you will be ready to pull up a model to fit your problem because now you have a dataset consisting of meaningful numbers.

Typically, a Python script to do all of this will require a huge amount of expertise and a lot of time. I have a Python application ready for you to glance at in the GitHub link: https://github.com/gangulyarin/codes/tree/master/chapter8. It should give you a fair idea of what a small NLP task can cost. But this chapter is not about Python. Let me show you our saviour for NLP tasks – Watson Discovery.

Watson Discovery is the most widely used NLP tool by many businesses. It handles all the steps I mentioned here as part of its NLP pre-processing, including extracting text from PDFs or images using its built-in OCR. It also gives us a lot of extended capabilities such as text recognition, pattern recognition by formats, and many more. Instead of bombarding the floor with jargons, let us dive into the tool and solve a NLP task.

NLP with IBM Watson Discovery

As I had mentioned earlier, for real-life problems, you will be handed a lot of client documents. But we will address a very general NLP task for two reasons – we don’t have any client data as they are confidential, we are just starting out!

So, the problem we will solve is entity extraction. You might have noticed that when you open a document in Microsoft Word, it recognizes all the titles and builds an index for you on the Navigation pane. Inspired from this, we will extract all titles from a document. You might be motivated further to build an application to build an index for any document so as to save the toil of building a content of index.

I have uploaded the PDF version of two of the chapters of this book. We will use chapter 3 – Features and Metrics, for training and chapter_4 for testing the model. So, without further ado, let’s dive in.

Setting up the environment

The first thing we will need to do is set up a Watson Discovery service in our account. So, log in to your IBM Cloud account and search for a Discovery instance under AI/Machine Learning. The Discovery service card will look like the one in Figure 8.1:

Figure 8.1: Discovery Service Card

Go ahead and create an instance. Once you have a Watson Discovery instance, launch the instance.

Once you launch the instance, you will be welcomed with pre-enriched data consisting of various news items named – Watson Discovery News, as shown in Figure 8.2:

Figure 8.2: Watson Discovery Home Page

Each of these data sets that you see on the home page is referred to as collections. As a matter of fact, the Watson Discovery News collection is widely used by various businesses to show and extract the current news data. We will see soon what the capabilities of IBM Watson to provide enrichments are and how we can leverage that.

Watson discovery news collection

At the time of writing this book, Watson Discovery also allows the creation of a COVID-19 kit during the time of the COVID-19 pandemic. But let us look into the pre-enriched collection that Watson already provides for now by clicking on the Watson Discovery News collection.

Once you open the collection, you will see a very comprehensible dashboard summarizing the important elements of the collection. For example, the dashboard says that there are more than 15 million documents ingested into this collection; it has already added five enrichments in the data (the reason why it’s called pre-enriched data). These enrichments are as follows:

- Entity extraction: You can add entity enrichments so as to extract certain entities such as countries (United States), organizations (Facebook, Twitter), etc.

- Concept tagging: You can add enrichments to extract concepts or topics based on clustering.

- Keyword extraction: Certain keywords based on terms synonymous to concepts or entities.

- Sentiment analysis: Sentiment analysis is a common NLP task to identify the emotion expressed in a text segment. Watson has its own algorithm to identify sentiment from a segment. It even has a separate service called Tone analyser solely for the purpose of Sentiment analysis.

- Category classification: Discovery can be enriched so as to classify document types.

We cannot include all types of enrichments in the scope of this book. We will try to learn how to add entity extraction as this is the most common enrichment applied to almost all NLP tasks.

Querying Watson discovery collection

There is a section on the same page suggesting some sample queries. Watson Discovery allows us to query the collection to get any kind of required data. Let us see how.

Click on the Search icon on the left-most panel as shown in Figure 8.3:

Figure 8.3: Build Queries View

Expand the Search for documents section. Go ahead and write a term (such as a bank) to see how it works under Use natural language and click on the Run query button at the bottom of the page. For example, in Figure 8.4, I have written bank and searched for it in the collection:

Figure 8.4: Search ‘bank’ in collection

The search results will appear on the right-hand side as you can see in Figure 8.5. Let us take a closer look at the Results section. It gives a Query URL at the top of the page. You can use this URL in your web application to get the results. Then, it shows the number of results. By default, the number of results per query is restricted to 10. You can increase it by expanding more options on the bottom left as shown in Figure 8.6. Do not increase the number from 10 because Watson News only allows 50 results to be displayed:

Figure 8.5: Increase Number of documents to return

You can expand each of the results to view all the enrichments it finds in the results. Since you have searched for the term bank, it will give you all the passages where it finds this term and the corresponding enrichments in those passages.

If you are using an API to query, you might be interested in the JSON version of the result which you can obtain by clicking on the JSON tab right next to Summary in the right pane as shown in Figure 8.6:

Figure 8.6: JSON view of the Search Result

You might have noticed while querying that you can also use something called the Discovery Query Language to query your extractions. Let’s use the Discovery Query Language to see what the entities Discovery associates for all passages are where it finds the term bank. Now, the Discovery Query Language is not like a programming language in case you are already scared!

You might notice that in JSON, response lists of entities come under the enriched_text object. As a matter of fact, this object stores all the enrichments (such as concepts, categories, etc.).

Figure 8.7: JSON response list of entities

So, what we are interested in is all the entities containing the term bank.

Now, if you expand the entities array, you will find the data in the format shown in Figure 8.8:

Figure 8.8: Detailed entities

The first entity extracted is of the type company and the text is Banking Systems Software, which means it has extracted a company by the name of Banking Systems Software. The next one is a job title – Banking Systems Software Industry. Although, it might sound like it is doing a pretty bad job at understanding the entity types, this is where we will build our own recognizer later. So, if we want to extract all entities containing the term bank, then we will need to find all enriched_text.entities.text containing the word bank.

We are almost ready to construct our first query! But before this, I want to introduce you to two operators:

- :: means equals

- : means contains

So, click on the Use the Discovery Query Language tab next to the Use natural language tab. You will be greeted with a drop-down menu of Field, Operator and Value. Above the Field in the drop-down menu, there is a drop-down menu asking you to choose between Select all of the following rules or Select any of the following rules. The all and any corresponds to Boolean AND and OR condition between several rules. You can add multiple rules by clicking on Add rule or Add group of rules just below the Field drop down option.

Now, select enriched_text.entities.text from the Field drop-down menu, select contains from the Operator drop-down option and type bank in the Value field and click on Run Query (refer to Figure 8.10). You might see some interesting extractions if you scroll down the JSON query result section as shown in Figure 8.9:

Figure 8.9: Querying using Discovery Query Language

Watson Discovery was able to identify Andhra Bank as the Company.

If you click on Edit in query language right below the Use a sample query button, you will see that the internal query it used is enriched_text.entities.text:”bank”. As expected, isn’t it!

You can also use multiple queries to be executed as shown in Figure 8.10:

Figure 8.10: Multiple Queries using Discovery Query Language

Here, we are searching for entities which contain the term ‘bank’ but there are also entities of type ‘company’. This will make sure that it does not return passages where just the bank term was referenced. As you can see from Figure 8.11, it extracted Union Bank of India rightly as a bank and a company. Note that all is selected above the Field drop-down option to make sure that both the query fields satisfy the condition.

If you click on Edit in the query language, you will see the following query:

enriched_text.entities.text:"bank",enriched_text.entities.type::"Company"

The comma (,) signifies AND condition. If you had selected any instead of all, there would have been | (pipe) instead of a comma to signify the OR condition. Also, since we are using is for the second query instead of contains, it uses the operator :: instead of :.

Working with new collections

Now that we have a fair idea of Discovery, let us ingest our own data. So, download the train pdf and go to the home page by clicking on the Manage data symbol at the top of the left pane as shown in Figure 8.11:

Figure 8.11: Options Pane in Watson Discovery

On the Manage data page, click on the Upload your own data button to create a new collection and you will be prompted to give a collection name. Type a collection name such as Chapters and click on the Create button to create the collection.

Your collection will be created and you will be taken to the collection’s dashboard. Since you don’t have any data in the new collection, it will ask you to upload a data file in the dashboard as shown in the Figure 8.12. It also provides you with the types you can upload and the maximum size of each document:

Figure 8.12: Blank Collection

Go ahead and click on select documents link and upload the fourth chapter’s PDF that you downloaded by browsing to it. As soon as you upload it, Watson Discovery starts processing you documents.

Figure 8.13: Uploading and Processing Data

This is the step where it performs all the NLP pre-processing steps that I had mentioned earlier such as analysing your documents, converting document data into raw formats, filtering out junk data (for example, special characters, unless it is what you need to identify), converting text to number using trained pre-embedding, and even more.

Once the upload is complete, you will see the dashboard as shown in Figure 8.14:

Figure 8.14: After Data Processing

As you might have noticed, it has already added some enrichments, which are not so effective. We will touch upon improving this in the second section of this chapter. As of now, you can go on and query the document or play with it a bit.

Annotating

Annotating is a method of manually labelling the data to some types so as to prepare the train data.

Recall that our task is to identify the titles and subtitles. So, we will annotate the titles (and subtitles).

Click on Configure data on the top-right corner of the dashboard and you will be taken to the Configure data page. This is where the magic happens!

Figure 8.15: Configure Data Screen

As you can see, Watson already provides you with a list of fields. You can also create your own field. For our task, I think we can make do with what is already there. We will label (annotate) using the title field.

Click on the Single page view button (Page symbol) on the left-hand side of the Zoom-in button (magnifying glass symbol). The annotations will appear on the text. Currently, everything is annotated as the text field. So, click on the title field and select the title of the page Build Your Own Chat Bot (Figure 8.16). Click on the Submit Page button at the bottom when you are done with the page:

Figure 8.16: Annotating Documents

As soon as you click on the Submit page, you will be taken to the next page to annotate. On page 2, annotate Intents, Entities, Dialogs, and First Ever Project-The Chat bot as titles:

Figure 8.17: Annotating Titles

Keep on annotating all the fields. I have annotated the following text as titles:

- Build Your Own Chat Bot

- Intents

- Entities

- Dialogs

- First Ever Project-The Chat bot

- Create IBM ID

- Create Resource

- The Use Case

- Create your Intents

- Create your Entities

- Create the Dialogs

You might be wondering what happens for large documents containing tens and thousands of pages. It is impossible to sit and manually annotate everything. Watson Discovery is intelligent in itself to learn as it annotates. You might have already encountered that when you are annotating that at one point in time, it recognizes the title before hand. Hence, it’s learning with you! As for me, Watson identified from Create your Intents automatically without manually annotating. So, once you see that Watson is recognizing now, you can stop and may be randomly check a few pages after that.

Once you are done, click on the Apply changes to collection button at the top-right of the page and Watson will prompt you to upload the document again. You will need to upload this document again along with any other document you want the model to work with. I am going to upload the same document again.

Once this is done, if you query, you will receive a title field along with text in the JSON result.

Now, let me break some news to you which you might not be very happy about. The enrichments that are applied using Watson Discovery annotations are based more on the data format than the data itself. It tries to find a pattern using the text styles such as font, size, etc. But a proper NLP algorithm tries to recognize or classify items based on the text alone, independent of the format of the text. This is because the format might be different in different documents and our algorithm should not be too stringent.

To address this issue and build a proper NLP model, Watson provides you with a service focussed on only training and building NLP machine learning models – Watson Knowledge Studio. Watson Knowledge Studio is a very powerful tool for any data scientist and I urge you to try it yourself as an exercise.

Conclusion

In this chapter, we introduced you to a new topic of machine learning algorithm, namely, Natural Language Processing (NLP). We got to know the building blocks of approaching an NLP problem from scratch. We understood that NLP problems need the data as raw documents to be converted to structured data to be used by machine learning algorithms and its various pre-processing and data preparation requirements, including embedding the mechanism where the raw data is converted to numerical feature columns.

Then, we learned about the tool Watson provides to solve NLP problems, namely, Watson Discovery. We learned how to use this tool and ingest data to create a collection and process it to build queries. Finally, we also added an extra step to modify the training procedure by annotating documents.

Now that we have an idea of how to approach different types of structured and unstructured machine learning problems, we must also think about productionizing them because in the end, the industry will ask you to deliver results and port it to client domains and infrastructures. We will focus on this post processing step in the upcoming chapters.

urge CHAPTER 9

Deployment and Others

I hope now you are fairly confident to take up a project. We have used Watson Cognitive Services like Watson Assistant to build a wonderful chatbot and Watson Discovery to perform natural language processing tasks such as extracting keywords from documents. But in real-life scenarios, we will need a place to deploy these as applications (quite possibly a web application).

So, before leaving the stage, I want to share some important deployment concepts. These will include some of the ways to deploy an end-to-end project using the Watson services you learned as well as some of the useful services which you cannot do without in a project. You can consider these services as utilities. They are easy to use and setup as well as essential features to have in any AI application.

But before we begin, I want you to know that this book does not teach you web development and neither does it teach you to be a Machine Learning expert. This book is about harnessing the power of IBM Watson Cognitive tools into production using your Machine Learning and Web Development skills that you may already possess. Machine Learning and Web development are completely different subjects and there are thousands of books just on these topics. I will urge you to go ahead and hone your Web Development and Machine Learning skills after you complete the book and then come back to enhance all your solutions you built here.

So without wasting any more time, let me take you through each of these topics, one section at a time, in no particular order. This chapter will teach you a lot of things together, so take your time!

Structure

- Building a Python server

- Deploying your web application to IBM Cloud

- IBM Watson Tone Analyzer

- IBM Watson Text to Speech

Objectives

- Learn how to build a small server using Python. We will use this Python server to connect and work with IBM Watson Cognitive services.

- Learn how to deploy the web application into IBM Cloud analogous to a production environment.

- Get hands-on experience on other Watson Cognitive Tools, namely, IBM Watson Tone Analyzer and IBM Watson Text to Speech.

Building a Python server

Today’s world is the world of cloud. A day without Internet will cause a disaster almost equating to the earth’s pause in rotation. In this section, we will create a very small and generic web application using Python. As I had already mentioned, we are not learning web development here. I assume you have some basic idea of the client server architecture that any web application follows nowadays. I also assume that you have a basic idea of HTML tags and HTTP request methods.

Any web application has two sections - a front-end and a back-end. The front-end is generally built using HTML, CSS, and JavaScript to create a look and feel for the end user to interact with the web application. The user interaction is sent to the back-end of the application which processes the interaction and sends a response back to the front-end for the user to view.

Creating scripts to interact with users using JavaScript is quite tedious. To reduce this effort, there are a lot of frameworks that can be used such as Angular, React, Vue, etc. I will suggest that you learn any of the frameworks to make your life easier. But here we will use simple HTML.

We will use Python for the backend. Watson services have several SDKs in different programming languages (Python being one of them). You can also use any other programming language to script your backend such as Node.js, Java, etc. Watson has SDKs for many such languages. If you do not find a SDK for your favourite language, you will find a cURL API, which can be used to develop your own SDK.

Let’s start with the backend code and build our first Python server. A Python server is a program that will listen on a port for any HTTP requests and will process them to send out a response. Now, we will use a Python module called Flask to prepare our server. Flask has all the features to initiate a server, listen for any kind of HTTP request, and send a response.

Before you begin, you need to install Flask using our favourite pip command in the command line:

pip install flask

Once it is installed, open your favourite Python editor and create a Python file. This will be the main file driving the server and where all the requests and response configurations will be. I have named the file flaskTemplate.py.

We will first import flask and two other classes.

import flask

from flask import request, render_template

Now, we will initialize flask and set a static URL path. A static URL path is one where you will keep all your static files to be rendered such as your CSS, images, etc.

app = flask.Flask(__name__, static_url_path='/static')

Now, we are ready to code our first request and response. We will receive a simple get request to the root (/) page and render some HTML. Now, HTML can be rendered in two ways. You can write your HTML code directly as a string in Python, or you can render a HTML file. Rendering a HTML file is preferred as your HTML might not be restricted to a few lines and can span hundreds of lines. We are going to do the same. Along with this, we will have some dynamic values also to be populated from the Python code. We will have a python variable, whose value will be populated in the HTML render.

A basic HTML code will be something like the following code:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Home</title>

</head>

<body>

<h1>Title</h2>

.. .

</body>

</html>

We need to insert a string variable’s value as the title in the h1 tag. Let’s consider the variable name is titleStr. To do this, we need to change the title line as follows:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Home</title>

</head>

<body>

<h1>{{titleStr}}</h2>

</body>

</html>

This will replace {{titleStr}} with the value of the variable titleStr.

So, we will create an HTML file with the name index.html and put it inside a folder called template. Flask will render all files in this folder when asked to.

Coming back to our Python file flaskTemplate.py, we will now render the index.html file with the dynamic content on a get request to the root (/). The following code does this:

@app.route('/', methods=['GET'])

def root():

title="Home Page!"

return render_template("index.html", titleStr=title)

The code is self explanatory. @app.route defines the path and HTTP method, and the render_template function renders the file with the file name as the first argument and the variable context in the second argument.

Now, we need to add the code to listen to a hostname and a port for any incoming request and we are done:

#app.run()

if __name__ == '__main__':

app.run(host="0.0.0.0", port=8080, debug=True)

We will be listening to 0.0.0.0, which is the localhost in the case of your local machine and port 8080.

Once this is done, run your Python file flaskTemplate.py using the Python command as usual, and you will see something like Figure 9.1 in the command line:

Figure 9.1

It is asking you to check your browser to the defined URL and port. So, open you browser and navigate to localhost:8080, you will see something like as shown in Figure 9.2:

Figure 9.2

Deploying your web application to IBM Cloud

Now that we know how to create a web application, we can now deploy it to IBM Cloud so as to have a production deployment. To do this, we need to first install the cloudfoundry CLI from the link https://docs.cloudfoundry.org/cf-cli/install-go-cli.html. CloudFoundry is a PaaS offered by IBM Cloud where you can deploy your application. Once you have installed the cloudfoundry CLI, you can verify your installation by opening your command prompt or terminal and type the following command:

cf login

It will prompt you to enter your email and password. If your login is successful, CF CLI will be installed correctly. Now, migrate to your application folder while you are already logged in. You will need to create an organization and a space. Create an organization (myOrg) first by entering the following command:

cf create-org myOrg

Then, create a space (dev) by running the following code:

cf create-space dev

If you have a lite plan and you already have an organization, you might not be allowed to create another. You can check your existing organizations using the following command:

cf orgs

You can check your current spaces using the following command:

cf spaces

Now, once you have your organization and space ready, you can go to a specific space in two ways:

You can log in again using cf login –o ORGNAME –s SPACENAME, where ORGNAME is your organization name and SPACENAME is your space name.

OR

You can run the command cf target –s SPACENAME if you are in your organization.

Now that you are in your organization and space, let’s make our application ready for deployment.

Create the following two files in your application’s root folder:

- Procfile: Create a file named Procfile (without any extension) and keep the contents as follows:

web: python flaskTemplate.py

This will tell IBM Cloud how to run the application.

- requirements.txt: Create a file named requirements.txt (a text file) and keep the following contents:

Flask>=1.0.0

This will tell IBM Cloud to install the required Python modules (Flask in this case).

Once these files are created, you are ready to deploy your application. To deploy your application, simply type the following command from your application’s root folder:

ibmcloud cf push MyFlaskInstance

MyFlaskInstance is the name of the application. You will see a success message on the terminal stating that your application is deployed. To check your application details, type cf apps and you will be able to see all your applications:

Figure 9.3

The table will also show the URL where your application is deployed in the last column URLS along with other details such as the amount of memory and disk space it is using. Open the URL and you will see the same web page as shown in Figure 9.2.

Congratulations! You now know how to build a web application to deploy to IBM Cloud. Let’s add a few more features to our web application now.

IBM Watson Tone Analyser

IBM Watson tone analyser is the go-to service when you want your solution to handle one of the most common and yet important tasks – Sentiment Analysis. IBM Watson Tone Analyser uses the NLP algorithm on features to evaluate emotional and language tones in a piece of text. At the time of writing this book, Watson Tone analyser supports English and French. You can use Watson Tone Analyzer using any of the following two endpoints:

- General-purpose: To analyse shorter data such as tweets, blog posts, etc.

- Customer-engagement: To monitor customer support conversation and take actions in case conversations turn sour.

Here, we will use the general purpose tone analyser. I leave the rest for you to explore.

A general purpose tone analyser takes in text as input and outputs a score for each emotional sentiment it finds for each sentence and for the whole document. The tones it identifies for general purpose endpoints are classified into two such as emotional tone and language tone. The emotional tones are anger, fear, joy, and sadness. The language tones are analytical, tentative, and confident.

Let’s integrate a tone analyser in our web application.

First, add a tone analyser service from the resources page:

Figure 9.4

Once your service is instantiated, you will get the API and URL details on the Manage page. Now, we will see how to integrate it in a web application.

Like I had said earlier, Watson provides APIs for all the services as well as some SDKs for some popular programming languages. We will use the Python SDK for the Tone Analyzer API. To check how to use it, go to the following API documentation link:

https://cloud.ibm.com/apidocs/tone-analyzer?code=python

Let us code our tone analyser Python service now.

Install the Python SDK module of IBM Watson using pip as follows (as mentioned in the API documentation):

pip install --upgrade "ibm-watson>=4.6.0"

Create a file toneAnalyzer.py in your application and add the following code to authenticate your tone analyser instance:

import json

from ibm_watson import ToneAnalyzerV3

from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

authenticator = IAMAuthenticator('your API key')

tone_analyzer = ToneAnalyzerV3(

version='2017-09-21',

authenticator=authenticator

)

tone_analyzer.set_service_url('your API URL')

Add your API key in place of the string ‘your API key’ and your API URL in place of ‘your API URL’ string. IAMAuthenticator is the preferred method to use for authenticating with Watson. The other method is BasicAuthenticator which takes in the username and password to authenticate.

Now that your tone analyser is authenticated, let’s create a function to take text as input and return the response got from the tone analyser:

def sendTone(text):

tone_analysis = tone_analyzer.tone(

{'text': text},

content_type='application/json'

).get_result()

return json.dumps(tone_analysis, indent=2)

We will use the sendTone method to take the text and pass it to the tone method of the tone_analyzer object that we instantiated in the previous code snippet. Once we get the result, we will return the response after formatting it to JSON using json.dumps.

Now that our tone analyser is ready, let’s change our flaskTemplate.py file and index.html to use the tone analyser.

But before that, let’s see a sample response from the following tone analyser:

{

"document_tone": {

"tones": [

{

"score": 0.6165,

"tone_id": "sadness",

"tone_name": "Sadness"

},

{

"score": 0.829888,

"tone_id": "analytical",

"tone_name": "Analytical"

}

]

},

"sentences_tone": [

{

"sentence_id": 0,

"text": "Team, I know that times are tough!",

"tones": [

{

"score": 0.801827,

"tone_id": "analytical",

"tone_name": "Analytical"

}

]

},

{

"sentence_id": 1,

"text": "Product sales have been disappointing for the past three quarters.",

"tones": [

{

"score": 0.771241,

"tone_id": "sadness",

"tone_name": "Sadness"

},

{

"score": 0.687768,

"tone_id": "analytical",

"tone_name": "Analytical"

}

]

},

{

"sentence_id": 2,

"text": "We have a competitive product, but we need to do a better job of selling it!",

"tones": [

{

"score": 0.506763,

"tone_id": "analytical",

"tone_name": "Analytical"

}

]

}

]

}

As you can see from the structure of JSON, the response contains a document tone and a sentence tone. We can change the setting or pass parameter in the API to get only the sentence tone or document tone. For each sentence tone, there is an array of tones containing the score tone_id and tone_name, where tone_id and tone_name signify the type of tone (anger, sad, etc.). So we have to parse JSON keeping the structure in mind.

What our application will do is ask the user to enter a text in a text area and if we get a response, then it will show all the tones from the document tone only.

To achieve this, let’s change the HTML first. We will consider that we already have the document_tone object from the response. We have to loop through all the tones and display their names and corresponding scores. Now, for this, we will need to use the if-else condition in the HTML template (to check whether there is a response or not) and the for loop to loop through all the tones in document_tone.

We will use the following format for the if-else condition in the HTML template in Flask templates:

{% if condition %}

HTML content

{% else %}

HTML content

{% endif %}

The format to use for the loop in HTML is as follows:

{% for x in iterable %}

HTML content

{% endfor %}

Keeping the preceding things in mind, I present to you the modified code for index.html as follows:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Home</title>

</head>

<body>

<h1>Home Page!</h1>

<form id="form1" method="post">

<textarea id="text" name="text"></textarea>

<button type="submit">Submit</button>

</form>

{% if jsonobj != undefined %}

<div>

{% for obj in jsonobj %}

<p>

<span>{{obj.tone_name}}</span>:<span>{{obj.score}}</span>

</p>

{% endfor %}

</div>

{% endif %}

</body>

</html>

The code is self-explanatory. We have a text area in a form to send the text in a POST request, and if there is a response in the variable jsonobj, then loop through all the tones. Here, we assumed that our Flask server has sent the document_tone part of the response from the tone analyser response. We will code this now in our flaskTemplate.py.

So, open up the flaskTemplate.py file and add the following import from our toneAnalyzer file that we created as follows:

from toneAnalyzer import sendTone

Now, let’s configure the post request to get the text and return the document_tone part of the response after getting the response from sendTone function that we imported:

@app.route('/', methods=['POST'])

def my_form_post():

text = request.form['text']

toneResponse = json.loads(sendTone(text))

return render_template("index.html",jsonobj=toneResponse['document_tone']['tones'])

Now, we are ready to run it in our localhost.

The web application will show a text area where you can type anything and press submit. As soon as you do, the tones will appear right below it as shown in Figure 9.5:

Figure 9.5

Congratulations! You have successfully used your Python SDK of the Watson API.

Now, deploy this application in your IBM Cloud cloudfoundry by opening the terminal/command prompt in the application root folder and log in using cf login (after ibmcloud login from your terminal as shown earlier).

Once you are logged in and in your organization and space, simply type cf push to deploy and your application URL will show exactly what you saw in Figure 9.5.

Now, let’s make our application a bit more interesting by adding another service.

IBM Watson Text to Speech

The documentation says – “The IBM Watson Text to Speech service converts written text to natural-sounding speech to provide speech-synthesis capabilities for applications.” Yes! You can convert text to natural sounding speech using this service! You can use a range of languages to encode your text to speech. You can even use a mark-up language called SSML to use tags to increase or reduce stress on a particular word or segment of text. You can also choose between a wide range of voices. But explaining all the capabilities of text-to-speech is beyond the scope of this book. So I urge you to go through the documentation once in the following link:

https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-gettingStarted

Let us dive in to creating the service and using it. You know the drill! The first step is to create the service from IBM Cloud Catalog:

Figure 9.6

Once your service is ready, you can go to the Manage page to obtain the API key and URL. Just like Watson Tone Analyzer, you can check out the authentication and usage of the API using the Python SDK in the following URL:

https://cloud.ibm.com/apidocs/text-to-speech?code=python

You will not need to install any other module. It uses the same ibm-watson module. The authentication and instantiation is similar to Tone Analyzer. So, we will create another Python file textToSpeech.py and add the following code:

from ibm_watson import TextToSpeechV1

from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

import os

authenticator = IAMAuthenticator('API Key')

text_to_speech = TextToSpeechV1(

authenticator=authenticator

)

text_to_speech.set_service_url('API URL')

Once this is instantiated, we will use the synthesize function to synthesize the audio from the input text. We will create a function for this. But we need to understand first that whatever audio is synthesized needs to be stored in a file every time. We will store it in a .wav file called voice.wav and we will keep this file in a folder called static since we know that flask renders all static files from the static folder. Once the audio file is created, we will play it in the HTML file using the <audio> tag. Since the file is created every time, we need to check for the existence of the file every time and delete it if it exists to simulate the overwrite behaviour of the file. Add the following code in the textToSpeech.py file to create the function to create the audio file and store the speech output:

def speak(text):

if (os.path.exists('static/voice.wav')):

os.remove('static/voice.wav')

with open('static/voice.wav', 'wb') as audio_file:

audio_file.write(

text_to_speech.synthesize(

text,

voice='en-US_AllisonV3Voice',

accept='audio/wav'

).get_result().content)

We have used the commonly used female voice US_AllisonV3Voice. Please check the documentation to change it if you want. Now, import this function in flaskTemplate.py as follows:

from textToSpeech import speak

Add the following line in my_form_post function before the return statement:

speak(text)

The only part of the application left is to add the audio tag in index.html to play the speech audio. So, add the following HTML code, right after the if template statement in index.html:

<audio autoplay>

<source src="/static/voice.wav" type="audio/wav">

Your browser does not support the audio tag.

</audio>

This will play the audio automatically as soon as the page reloads.

Now, run the application and open your browser. Type your words in the text area and as soon as you click on submit, the page reloads, shows your tone analysis and also speaks out your words out loud. Isn’t it amazing?

But it isn’t amazing until you can show case your talent. And to do that, deploy your application into the cloud using cf push and share your deployed URL to show your Machine Learning skills using IBM Watson!

There are several other services like Speech to Text, Watson Knowledge Studio, and Natural Language Understanding. As of now, you have a fair idea of how to use a service, I urge you to try these services out as well.

There is never an end to learning!

Conclusion

In this chapter, we began with creating a Python server. Using the Python server, we have built a web application which consists of both the front-end as well as the back-end. After we built an end-to-end web application, we learned how to deploy the application into IBM Cloud as a cloudfoundry application so as to maintain a production environment. Then, we checked out two of the frequently used Watson services, namely, Tone Analyzer and Text to Speech. We embedded them into our web application using the IBM Watson API Packages to get an interesting application which speaks out what we type and analyses the tone of the user.

Now that we are confident about building an end-to-end web application, let’s try to deploy our chatbot into production that we had built in the fourth chapter.

CHAPTER 10

Deploy the Food Ordering Bot

We learned how to use APIs to automate services using Python in the previous chapter. We also saw how to deploy a complete machine learning application into the cloud (IBM Cloud to be specific). Now, we will leverage that knowledge to deploy the chat bot that we built in chapter 4 for ordering. Please read chapters 4 and 9 before proceeding.

Structure

- Link your dialog skill to your Assistant

- Other ways to deploy a Watson Assistant

- Create a Python application to use the Watson Assistant API

Objectives

- Link your Watson chatbot to a deployable Assistant and check out the different web integrations and deployment options provided by the Watson Assistant.

- Create an end-to-end Python web application to embed your chatbot and deploy it into IBM Cloud as a production environment.

Link your dialog skill to your assistant

Before you begin, launch your Watson Assistant from your IBM Cloud account (https://cloud.ibm.com) and check whether the desired skill is linked to an assistant or not. To link your skill to your assistant, go to the assistant page by clicking on the first icon from the left panel. It will show your assistant details (if you have any). If you want a new assistant, you can click on create assistant.

Once your assistant is created, click on the assistant and you will be directed to the assistant details page. Here, you can add the skill from your list of created dialog skills.

Once your dialog skill is linked, you will be able to see the skill linked to your assistant, as shown in Figure 10.1:

Figure 10.1: Linking a Skill to Watson Assistant

Other ways to deploy a Watson Assistant

Once you have your skill linked to your assistant, you can use the assistant to deploy your chat bot. Before deploying the chat bot using Python into the IBM Cloud, I want to show you some other interesting ways to deploy your chat bot.

On the assistant details page, click on Add integration+ link on the right pane for Integrations. You will see that IBM Watson offers several options for you to deploy your chat application. You can integrate in some popular mediums like Facebook, Messenger, Slack, etc.

Figure 10.2: Different Integrations provided by IBM Watson Assistant

We will urge you to try out the Preview link option. Once you click on Preview link and set it up, you will be able to see your added integrations in the right pane under the Saved Integrations section.

Click on the Preview link tab under Saved Integrations, and you will be able to see the link which you can use to share as shown in Figure 10.3:

Figure 10.3: Preview Link

Click on the link given under the Try it out and share the link section or copy and paste in a tab, and your chat application will open up. You can play around, or share it for demo.

Create a Python application to use the Watson Assistant API

Now, let us come to the main section where we will create our Python web application to deploy it to cloud.

Before we begin, create a folder structure under your application root folder and the files as shown in Figure 10.4:

Figure 10.4: Web Application Folder Structure

Here is the significance of each of the files:

- index.py is the main Python file containing the main function and Flask configurations.

- chat.py contains the Watson Assistant API functions which we will use in index.py.

- index.html contains the user interface design.

- script.js is the JavaScript code we will use to display chat messages as they arrive.

We have exposed our own API in index.py to receive the chat messages the user types, and we are then using the function in chat.py to send the text to our Watson Assistant through the IBM Watson Assistant API and send the response.

In this application, we will use JQuery in script.js to leverage ajax calls for calling the custom API we created in index.py and populating the chat area with the messages and responses. So, you will need to have knowledge of some concepts of JQuery to understand the code. I will recommend that you to check out https://www.w3schools.com/. They have some great tutorials in JQuery.

I have also used Bootstrap (version 4) in index.html for styling. You can check out bootstrap from their official web site at https://getbootstrap.com/docs/4.0/getting-started/introduction/. They some awesome prebuilt designs which you can add in your code in just a few simple lines of code.

Now, let’s start coding.

Fill in index.html first with the following lines of code:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Latest compiled and minified CSS -->

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<!-- jQuery library -->

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- Popper JS -->

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

<!-- Latest compiled JavaScript -->

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

<script src="static/script.js"></script>

<title>My Chat Bot</title>

</head>

<body>

<div class="container">

<h2>My Chat Bot</h2>

<div>

<p class="bg-secondary text-white">Hello! How can I help you today?</p>

<div id="chat">

</div>

</div>

<label for="message">Type your message:</label>

<textarea class="form-control" id="message" rows="4"></textarea>

<button class="btn btn-primary" id="send">Send</button>

</div>

</body>

</html>

The code is pretty straight forward. We have included all the necessary CDNs first for using Bootstrap 4. We have also included the JQuery script (script.js) which we will use to send and receive chats and populate them as well. We will build that in some time. In the body, we have hard coded the first message from the Watson assistant so that on response, we can call the Watson Assistant API. We also have a div (with id=”chat”) where we will populate all the messages. Finally, we have a text area and a button to type and send the user’s chat. As you can see, we have used Bootstrap 4 to style the page using class values.

Next, let us build the chat.py file, where we will authenticate and send and receive the Watson Assistant API. The Watson Assistant API asks you to create a session before starting a sessioned chat. We have created the session ID using the create_session function of the Python SDK and then, we have used the message function of the Python SDK to send and receive chat responses. We have defined a custom function sendChat() which we can call whenever the user sends a chat. This function takes the user chat and passes on to the Watson Assistant using the message function of the Python SDK to get the response. You will find the Watson Assistant API details and how to use the Python SDK on the following link:

https://cloud.ibm.com/apidocs/assistant/assistant-v2?code=python

#chat.py

from ibm_watson import AssistantV2

from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

import json

authenticator = IAMAuthenticator('<your API Key>')

assistant = AssistantV2(

version='2020-04-01',

authenticator=authenticator

)

assistant.set_service_url('<your API URL>')

response = assistant.create_session(

assistant_id=’<your assistant id>’

).get_result()

session_id = response["session_id"]

def sendChat(text):

response = assistant.message(

assistant_id='<your assistant id>',

session_id=session_id,

input={

'message_type': 'text',

'text': text

}

).get_result()

return json.dumps(response, indent=2)

Replace <your API Key>, <your API URL> and <your assistant ID> with your API Key, your API URL, and your Assistant ID. To find the details, click on settings on the Assistant page as shown in Figure 10.5 and then, go to API Details on the Settings page:

Figure 10.5: Assistants Page

Next, let us create the main Python file index.py where we will configure our Flask server:

#index.py

import flask

from flask import request, render_template

from chat import sendChat

app = flask.Flask(__name__, static_url_path="/static")

@app.route('/', methods=['GET'])

def root():

return render_template("index.html")

@app.route('/sendChat', methods=['POST'])

def my_form_post():

text = request.form['text']

return sendChat(text)

if __name__ == '__main__':

app.run(host="0.0.0.0", port=8080)

The code is pretty straightforward. We will configure a post request (in our JQuery file) whenever the user clicks on the send button so that we get the text that the user types in the text-area, and we call the sendChat() from the chat.py file to allow the Watson API do its job.

Now, let us add the last piece of the application, i.e., the JavaScript file containing the JQuery code to send post request to send the text that the user types in the text area and populate the text from the response from the Watson Assistant API.

To extract the text from the Watson Assistant API response, we need to understand the response structure for the option and text chat responses. A sample response for the text is as follows:

{

"output": {

"generic": [

{

"response_type": "text",

"text": "Hello! What can I do for you?"

}

],

"intents": [

{

"intent": "hello",

"confidence": 0.9281370162963867

}

],

"entities": []

},

"context": {

"global": {

"system": {

"turn_count": 1

},

"session_id": "55cd47b1-3847-430b-ba28-1739e0654576"

},

"skills": {

"main skill": {

"system": {

"state":

"eyJzZXNzaW9uX2lkIjoiNTVjZDQ3YjEtMzg0Ny00 MzBiLWJhMjgtMTczO WUwNjU0NTc2Iiwic2tp bGxfcmVmZXJlbmNlIjoibWFpbiBza2lsbCIsImFzc 2lzdGFudF9pZCI6ImViM2RmZGR lLTJkNDUtNDBmYS05NDZlLTk2ODVmNTU2NzhhOS IsImluaXRpYWxpemVkIjp0cnVlLCJkaWFsb2dfc3RhY2siOlt7 ImRpYWxvZ19ub2RlIjoicm9vdCJ9XSwibGFzdF9icm FuY2hfbm9kZSI6ImdyZWV0aW5nX29wdGlvbl8zIn0="

}

}

}

}

}

So based on the preceding response, we need to extract the field name text if the message_type value is text from the generic array of the output object from the object. Each value in generic is a response (if there are multiple responses).

In case of option responses, there will be an array of objects called options in the generic object array and the message_type will be option instead of text. To get the labels, use the label value of each options array element. We have used this method of parsing inside the JavaScript file. You can do this in your Python file and send the parsed response as well. The rest of the file is simple JQuery to append messages in the chat div in html and also call the post request in chat.py to call the sendChat() function. I assume you have the knowledge of JQuery and JavaScript. You can use any other front-end framework or packages as well like Angular, React.js, etc.

The code is as follows:

//script.js

$(document).ready(function(){

$("#send").click(function(){

text = $("#message").val()

$('#chat').append("<p class=\"bg-primary text-white\">"+text+"</p>");

$('#message').val('');

$.ajax({

type: "POST",

url: "/sendChat",

data: {'text':text.trim()},

dataType: "json",

success: function(data){

for(var i=0; i<data.output.generic.length; i++){

if(data.output.generic[i].response_type == 'text'){

$('#chat').append("<p class=\"bg-secondary text-white\">"+data.output.generic[i].text+"</p>");

}

if(data.output.generic[i].response_type == 'option'){

for (var j = 0; j < data.output.generic[i].options.length; j++)

$("#chat").append("<div class=\"badge\">"+data.output.generic[i].options[j].label+"</div>");

}

}

document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight;

}

})

})

})

Once all the files are coded, let’s run Python index.py to pull up our browser and check our localhost:8080:

Figure 10.6: Deployed Chatbot

It’s not an impressive design but this will do for now. You can go ahead and use your CSS or bootstrap skills to beautify it.

Next, you need to deploy it in the IBM Cloud using the same procedure we used in the previous chapter.

1. Create the Procfile and requirements.txt with the same contents as the previous chapter (You can copy it from the previous file.).

2. Open the terminal/command prompt in the application root folder.

3. Log in to cloudfoundry using the CF CLI command cf login.

4. Next, create a space (and organization) if needed.

5. Finally, ibmcloud cf push <app name> will create and push your application.

Now, you should have the complete Chat Bot in the IBM Cloud up in running by now.

Before adieu, I want you to try to integrate other services such as Watson Text to Speech and Speech to Text. You can also use Discovery to search for answers to intents and Tone Analyzer to vary your response based on sentiment; the list is endless.

Don’t forget to try out the other Watson AI/ML services.

Conclusion

In this chapter, we integrated all we learned so far into a production-level application which is deployed on the cloud. We configured a deployable chatbot into the Watson Assistant and checked out the various integration options provided by IBM Watson such as Slack, Messenger, and so on.

After that, we started planning and creating the various components of our application. We designed the front end using HTML and Bootstrap so as to have a beautiful chatbot user interface. We then built our backend Python server to interact with the front end so that it can take the text typed by the user and send the request to the Watson Assistant with the API that Watson provides and take the response from the Watson Assistant that you have configured yourself.

There is never an end to learning! Now that you have a hands-on experience of Artificial Intelligence, we urge you to dive more and build more awesome applications. This book is a complete hands-on approach to learning. Hence, we would suggest you to build more so as to learn more.

Never Give up! Happy Machine Learning!

Index

A

area under the curve (AUC) 51

Artificial Intelligence (AI)

about 1, 2

example 2, 3

artificial neuron

about 22, 23

AND and OR gate 23

McCulloch Pitts neuron 22

OR gate 24

assistant

building blocks 55

creating 54

Auto AI

about 129

dataset, preparing 130, 131

implementing 129

Auto AI instance

creating 131, 132

deploying 136

deploy model 137

details page, configuring 133

experiment settings 133

model, selecting 136

Pipeline comparison 135

prediction settings 134

running 134

B

backpropagation 32, 33

biological neuron

about 21

components 21, 22

bootstrap

reference link 189

Boston Housing Dataset

about 99

columns 99

building blocks, assistant

dialogs 55

entities 55

intents 55

C

chatbot

assistant, creating 54

building 54, 56

IBM ID, creating 56

chat.py 189

CloudFoundry

about 172

URL 172

computer

learning 8, 9

context variables 81

D

data analysis, machine learning project

performing 107-111

data analysis, with Pandas

about 40

performing 40-47

data, machine learning project

downloading 98-100

data preparation, machine learning project 111, 112

decision tree

about 124

adding 126

evaluating 126

decision tree regressor

about 124

implementing 125, 126

deep learning

history 20, 21

dialog 55

dialog skill

linking, to assistant 186

E

enrichments

category classification 154

concept tagging 154

entity extraction 154

keyword extraction 154

Sentiment analysis 154

entities

about 55

@burger_type 68

@chicken_type 68

@food_type 68

environment, for Watson visual recognition

setting up 140-142

environment, machine learning project

setting up 100, 107

F

False Negatives (FN) 48

false positive rate (FPR) 50

False Positives (FP) 48

Fashion MNIST dataset 33

feed forward neural network 30, 31

food ordering bot

deploying 186-188

dialog skill, linking to assistant 186

G

general purpose tone analyser 174

GitHub

reference link 152

gradient 29

gradient descent

about 28-30

using 30

Grid search cross validation

about 128

implementing 128, 129

I

IBM Cloud

account, setting up 56

web application, deploying to 172

IBM ID

setting up 56-58

IBM Watson 54

IBM Watson Assistant. See Watson Assistant

IBM Watson Text to Speech

about 180

creating 181, 182

documentation link 181

using 182, 183

IBM Watson tone analyser

about 174

customer-engagement 174

general-purpose 174

integrating, in web application 174-180

index.html 189

index.py 189

input data 3

intents

about 55

#exit 65

#greet 64

#order 65

J

JQuery

using 189

K

Kaggle dataset 99

Keras

about 33

including, in script 34

installing 33

neural network, defining 35

URL 33

k-nearest neighbour classifier 15-17

L

linear regression

about 5-8

Python code 9

M

machine learning

about 3

example 4

k-nearest neighbour classifier 15

linear regression 5

support vector machine 13

types 4

machine learning project

data analysis 107-111

data, downloading 98-100

data preparation 111, 112

environment, setting up 100-107

model training 112, 113

Matplotlib 10

McCulloch Pitts neuron 22

metrics 47-50

ML model

deploying, in Watson Machine Learning repository 116-122

evaluating 113

storing, in Watson Machine Learning repository 113-115

training 112

model training, machine learning project 112, 113

MSE (mean square error) 29

MyFlaskInstance 173

N

Natural Language Processing (NLP)

about 149

document data, converting into raw formats 150

documents, analysing 149, 150

junk data, filtering out 150, 151

model, applying 152

right resources, finding 149

text, converting to number with pre-trained embedding 151, 152

NLP, with IBM Watson Discovery

about 152

annotating 163-166

documents, annotating 164

environment, setting up 153, 154

new collections, working with 160-163

titles, annotating 164

Watson Discovery collection, querying 155-160

Watson Discovery news collection 154

non-trivial data types

arrays 38

dictionary 39

list 38

tuple 39

normal equation 8

NumPy 10

O

output data 3

P

Pandas 10, 40

Pandas DataFrame 41

perceptron

about 24-27

multilayer perceptron 26

precision 48

Python

basics 38-40

Python application

creating, for using Watson Assistant API 188-196

Python code, for linear regression 9-13

Python server

building 168-172

R

Random Forest 126

Random Forest regressor

adding 127

evaluating 127

receiver operating characteristic (ROC) curve 50

Rectified Linear Unit (ReLU) function 31, 32

resource, Watson Assistant

categorical list 59

creating 58-63

dialogs, creating 74-95

entities, creating 67-74

intents, creating 64-67

use case 64

S

Scikit-learn 10

script.js 189

sensitivity 49

sigmoid neuron 27, 28

supervised machine learning 4, 5

support vector machine 13, 14

T

TensorFlow

about 33

including, in script 34

installing 33

training data 3

True Negatives (TN) 48

True Positive Rate (TPR) 49

True Positives (TP) 48

types, machine learning

supervised machine learning 4, 5

unsupervised machine learning 5

U

unsupervised machine learning 5

W

W3schools

URL 38

Watson Assistant 54, 55

Watson Assistant API

using 188

Watson Assistant Resources 59

Watson Discovery 147, 152

Watson Machine Learning repository

model, deploying 116

model, storing 113

Watson visual recognition project

custom model, creating 143, 144

environment, setting up 140-142

image classification 142

image data, adding 144

model training 145

object detection 143

problem, identifying 142

web application

creating 168

deploying, to IBM Cloud 172, 173

Procfile 173

requirements.txt 173

tone analyser, integrating 174