产品经理人工智能/模式识别/机器学习精华专题自然语言处理(NLP)

Rasa 入门教程 Core 系列(六)

2019-12-18  本文已影响0人  6c643a7fc0e6
rasa_tutorial_core_background.png

Rasa 入门教程 Core 系列包括十一个部分,前面介绍了 Rasa 框架 Core 系列的第五部分:策略。本文主要介绍 Rasa 框架 Core 系列的第六部分:槽位

本文的目录结构:

  1. 什么是槽位?
  2. Rasa 如何使用槽位
  3. 如何设置槽位
  4. 槽位类型
  5. 自定义槽位类型

1. 什么是槽位?

槽位是机器人的内存。它们以键值对存储,可用于存储用户提供的信息(例如:他们的家乡)以及有关外界的信息(例如:数据库查询的结果)。

在大多数情况下,你希望槽位能够影响对话流程。对于不同的行为,有不同类型的槽位。

例如:如果你的用户提供了他们的居住城市,则可能有一个名为 text 的槽位叫 home_city。如果用户询问天气,而你不知道他们的家乡,则必须向他们询问什么城市。一个 text 槽位仅仅告诉 Rasa 是否有槽位值。text 槽位的具体值(例如:班加罗尔、纽约或香港)没有任何区别。

如果该值本身很重要,请使用 categoricalbool 槽位,也有 floatlist 槽位。如果你只想存储一些数据,但又不想影响对话的流程,请使用 unfeaturized 槽位。

2. Rasa 如何使用槽位

Policy 没有访问槽位值,它接收一个特征化表示。如上所述,对于 text 槽位,该值无关紧要。该策略只会通过 10 来判断它是否设置。请仔细选择槽位类型!

3. 如何设置槽位

你可以在 domain 文件中的槽位初始化值:

slots:
  name:
    type: text
    initial_value: "human"

对话期间可以使用多种方式设置槽位:

3.1 使用 NLU 设置槽位

如果你的 NLU 模型要提取实体,并且在 domain 文件中配置了一个相同名称的槽位,则该槽位将自动设置。例如:

# story_01
* greet{"name": "Ali"}
  - slot{"name": "Ali"}
  - utter_greet

在上述情况下,你不需要在 stories 文件中包括 - slot{} ,因为它是自动提取的。

要为特定槽位禁用此行为,可以在 domain 文件中将 auto_fill 属性设置为 False

slots:
  name:
    type: text
    auto_fill: False

3.2 使用点击按钮设置槽位

你可以将按钮用作快捷方式。Rasa Core 以 / 开头将消息发送给 RegexInterpreter,要求 NLU 输入的格式与 stories 文件中的格式相同,例如:/intent{entities}。比如:如果让用户通过单击按钮来选择颜色,则按钮的装载量可能是 /choose{"color": "blue"}/choose{"color": "red"}

你可以在 domain 文件中指定以下内容:(详细信息请参阅:Rasa 框架 Core 系列的第二部分:Domains)

utter_ask_color:
- text: "what color would you like?"
  buttons:
  - title: "blue"
    payload: '/choose{"color": "blue"}'
  - title: "red"
    payload: '/choose{"color": "red"}'

3.3 使用动作设置槽位

你也可以通过在自定义动作中返回事件来设置槽位,在这种情况下,你的 stories 需要包含槽位。例如:你有一个自定义动作来获取用户的个人信息,并且有一个名为 account_typecategorical 槽位,当 fetch_profile 动作运行时,它返回一个 rasa.core.events.SlotSet 事件:

slots:
   account_type:
      type: categorical
      values:
      - premium
      - basic
from rasa_sdk.actions import Action
from rasa_sdk.events import SlotSet
import requests

class FetchProfileAction(Action):
    def name(self):
        return "fetch_profile"

    def run(self, dispatcher, tracker, domain):
        url = "http://myprofileurl.com"
        data = requests.get(url).json
        return [SlotSet("account_type", data["account_type"])]
# story_01
* greet
  - action_fetch_profile
  - slot{"account_type" : "premium"}
  - utter_welcome_premium

# story_02
* greet
  - action_fetch_profile
  - slot{"account_type" : "basic"}
  - utter_welcome_basic

在这种情况下,你必须将 - slot() 包括在你的 stories 文件中。Rasa Core 将学习使用这些信息来决定要采取的正确措施(例如上例中:utter_welcome_premiumutter_welcome_basic)。

4. 槽位类型

4.1 text 槽位

  1. 用途:是否指定用户首选项

  2. 示例:

    slots:
       cuisine:
          type: text
    
  3. 描述:如果设置任何值,则槽位的特征化为 1;否则特征化为0(未设置任何值)。

4.2 bool 槽位

  1. 用途:TrueFalse

  2. 示例:

    slots:
       is_authenticated:
          type: bool
    
  3. 描述:检查是否设置了槽位以及是否为 True

4.3 categorical 槽位

  1. 用途:槽位可以采用 N 个值中的一个

  2. 示例:

    slots:
       risk_level:
          type: categorical
          values:
          - low
          - medium
          - high
    
  3. 描述:创建一个 one-hot 编码用来描述与哪个 values 匹配。

4.4 float 槽位

  1. 用途:连续值

  2. 示例:

    slots:
       temperature:
          type: float
          min_value: -100.0  # 默认值 0.0
          max_value:  100.0  # 默认值 1.0
    
  3. 描述:小于 min_value 的所有值将作为 min_value 处理,同理 max_value。因此,如果 max_value 被设置为 1,则槽位值 23.5 在特征化时没有区别(例如:两个值以相同的方式影响对话,并且模型无法学习到它们之间的区别)。

4.5 list 槽位

  1. 用途:值的清单列表

  2. 示例:

    slots:
       shopping_items:
          type: list
    
  3. 描述:如果设置了带有列表的值(列表不为空),则设置此槽位的特征化值为 1。如果未设置任何值或者空白列表,则该特征化值为 0存储在槽位中的列表长度不影响对话

4.6 unfeaturized 槽位

  1. 用途:存储不影响对话流程的数据

  2. 示例:

    slots:
       internal_user_id:
          type: unfeaturized
    
  3. 描述:该槽位不具有任何特征化,因此其值不会影响对话流程,在预测机器人应执行下一个动作时会被忽略。

5. 自定义槽位类型

假设你的餐厅预订系统最多只能处理 6 个人的预订。在这种情况下,你希望槽位值影响下一个选定的动作(而不只是影响是否已指定),你可以通过自定义槽位类来实现。

在下面的代码中,我们定义了一个名为 NumberOfPeopleSlot 的槽位类。特征化定义了如何将此槽位值转换为向量,以供机器学习模型进行处理。我们的槽位有三个可能的“值”,我们可以用长度为 2 的矢量来表示。

矢量表示 描述
(0,0) 尚未设定
(1,0) 1至6之间
(0,1) 超过6
from rasa.core.slots import Slot

class NumberOfPeopleSlot(Slot):

    def feature_dimensionality(self):
        return 2

    def as_feature(self):
        r = [0.0] * self.feature_dimensionality()
        if self.value:
            if self.value <= 6:
                r[0] = 1.0
            else:
                r[1] = 1.0
        return r

现在我们还需要一些训练数据,以便 Rasa Core 可以从中学习如何处理不同情况:

# story1
...
* inform{"people": "3"}
  - action_book_table
...
# story2
* inform{"people": "9"}
  - action_explain_table_limit

作者:关于我

备注:转载请注明出处。

如发现错误,欢迎留言指正。

上一篇 下一篇

猜你喜欢

热点阅读