如何在MySQL数据库中保存Python Chatbot的对话

问题描述

我已经使用python实现了一个聊天机器人。该聊天机器人向用户询问与房屋建造过程有关的问题(您可以在intents.json文件中检查问题模式)。聊天机器人主要有两个python文件,例如train.py(用于实现聊天机器人的模型)和gui.py(用于实现聊天机器人的聊天接口)。聊天机器人运行正常。

我的问题是如何将与用户的聊天机器人对话保存在MysqL数据库中。我试图找到一种解决方案,但是不幸的是,我找不到可行的解决方案。如果有人能回答这个问题,我将不胜感激。下面显示了主要python文件代码结构。

1.train.py-包括chatbot模型的实现

import numpy as np
from keras.models import Sequential
from keras.layers import Dense,Activation,Dropout
from keras.optimizers import SGD
import random

import nltk
nltk.download('wordnet')
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
import json
import pickle

words=[]
classes = []
documents = []
ignore_letters = ['!','?',','.']
intents_file = open('intents.json').read()
intents = json.loads(intents_file)

for intent in intents['intents']:
   for pattern in intent['patterns']:
      #tokenize each word
        word = nltk.word_tokenize(pattern)
        words.extend(word)
      #add documents in the corpus
        documents.append((word,intent['tag']))
      # add to our classes list
        if intent['tag'] not in classes:
          classes.append(intent['tag'])
   print(documents)
    # lemmaztize and lower each word and remove duplicates
  words = [lemmatizer.lemmatize(w.lower()) for w in words if w not in ignore_letters]
  words = sorted(list(set(words)))
   # sort classes
  classes = sorted(list(set(classes)))
  # documents = combination between patterns and intents
  print (len(documents),"documents")
  # classes = intents
  print (len(classes),"classes",classes)
  # words = all words,vocabulary
   print (len(words),"unique lemmatized words",words)

  pickle.dump(words,open('words.pkl','wb'))
  pickle.dump(classes,open('classes.pkl','wb'))

  # create our training data
   training = []
  # create an empty array for our output
   output_empty = [0] * len(classes)
  # training set,bag of words for each sentence
 for doc in documents:
    # initialize our bag of words
    bag = []
    # list of tokenized words for the pattern
    pattern_words = doc[0]
   # lemmatize each word - create base word,in attempt to represent related words
    pattern_words = [lemmatizer.lemmatize(word.lower()) for word in pattern_words]
   # create our bag of words array with 1,if word match found in current pattern
    for word in words:
      bag.append(1) if word in pattern_words else bag.append(0)
    
   # output is a '0' for each tag and '1' for current tag (for each pattern)
    output_row = list(output_empty)
    output_row[classes.index(doc[1])] = 1

   training.append([bag,output_row])
  # shuffle our features and turn into np.array
   random.shuffle(training)
   training = np.array(training)
 # create train and test lists. X - patterns,Y - intents
   train_x = list(training[:,0])
   train_y = list(training[:,1])
    print("Training data created")

  # Create model - 3 layers. First layer 128 neurons,second layer 64 neurons and 3rd output        layer  contains number of neurons
  # equal to number of intents to predict output intent with softmax
   model = Sequential()
   model.add(Dense(128,input_shape=(len(train_x[0]),),activation='relu'))
   model.add(Dropout(0.5))
   model.add(Dense(64,activation='relu'))
   model.add(Dropout(0.5))
   model.add(Dense(len(train_y[0]),activation='softmax'))

 # Compile model. stochastic gradient descent with nesterov accelerated gradient gives good    results for this model
  sgd = SGD(lr=0.01,decay=1e-6,momentum=0.9,nesterov=True)
  model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])

 #fitting and saving the model 
  hist = model.fit(np.array(train_x),np.array(train_y),epochs=200,batch_size=5,verbose=1)
  model.save('chatbot_model.h5',hist)

  print("model created")

2.gui.py(内容为聊天机器人的聊天界面。该界面由tkinter实现)

import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
import pickle
import numpy as np

from keras.models import load_model
model = load_model('chatbot_model.h5')
import json
import random
intents = json.loads(open('intents.json').read())
words = pickle.load(open('words.pkl','rb'))
classes = pickle.load(open('classes.pkl','rb'))


def clean_up_sentence(sentence):
   # tokenize the pattern - splitting words into array
      sentence_words = nltk.word_tokenize(sentence)
   # stemming every word - reducing to base form
      sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
      return sentence_words


      # return bag of words array: 0 or 1 for words that exist in sentence
def bag_of_words(sentence,words,show_details=True):
      # tokenizing patterns
        sentence_words = clean_up_sentence(sentence)
       # bag of words - vocabulary matrix
        bag = [0]*len(words)  
     for s in sentence_words:
          for i,word in enumerate(words):
            if word == s: 
              # assign 1 if current word is in the vocabulary position
              bag[i] = 1
            if show_details:
                print ("found in bag: %s" % word)
     return(np.array(bag))

  def predict_class(sentence):
     # filter below  threshold predictions
       p = bag_of_words(sentence,show_details=False)
       res = model.predict(np.array([p]))[0]
       ERROR_THRESHOLD = 0.25
       results = [[i,r] for i,r in enumerate(res) if r>ERROR_THRESHOLD]
    # sorting strength probability
       results.sort(key=lambda x: x[1],reverse=True)
       return_list = []
    for r in results:
       return_list.append({"intent": classes[r[0]],"probability": str(r[1])})
      return return_list

   def getResponse(ints,intents_json):
      tag = ints[0]['intent']
      list_of_intents = intents_json['intents']
       for i in list_of_intents:
         if(i['tag']== tag):
           result = random.choice(i['responses'])
           break
       return result


 #Creating tkinter GUI
  import tkinter
  from tkinter import *

  def send():
     msg = EntryBox.get("1.0",'end-1c').strip()
     EntryBox.delete("0.0",END)

  if msg != '':
     ChatBox.config(state=norMAL)
     ChatBox.insert(END,"You: " + msg + '\n\n')
     ChatBox.config(foreground="#446665",font=("Verdana",12 ))

      ints = predict_class(msg)
      res = getResponse(ints,intents)
    
      ChatBox.insert(END,"Bot: " + res + '\n\n')
        
      ChatBox.config(state=disABLED)
      ChatBox.yview(END)


    root = Tk()
    root.title("chatbot")
    root.geometry("400x500")
    root.resizable(width=FALSE,height=FALSE)

    #Create Chat window
    ChatBox = Text(root,bd=0,bg="white",height="8",width="50",font="Arial",)

    ChatBox.config(state=disABLED)

  #Bind scrollbar to Chat window
   scrollbar = Scrollbar(root,command=ChatBox.yview,cursor="heart")
   ChatBox['yscrollcommand'] = scrollbar.set

  #Create Button to send message
    SendButton = Button(root,12,'bold'),text="Send",width="12",height=5,bg="#f9a602",activebackground="#3c9d9b",fg='#000000',command= send )

   #Create the Box to enter message
   EntryBox = Text(root,width="29",height="5",font="Arial")
   #EntryBox.bind("<Return>",send)


   #Place all components on the screen
   scrollbar.place(x=376,y=6,height=386)
   ChatBox.place(x=6,height=386,width=370)
   EntryBox.place(x=128,y=401,height=90,width=265)
   SendButton.place(x=6,height=90)

 root.mainloop()

3.intents.json(此文件包含根据JSON格式的不同标记,模式和响应)

{ "intents" : [
{"tag":"greeting","patterns": ["Hi","Hello","Good Day"],"responses":["Hi,This is the building chatbot,How Can I Help You?"],"context_set":""
},{"tag":"LandShape","patterns":["I need to get the details of the Home Plans","Hi I like to kNow about the  samples house plans"],"responses":["Sure,I can Help you. What is the shape of your land?"],{"tag":"LandSize","patterns":["Circle","Rectangle","Square","Long Land","Trapezium","Triangle"],"responses":["What is the size of your land?"],{"tag":"FamilyInfo","patterns":["10 perches","12 perches","13 perches","14 perches","15 perches","18 perches","20 perches","22 perches","25 perches","30 perches","50 perches","100 perches"],"responses":["How many members in your family? "],{"tag":"FloorType","patterns":["1","2","3","4","5","6","7","8","9","10"],"responses":["What is the house type you want One storey or two storey?"],{"tag":"OneFloorHome","patterns":["One Storey Home"],"responses":["How many living rooms need for the home?"],{"tag":"OneFloorLiving","patterns":["One Living Room","Two Living Rooms","Three Living Rooms"],"responses":["How many bed rooms need for your home?"],{"tag":"OneFloorbed","patterns":["One bed Room","Two bed Rooms","Three bed Rooms","Four bed Rooms","Five bed Rooms"],"responses":["How many bathrooms need for your home?"],{"tag":"OneFloorBathroom","patterns":["One Bathroom","Two Bathrooms","Three Bathrooms"],"responses":["Do you need the bathrooms as attached or non-attached?"],{"tag":"OneFloorBathroomType","patterns":["Attached","Non-Attached"],"responses":["How many kitchen need for your home?"],{"tag":"OneFloorKitchen","patterns":["One kitchen","Two Kitchen","Three Kitchen"],"responses":["How many dining areas need for your home?"],{"tag":"OneFloorRoof","patterns":["One Dining Area","Two Dining Areas","Three Dining Areas"],"responses":["Does you need partial or non-partial roof?"],{"tag":"OneFloorRoofRes","patterns":["partial","full"],"responses":["What are the other additional features you suppose to add?"],{"tag":"OneFloorAdditionalFeatures","patterns":["children play area","ReligIoUs Place","Home Gym","nothing special"],"responses":["Thanks for your responses"],{"tag":"OneFloorConclusion","patterns":["Thanks for the assistance"],"responses":["Thanks for the time. collected your details!!"],{"tag":"TwoFloorHome","patterns":["Two Storey Home"],"responses":["How many living rooms need for the first floor?"],{"tag":"TwoFloorLiving","patterns":["1 living room","2 living rooms","3 living rooms"],"responses":["How many bed rooms need for the first floor?"],{"tag":"TwoFloorbed","patterns":["1 bed room","2 bed rooms","3 bed rooms","4 bed rooms","5 bed rooms"],"responses":["How many bathrooms need for the first floor?"],{"tag":"TwoFloorBathroom","patterns":["1 bathroom","2 bathrooms","3 bathrooms","4 bedrooms"],{"tag":"TwoFloorBathroomType","responses":["How many kitchen need for the first floor?"],{"tag":"TwoFloorKitchen","patterns":["1 kitchen","2 kitchen","3 kitchen"],"responses":["How many dining areas need for the first floor?"],{"tag":"TwoFloorDining","patterns":["1 Dining Area","2 Dining Areas","3 Dining Areas","4 Dining Areas"],"responses":["How many living rooms need for the second floor?"],{"tag":"TwoFloorLivingSecond","patterns":["one living","two living","three living","four living"],"responses":["How many bed rooms need for the second floor?"],{"tag":"TwoFloorbedSecond","patterns":["one bed","two bed","three bed","four bed","five bed"],"responses":["How many bathrooms need for the second floor?"],{"tag":"TwoFloorBathroomSecond","patterns":["one bath","two bath","three bath","four bath"],"responses":["How many kitchen need for the second floor?"],{"tag":"TwoFloorKitchenSecond","patterns":["one dining","two dining","three dining","four dining"],"responses":["How many dining ares need for the second floor?"],{"tag":"TwoFloorDiningSecond","responses":["Thank you for the responses"],{"tag":"TwoFloorConclusion","patterns":["ok thank you for the assistance"],"responses":["Thanks for your time. collected the details!!"],"context_set":""
}

] }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)