自定义Graph Component:1.2-其它Tokenizer具体实现
本文主要介绍了Rasa中相关Tokenizer的具体实现,包括默认Tokenizer和第三方Tokenizer。前者包括JiebaTokenizer、MitieTokenizer、SpacyTokenizer和WhitespaceTokenizer,后者包括BertTokenizer和AnotherWhitespaceTokenizer。
一.JiebaTokenizer
JiebaTokenizer类整体代码结构,如下所示:

加载自定义字典代码,如下所示[3]:
@staticmethod
def _load_custom_dictionary(path: Text) -> None:
"""Load all the custom dictionaries stored in the path. # 加载存储在路径中的所有自定义字典。
More information about the dictionaries file format can be found in the documentation of jieba. https://github.com/fxsjy/jieba#load-dictionary
"""
print("JiebaTokenizer._load_custom_dictionary()")
import jieba
jieba_userdicts = glob.glob(f"{path}/*") # 获取路径下的所有文件。
for jieba_userdict in jieba_userdicts: # 遍历所有文件。
logger.info(f"Loading Jieba User Dictionary at {jieba_userdict}") # 加载结巴用户字典。
jieba.load_userdict(jieba_userdict) # 加载用户字典。
实现分词的代码为tokenize()方法,如下所示:
def tokenize(self, message: Message, attribute: Text) -> List[Token]:
"""Tokenizes the text of the provided attribute of the incoming message.""" # 对传入消息的提供属性的文本进行tokenize。
print("JiebaTokenizer.tokenize()")
import jieba
text = message.get(attribute) # 获取消息的属性
tokenized = jieba.tokenize(text) # 对文本进行标记化
tokens = [Token(word, start) for (word, start, end) in tokenized] # 生成标记
return self._apply_token_pattern(tokens)
self._apply_token_pattern(tokens)数据类型为List[Token]。Token的数据类型为:
class Token:
# 由将单个消息拆分为多个Token的Tokenizers使用
def __init__(
self,
text: Text,
start: int,
end: Optional[int] = None,
data: Optional[Dict[Text, Any]] = None,
lemma: Optional[Text] = None,
) -> None:
"""创建一个Token
Args:
text: The token text. # token文本
start: The start index of the token within the entire message. # token在整个消息中的起始索引
end: The end index of the token within the entire message. # token在整个消息中的结束索引
data: Additional token data. # 附加的token数据
lemma: An optional lemmatized version of the token text. # token文本的可选词形还原版本
"""
self.text = text
self.start = start
self.end = end if end else start + len(text)
self.data = data if data else {}
self.lemma = lemma or text
特别说明:JiebaTokenizer组件的is_trainable=True。
二.MitieTokenizer
MitieTokenizer类整体代码结构,如下所示:

核心代码tokenize()方法代码,如下所示:
def tokenize(self, message: Message, attribute: Text) -> List[Token]:
"""Tokenizes the text of the provided attribute of the incoming message.""" # 对传入消息的提供属性的文本进行tokenize
import mitie
text = message.get(attribute)
encoded_sentence = text.encode(DEFAULT_ENCODING)
tokenized = mitie.tokenize_with_offsets(encoded_sentence)
tokens = [
self._token_from_offset(token, offset, encoded_sentence)
for token, offset in tokenized
]
return self._apply_token_pattern(tokens)
特别说明:mitie库在Windows上安装可能麻烦些。MitieTokenizer组件的is_trainable=False。
三.SpacyTokenizer
首先安装Spacy类库和模型[4][5],如下所示:
pip3 install -U spacy
python3 -m spacy download zh_core_web_sm
SpacyTokenizer类整体代码结构,如下所示:

核心代码tokenize()方法代码,如下所示:
def tokenize(self, message: Message, attribute: Text) -> List[Token]:
"""Tokenizes the text of the provided attribute of the incoming message.""" # 对传入消息的提供属性的文本进行tokenize
doc = self._get_doc(message, attribute) # doc是一个Doc对象
if not doc:
return []
tokens = [
Token(
t.text, t.idx, lemma=t.lemma_, data={POS_TAG_KEY: self._tag_of_token(t)}
)
for t in doc
if t.text and t.text.strip()
]
特别说明:SpacyTokenizer组件的is_trainable=False。即SpacyTokenizer只有运行组件run_SpacyTokenizer0,没有训练组件。如下所示:

四.WhitespaceTokenizer
WhitespaceTokenizer主要是针对英文的,不可用于中文。WhitespaceTokenizer类整体代码结构,如下所示:

其中,predict_schema和train_schema,如下所示:

rasa shell nlu --debug结果,如下所示:

特别说明:WhitespaceTokenizer组件的is_trainable=False。
五.BertTokenizer
rasa shell nlu --debug结果,如下所示:

  BertTokenizer代码具体实现,如下所示:
"""
https://github.com/daiyizheng/rasa-chinese-plus/blob/master/rasa_chinese_plus/nlu/tokenizers/bert_tokenizer.py
"""
from typing import List, Text, Dict, Any
from rasa.engine.recipes.default_recipe import DefaultV1Recipe
from rasa.shared.nlu.training_data.message import Message
from transformers import AutoTokenizer
from rasa.nlu.tokenizers.tokenizer import Tokenizer, Token
@DefaultV1Recipe.register(
DefaultV1Recipe.ComponentType.MESSAGE_TOKENIZER, is_trainable=False
)
class BertTokenizer(Tokenizer):
def __init__(self, config: Dict[Text, Any] = None) -> None:
"""
:param config: {"pretrained_model_name_or_path":"", "cache_dir":"", "use_fast":""}
"""
super().__init__(config)
self.tokenizer = AutoTokenizer.from_pretrained(
config["pretrained_model_name_or_path"], # 指定预训练模型的名称或路径
cache_dir=config.get("cache_dir"), # 指定缓存目录
use_fast=True if config.get("use_fast") else False # 是否使用快速模式
)
@classmethod
def required_packages(cls) -> List[Text]:
return ["transformers"] # 指定依赖的包
@staticmethod
def get_default_config() -> Dict[Text, Any]:
"""The component's default config (see parent class for full docstring)."""
return {
# Flag to check whether to split intents
"intent_tokenization_flag": False,
# Symbol on which intent should be split
"intent_split_symbol": "_",
# Regular expression to detect tokens
"token_pattern": None,
# Symbol on which prefix should be split
"prefix_separator_symbol": None,
}
def tokenize(self, message: Message, attribute: Text) -> List[Token]:
text = message.get(attribute) # 获取文本
encoded_input = self.tokenizer(text, return_offsets_mapping=True, add_special_tokens=False) # 编码文本
token_position_pair = zip(encoded_input.tokens(), encoded_input["offset_mapping"]) # 将编码后的文本和偏移量映射成一个元组
tokens = [Token(text=token_text, start=position[0], end=position[1]) for token_text, position in token_position_pair] # 将元组转换成Token对象
return self._apply_token_pattern(tokens)
特别说明:BertTokenizer组件的is_trainable=False。
六.AnotherWhitespaceTokenizer
AnotherWhitespaceTokenizer代码具体实现,如下所示:
from __future__ import annotations
from typing import Any, Dict, List, Optional, Text
from rasa.engine.graph import ExecutionContext
from rasa.engine.recipes.default_recipe import DefaultV1Recipe
from rasa.engine.storage.resource import Resource
from rasa.engine.storage.storage import ModelStorage
from rasa.nlu.tokenizers.tokenizer import Token, Tokenizer
from rasa.shared.nlu.training_data.message import Message
@DefaultV1Recipe.register(
DefaultV1Recipe.ComponentType.MESSAGE_TOKENIZER, is_trainable=False
)
class AnotherWhitespaceTokenizer(Tokenizer):
"""Creates features for entity extraction."""
@staticmethod
def not_supported_languages() -> Optional[List[Text]]:
"""The languages that are not supported."""
return ["zh", "ja", "th"]
@staticmethod
def get_default_config() -> Dict[Text, Any]:
"""Returns the component's default config."""
return {
# This *must* be added due to the parent class.
"intent_tokenization_flag": False,
# This *must* be added due to the parent class.
"intent_split_symbol": "_",
# This is a, somewhat silly, config that we pass
"only_alphanum": True,
}
def __init__(self, config: Dict[Text, Any]) -> None:
"""Initialize the tokenizer."""
super().__init__(config)
self.only_alphanum = config["only_alphanum"]
def parse_string(self, s):
if self.only_alphanum:
return "".join([c for c in s if ((c == " ") or str.isalnum(c))])
return s
@classmethod
def create(
cls,
config: Dict[Text, Any],
model_storage: ModelStorage,
resource: Resource,
execution_context: ExecutionContext,
) -> AnotherWhitespaceTokenizer:
return cls(config)
def tokenize(self, message: Message, attribute: Text) -> List[Token]:
text = self.parse_string(message.get(attribute))
words = [w for w in text.split(" ") if w]
# if we removed everything like smiles `:)`, use the whole text as 1 token
if not words:
words = [text]
# the ._convert_words_to_tokens() method is from the parent class.
tokens = self._convert_words_to_tokens(words, text)
return self._apply_token_pattern(tokens)
特别说明:AnotherWhitespaceTokenizer组件的is_trainable=False。
参考文献:
[1]自定义Graph Component:1.1-JiebaTokenizer具体实现:https://mp.weixin.qq.com/s/awGiGn3uJaNcvJBpk4okCA
[2]https://github.com/RasaHQ/rasa
[3]https://github.com/fxsjy/jieba#load-dictionary
[4]spaCy GitHub:https://github.com/explosion/spaCy
[5]spaCy官网:https://spacy.io/
[6]https://github.com/daiyizheng/rasa-chinese-plus/blob/master/rasa_chinese_plus/nlu/tokenizers/bert_tokenizer.py
自定义Graph Component:1.2-其它Tokenizer具体实现的更多相关文章
- 自定义组件Component
定义compa组件 由4个页面构成 compa.js: compa.json: compa.wxml: compa:wxss: 1.compa.json:在json文件进行自定义组件声明 { &quo ...
- ionic3.x angular4.x ng4.x 自定义组件component双向绑定之自定义计数器
本文主要示例在ionic3.x环境下实现一个自定义计数器,实现后最终效果如图: 1.使用命令创建一个component ionic g component CounterInput 类似的命令还有: ...
- Yii2.0 高级模版编写使用自定义组件(component)
翻译自:http://www.yiiframework.com/wiki/760/yii-2-0-write-use-a-custom-component-in-yii2-0-advanced-tem ...
- angular custom Element 自定义web component
angular 自定义web组件: 首先创建一个名为myCustom的组件. 引入app.module: ... import {customComponent} from ' ./myCustom. ...
- Magicodes.WeiChat——自定义knockoutjs template、component实现微信自定义菜单
本人一向比较喜欢折腾,玩了这么久的knockoutjs,总觉得不够劲,于是又开始准备折腾自己了. 最近在完善Magicodes.WeiChat微信开发框架时,发现之前做的自定义菜单这块太不给力了,而各 ...
- weex 自定义Component
扩展iOS的功能 ~ Component 与UI控件相关 ,即通过原生方法创建UI界面,返回给weex 使用 一. 新建 WXComponent 的子类 在子类实现WXComponent 的 ...
- springboot +spring security4 自定义手机号码+短信验证码登录
spring security 默认登录方式都是用户名+密码登录,项目中使用手机+ 短信验证码登录, 没办法,只能实现修改: 需要修改的地方: 1 .自定义 AuthenticationProvide ...
- Spring Security验证流程剖析及自定义验证方法
Spring Security的本质 Spring Security本质上是一连串的Filter, 然后又以一个独立的Filter的形式插入到Filter Chain里,其名为FilterChainP ...
- zabbix监控之自定义item
zabbix安装完成后,当需要使用自定义脚本构建自定义item必须注意以下几点: 1.首先使用zabbix_get手动在zabbix-server服务端获取监控的默认的item值,如下: [root@ ...
- Cacti自定义脚本,监测Docker信息(Script/Command方式)
一 环境背景 监控主机A:192.168.24.231:被监控主机B:192.168.24.233 A/B主机,通过公私钥建立ssh连接 [操作B主机时不需要输入密码,详见笔记:http://app. ...
随机推荐
- 武汉工程大学第五届程序设计新生赛 I题 题解
(2022,12,3) 原题链接(来自牛客竞赛) 抽象题意 题目有点长,我们需要抽象出一个模型: 一个长度为\(n\)的序列\(a_i\),从\(a_1\)开始向后跳,每次可以从\(a_i\)跳到下一 ...
- java if switch
强制类型转换 注意事项:大的转小的需要强制转换 例如: double b=3.4 int小于double所以想让int=b,要在b后面加个(int)b. int a=(int)b 得到3 因为大 ...
- 【实践篇】DDD脚手架及编码规范
一.背景介绍 我们团队一直在持续推进业务系统的体系化治理工作,在这个过程中我们沉淀了自己的DDD脚手架项目.脚手架项目是体系化治理过程中比较重要的一环,它的作用有两点: (1)可以对新建的项目进行统一 ...
- Vue【原创】可拖动列表 darg-list
可拖动排序的列表 drag-list,这个比较简单易懂,拿例子直接运行看效果就好了. 组件代码: 1 <template> 2 <ul class="list" ...
- Linux 干货整理(持续更新)
博客地址:https://www.cnblogs.com/zylyehuo/ 如果虚拟机开机没有 ip 怎么办 1.vim编辑网卡配置文件,修改如下参数 [root@s25linux tmp]# cd ...
- LeetCode952三部曲之三:再次优化(122ms -> 96ms,超51% -> 超91%)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<LeetCode952三部曲之 ...
- 程序员:你如何写可重复执行的SQL语句?
上图的意思: 百战百胜,屡试不爽. 故事 程序员小张: 刚毕业,参加工作1年左右,日常工作是CRUD 架构师老李: 多个大型项目经验,精通各种开发架构屠龙宝术: 小张注意到,在实际的项目开发场景中,很 ...
- ZooKeeper核心概念和架构
ZooKeeper简介 ZooKeeper是一个分布式应用程序协调服务,主要用于解决分布式集群中应用系统的一致性问题.它能提供类似文件系统的目录节点树方式的数据存储,主要用途是维护和监控所存数据的状态 ...
- 面霸的自我修养:ThreadLocal专题
王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 今天是<面霸的自我修养>第5篇文章,我们一起来看看面试中会问到哪些关于ThreadLocal ...
- C#希尔排序算法
前言 希尔排序简单的来说就是一种改进的插入排序算法,它通过将待排序的元素分成若干个子序列,然后对每个子序列进行插入排序,最终逐步缩小子序列的间隔,直到整个序列变得有序.希尔排序的主要思想是通过插入排序 ...