【转载】基于rasa的对话系统搭建(上)

文章介绍使用rasa nlu和 rasa core 实现一个电信领域对话系统demo,实现简单的业务查询办理功能,更完善的实现需要进一步数据的收集。demo基于玩具数据集,可以达到下面的效果:

Bot loaded. Type a message and press enter : 
YOU:你是谁
BOT:您好!,我是机器人小热,很高兴为您服务。
YOU:我想看一下消费情况
BOT:您想查询哪个月的消费?
YOU:十月份的
BOT:好,请稍等
BOT:您好,您十月份共消费二十八元。
YOU:好谢谢
BOT:您开心我就开心
BOT:您还想干什么
YOU:没什么了
BOT:Bye, 下次再见

用Rasa_NLU构建自己的中文NLU系统

系统demo 的数据和代码路径:
https://github.com/zqhZY/_rasa_chatbot

项目依赖安装(包括rasa nlu 和 rasa core)参考相应路径:
https://github.com/zqhZY/_rasa_chatbot/blob/master/INSTALL.md

关于rasa nlu的使用方法,可以参考:
https://github.com/RasaHQ/rasa_nlu
http://www.crownpku.com/2017/07/27/用Rasa_NLU构建自己的中文NLU系统.html

确定意图和实体类别

根据业务查询和办理的场景,首先需要确定意图和实体的类别,这里系统包含如下意图和实体类型:

intents:
  • greet
  • confirm # 确认
  • goodbye
  • thanks
  • inform_item # 告知业务类型
  • inform_package # 告知套餐类型
  • inform_time # 告知时间
  • request_management # 办理请求
  • request_search # 查询请求
  • deny # 否定
  • inform_current_phone # 告知本机号码
  • inform_other_phone # 告知其他号码
entities:
  • item # 业务类型
  • time # 时间
  • phone_number # 电话号码
  • price # 价格

数据准备

通常项目刚开始,往往伴随着冷启动的问题。没有数据的情况下可以根据实际业务场景自行标注数据并结合规则方式先实现第一版本,线上收集真实数据(如果有机会上线的话-),并反过来迭代模型。 这里使用的训练数据为结合实际场景的自造数据,并转换为rasa nlu训练数据的格式,供学习使用。

数据格式如下:

{
  "rasa_nlu_data": {
    "common_examples": [
      {
        "text": "帮我查一下我的流量这里还有多少",
        "intent": "request_search",
        "entities": [
          {
            "start": 7,
            "end": 9,
            "value": "流量",
            "entity": "item"
          }
        ]
      },
      ...
      ...
      {
        "text": "给我办一个三十的新流量业务",
        "intent": "request_management",
        "entities": [
          {
            "start": 10,
            "end": 12,
            "value": "流量",
            "entity": "item"
          },
          {
            "start": 5,
            "end": 7,
            "value": "三十",
            "entity": "price"
          }
        ]
      },
      ...
      ...
    ],
    "regex_features": [],
    "entity_synonyms": [{
        "value": "消费",
        "synonyms": ["话费"]
      }]
  }
}

训练自然语言理解模型

这里使用rasa nlu 的pipeline 为 MITIE+Jieba+sklearn, rasa nlu 的配置文件为:

{
  "name": "rasa_nlu",
  "project": "ivr",
  "fixed_model_name": "demo",
  "pipeline": ["nlp_mitie",
        "tokenizer_jieba",
        "ner_mitie",
        "ner_synonyms",
        "intent_entity_featurizer_regex",
        "intent_featurizer_mitie",
        "intent_classifier_sklearn"],
  "language": "zh",
  "mitie_file": "data/total_word_feature_extractor.dat",
  "path" : "models",
  "data" : "data/mobile_nlu_data.json"
}
MITIE模型训练

由于使用了mitie 所以需要事先准备相应的词特征向量(total_word_feature_extractor.dat),类似训练word2vec,
方法如下:

把所有分好词的语料文件放在同一个文件路径下。接下来我们要训练MITIE模型。

首先将MITIE clone下来:

$ git clone https://github.com/mit-nlp/MITIE.git

我们要使用的只是MITIE其中wordrep这一个工具。我们先build它。

$ cd MITIE/tools/wordrep
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build . --config Release

然后训练模型,得到total_word_feature_extractor.dat。注意这一步训练会耗费几十GB的内存,大概需要两到三天的时间。

$ ./wordrep -e /path/to/your/folder_of_cutted_text_files

项目链接里包含了用真实电信业务数据训练的total_word_feature_extractor.dat,也可以使用wiki百科训练的相应模型。

链接:http://pan.baidu.com/s/1micEF0G 密码:opli
训练rasa nlu 模型

使用rasa nlu 的终端接口训练模型:

python -m rasa_nlu.train -c mobile_nlu_model_config.json

也可以使用bot.py 里的Python 接口:

def train_nlu():
    from rasa_nlu.converters import load_data
    from rasa_nlu.config import RasaNLUConfig
    from rasa_nlu.model import Trainer
training_data = load_data(<span class="hljs-string">"data/mobile_nlu_data.json"</span>)
trainer = Trainer(RasaNLUConfig(<span class="hljs-string">"mobile_nlu_model_config.json"</span>))
trainer.train(training_data)
model_directory = trainer.persist(<span class="hljs-string">"models/"</span>, project_name=<span class="hljs-string">"ivr"</span>, fixed_model_name=<span class="hljs-string">"demo"</span>)

<span class="hljs-keyword">return</span> model_directory

运行相应命令:

python bot.py train-nlu

两种方式都会在项目根目录models下生成模型:

models/
└── ivr
    ├── demo
       ├── entity_extractor.dat
       ├── entity_synonyms.json
       ├── intent_classifier.pkl
       ├── metadata.json
       └── training_data.json

rasa nlu 测试

训练好模型后可以使用http接口进行测试,启动项目的httpserver,服务会load模型,并接受http请求,对新文本进行预测:

$ python httpserver.py 
2018-01-12 11:48:23+0800 [-] Log opened.
2018-01-12 11:48:23+0800 [-] Site starting on 1235
2018-01-12 11:48:23+0800 [-] Starting factory <twisted.web.server.Site object at 0x7f090a9d49b0>

向服务发送http请求测试结果:

$ curl -XPOST 127.0.0.1:1235/parse -d '{"text":"给我查一下我上个月的流量"}'
{"text": "给我查一下我上个月的流量", "intent": "request_search", "entities": {"time": "上个月", "item": "流量"}}

同时httpserver 后台打印完整log,包括每个intent的预测confidence。

小结

篇幅原因,这里只介绍训练rasa nlu的流程,更多rasa nlu的用法可以到官方文档了解。下篇文章介绍利用这里训练的nlu模型,使用rasa core 的online learning (或强化学习)方式进行对话管理模型的训练和测试。

原创文章,转载注明出处
更多关注公众号:

wechat

      </div>
    </div>
posted @ 2018-10-28 21:06  致林  阅读(1030)  评论(0编辑  收藏  举报