热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

rasa算法_智能问答rasa框架02自定义action

问答机器人框架中非常重要的几个概念为意图识别、槽位填充通常使用机器学习算法进行意图的分类,但最终我们是让将用户的输入提取出我们想要的核心信息。--槽位提取因此slot

问答机器人框架中非常重要的几个概念为意图识别、槽位填充

通常使用机器学习算法进行意图的分类,但最终我们是让将用户的输入提取出我们想要的核心信息。--槽位提取

因此slot在rasa中极为重要, 如何我们想要深入自定义slot,以及solt前后逻辑,那么FormAction是必须要了解清楚的。

位于rasa_sdk/forms.py

class FormAction(Action):def name(self) -> Text:"""Unique identifier of the form"""raise NotImplementedError("A form must implement a name")@staticmethoddef required_slots(tracker: "Tracker") -> List[Text]:"""A list of required slots that the form has to fill.Use `tracker` to request different list of slotsdepending on the state of the dialogue"""raise NotImplementedError("A form must implement required slots that it has to fill")

源码中可以看到name,required_slots,是必须实现的函数,作用是告诉rasa 此action都有哪些slot,此aciton名为什么,rasa官方demo中也如此进行了简介

class SalesForm(FormAction):"""Collects sales information and adds it to the spreadsheet"""def name(self) -> Text:return "sales_form"@staticmethoddef required_slots(tracker) -> List[Text]:return ["job_function","use_case","budget","person_name","company","business_email",]

那么rasa将按照required_slots list顺序进行slot填充

流程是一致的,我们在story中定义意图以及匹配此意图是的机器人行为,

我们想要使用自定义的action,需要在 domain.yml 和stories.md中进行配置

## sales form
* contact_sales- sales_form - form{"name": "sales_form"} - form{"name": null}

domain中定义fromaction

forms:- sales_form

当我们运行 rasa run, 和 新开一个窗口 rasa run actions时,会进行sales_form注册到rasa中

python ../start.py run actions
2020-09-07 14:03:54 INFO rasa_sdk.endpoint - Starting action endpoint server...
2020-09-07 14:03:54 INFO rasa_sdk.executor - Registered function for 'sales_form'.
2020-09-07 14:03:54 INFO rasa_sdk.endpoint - Action endpoint is up and running on http://localhost:5055

重点知识-story中的定义的何时触发action, domain.yml 中定义。

运行之后,发现会自动识别每一个slot槽位的,向用户提问。这里是因为formaction会自动循环required_slots中的slot,同时自动匹配 domain.yml utter_ask_+ 意图。

源码中此处进行了定义

def request_next_slot(self,dispatcher: "CollectingDispatcher",tracker: "Tracker",domain: Dict[Text, Any],) -> Optional[List[EventType]]:"""Request the next slot and utter template if needed,else return None"""for slot in self.required_slots(tracker):if self._should_request_slot(tracker, slot):logger.debug(f"Request next slot '{slot}'")dispatcher.utter_message(template=f"utter_ask_{slot}", **tracker.slots)return [SlotSet(REQUESTED_SLOT, slot)]# no more required slots to fillreturn None

因此我们可以重写request_next_slot,做前后slot信息验证

def validate_business_email(self, value, dispatcher, tracker, domain) -> Dict[Text, Any]:"""Check to see if an email entity was actually picked up by duckling."""if any(tracker.get_latest_entity_values("email")):# entity was picked up, validate slotreturn {"business_email": value}else:# no entity was picked up, we want to ask againdispatcher.utter_message(template="utter_no_email")return {"business_email": None}

函数定义以 validate_ + slot rasa将自动进行输入校验

源码定义如下:

async def validate_slots(self,slot_dict: Dict[Text, Any],dispatcher: "CollectingDispatcher",tracker: "Tracker",domain: Dict[Text, Any],) -> List[EventType]:"""Validate slots using helper validation functions.Call validate_{slot} function for each slot, value pair to be validated.If this function is not implemented, set the slot to the value."""for slot, value in list(slot_dict.items()):validate_func = getattr(self, f"validate_{slot}", lambda *x: {slot: value})if utils.is_coroutine_action(validate_func):validation_output = await validate_func(value, dispatcher, tracker, domain)else:validation_output = validate_func(value, dispatcher, tracker, domain)if not isinstance(validation_output, dict):logger.warning("Returning values in helper validation methods is deprecated. "+ f"Your `validate_{slot}()` method should return "+ "a dict of {'slot_name': value} instead.")validation_output = {slot: validation_output}slot_dict.update(validation_output)# validation succeed, set slots to extracted valuesreturn [SlotSet(slot, value) for slot, value in slot_dict.items()]

定义特定槽位的用户输入验证,有时候还是无法满足我们需求,我们得自定义request_next_slot, 方法中放飞自我

def request_next_slot(self,dispatcher: "CollectingDispatcher",tracker: "Tracker",domain: Dict[Text, Any],) -> Optional[List[EventType]]:"""Request the next slot and utter template if needed,else return None"""for slot in self.required_slots(tracker):print(slot)if slot == "person_name" and tracker.get_slot("person_name") == "yxp":dispatcher.utter_message(text="对不起,不欢迎你,走开!!")return self.deactivate()if self._should_request_slot(tracker, slot):print("_should_request_slot")## Condition of validated slot that triggers deactivationif slot == "person_name" and tracker.get_slot("person_name") == "yxp":dispatcher.utter_message(text="对不起,不欢迎你,走开!!")return self.deactivate()## For all other slots, continue as usuallogger.debug(f"Request next slot '{slot}'")dispatcher.utter_message(template=f"utter_ask_{slot}", ** tracker.slots)REQUESTED_SLOT = "requested_slot"return [SlotSet(REQUESTED_SLOT, slot)]print("not _should_request_slot")return None

最后两个重要方法为 slot_mappings, 和 submit

slot_mappings 正如函数名称定义的那样,允许用户进行slot槽位提取时的复杂方式。

比如用户输入 确认意图,填充true,输入否定意图,填充false等

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:"""A dictionary to map required slots to- an extracted entity- intent: value pairs- a whole messageor a list of them, where a first match will be picked"""return {"job_function": [self.from_entity(entity="job_function"),self.from_text(intent="enter_data"),],"use_case": [self.from_text(intent="enter_data")],"budget": [self.from_entity(entity="amount-of-money"),self.from_entity(entity="number"),self.from_text(intent="enter_data"),],"person_name": [self.from_entity(entity="name"),self.from_text(intent="enter_data"),],"company": [self.from_entity(entity="company"),self.from_text(intent="enter_data"),],"business_email": [self.from_entity(entity="email"),self.from_text(intent="enter_data"),],}

最后一个action结束时候,进行最后处理 submit函数为,当收集到所有的意图slot,最终处理方法。

def submit(self,dispatcher: CollectingDispatcher,tracker: Tracker,domain: Dict[Text, Any],) -> List[Dict]:person_name = tracker.get_slot("person_name")import datetimebudget = tracker.get_slot("budget")company = tracker.get_slot("company")email = tracker.get_slot("business_email")job_function = tracker.get_slot("job_function")person_name = tracker.get_slot("person_name")use_case = tracker.get_slot("use_case")date = datetime.datetime.now().strftime("%d/%m/%Y")sales_info = [company, use_case, budget, date, person_name, job_function, email]print(sales_info)dispatcher.utter_message(template="utter_confirm_salesrequest", user_name=person_name)return []

以上,我们完成了FormAction 自定义处理, 可以帮助我们实现复杂的多轮次对话。



推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
  • cs231n Lecture 3 线性分类笔记(一)
    内容列表线性分类器简介线性评分函数阐明线性分类器损失函数多类SVMSoftmax分类器SVM和Softmax的比较基于Web的可交互线性分类器原型小结注:中文翻译 ... [详细]
  • 本博文基于《Amalgamationofproteinsequence,structureandtextualinformationforimprovingprote ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • vue使用
    关键词: ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 建立分类感知器二元模型对样本数据进行分类
    本文介绍了建立分类感知器二元模型对样本数据进行分类的方法。通过建立线性模型,使用最小二乘、Logistic回归等方法进行建模,考虑到可能性的大小等因素。通过极大似然估计求得分类器的参数,使用牛顿-拉菲森迭代方法求解方程组。同时介绍了梯度上升算法和牛顿迭代的收敛速度比较。最后给出了公式法和logistic regression的实现示例。 ... [详细]
author-avatar
专业破解王_920
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有