还记得这个价值一个亿的 AI 核心代码?
- while True:
- AI = input('我:')
- print(AI.replace("吗", "").replace('?','!').replace('?','!'))
以上这段代码就是我们今天的主题, 基于规则的聊天机器人
聊天机器人
聊天机器人本身是一种机器或软件, 它通过文本或句子模仿人类交互. 简而言之, 可以使用类似于与人类对话的软件进行聊天.
为什么要尝试创建聊天机器人? 也许你对一个新项目感兴趣, 或者公司需要一个, 或者想去拉投资. 无论动机是什么, 本文都将尝试解释如何创建一个简单的基于规则的聊天机器人.
基于规则的聊天机器人
什么是基于规则的聊天机器人? 它是一种基于特定规则来回答人类给出的文本的聊天机器人. 由于它基于强加的规则所以这个聊天机器人生成的响应几乎是准确的; 但是, 如果我们收到与规则不匹配的查询, 聊天机器人将不会回答. 与它相对的另一个版本是基于模型的聊天机器人, 它通过机器学习模型来回答给定的查询.(二者的区别就是基于规则的需要我们指定每一条规则, 而且基于模型的会通过训练模型自动生成规则, 还记得我们上一篇的 "机器学习介绍" 吗,"机器学习为系统提供无需明确编程就能根据经验自动学习和改进的能力.")
基于规则的聊天机器人可能基于人类给出的规则, 但这并不意味着我们不使用数据集. 聊天机器人的主要目标仍然是自动化人类提出的问题, 所以我们还是需要数据来制定特定的规则.
在本文中, 我们将利用余弦相似距离作为基础开发基于规则的聊天机器人. 余弦相似度是向量 (特别是内积空间的非零向量) 之间的相似度度量, 常用于度量两个文本之间的相似度.
我们将使用余弦相似度创建一个聊天机器人, 通过对比查询与我们开发的语料库之间的相似性来回答查询提出的问题. 这也是我们最初需要开发我们的语料库的原因.
创建语料库
对于这个聊天机器人示例, 我想创建一个聊天机器人来回答有关猫的所有问题. 为了收集关于猫的数据, 我会从网上抓取它.
- import bs4 as bs
- import urllib.request#Open the cat web data page
- cat_data = urllib.request.urlopen('https://simple.wikipedia.org/wiki/Cat').read()
- #Find all the paragraph html from the Web page
- cat_data_paragraphs = bs.BeautifulSoup(cat_data,'lxml').find_all('p')
- #Creating the corpus of all the Web page paragraphs
- cat_text = ''
- #Creating lower text corpus of cat paragraphs
- for p in cat_data_paragraphs:
- cat_text += p.text.lower()
- print(cat_text)
使用上面的代码, 会得到来自 wikipedia 页面的段落集合. 接下来, 需要清理文本以去除括号编号和空格等无用的文本.
- import re
- cat_text = re.sub(r'\s+', '',re.sub(r'\[[0-9]*\]',' ', cat_text))
上述代码将从语料库中删除括号号. 我特意没有去掉这些符号和标点符号, 因为当与聊天机器人进行对话时, 这样听起来会很自然.
最后, 我将根据之前创建的语料库创建一个句子列表.
- import nltk
- cat_sentences = nltk.sent_tokenize(cat_text)
我们的规则很简单: 将聊天机器人的查询文本与句子列表中的每一个文本之间的进行余弦相似性的度量, 哪个结果产生的相似度最接近 (最高余弦相似度) 那么它就是我们的聊天机器人的答案.
创建一个聊天机器人
我们上面的语料库仍然是文本形式, 余弦相似度不接受文本数据; 所以需要将语料库转换成数字向量. 通常的做法是将文本转换为词袋 (单词计数) 或使用 TF-IDF 方法(频率概率). 在我们的例子中, 我们将使用 TF-IDF.
我将创建一个函数, 它接收查询文本, 并根据以下代码中的余弦相似性给出一个输出. 让我们看一下代码.
- from sklearn.metrics.pairwise import cosine_similarity
- from sklearn.feature_extraction.text import TfidfVectorizer
- def chatbot_answer(user_query):
- #Append the query to the sentences list
- cat_sentences.append(user_query)
- #Create the sentences vector based on the list
- vectorizer = TfidfVectorizer()
- sentences_vectors = vectorizer.fit_transform(cat_sentences)
- #Measure the cosine similarity and take the second closest index because the first index is the user query
- vector_values = cosine_similarity(sentences_vectors[-1], sentences_vectors)
- answer = cat_sentences[vector_values.argsort()[0][-2]]
- #Final check to make sure there are result present. If all the result are 0, means the text input by us are not captured in the corpus
- input_check = vector_values.flatten()
- input_check.sort()
- if input_check[-2] == 0:
- return "Please Try again"
- else:
- return answer
我们可以把上面的函数使用下面的流程图进行表示:
最后, 使用以下代码创建一个简单的回答交互.
- print("Hello, I am the Cat Chatbot. What is your meow questions?:")
- while(True):
- query = input().lower()
- if query not in ['bye', 'good bye', 'take care']:
- print("Cat Chatbot:", end="")
- print(chatbot_answer(query))
- cat_sentences.remove(query)
- else:
- print("See You Again")
- break
上面的脚本将接收查询, 并通过我们之前开发的聊天机器人处理它们.
从上面的图片中看到的, 结果还是可以接受的, 但有也有些奇怪的回答. 但是我们要想到, 目前只从一个数据源中得到的结果, 并且也没有做任何的优化. 如果我们用额外的数据集和规则来改进它, 它肯定会更好地回答问题.
总结
聊天机器人项目是一个令人兴奋的数据科学项目, 因为它在许多领域都有帮助. 在本文中, 我们使用从网页中获取的数据, 利用余弦相似度和 TF-IDF, 用 Python 创建了一个简单的聊天机器人项目, 真正的将我们的 1 个亿的项目落地. 其实这里面还有很多的改进:
向量化的选择, 除了 TF-IDF 还可以使用 word2vec, 甚至使用预训练的 bert 提取词向量.
回答环节, 其实就是通过某种特定的算法或者规则从我们的语料库中搜索最匹配的答案, 本文中使用的相似度 TOP1 的方法其实就是一个最简单的类 greedsearch 的方法, 对于答案结果的优化还可以使用类 beamsearch 的算法提取回答的匹配项.
等等很多
在端到端的深度学习兴起之前, 很多的聊天机器人都是这样基于规则来运行的并且也有很多落地案例, 如果你想快速的做一个 POC 展示, 这种基于规则方法还是非常有用的.
来源: http://developer.51cto.com/art/202110/687816.htm