Tokenizer与分词

1. 分词和Tokenizer的核心概念

1.1 分词的定义

分词(Word Segmentation) window是NLP的基础任务,目的是将连续的文本(句子或段落)分割成有意义的语言单位(通常是单词、词语、子词或字符)。这些单位是后续NLP任务(如词性标注、句法分析、机器翻译、情感分析等)的基础。

英文分词:英文通常以空格和标点为分隔符,分词相对简单。例如:

输入:“I love to eat apples.”
输出:[“I”, “love”, “to”, “eat”, “apples”]

中文分词:中文没有明确的词语边界,分词需要依赖词典、上下文或模型。例如:

输入:“我爱吃苹果”
输出:[“我”, “爱”, “吃”, “苹果”]

1.2 Tokenizer的定义

Tokenizer(分词器)是一个工具、算法或模块,用于将原始文本分解为一系列“标记”(Tokens)。Tokens可以是:

单词(Word-level):如“I”, “love”。
子词(Subword-level):如“playing” → [“play”, “##ing”]。
字符(Character-level):如“我” → [“我”]。
字节(Byte-level):如Unicode字符的字节表示。

Tokenizer不仅限于分词,还可能包括:

去除标点或特殊字符。
转换为小写(英文)。
添加特殊标记(如[CLS]、[SEP],用于BERT)。
将Tokens映射为ID(用于模型输入)。

1.3 分词和Tokenizer的重要性

结构化文本:将无结构的文本转化为离散的、计算机可处理的单位。
语义保持:确保分割后的单位具有语义(如“苹果”作为一个词,而不是“苹”和“果”)。
模型输入:深度学习模型(如Transformer)需要将文本转化为数值化输入,分词是第一步。
跨语言适配:处理不同语言的分词规则(如英文的空格分隔、中文的连续性)。

1.4 分词 vs Tokenizer

分词:一个任务,目标是分割文本为语义单位。
Tokenizer:实现分词任务的工具,可能包括额外的预处理步骤(如归一化、映射ID)。


2. 分词的挑战与语言特性

分词看似简单,但实际上面临诸多挑战,尤其是在不同语言、复杂场景和特定领域中。

2.1 语言差异

英文

通常以空格和标点分隔,分词较简单。
挑战:缩写(如“don’t”)、连字符(如“well-known”)、专有名词(如“New York”)。

中文

无明确词界,需依赖词典或模型判断。
例子:“南京市长江大桥”可能分为:

正确:[“南京市”, “长江大桥”]
错误:[“南京”, “市长”, “江大桥”]

日韩语

类似中文,无明确词界,且有复杂的形态学(如日语的假名和汉字混合)。

泰语、越南语

泰语无空格,越南语虽有空格但词界复杂。

多语言混合

社交媒体文本(如“今天天气很好,btw I’m coding”)包含多语言、表情符号、缩写等。

2.2 歧义问题

分词结果因上下文而异:

中文

“研究生物”:

[“研究生”, “物”](研究生和物体)
[“研究”, “生物”](研究生物学)

“他说的确实在理”:

[“他”, “说”, “的”, “确实”, “在理”]
[“他”, “说”, “的”, “确”, “实在”, “理”]

英文

“New York”应作为一个Token,而不是[“New”, “York”]。
“bank”可能是“银行”或“河岸”,需上下文消歧。

2.3 未登录词(OOV, Out-Of-Vocabulary)

定义:不在词典中的新词或专有名词(如“区块链”“自拍杆”)。
挑战:传统词典方法无法处理OOV。
解决方案

子词分词(如BPE)。
字符级分词。
动态词典更新。

2.4 粒度选择

分词的粒度影响模型性能:

单词级

优点:语义明确。
缺点:词汇表大,OOV问题严重。

子词级

优点:平衡语义和泛化能力,适合多语言和OOV。
缺点:可能丢失部分语义。

字符级

优点:词汇表最小,泛化能力强。
缺点:序列长,语义信息少。

字节级

优点:支持任何语言,无需预处理。
缺点:计算成本高。

2.5 领域特定性

医疗:如“心肌梗死”需作为一个整体。
法律:如“有限责任公司”需保持完整。
技术:如“Transformer模型”需正确分割。

2.6 文化与地域差异

分词规则可能因文化或地域而异:

中文:大陆和台湾的词典差异(如“软件” vs “软体”)。
英文:美式和英式拼写(如“color” vs “colour”)。


3. 分词和Tokenizer的方法

分词方法从传统到现代,经历了规则、统计、深度学习和子词分词的演变。

3.1 基于规则的分词

原理:使用预定义规则(如空格、标点)或词典匹配。
方法

最大匹配法

正向最大匹配(FMM):从左到右匹配词典中最长词。

例子:文本“南京市长江大桥”,词典[“南京”, “南京市”, “长江”, “大桥”]。
过程:

“南京市”匹配 → 输出“南京市”。
“长江”匹配 → 输出“长江”。
“大桥”匹配 → 输出“大桥”。

结果:[“南京市”, “长江”, “大桥”]

逆向最大匹配(BMM):从右到左匹配。

最短路径分词:选择词数最少的分割。

优点:简单、快速。
缺点:无法处理歧义和OOV,词典维护成本高。
适用:英文简单分词,中文初级分词。

3.2 基于统计的分词

原理:利用统计模型根据语料库中的词频和上下文概率分词。
常用模型

隐马尔可夫模型(HMM)

将分词建模为序列标注问题,字符标记为:

B(词的开头)
M(词的中间)
E(词的结尾)
S(单个字符词)

例子:“我爱吃” → 标注为 [S, S, S] → [“我”, “爱”, “吃”]。

条件随机场(CRF)

结合上下文特征(如前后字符、词性)优化分词。
例子:输入“我爱吃苹果”,CRF可根据上下文概率选择最佳分割。

优点:能处理歧义,适应性强。
缺点:依赖标注数据,训练成本高。
工具:Jieba(结合词典和HMM)。

3.3 基于深度学习的Tokenizer

原理:使用神经网络(如LSTM、Transformer)学习分词或生成Tokens。
方法

序列标注

输入:字符序列。
输出:B、M、E、S标签。
模型:BiLSTM+CRF、Transformer。

预训练模型

如BERT的WordPiece,结合子词分词和语言模型。
例子:“playing” → [“play”, “##ing”]。

端到端分词

直接从字符序列生成Tokens,无需显式标注。

优点:泛化能力强,处理OOV和复杂场景。
缺点:需大量数据和计算资源。
例子:BERT、RoBERTa的Tokenizer。

3.4 子词分词(Subword Tokenization)

子词分词是现代NLP的主流,兼顾单词和字符的优点。

Byte Pair Encoding (BPE)

原理

初始化:将文本拆为字符,统计字符对频率。
合并:迭代合并频率最高的字符对,生成子词。
停止:达到预设词汇表大小。

例子

输入:[“play”, “player”, “playing”]。
初始:[“p”, “l”, “a”, “y”, …]。
合并:[“pl”, “ay”, …] → [“play”, “##er”, “##ing”]。

应用:GPT、T5。

WordPiece

原理:类似BPE,但基于最大化语言模型概率选择合并。
例子:与BPE类似,但更注重语义。
应用:BERT。

SentencePiece

原理:将文本视为Unicode字符序列,无需预分词,直接生成子词。
特点:支持多语言,适合低资源语言。
应用:T5、XLNet。

Unigram Language Model

原理:基于语言模型概率选择子词,允许多种分割路径。
应用:SentencePiece的可选模式。

优点:词汇表可控,处理OOV能力强,适合多语言。
缺点:可能丢失语义,需上下文建模。

3.5 字符级和字节级分词

字符级

输入:分解为字符(如“我爱吃” → [“我”, “爱”, “吃”])。
优点:词汇表最小,泛化能力强。
缺点:序列长,语义信息少。

字节级

输入:分解为Unicode字节。
优点:支持任何语言,无需语言特定预处理。
缺点:序列更长,计算成本高。
应用:LLaMA、Grok。


4. 主流Tokenizer工具与实现

以下是常用的分词和Tokenizer工具,适合学习和实践:

4.1 Jieba(中文分词)

特点:开源Python库,支持词典、HMM和CRF。
模式

精确模式:适合文本分析。
全模式:列出所有可能分词。
搜索引擎模式:细粒度分词。

用法

import jieba
text = "我爱吃苹果"
tokens = jieba.cut(text)  # 精确模式
print(list(tokens))  # ['我', '爱', '吃', '苹果']

优点:易用,支持自定义词典。
适用:中文NLP。

4.2 NLTK / SpaCy(英文分词)

NLTK

特点:Python的NLP库,提供简单分词。
用法:

from nltk.tokenize import word_tokenize
text = "I love to eat apples"
tokens = word_tokenize(text)
print(tokens)  # ['I', 'love', 'to', 'eat', 'apples']

SpaCy

特点:支持多语言分词、词性标注等。
用法:

import spacy
nlp = spacy.load("en_core_web_sm")
text = "I love to eat apples"
doc = nlp(text)
tokens = [token.text for token in doc]
print(tokens)  # ['I', 'love', 'to', 'eat', 'apples']

适用:英文及其他空格分隔语言。

4.3 Hugging Face Tokenizers

特点:支持BPE、WordPiece、SentencePiece,集成于Transformers库。
用法

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
text = "I love to eat apples"
tokens = tokenizer.tokenize(text)
print(tokens)  # ['i', 'love', 'to', 'eat', 'apples']
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)  # [101, 1045, 2293, 2000, 4521, 18108, 102]

优点:支持预训练模型,适合深度学习。
适用:多语言、深度学习。

4.4 SentencePiece

特点:Google开源,支持多语言子词分词。
用法

import sentencepiece as spm
sp = spm.SentencePieceProcessor(model_file='spm.model')
text = "I love to eat apples"
tokens = sp.encode_as_pieces(text)
print(tokens)  # 取决于模型

适用:跨语言、大规模NLP。

4.5 Stanford CoreNLP

特点:Java库,支持中文、英文等多语言分词。
适用:学术研究,中文分词。


5. 分词和Tokenizer在NLP任务中的应用

分词是NLP流水线的起点,影响几乎所有任务:

5.1 词嵌入(Word Embedding)

Tokens被映射为向量:

静态嵌入:Word2Vec、GloVe。
上下文嵌入:BERT、RoBERTa。

子词分词(如WordPiece)解决OOV问题。

5.2 机器翻译

分词影响源语言和目标语言的对齐。
例子:中文“苹果”需 需正确分为一个词,确保翻译为“apple”。

5.3 情感分析

分词影响关键词提取。
例子:“不高兴”需分为一个词,而不是“不”和“高兴”。

5.4 信息检索

搜索引擎依赖分词构建索引。
例子:Google的Tokenizer处理多语言查询。

5.5 语音处理

分词用于语音转文本(ASR)或文本转语音(TTS)的对齐。

5.6 命名实体识别(NER)

分词影响实体边界的识别。
例子:“南京市”需作为一个实体。


6. 评估分词质量

6.1 评估指标

精确率(Precision):正确分词的Tokens占输出Tokens的比例。
召回率(Recall):正确分词的Tokens占金标准Tokens的比例。
F1分数:Precision和Recall的调和平均数。
错误类型

分割错误:如“南京市”分为“南京”和“市”。
合并错误:如“长江大桥”分为一个词。

6.2 金标准

人工标注的分词数据集(如SIGHAN Bakeoff)。
挑战:不同标注者可能有不同标准。

6.3 自动评估

比较不同分词器在下游任务(如分类、翻译)中的性能。
例子:BERT的Tokenizer对分类任务的F1分数影响。


7. 数据集与语料库

7.1 中文数据集

SIGHAN Bakeoff

包含PKU、MSR、AS等数据集。
用途:中文分词评测。

CTB(Chinese Treebank)

包含分词和句法标注。

Weibo语料

社交媒体文本,包含新词和非标准表达。

7.2 英文数据集

Penn Treebank

包含分词、词性标注等。

Brown Corpus

多领域英文文本。

7.3 多语言数据集

Universal Dependencies (UD)

多语言的分词和句法标注。

CONLL Shared Tasks

包含多语言NER和分词任务。


8. 进阶话题与发散思考

8.1 多语言和低资源语言

挑战:低资源语言(如藏语、豪萨语)缺乏语料和词典。
解决方案

SentencePiece或字节级分词。
无监督分词(如统计字符共现)。
跨语言迁移学习。

研究方向:通用多语言Tokenizer。

8.2 领域特定分词

医疗:如“急性心肌梗死”需作为一个词。
法律:如“有限责任公司”。
方法

领域词典。
预训练模型微调。

研究方向:自动化领域术语提取。

8.3 分词与大模型

大模型(如GPT、LLaMA)使用BPE或SentencePiece。
思考

分词粒度如何影响模型性能?
字节级分词是否是未来趋势?

研究方向:优化Tokenizer以减少计算成本。

8.4 端到端分词

趋势:Transformer直接处理字符序列,隐式学习分词。
例子:ByT5、CANINE模型。
思考:显式分词会被取代吗?

8.5 分词与文化

分词规则反映文化习惯:

中文:大陆“软件” vs 台湾“软体”。
英文:美式“organize” vs 英式“organise”.

研究方向:分词中的文化偏见。

8.6 分词与可解释性

子词分词(如“playing” → [“play”, “##ing”])可能降低语义可解释性。
研究方向:可视化Tokenizer输出以提高可解释性。

8.7 分词与隐私

分词可能泄露敏感信息(如专有名词)。
研究方向:隐私保护的分词方法。


9. 学习建议与实践

9.1 理论学习

书籍

《Speech and Language Processing》(Jurafsky & Martin)。
《Natural Language Processing with Python》(NLTK书)。
《Deep Learning for Natural Language Processing》(Palash Goyal)。

论文

“Neural Word Segmentation for Chinese” (2018).
“Subword Regularization” (2018).
“BPE: A Simple Algorithm for Word Segmentation” (2016).

课程

Stanford CS224N: Natural Language Processing with Deep Learning.
Coursera: NLP Specialization.

9.2 实践项目

基础

实现FMM分词算法(Python)。
使用Jieba分词中文文本。
使用NLTK分词英文文本。

进阶

训练SentencePiece模型,比较BPE和Unigram。
微调BERT的Tokenizer在医疗领域。
评估不同Tokenizer对分类任务的影响。

数据集

SIGHAN Bakeoff(中文)。
Penn Treebank(英文)。
Universal Dependencies(多语言)。

9.3 工具与框架

Jieba:中文分词。
Hugging Face Tokenizers:子词分词。
SpaCy:多语言NLP。
SentencePiece:跨语言分词。
Stanford CoreNLP:学术研究。

9.4 研究方向

开发无监督分词算法。
优化子词分词的词汇表大小。
探索多语言Tokenizer的迁移学习。


10. 总结

分词和Tokenizer是NLP的基石,涵盖从规则匹配到神经网络的多种方法。它们不仅是技术问题,还涉及语言特性、计算效率和文化差异。核心要点:

分词将文本分解为语义单位,Tokenizer是实现工具。
方法包括规则、统计、深度学习和子词分词。
挑战包括歧义、OOV、粒度和语言差异。
应用覆盖词嵌入、翻译、情感分析等。
未来方向包括多语言支持、端到端分词和隐私保护。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容