
本文共 6754 字,大约阅读时间需要 22 分钟。
如今,语音聊天机器人至少取代了85%的人工服务。今天我会带着大家一步一步用python实现简单的聊天机器人。
那么什么是聊天机器人?
聊天机器人是一种人工智能驱动的软件(比如苹果的Siri、小爱同学,谷歌助理等),模拟人类对话的聊天机器人如今可在呼叫中心和客户服务工作流程(开发运营管理)中找到,并担任私人助理。如今,几乎每家公司都部署了一个聊天机器人来与用户互动。常见的聊天机器人使用案例:
- 企业生产力
- 私人助理
- 呼叫中心应用程序
本篇文章较长,预计阅读10分钟,聊天机器人的源代码我已经为大家准备好了,如果您需要的话, 可以关注转发文章之后点击获取
聊天机器人如何工作?
聊天机器人大致有两种变体:基于规则的学习和自主学习。
- 在基于规则的方法中,机器人根据训练所依据的一些规则回答问题。定义的规则可能非常简单,也可能非常复杂。这些漫游器可以处理简单的查询,但无法管理复杂的查询。
- 自主学习机器人是使用某些基于机器学习的方法的机器人,并且绝对比基于规则的机器人更高效。这些漫游器可以分为两种:基于检索的或生成的
在基于检索的模型中,聊天机器人使用一些从预定义响应库中选择响应的启发式。聊天机器人使用消息和会话上下文从预定义的机器人消息列表中选择最佳响应。上下文可以包括对话树中的当前位置,对话中的所有先前消息,先前保存的变量(例如用户名)。从基于规则的if-else条件逻辑到机器学习分类器,可以通过多种不同的方式设计用于选择响应的试探法。
生成型机器人可以生成答案,而并非总是用一组答案中的一个回答。这使他们变得更聪明,因为他们从查询中逐字逐句地获取答案。
在本文中,我们将基于python中的NLTK库构建一个基于检索的简单聊天机器人。
建立机器人
先决条件
假设你具有scikit库和NLTK的动手知识。但是,如果你是NLP的新手,你仍然可以阅读该文章,然后再参考资源。
自然语言处理
专注于人类语言与计算机之间相互作用的研究领域称为自然语言处理,简称NLP。它位于计算机科学,人工智能和计算语言学的交汇处。NLP是计算机以一种智能且有用的方式分析,理解和从人类语言中获取含义的方法。通过利用NLP,开发人员可以组织和构造知识来执行诸如自动摘要,翻译,命名实体识别,关系提取,情感分析,语音识别和主题细分之类的任务。
NLTK:简介
NLTK(自然语言工具包)是用于构建Python程序以处理人类语言数据的领先平台。它为50多种语料库和词汇资源(如WordNet)提供了易于使用的界面,以及用于分类,标记化,词干分析,标记,解析和语义推理的文本处理库套件,以及具有工业强度的NLP库的包装器。
NLTK被称为“使用Python进行计算语言学教学和工作的绝佳工具”,以及“使用自然语言的出色库”。
下载并安装NLTK
- 安装NLTK:运行 pip install nltk
- 测试安装:运行,python然后键入import nltk
安装NLTK软件包
导入NLTK并运行nltk.download().这将打开NLTK下载器,你可以从中选择要下载的语料库和模型。你也可以一次性下载所有软件包。
使用NLTK进行文本预处理
文本数据的主要问题是它们全部为文本格式(字符串)。但是,机器学习算法需要某种数字特征向量才能执行任务。因此,在开始任何NLP项目之前,我们需要对其进行预处理以使其适合工作。基本的文本预处理包括:
- 将整个文本转换为大写或小写,这样算法就不会将相同单词在不同情况下视为不同
- 标记化:标记化只是用于描述将普通文本字符串转换为标记列表(即我们实际需要的单词)的过程的术语。句子标记器可用于查找句子列表,单词标记器可用于查找字符串中的单词列表。
NLTK数据包包括一个经过预训练的Punkt令牌生成器。
- 消除噪音,即所有不是标准数字或字母的东西。
- 删除停止词。有时,一些极为常见的词汇在帮助用户选择符合用户需求的文档时似乎没有什么价值,但却被完全排除在词汇表之外。这些词被称为停止词
- 词干分析:词干分析是将词形变化(有时是派生的)的单词还原为词干、词根或词根的过程,通常是书面形式。
- 词法化:词干法的一个小变种是词法化。它们之间的主要区别在于,词干通常可以创建不存在的词,而引理是实际的词。因此,你的词根意思不是你只能在字典中查找的内容,而是你可以查找引理的意思。合法化的例子是“运行”是“运行”或“奔跑”等词的基本形式,或者“更好”和“好”一词处于同一引理中,因此它们被认为是相同的。
言语包
在初始预处理阶段之后,我们需要将文本转换为有意义的数字矢量(或数组)。词袋是文本的表示形式,描述了文档中单词的出现。它涉及到两件事:
- 已知单词的词汇表。
- 衡量已知词汇的存在。
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次。
那么电话的术语频率(即tf)为(5/100)= 0.05。现在,假设我们有1000万个文档,其中有1000万个单词出现在电话中。然后,反向文档频率(即IDF)计算为log(10,000,000 / 1,000)=4。因此,Tf-IDF权重是这些数量的乘积:0.05 * 4 = 0.20。
TF-IDF可以在scikit学习中实现为:
从
sklearn.feature_extraction.text导入TfidfVectorizer
余弦相似度
TF-IDF是一种应用于文本的变换,用于在向量空间中获得两个实值向量。然后,我们可以通过取向量的点积并将其除以其范数的乘积来获得任何一对向量的余弦相似度。得出向量之间角度的余弦值。余弦相似度是两个非零向量之间相似度的量度。使用此公式,我们可以找出任意两个文档d1和d2之间的相似性。
Cosine Similarity (d1, d2) = Dot product(d1, d2) / ||d1|| * ||d2||
其中d1,d2是两个非零向量。
现在,我们对NLP流程有了一个清晰的想法。现在是时候完成真正的任务,即创建聊天机器人了。我们在这里将聊天机器人命名为“ ROBO ”。
导入必要的库
import nltkimport numpy as npimport randomimport 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 lowercasenltk.download('punkt') # first-time use onlynltk.download('wordnet') # first-time use onlysent_tokens = nltk.sent_tokenize(raw)# converts to list of sentences word_tokens = nltk.word_tokenize(raw)# converts to list of words
让我们看一个send_tokens和word_tokens的例子
sent_tokens[:2]['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.', 'such programs are often designed to convincingly simulate how a human would behave as a conversational partner, thereby passing the turing test.']word_tokens[:2]['a', 'chatbot', '(', 'also', 'known']
预处理原始文本
现在,我们将定义一个名为LemTokens的函数,该函数将把令牌作为输入并返回标准化的令牌。
lemmer = nltk.stem.WordNetLemmatizer()#WordNet is a semantically-oriented dictionary of English included in NLTK.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学习库中,导入TFidf矢量化器,以将原始文档的集合转换为TF-IDF功能的矩阵。
from sklearn.feature_extraction.text import TfidfVectorizer
- 另外,从scikit学习库导入余弦相似度模块
from sklearn.metrics.pairwise import cosine_similarity
这将用于查找用户输入的单词与语料库中的单词之间的相似性。这是聊天机器人的最简单的实现。
我们定义了一个函数响应,该函数在用户的发声中搜索一个或多个已知关键字,并返回几种可能的响应之一。如果找不到与任何关键字匹配的输入,它将返回一个响应:“对不起!我不明白你的意思。”
def response(user_response): robo_response='' sent_tokens.append(user_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=Trueprint("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: print("ROBO: ",end="") print(response(user_response)) sent_tokens.remove(user_response) else: flag=False print("ROBO: Bye! take care..")
就是这样。我们已经用NLTK编写了我们的第一个聊天机器人。现在,让我们看看它如何与人类互动:
这还不错。即使聊天机器人在某些问题上不能给出满意的答案,它在其他问题上的表现也很好。
结论
尽管它是一个非常简单的机器人,几乎没有任何认知能力,但它是进入NLP并了解聊天机器人的好方法。尽管“ ROBO”会响应用户输入。
聊天机器人的源代码我已经为大家准备好了,如果您需要的话, 可以关注转发文章之后点击获取
发表评论
最新留言
关于作者
