02.26 ​快來!建立你的第一個Python聊天機器人項目

全文共7900字,預計學習時長

23分鐘

​快來!建立你的第一個Python聊天機器人項目


利用Python,我們可以實現很多目標,比如說建立一個你專屬的聊天機器人程序。

聊天機器人程序不光滿足個人需求,它對商業組織和客戶都非常有幫助。大多數人喜歡直接通過聊天室交談,而不是打電話給服務中心。


Facebook發佈的數據證明了機器人的價值。每月有超過20億條信息在人和公司之間發送。HubSpot的研究顯示,71%的人希望從信息應用程序獲得客戶支持。這是解決問題的快速方法,因此聊天機器人在組織中有著光明的未來。


今天要做的是在Chatbot上建立一個令人興奮的項目。,從零開始完成一個聊天機器人,它將能夠理解用戶正在談論的內容並給出適當的回應。


先決條件


為了實現聊天機器人,將使用一個深度學習庫Keras,一個自然語言處理工具包NLTK,以及一些有用的庫。運行以下命令以確保安裝了所有庫:


<code>pip installtensorflow keras pickle nltk/<code>


聊天機器人是如何工作的?


聊天機器人只是一個智能軟件,可以像人類一樣與人互動和交流。很有趣,不是嗎?現在來看看它們是如何工作的。


所有聊天機器人都基於自然語言處理(NLP)概念。NLP由兩部分組成:


· NLU(自然語言理解):機器理解人類語言(如英語)的能力。


· NLG(自然語言生成):機器生成類似於人類書面句子的文本的能力。


想象一個用戶問聊天機器人一個問題:“嘿,今天有什麼新聞?”


該聊天機器人就會將用戶語句分解為兩個部分:意圖和實體。這句話的目的可能是獲取新聞,因為它指的是用戶希望執行的操作。實體告訴了關於意圖的具體細節,所以“今天”將是實體。因此,這裡使用機器學習模型來識別聊天的意圖和實體。


​快來!建立你的第一個Python聊天機器人項目


項目文件結構


項目完成後,將留下所有這些文件。快速瀏覽每一個。它將給開發員一個如何實施該項目的想法。


· Train_chatbot.py-在本文件中,構建和訓練深度學習模型,該模型可以分類和識別用戶向機器人提出的要求。


· Gui_Chatbot.py-這個文件是構建圖形用戶界面用來與訓練後的聊天機器人聊天的地方。


· Intents.json-Intents文件包含將用於訓練模型的所有數據。它包含一組標記及其相應的模式和響應。


· Chatbot_model.h5-這是一個分層數據格式文件,其中存儲了訓練模型的權重和體系結構。


· Classes.pkl-pickle文件可用於存儲預測消息時要分類的所有標記名。


· Words.pkl-Words.pklpickle文件包含模型詞彙表中的所有唯一單詞。


下載源代碼和數據集:


mailto:https://drive.google.com/drive/folders/1r6MrrdE8V0bWBxndGfJxJ4Om62dJ2OMP?usp=sharing


如何建立自己的聊天機器人?


筆者將這個聊天機器人的構建簡化為5個步驟:


第一步。導入庫並加載數據


創建一個新的python文件並將其命名為train_chatbot,然後導入所有必需的模塊。之後,從Python程序中讀取JSON數據文件。


<code>importnumpy as np/<code>
<code>fromkeras.models importSequential/<code>
<code>fromkeras.layers importDense, Activation,Dropout/<code>
<code>fromkeras.optimizers importSGD/<code>
<code>importrandom/<code>
<code>importnltk/<code>
<code>fromnltk.stem importWordNetLemmatizer/<code>
<code>lemmatizer = WordNetLemmatizer()/<code>
<code>importjson/<code>
<code>importpickle/<code>
<code>intents_file = open('intents.json').read()/<code>
<code>intents= json.loads(intents_file)/<code>

第二步。數據預處理


模型無法獲取原始數據。為了使機器容易理解,必須經過許多預處理。對於文本數據,有許多預處理技術可用。第一種技術是標記化,把句子分解成單詞。


通過觀察intents文件,可以看到每個標記包含模式和響應的列表。標記每個模式並將單詞添加到列表中。另外,創建一個類和文檔列表來添加與模式相關的所有意圖。


<code>words=[]/<code>
<code>classes= []/<code>
<code>documents= []/<code>
<code>ignore_letters = ['!', '?', ',', '.']/<code>
<code>forintent in intents['intents']:/<code>
<code>forpattern in intent['patterns']:/<code>
<code>#tokenize each word/<code>
<code>word= nltk.word_tokenize(pattern)/<code>
<code>words.extend(word)/<code>
<code>#add documents in the corpus/<code>
<code>documents.append((word, intent['tag']))/<code>
<code># add to our classes list/<code>
<code>ifintent['tag'] notin classes:/<code>
<code>classes.append(intent['tag'])/<code>
<code>print(documents)/<code>

另一種技術是詞形還原。我們可以將單詞轉換成引理形式,這樣就可以減少所有的規範單詞。例如,單詞play、playing、playing、played等都將替換為play。這樣,可以減少詞彙表中的單詞總數。所以將每個單詞進行引理,去掉重複的單詞。


<code># lemmaztize and lower each word andremove duplicates/<code>
<code>words= [lemmatizer.lemmatize(w.lower()) forw in words if w notinignore_letters]/<code>
<code>words= sorted(list(set(words)))/<code>
<code># sort classes/<code>
<code>classes= sorted(list(set(classes)))/<code>
<code># documents = combination betweenpatterns and intents/<code>
<code>print(len(documents), "documents")/<code>
<code># classes = intents/<code>
<code>print(len(classes), "classes", classes)/<code>
<code># words = all words, vocabulary/<code>
<code>print(len(words), "unique lemmatized words", words)/<code>
<code>pickle.dump(words,open('words.pkl','wb'))/<code>
<code>pickle.dump(classes,open('classes.pkl','wb'))/<code>

最後,單詞包含了項目的詞彙表,類包含了要分類的所有實體。為了將python對象保存在文件中,使用pickle.dump()方法。這些文件將有助於訓練完成後進行預測聊天。


​快來!建立你的第一個Python聊天機器人項目


第三步。創建訓練集和測試集


為了訓練模型,把每個輸入模式轉換成數字。首先,對模式中的每個單詞進行引理,並創建一個長度與單詞總數相同的零列表。只將值1設置為那些在模式中包含單詞的索引。同樣,將1設置為模式所屬的類輸入,來創建輸出。


<code># create the training data/<code>
<code>training= []/<code>
<code># create empty array for the output/<code>
<code>output_empty = [0] * len(classes)/<code>
<code># training set, bag of words for everysentence/<code>
<code>fordoc in documents:/<code>
<code># initializing bag of words/<code>
<code>bag= []/<code>
<code># list of tokenized words for thepattern/<code>
<code>word_patterns = doc[0]/<code>
<code># lemmatize each word - create baseword, in attempt to represent related words/<code>
<code>word_patterns = [lemmatizer.lemmatize(word.lower()) for word in word_patterns]/<code> 
<code># create the bag of words array with1, if word is found in current pattern/<code>
<code>forword in words:/<code>
<code>bag.append(1) if word inword_patterns else bag.append(0)/<code>
<code># output is a '0' for each tag and '1'for current tag (for each pattern)/<code>
<code>output_row = list(output_empty)/<code>
<code>output_row[classes.index(doc[1])] = 1/<code>
<code>training.append([bag, output_row])/<code>
<code># shuffle the features and make numpyarray/<code>
<code>random.shuffle(training)/<code>
<code>training= np.array(training)/<code>
<code># create training and testing lists. X- patterns, Y - intents/<code>
<code>train_x= list(training[:,0])/<code>
<code>train_y= list(training[:,1])/<code>
<code>print("Training data is created")/<code>

第四步。訓練模型


該模型將是一個由3個密集層組成的神經網絡。第一層有128個神經元,第二層有64個,最後一層的神經元數量與類數相同。為了減少模型的過度擬合,引入了dropout層。使用SGD優化器並對數據進行擬合,開始模型的訓練。在200個階段的訓練完成後,使用Kerasmodel.save(“chatbot_model.h5”)函數保存訓練的模型。


<code># deep neural networds model/<code>
<code>model= Sequential()/<code>
<code>model.add(Dense(128,input_shape=(len(train_x[0]),), activation='relu'))/<code>
<code>model.add(Dropout(0.5))/<code>
<code>model.add(Dense(64,activation='relu'))/<code>
<code>model.add(Dropout(0.5))/<code>
<code>model.add(Dense(len(train_y[0]), activation='softmax'))/<code>
<code># Compiling model. SGD with Nesterovaccelerated gradient gives good results for this model/<code>
<code>sgd= SGD(lr=0.01,decay=1e-6, momentum=0.9, nesterov=True)/<code>
<code>model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])/<code>
<code>#Training and saving the model/<code>
<code>hist= model.fit(np.array(train_x), np.array(train_y), epochs=200, batch_size=5,verbose=1)/<code>
<code>model.save('chatbot_model.h5', hist)/<code>
<code>print("model is created")/<code>

第五步。與聊天機器人互動


模型已經準備好聊天了,現在在一個新文件中為聊天機器人創建一個很好的圖形用戶界面。可以將文件命名為gui_chatbot.py


在GUI文件中,使用Tkinter模塊構建桌面應用程序的結構,然後捕獲用戶消息,並在將消息輸入到訓練模型之前,再次執行一些預處理。


然後,模型將預測用戶消息的標籤,從intents文件的響應列表中隨機選擇響應。


這是GUI文件的完整源代碼。


<code>importnltk/<code>
<code>fromnltk.stem importWordNetLemmatizer/<code>
<code>lemmatizer = WordNetLemmatizer()/<code>
<code>importpickle/<code>
<code>importnumpy as np/<code>
<code>fromkeras.models importload_model/<code>
<code>model= load_model('chatbot_model.h5')/<code>
<code>importjson/<code>
<code>importrandom/<code>
<code>intents= json.loads(open('intents.json').read())/<code>
<code>words= pickle.load(open('words.pkl','rb'))/<code>
<code>classes= pickle.load(open('classes.pkl','rb'))/<code>
<code>defclean_up_sentence(sentence):/<code>
<code># tokenize the pattern - splittingwords into array/<code>
<code>sentence_words = nltk.word_tokenize(sentence)/<code>
<code># stemming every word - reducing tobase form/<code>
<code>sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]/<code>
<code>returnsentence_words/<code>
<code># return bag of words array: 0 or 1for words that exist in sentence/<code>
<code>defbag_of_words(sentence, words,show_details=True):/<code>
<code># tokenizing patterns/<code>
<code>sentence_words = clean_up_sentence(sentence)/<code>
<code># bag of words - vocabulary matrix/<code>
<code>bag= [0]*len(words)/<code>
<code>fors in sentence_words:/<code>
<code>fori,word inenumerate(words):/<code>
<code>ifword == s:/<code>
<code># assign 1 if current word is in thevocabulary position/<code>
<code>bag[i] = 1/<code>
<code>ifshow_details:/<code>
<code>print("found in bag:%s" % word)/<code>
<code>return(np.array(bag))/<code>
<code>defpredict_class(sentence):/<code>
<code># filter below thresholdpredictions/<code>
<code>p= bag_of_words(sentence,words,show_details=False)/<code>
<code>res= model.predict(np.array([p]))[0]/<code>
<code>ERROR_THRESHOLD = 0.25/<code>
<code>results= [[i,r] fori,r inenumerate(res) ifr>ERROR_THRESHOLD]/<code>
<code># sorting strength probability/<code>
<code>results.sort(key=lambdax: x[1],reverse=True)/<code>
<code>return_list = []/<code>
<code>forr in results:/<code>
<code>return_list.append({"intent": classes[r[0]],"probability": str(r[1])})/<code>
<code>returnreturn_list/<code>
<code>defgetResponse(ints, intents_json):/<code>
<code>tag= ints[0]['intent']/<code>
<code>list_of_intents = intents_json['intents']/<code>
<code>fori in list_of_intents:/<code>
<code>if(i['tag']== tag):/<code>
<code>result= random.choice(i['responses'])/<code>
<code>break/<code>
<code>returnresult/<code>
<code>#Creating tkinter GUI/<code>
<code>importtkinter/<code>
<code>fromtkinter import */<code>
<code>defsend():/<code>
<code>msg= EntryBox.get("1.0",'end-1c').strip()/<code>
<code>EntryBox.delete("0.0",END)/<code>
<code>ifmsg != '':/<code>
<code>ChatBox.config(state=NORMAL)/<code>
<code>ChatBox.insert(END, "You: " + msg+ '\\n\\n')/<code>
<code>ChatBox.config(foreground="#446665", font=("Verdana", 12 ))/<code>
<code>ints= predict_class(msg)/<code>
<code>res= getResponse(ints,intents)/<code>
<code>ChatBox.insert(END, "Bot: " + res+ '\\n\\n')/<code>
<code>ChatBox.config(state=DISABLED)/<code>
<code>ChatBox.yview(END)/<code>
<code>root= Tk()/<code>
<code>root.title("Chatbot")/<code>
<code>root.geometry("400x500"/<code>
<code>root.resizable(width=FALSE, height=FALSE)/<code>
<code>#Create Chat window/<code>
<code>ChatBox= Text(root, bd=0, bg="white",height="8", width="50", font="Arial",)/<code>
<code>ChatBox.config(state=DISABLED)/<code>
<code>#Bind scrollbar to Chat window/<code>
<code>scrollbar= Scrollbar(root,command=ChatBox.yview, cursor="heart")/<code>
<code>ChatBox['yscrollcommand'] = scrollbar.set/<code>
<code>#Create Button to send message/<code>
<code>SendButton = Button(root,font=("Verdana",12,'bold'),text="Send", width="12", height=5,/<code>
<code>bd=0,bg="#f9a602",activebackground="#3c9d9b",fg='#000000',/<code>
<code>command=send )/<code>
<code>#Create the box to enter message/<code>
<code>EntryBox= Text(root, bd=0, bg="white",width="29", height="5", font="Arial")/<code>
<code>#EntryBox.bind("<return>",send)/<return>/<code>
<code>#Place all components on the screen/<code>
<code>scrollbar.place(x=376,y=6, height=386)/<code>
<code>ChatBox.place(x=6,y=6, height=386,width=370)/<code>
<code>EntryBox.place(x=128,y=401, height=90,width=265)/<code>
<code>SendButton.place(x=6,y=401, height=90)/<code>
<code>root.mainloop()/<code>

運行聊天機器人


​快來!建立你的第一個Python聊天機器人項目

現在有兩個獨立的文件,一個是train_chatbot.py,首先使用它來訓練模型。


<code>pythontrain_chatbot.py/<code>


快來試試吧~

​快來!建立你的第一個Python聊天機器人項目

​快來!建立你的第一個Python聊天機器人項目

我們一起分享AI學習與發展的乾貨


分享到:


相關文章: