Tokenization

关于Tokenization,网上有翻译成"分词"的,但是我觉得不是很准确,容易引起误导。一直找不到合适的中文来恰当表达,所以下文采用原汁原味的英文表达。

在正式进入主题之前,先来看看NLP任务中最基础也最先需要进行的一步:tokenization。简单说,该操作的目地是将输入文本分割成一个个token,和词典配合以让机器认识文本。Tokenization的难点在于如何获得理想的切分,使文本中所有的token都具有正确的表义,并且不会存在遗漏(OOV问题)。

接下来,我们简单梳理下目前主流的tokenization方法,及其优缺点。

词粒度

词粒度的切分就跟人类平时理解文本原理一样,常常用一些工具来完成,例如英文的NLTK、SpaCy,中文的jieba、LTP等。举个栗子:

英文:

live in New York ------> live / in / New York /

中文:

在纽约生活 -----> 在 / 纽约 / 生活

词粒度的切分能够非常好地保留完整语义信息,但是如果出现拼写错误、英文中的缩写等情况,鲁棒性一般。另一方面,词切分会产生非常巨大的词表,而且这都不能确保不会出现out of vocabulary问题。

字粒度

字粒度最早应该是2015年Karpathy[1]提出,简单说英文就是以字母为单位(对于大小写不敏感的任务,甚至可以先转小写再切分),中文就是以字为单位,举个栗子,

英文:

live in New York -----> l / i / v /e / i / n / N / e / w / Y / o / r /k

中文:

在纽约生活 -----> 在 / 纽 / 约 / 生 / 活

可以看出,字粒度的切分很好地解决了词粒度的缺陷,鲁棒性增强、词表大大减小。但另一方面,也会带来一些麻烦:

  • 「毫无意义」:一个字母或一个单字本质上并没有任何语义意义;

  • 「增加输入计算压力」:减小词表的代价就是输入长度大大增加,从而输入计算变得更耗时耗力;

如果词粒度不理想,而且字粒度似乎也有自己的问题,那么还有什么替代方法呢?

Here comes subword tokenization!

Subword粒度

我们理想中的tokenization需要满足:

  • 它能够在不需要无限词汇表的情况下处理缺失的标记,即通过有限的已知单词列表来处理无限的潜在词汇;

  • 此外,我们不希望将所有内容分解为单个字符的额外复杂性,因为字符级别可能会丢失单词级别的一些含义和语义细节。

为此,我们需要考虑如何重新利用『小』单词来创建『大』单词。subword tokenization不转换最常见的单词,而是将稀有单词分解成有意义的子词单元。如果unfriendly被标记为一个稀有词,它将被分解为un-friendly-ly,这些单位都是有意义的单位,un的意思是相反的,friend是一个名词,ly则变成副词。这里的挑战是如何进行细分,我们如何获得un-friend-ly而不是unfr-ien-dly

NLP最火的网红 TransformerBERT 就是Subword的带盐人,来看个它们做tokenization的栗子,

I have a new GPU  ----> [’i’, ’have’, ’a’, ’new’, ’gp’, ’##u’, ’.’]

subword粒度切分算法又有以下几种:

  • BPE

  • WordPiece

  • ULM

BPE

BPE全称Byte Pair Encoding,字节对编码,首先在Neural Machine Translation of Rare Words with Subword Units[2] 中提出。BPE 迭代地合并最频繁出现的字符或字符序列,具体步骤:

  1. 准备足够大的语料库

  2. 定义好所需要的词表大小

  3. 将单词拆分为字符序列,在末尾添加后缀 </ w>,并统计单词频率。本阶段的subword的粒度是字符。例如,“ low”的频率为5,那么我们将其改写为l o w </ w>:5

  4. 统计每一个连续字节对的出现频率,选择最高频者合并成新的subword

  5. 重复第4步直到达到第2步设定的subword词表大小或下一个最高频的字节对出现频率为1

举个栗子,我们输入,

{'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w e s t </w>': 6, 'w i d e s t </w>': 3}

第一轮迭代,统计连续的每两个字节出现的次数,发现 es 共现次数最大,合并成es,有,

{'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w es t </w>': 6, 'w i d es t </w>': 3}

第二轮迭代,统计连续的每两个字节出现的次数,发现 est 共现次数最大,合并成est,有,

{'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w est </w>': 6, 'w i d est </w>': 3}

依次继续迭代直到达到预设的subword词表大小或下一个最高频的字节对出现频率为1。

以上是BPE的整体流程,关于BPE更多细节可以参考:Byte Pair Encoding[3]

Unigram LM

Unigram语言建模首先在Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates[4]中提出,基于所有子词出现是独立的假设,因此子词序列由子词出现概率的乘积生成。算法步骤如下:

  1. 准备足够大的语料库

  2. 定义好所需要的词表大小

  3. 给定词序列优化下一个词出现的概率

  4. 计算每个subword的损失

  5. 基于损失对subword排序并保留前X%。为了避免OOV,保留字符级的单元

  6. 重复第3至第5步直到达到第2步设定的subword词表大小或第5步的结果不再变化

unigram-LM模型比BPE更灵活,因为它基于概率LM,并且可以输出具有概率的多个分段。它不是从一组基本符号开始,更具某些规则进行合并,如BPE或WordPiece,而是从一个庞大的词汇量开始,例如所有预处理的单词和最常见的子字符串,并逐步减少。

WordPiece

WordPiece首先在 JAPANESE AND KOREAN VOICE SEARCH[5] 中提出,最初用于解决日语和韩语语音问题。它在许多方面类似于BPE,只是它基于可能性而不是下一个最高频率对来形成一个新的子词。算法步骤如下:

  1. 准备足够大的语料库

  2. 定义好所需要的词表大小

  3. 将单词拆分成字符序列

  4. 基于第3步数据训练语言模型

  5. 从所有可能的subword单元中选择加入语言模型后能最大程度地增加训练数据概率的单元作为新的单元

  6. 重复第5步直到达到第2步设定的subword词表大小或概率增量低于某一阈值

WordPiece更像是BPE和Unigram LM的结合。

小结

简单几句话总结下Subword的三种算法:

  • BPE:只需在每次迭代中使用「出现频率」来确定最佳匹配,直到达到预定义的词汇表大小;

  • Unigram:使用概率模型训练LM,移除提高整体可能性最小的token;然后迭代进行,直到达到预定义的词汇表大小;

  • WordPiece:结合BPE与Unigram,使用「出现频率」来确定潜在匹配,但根据合并token的概率做出最终决定.

Sentencepiece

到目前为止,可以发现subword结合了词粒度和字粒度方法的优点,并避免了其不足。但是,仔细想会发现上述三种subword算法都存在一些问题:

  • 「都需要提前切分(pretokenization)」 :这对于某些语言来说,可能是不合理的,因为不可以用空格来分隔单词;

  • 「无法逆转」:原始输入和切分后序列是不可逆的。举个栗子,下面两者的结果是相等的,即空格的信息经过该操作被丢失

    Tokenize(“World.”) == Tokenize(“World .”)

  • 「不是End-to-End」:使用起来并没有那么方便

ok,here comes SentencePiece!来看看是怎么解决上述问题的

  • SentencePiece首先将所有输入转换为unicode字符。这意味着它不必担心不同的语言、字符或符号,可以以相同的方式处理所有输入;

  • 空白也被当作普通符号来处理。Sentencepiece显式地将空白作为基本标记来处理,用一个元符号 “▁”( U+2581 )转义空白,这样就可以实现简单地decoding

  • Sentencepiece可以直接从raw text进行训练,并且官方称非常快!

快结束了,我想说一下,这真的不是Sentencepiece的软文(谷歌,打钱!)

SentencePiece集成了两种subword算法,BPE和UniLM, WordPiece 则是谷歌内部的子词包,没对外公开。感兴趣的可以去官方开源代码库玩玩:google/sentencepiece[6]

放个栗子:

>>> import sentencepiece as spm
>>> s = spm.SentencePieceProcessor(model_file='spm.model')
>>> for n in range(5):
...     s.encode('New York', out_type=str, enable_sampling=True, alpha=0.1, nbest=-1)
...
['▁', 'N', 'e', 'w', '▁York']
['▁', 'New', '▁York']
['▁', 'New', '▁Y', 'o', 'r', 'k']
['▁', 'New', '▁York']
['▁', 'New', '▁York']

最后,如果想尝试WordPiece,大家也可以试试HuggingFace的Tokenization库[7]

from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.pre_tokenizers import Whitespace
from tokenizers.trainers import BpeTrainertokenizer = Tokenizer(BPE())
tokenizer.pre_tokenizer = Whitespace()trainer = BpeTrainer(special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"])
tokenizer.train(trainer, ["wiki.train.raw", "wiki.valid.raw", "wiki.test.raw"])output = tokenizer.encode("Hello, y'all! How are you ???? ?")
print(output.tokens)
# ["Hello", ",", "y", "'", "all", "!", "How", "are", "you", "[UNK]", "?"]

本文参考资料

[1]

2015年Karpathy: https://github.com/karpathy/char-rnn

[2]

Neural Machine Translation of Rare Words with Subword Units: https://arxiv.org/abs/1508.07909

[3]

Byte Pair Encoding: https://leimao.github.io/blog/Byte-Pair-Encoding/

[4]

Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates: https://arxiv.org/abs/1804.10959

[5]

JAPANESE AND KOREAN VOICE SEARCH: https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf

[6]

google/sentencepiece: https://github.com/google/sentencepiece

[7]

HuggingFace的Tokenization库: https://github.com/huggingface/tokenizers

END -


往期精彩回顾适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑
AI基础下载机器学习的数学基础专辑
获取本站知识星球优惠券,复制链接直接打开:
https://t.zsxq.com/qFiUFMV
本站qq群704220115。加入微信群请扫码:

【NLP】机器如何认识文本 ?NLP中的Tokenization方法总结相关推荐

  1. window统计文本字节_【NLP】机器如何认识文本 ?NLP中的Tokenization方法总结

    Tokenization 关于Tokenization,网上有翻译成"分词"的,但是我觉得不是很准确,容易引起误导.一直找不到合适的中文来恰当表达,所以下文采用原汁原味的英文表达. ...

  2. Princeton NLP Group姚顺雨博士:文本游戏中基于语言模型的动作生成

    ⬆⬆⬆              点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! "你在卧室,东边是一个走廊,西边有一个紧闭的木门,屋子中间有一个厚地毯,一个储物柜,你有一个 ...

  3. 【NLP理论】——文本在计算机中的表示方法总结

    文章目录 1. 概述 2. 离散式表示(Discrete Representation) 2.1 One-Hot Demo 缺点 2.2 词袋模型(Bag Of Word,BOW) Demo 缺点 2 ...

  4. 【NLP】如何在文本分类任务中Fine-Tune BERT

    问 题 BERT在许多自然语言理解(NLU)任务中取得了惊人的成果,但它的潜力还有待充分挖掘.目前很少有如何能进一步提高BERT性能的研究,因此,如何通过一些技巧和方法最大限度的提升BERT在文本分类 ...

  5. NLP文本提取中打标签列表和方案

    标签列表如下: B,即Begin,表示开始 I,即Intermediate,表示中间 E,即End,表示结尾 S,即Single,表示单个字符 O,即Other,表示其他,用于标记无关字符 常用的较为 ...

  6. 自然语言处理(NLP)技术在医疗保健领域中的八个案例

    译者 | 东哥 审校 | 梁策 孙淑娟 在医疗保健领域,数据并不只是来自患者健康记录.医嘱条目和医生处方.事实上,目前已有数百万人通过家用工具包将他们的基因信息上传到商业数据库. 可穿戴技术也为消费者 ...

  7. NLP机器阅读理解:四大任务及相应数据集、比赛

    作者 | 周俊贤 整理 | NewBeeNLP 关于机器阅历理解应用,首先介绍大家一个真实的业务场景,从网购平台的退单工单中抽取实际退款金额,数据大概是这样: 你好,我3月份在网上买的洗衣服务,当时买 ...

  8. NLP判断语言情绪_机器学习中的NLP简介

    在1970年代,许多程序员开始编写"概念本体",将现实世界的信息结构化为计算机可理解的数据.例子有MARGIE(Schank,1975),SAM(Cullingford,1978) ...

  9. nlp文本数据增强_如何使用Texthero为您的NLP项目准备基于文本的数据集

    nlp文本数据增强 Natural Language Processing (NLP) is one of the most important fields of study and researc ...

最新文章

  1. 如何查看ubuntu的版本信息和查看几位 32 or 64位
  2. NanoHttpd源码分析
  3. 【杂谈】超过12个,150页深度学习开源框架指导手册与GitHub项目,初学CV你值得拥有...
  4. C++SEG TREE线段树的实现算法(附完整源码)
  5. CodeForces - 1407E Egor in the Republic of Dagestan(最短路+dp)
  6. 海思Hi3516A(5)3D降噪
  7. 递归学习 斐波那契 java代码实现
  8. js根据name获取value_js 函数的重载
  9. mysql保存表出错1075_navicat出现错误1075怎么办
  10. 百度前端技术学院-task1.8源代码以及个人总结
  11. Packet Voice Modeling 语音包模型
  12. 20211104 为什么相似矩阵的迹相同
  13. zoj_2481 Unique Ascending Array
  14. 如何进行“基于示例”的搜索
  15. mysql 统计当个用户从当前时间连续登录天数,以及多用户某时间段,最长连续登录天数查询
  16. 女生做软件测试的利弊如何权衡?
  17. Qt扫盲-QSystemTrayIcon理论总结
  18. 如何使用CorelDRAW 2019快速制作幻影图像效果
  19. Android自定义导览地图组件(一)
  20. 稀土掘金 2022 开发者大会观后总结

热门文章

  1. silverlight bing maps sdk MapControl Sdk
  2. 【ASP】Menu菜单导航
  3. 设计模式笔记15:代理模式(Proxy Pattern)
  4. MS SQL数据库日志压缩方法[转]
  5. 写一个ajax程序就是如此简单
  6. python小白——进阶之路——day6天---字符串相关相关函数,格式化(format)
  7. SpringMVC源码阅读系列汇总
  8. 24-单调递增最长子序列(多种解法总结)
  9. 第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页...
  10. object-c 1