pydial的主要目标便是提供一个通用的语言统计对话模型,开发者可以方便的向其中添加集成和测试自己的模型.pydial位主要模块都设计了明确定义的通用接口,为了了解这个,我们首先来看一下pydial的整体框架.
如上所示,多域功能的对话模型主要使用主题跟踪器来进行实现,主题跟踪器来识别用户输入的主题,可以保证切换,从上一个对话领域切换到用户当前想要的对话领域,由上图可以看出,主题追踪器在整个对话系统中扮演了一个核心的角色,其触发了对用户的语义理解,对话状态的追踪,从而影响到了最核心的对话决策部分,继而转到语言生成即输出部分,完成了整个的一个对话流程.
生成新的模块:
为了便于集成你自己的模块,pydial为模块都提供了简单的接口类.如下:
- Topic Tracking: topictracking.RuleTopicTrackers.TopicTrackerInterface
- Semantic Belief Tracking (from words to belief state): semanticbelieftracking.SemanticBeliefTrackingManager.SemanticBeliefTracker
- Semantic Decoding (from words to semantics): semi.SemI.SemI
- Belief Tracking (from semantics to belief state): belieftracking.BeliefTracker.BeliefTracker
- Policy: policy.Policy.Policy
- Language Generation: semo.SemOManager.SemO
- Evaluation: EvaluationManager.Evaluator
所有这些模块都被同样的模块组织结构定义,pydial的主要目标是提供一个多领域的对话平台,一个叫做管理器(manager)的概念将被介绍,它使用了类似词典的结构处理方式来处理每个模块的域实例.实现一个未在pydial中实现的模型如下所示:
为了实现你自己的模型,查看基类中的一些方法,并继承基类来重写你自己需要实现的方法,为了使用你自己定义的模型,需要在配置文件中定义和加载对应的模型.config/dynamically_load_modules.cfg中便是动态加载模型的例子.
应用举例:
我们创建了一个新的parrotPolicy决策类,它简单的接受用户的操作并作为用户的操作返回,就像鹦鹉学舌一般,为此,第一步创建一个继承自policy的基类.
from policy import Policy
class Parrot(Policy.Policy):
def nextAction(self, beliefstate):
pass
为了实现用户的行为,我们必须从信念状态中提取最后一个用户状态信息,稍微做一下解析,然后返回它。在开始时,我们默认使用hello() system act。
from policy import Policy
import re
class Parrot(Policy.Policy):
def nextAction(self, beliefstate):
userActs = beliefstate['userActs']
if userActs is not None:
systemAct = userActs[0][0]
else:
systemAct = "hello()"
return systemAct
在配置文件中进行加载和预处理.
用户意图:
用户行为表示为意图的字符串、槽或槽值对的列表。下面是系统当前使用的系统操作列表
- request(slot)
- inform(slot=value)
- confirm(slot=value)
- confreq(slot=value,slot)
- affirm()
- hello()
- negate()
- repeat()
- requalts()
- bye()
信念状态封装在一个对话的对象当中,在内部,每个域的信念都使用以下的字典结构建模.
{'beliefs': {u'informable_slot1': {'**NONE**': 1.0,
u'value1': 0.0,
u'value2': 0.0,
... },
u'informable_slot2': {'**NONE**': 1.0,
u'value1': 0.0,
u'value2': 0.0,
... },
...
'discourseAct': {u'ack': 0.0,
'bye': 0.0,
u'hello': 0.0,
u'none': 1.0,
u'repeat': 0.0,
u'silence': 0.0,
u'thankyou': 0.0},
'method': {u'byalternatives': 0.0,
u'byconstraints': 0.5,
u'byname': 0.0,
u'finished': 0.0,
u'none': 0.5,
u'restart': 0.0},
'requested': {u'infromable_slot1': 0.0,
u'informable_slot2': 0.0,
...
u'requestable_slot1': 0.0,
u'requestable_slot2': 0.0,
...
u'name': 0.0}},
'userActs': [('hypo1', 0.8),('hypo2',0.1),...]}
进行输出.
信息插槽、话语、方法和请求字段的实际值直接从本体文件中提取。而informable slot、discourse seact和method都代表了一个概率分布,即每个字段的数值总和为1,这对于被请求的字段是不同的。在这里,每个数值都可能在[0,1]中。