admin管理员组

文章数量:1579086

原文:https://blog.rasa/how-to-handle-multiple-intents-per-input-using-rasa-nlu-tensorflow-pipeline/

随着Rasa NLU 0.12的发布,我们介绍了一个新Rasa NLU pipeline。简而言之,新的pipeline解决了当前chatbot开发者面临的两个问题:

1.如何超出预训练嵌入限制?

2.人们输入多意图消息,如何建立处理多意图的chatbot?

 

本文章,我们将会全面了解基于tensorflow pipeline如何解决第二个问题:多意图。

本教程代码及数据集:here

 

新的tensorflow pipeline是关于什么?

pipeline是用来构建Rasa NLU模型块,pipeline定义了用户输入是如何被解析、分词和特征提取。pipeline的组件是非常重要的,因为他们对NLU模型如何执行有着直接的影响。与常规的Rasa NLU pipelines相比,新的tensorflow pipeline使训练模型将两个及多个意图分配给单输入消息成为可能。例如,用户说“Yes, make a booking. Can you also book me a taxi from the airport to the hotel?”;这里有两个意图 -确认预定 和 -预定出租车。(confirm+book_taxi)

创建一个聊天机器人

让我们开始探索这个教程是关于什么-pipeline。下面代码块包含pipeline配置config.yml。它包含了处理参数intent_featurizer_count_vectors ,这个参数定义了模型特征如何被抽取(参数更多细节 here);并包含参数分类器 intent_classifier_tensorflow_embedding ,这个参数表明我们将会使用tensorflow embeddings进行意图分类。通过设置参数 intent_tokenization_flag: true ,我们告诉模型我们想将意图标签分割成标记,这意味着模型是知道了哪些意图是多类型意图。参数 intent_split_symbol 被用来作分割,本例使用字符 +

pipeline:
- name: "intent_featurizer_count_vectors"
- name: "intent_classifier_tensorflow_embedding"
  intent_tokenization_flag: true
  intent_split_symbol: "+"

NLU training data

对于使用tensorflow pipeline的模型训练数据是什么样呢?与常规的方法没什么不同,仅仅是增加了多意图输入的例子和分配给它们相关的多意图标签。下面data/nlu_data.md片段我用之使用训练NLU model。正如你看到的,我又一些输入、意图一对一例子和分配了多意图的例子。例如,输入"Can you suggest any cool meetups in Berlin area?" 仅仅有一个意图-the user asks for meetup recommendations,这就是它有单意图的原因。另外,输入"Sounds good. Do you know how I could get there from home?" 意味着两个意图-用户想参加会议的确认和查询交通,这解释了多意图 affirm+ask_transport。

## intent: meetup
- I am new to the area. What meetups I could join in Berlin? 
- I have just moved to Berlin. Can you suggest any cool meetups for me?

## intent: affirm+ask_transport
- Yes. How do I get there?
- Sounds good. Do you know how I could get there from home?

Training and testing the NLU model

NLU 数据准备完成,执行下列命令训练:

python -m rasa_nlu.train -c config.yml --data data/nlu_data.md -o models --fixed_model_name nlu_model --project current --verbose

它会条用Rasa NLU的训练函数并提供pipeline配置和训练数据,它设置了一个固定的模型名和打印出训练结果。

 

当模型训练好了,我们可以加载并使用不同的输入测试它,我们使用 load_nlu_model.py 代码加载它,如下:

interpreter = Interpreter.load('models/current/nlu_model')
print(interpreter.parse("Yes. Can you give me suggestions on how to get there?"))

这个方法 Interpreter.load 加载了一个模型,interpreter.parse返回了一个意图分类的结果。

 

下面我们可以看到输入消息的模型输出结果"Yes. Can you give me suggestions on how to get there?"。正如我们看到的,输入被分类器识别出多意图 affirm+adk_transport 。

{  
   'intent':{  
      'name':'affirm+ask_transport',
      'confidence':0.918471097946167
   },
   'entities':[  

   ],
   'intent_ranking':[  
      {  
         'name':'affirm+ask_transport',
         'confidence':0.918471097946167
      },
      {  
         'name':'ask_transport',
         'confidence':0.32662829756736755
      },
      {  
         'name':'thanks+goodbye',
         'confidence':0.004435105249285698
      },
      {  
         'name':'meetup',
         'confidence':-0.06692223995923996
      },
      {  
         'name':'deny',
         'confidence':-0.07153981924057007
      },
      {  
         'name':'goodbye',
         'confidence':-0.08976072818040848
      },
      {  
         'name':'greet',
         'confidence':-0.09185336530208588
      },
      {  
         'name':'thanks',
         'confidence':-0.1762458086013794
      },
      {  
         'name':'affirm',
         'confidence':-0.3415682911872864
      }
   ],
   'text':'Yes. Can you give me suggestions on how to get there?'
}

Defining the domain and training data

为了说明所有片段是如何组合在一起,我们用一些模板作为响应建立一个对话管理模型(为了重复性和简化性,我们不会使用任何的实时API和数据库)。domain.yml 文件包含模板,对话管理系统将会使用它响应用户输入。

templates:
  utter_greet:
    - "Hey, how can I help you?"
  utter_goodbye:
    - "Talk to you later!"
    - "Goodbye :("
    - "Bye!"
    - "Have a great day!"
  utter_confirm:
    - "Done - I have just booked you a spot at the Bots Berlin meetup."
    - "Great, just made an RSVP for you."
  utter_meetup:
    - "Rasa Bots Berlin meetup is definitely worth checking out! They are having an event today at Behrenstraße 42. Would you like to join?"
  utter_affirm_suggest_transport:
    - "Great, I have just booked a spot for you. The venue is close to the Berlin Friedrichstraße station, you can get there by catching U-Bahn U6."
  utter_suggest_transport:
    - "The venue is close to the Berlin Friedrichstraße station, so the best option is to catch a U-Bahn U6."
  utter_thanks:
    - "You are very welcome."
    - "Glad I could help!"
  utter_deny:
    - "That's a shame. Let me know if you change your mind."

这些模板将会对用户的输入做出响应,这取决于构建stories data的场景。

 

在继续之前,我想指出模板可以有多于一个可能响应。如 utter_goodbye,多个可用选项是为了让chatbot更加有趣并防止chatbot单一回复。

Generating the stories

通常,为了训练对话管理系统模型,我们需要stories。新的tensorflow pipeline对stories data没有任何的特殊格式-我们可以用先前定义的 多-单意图做出响应行为。在下表中,你可以找到两个我使用与模型中国的相似stories,一个多意图,一个单意图。data/stories.md 文件中。

## find_meetup_01## find_meetup_02
* greet
    - utter_greet
* meetup
    - utter_meetup
* affirm+ask_transport
    - utter_affirm_suggest_transport
* thanks+goodbye
    - utter_thanks
    - utter_goodbye
* greet
    - utter_greet
* meetup
    - utter_meetup
* affirm
    - utter_confirm
* ask_transport
    - utter_suggest_transport
* goodbye
    - utter_goodbye

第一个story有两个多意图, affirm+ask_transport 可响应用户输入"Yes, book me a spot at the meetup. Also, can you tell me how should I get to the venue?";另一个多意图 thanks+goodbye 用来响应用户 "Thank you. Talk to you later"。第二个story呈现出了一个非常相似的对话场景,但使用的是单意图。跟第二个story相比,第一个story更加有生物性和人类化的特征。

 

另一个需要强调的是有很多不同的方式来写具有多个意图。下表有三张方法:

story find_meetup_01 使用自定义行为 utter_affirm_suggest_transport 作为多意图 affirm_ask_transport 的响应。或者,像 find_meetup_03,我们可以通过两个分开的模板 -utter_confirm 和 -utter_suggest_transport ,它们通常被用来响应单意图。这里有个要点,无需对多意图的每个意图都做出响应的响应action。例如story find_meetup_03对具有两个意图的 thanks+goodbye做出了两个action。然而story find_meetup_04,它没有对thanks意图做出响应的action,这也是可以的。

 

哪种方法最合适使用取决于domain和chatbot的逻辑处理-在某些场景下,为多意图分配多行为是没有必要的,可以对多意图和单意图使用相同action。在构建机器人之前,设计出哪些行为用来确保更为自然的对话是一个很好的练习。

Training the dialogue management model and testing the bot

我们可以使用下面命令调用Rasa Core训练函数来训练模型,传递先前定义的domain.yml和stories.md,定义模型保存位置和数据迭代多少轮来训练模型。

python -m rasa_core.train -d domain.yml -s data/stories.md -o models/current/dialogue --epochs 200

一旦模型训练完成,就到了最令人激动得时刻-测试模型。我们可以使用下列命令运行它,it将加载对话管理和nlu模型并运行chatbot。

python -m rasa_core.run -d models/current/dialogue -u models/current/nlu_model

结果如下:

User: Hello
Bot: Hey, how can I help you?
User: I am new to Berlin and I would like to join some meetups. Any suggestions?
Bot: Rasa Bots Berlin meetup is definitely worth checking out! They are having an event today at Behrenstraße 42. Would you like to join?
User: Sure! Can you also tell me how can I get to the venue?
Bot: Great, just made an RSVP for you. 
Bot: The venue is close to the Berlin Friedrichstraße station, so the best option is to catch a U-Bahn U6.
User: Thanks a lot. Talk to you later.
Bot: Glad I could help!
Bot: Talk to you later! 

以上就是我们如何构建一个简单得理解并使用多意图的机器人。

 

你可能注意到,教程中没有实体识别。目前,tensorflow pipelin仅仅做到意图分类任务,关于实体识别正处于更新。

When should you use multi-intents?

这里我们使用了一个非常简单得例子,当你的chatbot逻辑需要多意图的时候,多意图设计尤为重要。但是过多的使用多意图会是系统太过复杂,所以仅仅只在确保系统交流更加人性化的时候去使用它。

译文完毕,感谢读者观看。如有译误,还请指正。谢谢!!!

本文标签: 如何处理意图Rasa