Wednesday, 2 October 2019

neural network 9 chatbot


AI is trained by AI cheatsheet.
input chat message, AI will predict the chat topic.
It will reply with random answer from cheatsheet.


AI reply in different ways for the same topic


AI is smart enough to distinguish good day (greeting) and have a good day (goodbye)


even user input is not exactly the same as on the cheatseet, AI figures out the topic.


if AI is not sure of or have no clue about the topic, it says don't know


#app/views

from django.shortcuts import render
import nltk
nltk.download('punkt')
from nltk.stem.lancaster import LancasterStemmer
stemmer = LancasterStemmer()
import numpy
import tflearn
import tensorflow
import random
import json
import pickle

#load data
def index(request):
    with open('intents.json') as file:
        data = json.load(file)
    try:
        with open('data.pickle', 'rb') as f:
            words, labels, training, output = pickle.load()
    except:
        # print(data['intents'])
        words = []
        labels = []
        docs_pattern = []
        docs_tag = []

        for intent in data['intents']:
            for pattern in intent['patterns']:
                # get all the words in pattern
                wds = nltk.word_tokenize(pattern)
                # copy word list to words[]
                words.extend(wds)
                # used for input of neural network
                docs_pattern.append(wds)
                # copy cosresponding category, used as output of neural network
                docs_tag.append(intent['tag'])
                # copy categories into labels[]
                if (intent['tag'] not in labels):
                    labels.append(intent['tag'])

        # format words so that they don't contain symbols...
        words = [stemmer.stem(w.lower()) for w in words if w != '?']
        # remove duplicate words, sort
        words = sorted(list(set(words)))
        labels = sorted(labels)
        # one hot encoding, if input entry word exists in dictionary, mark 1 else 0
        training = []
        output = []
        # output default [0,0,0...] length = # of categories
        out_empty = [0 for _ in range(len(labels))]
        # print(words, labels, out_empty)
        # print(docs_pattern, docs_tag)

        for n, doc in enumerate(docs_pattern):
            bag = []
            # clean input words
            wd_ = [stemmer.stem(w) for w in doc]
            # one hot encoding, training input, look through dictionary,
            # mark the words exist in user entry as 1, the rest 0
            for w in words:
                if w in wd_:
                    bag.append(1)
                else:
                    bag.append(0)

            output_ = out_empty[:]
            # the training output, mark 1 category, the rest 0
            output_[labels.index(docs_tag[n])] = 1

            training.append(bag)
            output.append(output_)

        training = numpy.array(training)
        output = numpy.array(output)
        # print(training, output)

        with open('data.pickle', 'wb') as f:
            pickle.dump((words, labels, training, output), f)

    tensorflow.reset_default_graph()

    #train AI
    # input shape
    net = tflearn.input_data(shape=[None, len(training[0])])
    net = tflearn.fully_connected(net, 8)
    net = tflearn.fully_connected(net, 8)
    net = tflearn.fully_connected(net, len(output[0]), activation='softmax')
    net = tflearn.regression(net)

    model = tflearn.DNN(net)

    try:
        model.load('model.tflearn')
    except:
        model.fit(training, output, n_epoch=1000, batch_size=8, show_metric=True)
        model.save('model.tflearn')

    #test AI
    def bag_of_words(s, words):
        bag1 = [0 for _ in range(len(words))]
        s_words = nltk.word_tokenize(s)
        s_words = [stemmer.stem(word.lower()) for word in s_words]

        for se in s_words:
            for i, w in enumerate(words):
                if w == se:
                    bag1[i] = 1

        return numpy.array(bag1)

    def chat(inp):
        results = model.predict([bag_of_words(inp, words)])[0]
        # print(results)
        results_index = numpy.argmax(results)
        tag = labels[results_index]
        # print(tag)
        #print(results, results_index)
        # response if more than 95% sure
        if results[results_index] > 0.95:
            for tg in data['intents']:
                if tg['tag'] == tag:
                    responses = tg['responses']
                    ai_reply = random.choice(responses)
        else:
            ai_reply = 'I didn\'t get that, try again'
        return ai_reply, results, tag, labels

    ai_reply_, ai_probability, ai_category, ai_categories = 'a', 'b', 'c', 'd'
    try:
        user_input = request.POST['userchat']
        ai_reply_, ai_probability, ai_category, ai_categories = chat(user_input)
        #print(ai_reply_, ai_probability, ai_category, ai_categories)
    except Exception as e:
        print(type(e))
        pass

    return render(request, 'index.html',
                  {'reply': ai_reply_,
                   'probability': ai_probability,
                   'category': ai_category,
                   'categories': ai_categories,
                   'cheatSheet': data})

-------------------------------
#templates/index

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chatbot</title>
    <style>
        table, th, td {
          border: 1px solid black;
          border-collapse: collapse;
        }
        th, td {
            padding: 3px;
        }
        </style>
</head>
<body>
    <h2>Simple Chatbot</h2>

    <form action="{% url 'app:index'  %}" method="post">
        {% csrf_token %}
        <label>Start enter chat message below</label><br/>
        <input name='userchat'><br/>
        <input type="submit" value="Chat"><br/><br/>
    </form>

    <label>AI thinks chat topic is </label><br/>
        {{category}}<br/><br/>
        <label>AI reply </label><br/>
        {{reply}}<br/><br/>

        <label>AI Prediction, has to be more than 95% sure</label>
        <table>
            <tr>
                {% for item in categories%}
                    <th>{{item}}</th>
                {% endfor %}
            </tr>
            <tr>
                {% for item in probability%}
                    <td>{{item}}</td>
                {% endfor %}
            </tr>
        </table><br/>

        <label>AI CheatSheet</label><br/><br/>
        {% for item in cheatSheet.intents%}
            <label>Tag </label>
             {{item.tag}}<br/>
            <label>Pattern</label><br/>
             {{item.patterns}}<br/>
            <label>Responses </label><br/>
            {{item.responses}}<br/><br/>
        {% endfor %}
</body>
</html>

reference:


1 comment:

  1. Can we use two methods in django one for html and one for response?

    ReplyDelete