如何使用 spaCy NLP 库在 Python 中创建智能聊天机器人

作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分,接受捐款。

介绍

在某些情况下,执行类似操作需要重复步骤,如浏览菜单或填写表单每次执行操作时。聊天机器人是虚拟助手,可帮助软件系统的用户访问信息或执行操作,而无需经过长时间的流程。

要创建一个聊天聊天机器人,你可以使用像 Dialogflow这样的平台来帮助你在高层次上设计聊天机器人,或者你可以使用像 spaCy这样的库来创建一个聊天机器人,这是一个快速而强大的基于Python的自然语言处理(NLP)库。

在此教程中,您将创建一个聊天器,它不仅帮助用户简化与软件系统的互动,而且具有足够智能,可以以自然语言(此教程中的美国英语)与用户进行交流. 聊天器将使用 [OpenWeather API] (https://home.openweathermap.org/) 告诉用户世界任何城市的当前天气是什么,但您可以执行您的聊天器处理另一个API的用例.

前提条件

在你开始之前,你需要以下几点:

本教程假定你已经熟悉了 Python - 如果你想提高你的知识的Python,看看我们的 How To Code in Python 3系列。本教程不需要预先了解自然语言处理。

第1步:设置你的环境

在此步骤中,您将安装spaCy库,这将帮助您的聊天机器人理解用户的句子。

根据 前提条件 设置了Python,你将有一个虚拟环境,让我们激活这个环境。

请确保您位于您设置环境的目录中,然后运行以下命令:

1source my_env/bin/activate

现在安装SpaceCy:

1pip install -U spacy

最后,你会下载一个语言模型. spacy 的 语言模型是预先训练的NLP模型,你可以使用它来处理陈述来提取含义。

运行以下命令:

1python -m spacy download en_core_web_md

如果您遇到以下错误:

1[secondary_label Output]
2ERROR: Failed building wheel for en-core-web-md

您需要安装轮子:

1pip install -U wheel

然后再下载英语模型。

要确认您正确安装了 spaCy,请打开 Python 解释器:

1python

接下来,导入spacy并加载英语模型:

1>>> import spacy
2>>> nlp = spacy.load("en_core_web_md")

如果这两个陈述在没有任何错误的情况下执行,那么你已经安装了spacy。

现在关闭 Python 解释器:

1>>> exit()

在下一节中,你将创建一个脚本来查询城市当前天气的OpenWeather API。

步骤2 - 创建城市天气计划

在本节中,您将创建一个脚本,该脚本将接受用户的城市名称,查询该城市当前天气的OpenWeather API,并显示响应。

首先,用您喜爱的编辑器创建并打开名为「weather_bot.py」的Python文件:

1nano weather_bot.py

接下来,您将创建一个 功能从 OpenWeather API 获取一个城市的当前天气情况。

将下列代码添加到您的 weather_bot.py 文件中:

 1[label weather_bot.py]
 2import requests
 3
 4api_key = "your_api_key"
 5
 6def get_weather(city_name):
 7    api_url = "http://api.openweathermap.org/data/2.5/weather?q={}&appid={}".format(city_name, api_key)
 8
 9    response = requests.get(api_url)
10    response_dict = response.json()
11
12    weather = response_dict["weather"][0]["description"]
13
14    if response.status_code == 200:
15    	return weather
16    else:
17    	print('[!] HTTP {0} calling [{1}]'.format(response.status_code, api_url))
18    	return None

首先,你要导入请求库,这样你就可以使用和执行HTTP请求。 请确保用自己的API密钥代替your_api_key

在此函数中,您构建了 OpenWeather API 的 URL. 此 URL 返回了该城市的天气信息(温度、天气描述、湿度等),并以 JSON 格式提供结果。 之后,您将 GET 请求发送到 API 终端,将结果存储在一个)以便于更轻松访问。

在下一行中,您只将天气描述提取到一个)。

如果请求出现问题,则将状态代码打印到控制台,然后返回

要测试脚本,请用您选择的城市(例如,伦敦)拨打get_weather()函数,然后打印结果。

 1[label ~/weather_bot.py]
 2import requests
 3
 4def get_weather(city_name):
 5
 6  ...
 7
 8  return weather
 9
10weather = get_weather("London")
11print(weather)

保存并运行脚本:

1python weather_bot.py

您将获得如下结果:

1[secondary_label Output]
2scattered clouds

成功完成后,您现在可以从脚本中删除最后两行。

打开它与:

1nano weather_bot.py

然后删除文件末尾的两个突出的行:

 1[label ~/weather_bot.py]
 2import requests
 3
 4def get_weather(city_name):
 5
 6  ...
 7
 8  return weather
 9
10weather = get_weather("London")
11print(weather)

保存并关闭文件。

你现在有一个函数,返回一个特定的城市的天气描述。

在下一步中,您将创建一个聊天机器人,可以弄清楚用户是否想要在一个城市获得当前天气,如果是这样,聊天机器人将使用get_weather()函数来响应。

第3步:创建Chatbot

在前两个步骤中,您安装了 spaCy,并创建了一个功能来获取特定城市的天气情况,现在,您将创建一个聊天机器人以使用weather_bot.py脚本以自然语言与用户进行交互。

您将写一个 chatbot() 函数,将用户的声明与代表在一个城市检查天气的声明进行比较。 要进行这种比较,您将使用 spaCy similarity() 方法。 这种方法计算了两个声明的语义相似性,即它们在意义上有多相似。 这将帮助您确定用户是否试图检查天气。

首先,打开脚本:

1nano weather_bot.py

然后,导入spacy并加载英语语言模型:

1[label ~/weather_bot.py]
2import spacy
3import requests
4
5nlp = spacy.load("en_core_web_md")
6
7. . .

在文件中使用)`函数,该函数将接受用户的声明并返回答复。

按照您的定义,添加突出的代码来创建 tokens为您将进行比较的两个陈述。 代币是陈述的不同有意义的部分,如单词和点数。 这是必要的,以便spacy计算语义相似性:

1[label ~/weather_bot.py]
2import spacy
3
4. . .
5
6def chatbot(statement):
7  weather = nlp("Current weather in a city")
8  statement = nlp(statement)

在这里,)`函数。

保存并关闭您的文件。

接下来,您将将 spaCy similarity() 方法引入到您的 chatbot() 函数中。 similarity() 方法将两个陈述的语义相似性计算为 01 之间的值,而更高的数字意味着更大的相似性。

例如,如果您检查声明 2 和声明 3 与声明 1 的相似性,您将获得:

  1. 城市中的当前天气 2. 伦敦的天气是什么? (相似性 = 0.86) 3. 玉米黄油和黄油(相似性 = 0.31)

要自己尝试,请打开 Python 解释器:

1python

接下来,导入spacy并加载英语模型:

1>>> import spacy
2>>> nlp = spacy.load("en_core_web_md")

现在,让我们从陈述 1 和 2 创建代币:

1>>> statement1 = nlp("Current weather in a city")
2>>> statement2 = nlp("What is the weather in London?")

最后,让我们获得这两个陈述的语义相似性:

1>>> print(statement1.similarity(statement2))

你会得到这样的结果:

1[secondary_label Output]
20.8557684354027663

设置低最低值(例如,0.1)会导致聊天机器人误解用户,将陈述(如陈述3)视为类似于陈述1,这是错误的,设置过高的最低值(如0.9)将排除一些与陈述1实际相似的陈述,如陈述2。

我们将任意选择0.75为了这个教程,但你可能想在你的项目工作时测试不同的值。

让我们将这个值添加到脚本中,首先打开文件:

1nano weather_bot.py

然后添加以下突出代码以输入最低值:

1[label ~/weather_bot.py]
2import spacy
3
4. . .
5
6def chatbot(statement):
7  weather = nlp("Current weather in a city")
8  statement = nlp(statement)
9  min_similarity = 0.75

现在检查用户声明与有关天气声明的相似性是否大于或等于您指定的最低相似性值。

 1[label ~/weather_bot.py]
 2import spacy
 3
 4. . .
 5
 6def chatbot(statement):
 7  weather = nlp("Current weather in a city")
 8  statement = nlp(statement)
 9  min_similarity = 0.75
10
11  if weather.similarity(statement) >= min_similarity:
12    pass

最后一步是从用户的声明中提取城市,这样您就可以将其传输到 get_weather() 函数来从 API 调用中获取天气。 添加以下突出的 for 环节来实现这一点:

 1[label ~/weather_bot.py]
 2import spacy
 3
 4...
 5
 6def chatbot(statement):
 7  weather = nlp("Current weather in a city")
 8  statement = nlp(statement)
 9  min_similarity = 0.75
10
11  if weather.similarity(statement) >= min_similarity:
12    for ent in statement.ents:
13      if ent.label_ == "GPE": # GeoPolitical Entity
14        city = ent.text
15        break

要做到这一点,您正在使用 spaCy 的 命名实体识别 功能。 A named entity 是一个真实世界的名称,具有一个名字,如一个人,或在我们的情况下,一个城市。您想要从用户的陈述中提取该城市的名字。

要提取城市名称,您将用户声明中的所有命名实体获取,并检查其中哪个实体是地缘政治实体(国家,州,城市)。 要做到这一点,您将spacCy从)是否是GPE,代表地缘政治实体。

您还需要通过添加一个else块来捕捉没有城市的案例:

 1[label ~/weather_bot.py]
 2import spacy
 3
 4...
 5
 6def chatbot(statement):
 7  weather = nlp("Current weather in a city")
 8  statement = nlp(statement)
 9  min_similarity = 0.75
10
11  if weather.similarity(statement) >= min_similarity:
12    for ent in statement.ents:
13      if ent.label_ == "GPE": # GeoPolitical Entity
14        city = ent.text
15        break
16      else:
17        return "You need to tell me a city to check."

现在你有这个城市,你可以调用get_weather()函数:

 1[label ~/weather_bot.py]
 2import spacy
 3
 4...
 5
 6def chatbot(statement):
 7  weather = nlp("Current weather in a city")
 8  statement = nlp(statement)
 9  min_similarity = 0.75
10
11  if weather.similarity(statement) >= min_similarity:
12    for ent in statement.ents:
13      if ent.label_ == "GPE": # GeoPolitical Entity
14        city = ent.text
15        break
16      else:
17        return "You need to tell me a city to check."
18
19    city_weather = get_weather(city)
20    if city_weather is not None:
21      return "In " + city + ", the current weather is: " + city_weather
22    else:
23      return "Something went wrong."
24  else:
25    return "Sorry I don't understand that. Please rephrase your statement."

回顾如果 OpenWeather API 返回出错, 您会将错误代码打印到终端, ) 函数是否返回 无 ` 。 如果它不这样做,那么你返回城市的天气,但如果它这样做,那么你返回一个字符串,说出了什么问题. 最终的"else"块是处理用户语句的相似性值没有达到阈值的情况. 在这种情况下,您要求用户重新表达他们的语句.

完成这一切后,你现在有一个聊天机器人,可以通过对话告诉用户一个城市的天气。这个机器人和基于规则的聊天机器人之间的区别在于,用户不必每次都输入相同的陈述。

调用chatbot()函数,并通过一个声明,询问一个城市的天气情况,例如:

 1[label ~/weather_bot.py]
 2import spacy
 3
 4. . .
 5
 6def chatbot(statement):
 7
 8. . .
 9
10response = chatbot("Is it going to rain in Rome today?")
11print(response)

保存并关闭文件,然后在终端运行脚本:

1python3 weather_bot.py

您将收到类似于以下的输出:

1[secondary_label Output]
2In Rome, the current weather is: clear sky

您已经成功创建了一个能够响应动态用户请求的智能聊天机器人。您可以尝试更多的示例来发现机器人的全部功能。 为了做到这一点,您可以从OpenWeather和其他来源获得其他API终端。 扩展聊天机器人的另一种方法是使它能够响应更多的用户请求。

结论

您已经创建了一个足够智能的聊天机器人来响应用户的声明,即使用户以不同的方式表达他们的声明。

为了进一步改进Chatbot,您可以:

  • 联合国 请检查access-date=中的日期值 (帮助) OpenWeather API指针 对于您可以添加的额外天气功能.
  • 联合国 访问spaCy website,以查看您可以执行的其他功能,使聊天器更加智能.
  • 提高你对自然语言处理的知识,我们用关于[如何使用自然语言工具包(NLTK)处理Python 3语言数据的教程(https://andsky.com/tech/tutorials/how-to-work-with-language-data-in-python-3-using-the-natural-language-toolkit-nltk),或在[如何使用自然语言工具包(NLTK)执行Python 3的感知分析(https://andsky.com/tech/tutorials/how-to-perform-sentiment-analysis-in-python-3-using-the-natural-language-toolkit-nltk)中尝试情绪分析。 .

您可以找到本教程的最终代码在这个DigitalOcean存储(https://github.com/do-community/weather-bot)。

Published At
Categories with 技术
Tagged with
comments powered by Disqus