自定义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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/141888.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5 新的关键字

动态内存分配 回想C语言中,动态内存是怎么分配的?通过C库里面的malloc free去进行动态内存分配。 C通过new关键字进行动态内存申请,动态内存申请是基于类型进行的。 delete 关键字用于内存释放。 //变量申请 type* pointer new type; dele…

arcgis提取栅格有效边界

方法一:【3D Analyst工具】-【转换】-【由栅格转出】-【栅格范围】 打开一幅栅格数据,利用【栅格范围】工具提取其有效边界(不包含NoData值): 方法二:先利用【栅格计算器】将有效值赋值为1,得到…

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline

模型简介 本基线模型共分为三个部分: 基于CNN的判断每张人脸是否是说话人的模型;基于Transformer-Encoder的判断同一段对话中不同轮次的说话人关系的模型;和使用上述两个预测结果求解二次型优化问题的说话人识别求解器。 基于CNN的判断每…

VSCode 好用的插件分享

文章目录 Introlistcode runner 【在文本编辑器中编辑好各类语言的源代码,然后一键运行】gitlens - 【git提交信息即时查看,类似IDEA中的 show annotation】还有更多,会日常补充。 Intro 大四毕业前,我只有一台dell latitude 455…

瑞萨e2studio(29)----SPI速率解析

瑞萨e2studio.29--SPI速率解析 概述视频教学时钟配置解析RA4M2的BRR值时钟速率7.5M下寄存器值3K下寄存器值 概述 在嵌入式系统的设计中,串行外设接口(SPI)的通信速率是一个关键参数,它直接影响到系统的性能和稳定性。瑞萨电子的…

No200.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【Android】画面卡顿优化列表流畅度四之Glide几个常用参数设置

好像是一年前快两年了,笔者解析过glide的源码,也是因为觉得自己熟悉一些,也就没太关注过项目里glide的具体使用对当前业务的影响;主要是自负,还有就是真没有碰到过这样的数据加载情况。暴露了经验还是不太足够 有兴趣的…

点大商城V2版 2.5.3全插件开源独立版 百度+支付宝+QQ+头条+小程序端+unipp开源端安装测试教程

点大商城V2是一款采用全新界面设计支持多端覆盖的小程序应用,支持H5、微信公众号、微信小程序、头条小程序、支付宝小程序、百度小程序,本程序是点大商城V2独立版,包含全部插件,代码全开源,并且有VUE全端代码。 适用范…

Java17新增特性

前言 前面的文章,我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍,对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…

Matlab论文插图绘制模板第126期—分组三维气泡图

在之前的文章中,分享了Matlab三维气泡图的绘制模板: 特征渲染的三维气泡图: 进一步,再来分享一下分组三维气泡图。 先来看一下成品效果: 特别提示:本期内容『数据代码』已上传资源群中,加群的朋…

手机能做静态二维码吗?用手机做二维码的教程

现在手机上有很多的功能,能够帮助我们应对日常生活中的各种问题,那么如果我们想要在手机上生成一个静态二维码,大家知道该怎么来操作吗?一般制作二维码需要专业的二维码生成工具才可以完成制作,那么下面小编来给大家分…

RabbitMQ-基础篇-黑马程序员

代码: 链接: https://pan.baidu.com/s/1nQBIgB_SbzoKu_XMWZ3JoA?pwdaeoe 提取码:aeoe 微服务一旦拆分,必然涉及到服务之间的相互调用,目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中,调…

2023年亚太杯数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 赛题思路算法介绍FP树表示法构建FP树实现代码 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法,就是频繁模式树算法&#…

Maya v2024(3D动画制作软件)

Maya 2024是一款三维计算机图形动画制作软件。它被广泛应用于电影、电视、游戏、动画等领域中,用于创建各种三维模型、场景、特效和动画。 以下是Maya的主要特点: 强大的建模工具:Maya提供了各种建模工具,如多边形建模、NURBS建模…

lamp环境搭建(kali,docker,ubuntu)

学了微专业,然后第一节课是学的搭建自己的环境,这里记录一下吧。 搭建一个lamp环境 (因为本人使用的是kali而且还带有集成环境的xampp,本身就自带了apache2,mysql和php。)后面有用ubuntu从0开始搭建的。 在kali环境下: 1.首先查看apache2和mysql和php 查看apache2 where…

Python中的数据增强技术

使用imgaug快速观察Python中的数据增强技术 在本文中,我们将使用imgaug库来探索Python中不同的数据增强技术 什么是图像增强 图像增强是一种强大的技术,用于在现有图像中人为地创建变化以扩展图像数据集。这是通过应用不同的变换技术来实现的&#xf…

矩阵置零00

题目链接 矩阵置零 题目描述 注意点 使用 原地 算法 解答思路 思路是需要存储每一行以及每一列是否有0,因为要尽可能使用更少的空间,且新设置为0的格子不能对后续的判断产生影响,所以要在原有矩阵上存储该信息先用两个参数存储第一行和第…

飞天使-django创建一个初始项目过程

创建django项目 运行项目 运行命令 pyhont manage.py runserver 然后访问 http://127.0.0.1:8000/, 则可以打开本地新建的项目 虚拟环境的部署-mac 在一台计算机上可以通过虚拟环境实现多个版本Django的开发环境 安装虚拟环境工具:如果你的系统中没有安…

properties文件乱码

出现如下乱码: 按照步骤修改编码方式就可以解决啦 修改之后结果就是下面这样~

搜索引擎项目

认识搜索引擎 1、有一个主页、有搜索框。在搜索框中输入的内容 称为“查询词” 2、还有搜索结果页,包含了若干条搜索结果 3、针对每一个搜索结果,都会包含查询词或者查询词的一部分或者和查询词具有一定的相关性 4、每个搜索结果包含好几个部分&…