1. 程式人生 > >從完全零基礎開始教你寫一個Python機器人!每天唯一秒回你的人!

從完全零基礎開始教你寫一個Python機器人!每天唯一秒回你的人!

註釋:全面教程,入門書籍,學習原始碼可以新增小編學習群943752371直接獲取。

提供航班資訊

連線客戶和他們的財務

作為客戶支援

可能性(幾乎)是無限的。

聊天機器人的歷史可以追溯到1966年,當時韋森鮑姆發明了一種名為“伊麗莎”(ELIZA)的電腦程式。它僅僅從200行程式碼中模仿一個心理治療師的言語。你現在仍然可以和它交談:伊麗莎。

在本文中,我們將在python中基於NLTK庫構建一個簡單的基於檢索的聊天機器人。

開始構建機器人

先決條件

具有scikit庫和NLTK的實際操作知識。但是你如果是NLP新手,仍然可以閱讀本文,然後參照參考資料。

NLP

研究人類語言和計算機互動的領域稱為自然語言處理,簡稱NLP。它位於電腦科學、人工智慧和計算語言學的交匯處(維基百科)。NLP是計算機分析、理解和從人類語言中獲取意義的一種聰明且有用的方法。利用NLP,開發人員可以組織和結構化知識來執行諸如自動摘要、翻譯、命名實體識別、關係提取、情感分析、語音識別和主題分割等任務。

NLTK: 簡要介紹

NLTK(自然語言工具包)是構建Python程式來處理人類語言資料的領先平臺。它為超過50個語料庫和詞彙資源(如WordNet)提供了易於使用的介面,同時提供了一套用於分類、詞語切分、詞幹、標記、解析和語義推理的文字處理庫,這些都是工業強度NLP庫的封裝器。

NLTK被稱為“使用Python進行計算語言學教學和工作的一個極好工具”,以及“一個與自然語言打交道的絕佳庫”。

Python的自然語言處理提供了語言處理程式設計的實用介紹。我強烈推薦這本書給使用Python的NLP初學者。

下載及安裝NLTK

安裝NLTK: 執行 pip install nltk

測試安裝: 執行 python 接著輸入 import nltk

對特定平臺的指令,點這。

安裝NLTK包

匯入NLTK 然後執行 nltk.download().這將開啟NLTK的下載程式,你可以從其中選擇要下載的語料庫和模型。也可以一次下載所有包。

用NLTK對文字進行預處理

文字資料的主要問題是它都是文字格式(字串)。然而,機器學習演算法需要某種數值特徵向量來完成任務。因此,在我們開始任何NLP專案之前,我們都需對其進行預處理。基本文字預處理包括:

將整個文字轉換為大寫或小寫,這樣演算法就不會將大小寫的相同單詞視為不同的單詞

詞語切分:指將普通文字字串轉換為符號列表的過程。也就是我們真正想要的詞。句子分詞器可用於查詢句子列表,單詞分詞器可用於查詢字串形式的單詞列表。

NLTK資料包包括一個用於英語的預訓練Punkt分詞器。

去除噪聲,即所有不是標準數字或字母的東西。

刪除停止詞。有時,一些在幫助選擇符合使用者需要的文件方面似乎沒有什麼價值的常見單詞被完全排除在詞彙表之外。這些單詞叫做停止詞。

詞幹提取:詞幹提取是將詞尾變化詞(有時是派生詞)還原為詞幹、詞根或詞根形式(通常是書面形式)的過程。例如,如果我們要提取下列詞:“Stems”,

“Stemming”, “Stemmed”, “and Stemtization”,結果將是一個詞“stem”。

詞形還原:詞幹提取的一個細微變體是詞形還原

。它們之間的主要區別在於,詞幹提取可以建立不存在的詞,而詞元是實際的詞。所以你的詞根,也就是你最終得到的詞,在字典裡通常是查不到的,但詞元你是可以查到的。詞形還原的例子如:“run”是“running”或“ran”等詞的基本形式,或者“better”和“good”是同一個詞元,因此它們被認為是相同的。

單詞袋

在初始預處理階段之後,我們需要將文字轉換為有意義的數字向量(或陣列)。單詞袋是描述文件中單詞出現情況的文字表示。它包括兩個東西:

•一個已知詞彙表。

•一個對已知詞存在的量度。

為什麼它被稱為一個單詞袋?這是因為關於文件中單詞的順序或結構的任何資訊都會被丟棄,模型只關心已知單詞是否出現在文件中,而不關心它們在文件中的位置。

單詞袋的直觀感受是,如果文件的內容相似,那麼文件就相似。此外,我們還可以從文件的內容中瞭解一些文件的含義。

例如,如果我們的字典包含單詞{Learning, is, the, not, great},並且我們想向量化文字“Learning is great”,我們將有以下向量:(1,1,0,0,1)。

TF-IDF 方法

單詞袋方法的一個問題是,頻繁出現的單詞開始在文件中佔據主導地位(例如,得分更高),但可能並沒有包含太多的“有資訊內容”。此外,它將給予較長的文件更多的權重。

一種方法是根據單詞在所有文件中出現的頻率重新調整單詞的頻率,以便對“the”等在所有文件中也經常出現的單詞適當降低權重。這種評分方法稱為檢索詞頻率-逆文件頻率,簡稱TF-IDF,其中:

檢索詞頻率: 是當前文件中單詞出現頻率的得分。

TF = (Number of times term t appears in a document)/(Number of terms in the document)

逆文件頻率:是這個詞在文件中罕見度的得分。

IDF = 1+log(N/n), where, N is the number of documents and n is the number of documents a term t has appeared in.

Tf-idf 權重是資訊檢索和文字挖掘中常用的一種權重。該權重是一種統計度量,用於評估單詞對集合或語料庫中的文件有多重要

例子:

考慮一個包含100個單詞的文件,其中單詞“phone”出現了5次。

“phone”的檢索詞頻率就是(5

/ 100) =

0.05。現在,假設我們有1000萬份文件,其中1000份文件中出現了“電話”這個詞。那麼逆文件頻率就是log(10,000,000 /

1,000) = 4。TF-IDF權重就是這兩者的乘積:0.05 * 4 = 0.20。

Tf-IDF 可以在scikit learn中呼叫:

from sklearn.feature_extraction.text import TfidfVectorizer

餘弦相似度

TF-IDF是一種在向量空間中得到兩個實值向量的文字變換。然後我們可以通過取點積然後除以它們的範數乘積來得到任意一對向量的餘弦相似度。接著以此得到向量夾角的餘弦值。餘弦相似度是兩個非零向量之間相似度的度量。利用這個公式,我們可以求出任意兩個文件d1和d2之間的相似性。

Cosine Similarity (d1, d2) = Dot product(d1, d2) / ||d1|| * ||d2||

其中d1,d2是非零向量。

TF-IDF和餘弦相似度的詳細說明和實際例子參見下面的文件。

Tf-Idf and Cosine similarity

In

the year 1998 Google handled 9800 average search queries every day. In

2012 this number shot up to 5.13 billion…janav.wordpress.com

現在我們對NLP過程有了一個基本概念。是我們開始真正工作的時候了。我們在這裡將聊天機器人命名為“ROBO”

匯入必備庫

import nltk

import numpy as np

import random

import string # to process standard python strings

語料庫

在我們的示例中,我們將使用聊天機器人的Wikipedia頁面作為我們的語料庫。從頁面複製內容並將其放入名為“chatbot.txt”的文字檔案中。然而,你可以使用你選擇的任何語料庫。

讀入資料

我們將閱讀corpus.txt檔案,並將整個語料庫轉換為句子列表和單詞列表,以便進行進一步的預處理。

f=open('chatbot.txt','r',errors = 'ignore')

raw=f.read()

raw=raw.lower()# converts to lowercase

nltk.download('punkt') # first-time use only

nltk.download('wordnet') # first-time use only

sent_tokens = nltk.sent_tokenize(raw)# converts to list of sentences

word_tokens = nltk.word_tokenize(raw)# converts to list of words

讓我們看看sent_tokens 和 the word_tokens的例子

['a chatbot (also known as a talkbot, chatterbot, bot, im bot, interactive agent, or artificial conversational entity) is a computer program or an artificial intelligence which conducts a conversation via auditory or textual methods.',

['a', 'chatbot', '(', 'also', 'known']

預處理原始文字

現在我們將定義一個名為LemTokens 的函式,它將接受符號作為輸入並返回規範化符號。

lemmer = nltk.stem.WordNetLemmatizer()

#

def LemTokens(tokens):

return [lemmer.lemmatize(token) for token in tokens]

remove_punct_dict = dict((ord(punct), None) for punct in string.punctuation)

def LemNormalize(text):

return LemTokens(nltk.word_tokenize(text.lower().translate(remove_punct_dict)))

關鍵字匹配

接下來,我們將通過機器人定義一個問候函式,即如果使用者的輸入是問候語,機器人將返回相應的回覆。ELIZA使用一個簡單的關鍵字匹配問候。我們將在這裡使用相同的概念。

GREETING_INPUTS = ("hello", "hi", "greetings", "sup", "what's up","hey",)

GREETING_RESPONSES = ["hi", "hey", "*nods*", "hi there", "hello", "I am glad! You are talking to me"]

def greeting(sentence):

for word in sentence.split():

if word.lower() in GREETING_INPUTS:

return random.choice(GREETING_RESPONSES)

生成回覆

為了讓我們的機器人為輸入問題生成回覆,這裡將使用文件相似性的概念。因此,我們首先需要匯入必要的模組。

從scikit learn庫中,匯入TFidf向量化器,將一組原始文件轉換為TF-IDF特徵矩陣。

from sklearn.feature_extraction.text import TfidfVectorizer

同時, 從scikit learn庫中匯入cosine similarity模組

from sklearn.metrics.pairwise import cosine_similarity

這將用於查詢使用者輸入的單詞與語料庫中的單詞之間的相似性。這是聊天機器人最簡單的實現。

我們定義了一個回覆函式,該函式搜尋使用者的表達,搜尋一個或多個已知的關鍵字,並返回幾個可能的回覆之一。如果沒有找到與任何關鍵字匹配的輸入,它將返回一個響應:“對不起!”我不明白你的意思"

def response(user_response):

robo_response=''

TfidfVec = TfidfVectorizer(tokenizer=LemNormalize, stop_words='english')

tfidf = TfidfVec.fit_transform(sent_tokens)

vals = cosine_similarity(tfidf[-1], tfidf)

idx=vals.argsort()[0][-2]

flat = vals.flatten()

flat.sort()

req_tfidf = flat[-2]

if(req_tfidf==0):

robo_response=robo_response+"I am sorry! I don't understand you"

return robo_response

else:

robo_response = robo_response+sent_tokens[idx]

return robo_response

最後,我們將根據使用者的輸入來決定機器人在開始和結束對話時說的話。

flag=True

print("ROBO: My name is Robo. I will answer your queries about Chatbots. If you want to exit, type Bye!")

while(flag==True):

user_response = input()

user_response=user_response.lower()

if(user_response!='bye'):

if(user_response=='thanks' or user_response=='thank you' ):

flag=False

print("ROBO: You are welcome..")

else:

if(greeting(user_response)!=None):

print("ROBO: "+greeting(user_response))

else:

sent_tokens.append(user_response)

word_tokens=word_tokens+nltk.word_tokenize(user_response)

final_words=list(set(word_tokens))

print("ROBO: ",end="")

print(response(user_response))

sent_tokens.remove(user_response)

else:

flag=False

print("ROBO: Bye! take care..")

差不多就是這樣。我們用NLTK中編寫了第一個聊天機器人的程式碼。你可以在這裡找到帶有語料庫的完整程式碼。現在,讓我們看看它是如何與人類互動的:

儘管聊天機器人在某些問題上不能給出令人滿意的答案,但在另一些問題上卻表現得很好。

結論

雖然它是一個非常簡單的機器人,幾乎沒有任何認知技能,但它是一個很好的方法來了解NLP和聊天機器人。雖然“ROBO”會對使用者輸入做出響應。但它愚弄不了你的朋友,對於一個生產系統,你可能希望考慮現有的機器人平臺或框架之一,但是這個示例應該能夠幫助你思考設計和建立聊天機器人的挑戰。網際網路充斥著大量的資源,在閱讀了這篇文章之後,我相信你會想要建立一個自己的聊天機器人。快樂程式設計!