聊天机器人是一种通过文本或语音文本格式管理在线聊天对话的应用程序。大多数聊天机器人可以通过各种网站或虚拟助手在线访问,并以弹出窗口的形式出现。例如,电子商务网站、健康、新闻等领域。
为了运行聊天机器人,需要以下组件:
train_chatbot.py:将自然语言文本/数据读入训练集的编码。还使用Keras创建一个顺序神经网络模型。chat_gui.py:为聊天机器人创建图形用户界面的代码。classes.pkl:包含各种响应类型的类列表。word.pkl:用于模式识别的各种词汇列表。intent.json:包含不同标签的JavaScript对象列表,这些标签与词汇模式相关。chatbot_model.h5:在train_chatbot.py和chat_gui.py中创建的任何模型都保存在.h5文件中。现在,让开始导入所有必要的库。确保机器上正确安装了Python。
        import nltk
        nltk.download('punkt')
        nltk.download('wordnet')
        from nltk.stem import WordNetLemmatizer
        lemmatizer = WordNetLemmatizer()
        import json
        import pickle
        import numpy as np
        from keras.models import Sequential
        from keras.layers import Dense, Activation, Dropout
        from keras.optimizers import SGD
        import random
    
在这里,导入了诸如nltk(自然语言工具包),它包含许多用于清理文本数据并为深度学习算法做准备的工具;json,可以直接将JSON文件加载到Python中;pickle,加载pickle文件;numpy,执行线性代数操作;Keras,深度学习框架或库。
现在将初始化所有列表,以便可以存储自然语言数据/文本。
        words=[]
        classes = []
        documents = []
        ignore_words = ['?', '!']
        data = open('intents.json').read()
        intents = json.loads(data)
    
将使用JSON模块加载文件并将其保存在变量“intents”中。
        for intent in intents['intents']:
            for pattern in intent['patterns']:
                w = nltk.word_tokenize(pattern)
                words.extend(w)
                documents.append((w, intent['tag']))
                if intent['tag'] not in classes:
                    classes.append(intent['tag'])
    
接下来,将对words列表进行词形还原,并把所有单词转换为小写。例如,“running”,“runs”等单词都有相同的词根,即“walk”,也就是根词。这与词干提取类似。
# 初始化训练数据
        training = []
        output_empty = [0] * len(classes)
        for doc in documents:
            bag = []
            pattern_words = doc[0]
            pattern_words = [lemmatizer.lemmatize(word.lower()) for word in pattern_words]
            for w in words:
                bag.append(1) if w in pattern_words else bag.append(0)
            output_row = list(output_empty)
            output_row[classes.index(doc[1])] = 1
            training.append([bag, output_row])
    
在这里,初始化训练数据变量training。还有一个名为output_row的特性,它是列表的关键。然后打乱训练集,并执行train_test_split,其中模式即x变量,意图即y变量。
        random.shuffle(training)
        training = np.array(training)
        train_x = list(training[:,0])
        train_y = list(training[:,1])
        print("Training data has created")
    
在这里初始化训练数据training。还创建了一个名为output_row的特性,它是列表的关键。然后打乱训练集,并执行train_test_split,其中模式即x变量,意图即y变量。
        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'))
        sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
        model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
        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")
    
已经准备好了训练和测试数据,将使用Keras中的深度学习模型,称为Sequential模型。一旦模型训练完成,整个数据将转换为numpy数组,并保存为chatbot_model.h5。
        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):
            sentence_words = nltk.word_tokenize(sentence)
            sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
            return sentence_words
        def bow(sentence, words, show_details=True):
            sentence_words = clean_up_sentence(sentence)
            bag = [0]*len(words)
            for s in sentence_words:
                for i,w in enumerate(words):
                    if w == s:
                        bag[i] = 1
                        if show_details:
                            print ("found in bag: %s" % w)
            return(np.array(bag))
        def predict_class(sentence, model):
            p = bow(sentence, words,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]
            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
        def chatbot_response(msg):
            ints = predict_class(msg, model)
            res = getResponse(ints, intents)
            return res
    
在这里,需要一些函数,这些函数对于运行GUI和将它们绑定到单元是必要的。有函数clean_up_sentence(),它清理任何句子(输入的)。函数bow()用于创建词袋。函数getResponse()取输出列表并检查JSON文件,并输出具有最高概率的响应。最后,chatbot_response()接收一条消息(通过GUI输入)并使用predict_class()函数预测类别。现在可以以文本形式告诉机器人一些事情,然后机器人会做出回应。
        import tkinter
        from tkinter import *
        def send():
            msg = EntryBox.get("1.0",'end-1c').strip()
            EntryBox.delete("0.0",END)
            if msg != '':
                ChatLog.config(state=NORMAL)
                ChatLog.insert(END, "You: " + msg + 'nn')
                ChatLog.config(foreground="#442265", font=("Verdana", 12 ))
                res = chatbot_response(msg)
                ChatLog.insert(END, "Bot: " + res + 'nn')
                ChatLog.config(state=DISABLED)
                ChatLog.yview(END)
        base = Tk()
        base.title("Hello")
        base.geometry("400x500")
        base.resizable(width=FALSE, height=FALSE)
        ChatLog = Text(base, bd=0, bg="white", height="8", width="50", font="Arial",)
        ChatLog.config(state=DISABLED)
        scrollbar = Scrollbar(base, command=ChatLog.yview, cursor="heart")
        ChatLog['yscrollcommand'] = scrollbar.set
        SendButton = Button(base, font=("Verdana",12,'bold'), text="Send", width="12", height=5,
                    bd=0, bg="#32de97", activebackground="#3c9d9b",fg='#ffffff',
                    command= send )
        EntryBox = Text(base, bd=0, bg="white",width="29", height="5", font="Arial")
        scrollbar.place(x=376,y=6, height=386)
        ChatLog.place(x=6,y=6, height=386, width=370)
        EntryBox.place(x=128, y=401, height=90, width=265)
        SendButton.place(x=6, y=401, height=90)
        base.mainloop()
    
还可以创建一个图形用户界面,使用tkinter(库),Python库允许创建它。