自然语言处理中的分词问题总结

编程/开发
361
0
0
2023-06-29

众所周知,英文是以词为单位的,词和词之间是靠空格隔开,而中文是以字为单位,句子中所有的字连起来才能描述一个意思。把中文的汉字序列切分成有意义的词,就是中文分词,有些人也称为切词。本文转载自明略研究院的技术经理牟小峰老师讲授的语言处理中的分词问题。

如何界定分词

中文分词指的是将一个汉字序列切分成一个一个单独的词。分词就是将连续的字序列按照一定的规范重新组合成词序列的过程;在英文中,单词之间是以空格作为自然分界符,汉语中词没有一个形式上的分界符。(见百度百科) 正因为缺乏形式上的分界符,导致我们对词的认定会出现很大的偏差。1996 年 Sproat 等通过对 6 个母语为汉语的人进行调研,让这 6 人对同一篇中文文本进行人工切分,文本包括 100 个句子,最后统计认同率,见下表:

不仅普通人有词语认识上的偏差,即使是语言专家,在这个问题上依然有不小的差异,这种差异反映在分词 语料库 上。不同语料库的数据无法直接拿过来混合训练。

以前曾经出过分词规范 (GB13715),以“结合紧密,使用稳定”作为分词建议,后来发现这个建议弹性太大,不同的人有不同的理解,无法有效实施。

为了统一对词语的认识,现在主要通过“分词规范、词表、分词语料库”来使得词语切分可计算,例如北大的“词语切分与词性标注”规范。基于上述种种工作,可以把词语切分问题变得可操作和标准化,大家在统一的平台上进行实验和比较。

对分词的诉求是什么?

从已有工程经验来看,几乎不存在通用而且效果非常好的分词系统,例如:在人民日报上训练的分词系统,在二次元的魔幻小说上切分效果不佳。每个领域有其独特的词汇表示,这很难通过有限的训练数据捕捉到所有语言现象。

不用使用场景对分词的要求差异很大。在搜索的索引阶段,往往会召回所有可能切分结果,对切分准确率要求不高,但对分词速度有很高的要求,例如某中型搜索系统,每天 4000 万篇文章入库,每秒要处理 500 篇文档,每秒处理的文档字节数约有 50MB;如果分词系统太慢的话,需要开大量线程才能处理这些文档。

在问答系统中,需要对文本实现较为深入的理解,对分词和实体识别的准确性要求很高。

不用的使用场景,对分词提出了不同的要求,不需要片面地追求高准确率。

别家系统的准确率怎么这么高?

在分词系统研发中,最容易产生误解的就是比较系统准确率。系统准确率与训练数据非常相关,脱离数据而谈论准确率无异于“刷流氓”。2003 年 863 分词评测中就出现了 98% 的准确率,2007 年 Sighan 评测中最高准确率是 97%,在最近某司组织的评测中,最高准确率下降到了 94%。所有不同数据下的评测结果都不能直接比较高低。

现在吹嘘分词准确率的公司和单位越来越少了。

分词稳定性很重要

分词稳定性是指分词系统的输出在不同上下文下都比较稳定,不会出现明显被上下文影响的情况。例如,在下面句子中,“黄代恒”有时识别为人名,第二次出现未识别出来:

实战 分享 三 黄代恒 /nr 与 轨道 交通 : 软硬 结合 到 人机 结合 黄代恒 “ 在 不同 的 客户 场景 下 , 我们 用 三 种 技术 实现 轨道 交通 的 数据 洞察

一般纯统计分词系统的稳定性比不上基于词典实现的分词系统。在搜索中,分词稳定性非常重要,否则极容易出现查询不到的情况。

已有分词系统小结

分词大概是投入人力非常大的 NLP 方向,几乎每一家“有追求”的公司都有员工实施过类似的任务,而且反复迭代更新;在 NLP 研究界,这个问题从上个世纪 80 年代就已经开始探索,一直到 ACL 2017 仍然有这方面的论文 (有 4 篇丛神经网络角度探索分词的文章)。

如此多的人力投入到分词理论研发和工程研发中,产生了一批各有特色的分词系统。下面仅仅就本人接触到的系统作说明 (排名无先后),比较“古老”的系统不在此罗列:

IK 系统

该系统采用 JAVA 开发,实现逻辑不复杂,由于对 Lucene 和 ES 支持较好,因而得到了比较普遍的使用。该系统可以实现英文单词、中文单词的切分,OOV 识别能力不强。该系统有几种使用模式,分别对应不同的使用场景,如索引、查询等。

IK 有些功能比较贴心,比如热更新用户词典,支持用户自定义词典非常方面,对搜索工程师比较友好。

IK 的代码实现上优化不够好,甚至能发现 BUG。我们发现的 BUG 会导致 ES 中长 Query 无法实现精准匹配。

对于中小企业的内部应用来说,使用 IK 足够了。在商业系统上使用的话,要非常慎重,参与优化的人员太少了。

Jieba 系统

Jieba 大概是最好用的基于 Python 实现的分词系统了,2-3 行代码就可以实现分词调用和词性标注,速度还不错。基于 HMM 模型实现,可以实现一定程度的未登录词识别。

Jieba 有精确模式、全模式、搜索模式三种。全模式是找到所有可能词语;搜索模式是在精确模式的基础上对长词进行切分,提高召回率。

支持繁体分词;支持自定义词典;支持并行分词,方便实现加速。

在分词速度上,精确模式能达到 400KB/ 秒,全模式下能达到 1.5MB/ 秒。

Jieba 除了 Python 版本外,还有多种语言实现的版本,包括 C++, JAVA, Golang 等。

Java 版本的 Jieba 功能上受限,仅面向搜索使用。明略 SCOPA 产品中使用了 Java 版本的 Jieba 作为分词组件,替换了 IK。

Hanlp 平台

Hanlp 是一个功能非常全面的 NLP 平台,它的分词接口借鉴了 Ansj 的设计,形式上和命名上都非常像。

Hanlp 有“简约版”和“加强版”,简约版的模型参数较小,分词能力还可以;加强版在模型参数上扩大了若干倍,分词能力进一步提升。

Hanlp 支持基于 HMM 模型的分词、支持索引分词、繁体分词、简单匹配分词(极速模式)、基于 CRF 模型的分词、N- 最短路径分词等。实现了不少经典分词方法。

Hanlp 的部分模块做了重要优化,比如双数组,匹配速度很快,可以直接拿过来使用。

Hanlp 做了不少重现经典算法的工作,可以去GitHub上看一下!

ICTCLAS 系统

ICTCLAS 大概是“最知名”的分词系统了,从参加 2003 年中文分词评测,一直延续到了现在。现在已经是商业系统了 (改名 NLPIR),需要 License 才能运行。

从未登录词识别准确率上说,ICTCLAS 已经明显落后于基于 CRF 的分词系统了。

尽管如此,它的优点仍然比较明显:很少出现“错得离谱”的切分结果,这在基于 CRF 模型的分词系统上不少见,尤其是迁移到其它领域时;模型和库不大,启动快;基于 C++ 实现,能够很快迁移到其它语言。

从分词稳定性上来说,ICTCLAS 值得信赖,从分词准确率、分词速度等方面来考量,有不少分词系统超过了它;NLPIR 的源代码已经不再开放,这让用户很纠结。

交大分词

所谓“交大分词”,是指上交大赵海老师个人主页上的分词系统。该系统在 2007 年 Sighan 评测中拿到了多项第一。

该系统基于 CRF 模型构建,在模型特征提取上做了大量工作,分词准确率比较高。目前可用版本支持简体、繁体分词,也支持不同分词标准。该系统被常常用来比较分词准确率。

该系统的问题是不开源,只有 Windows 上的可执行文件,C++ 源码需要向作者申请。虽然该系统不开源,但作者的一系列论文基本上揭示了其原理,复制起来并不难。

从工程角度来考虑,该系统只适合做 DEMO 组件,不适合大规模工业化使用。

Stanford 分词

Stanford 分词系统的优点是准确率高,未登录词识别能力比较强;缺点非常明显,模型很大,约 300MB-400MB,启动非常慢,大概需要 10 秒 -20 秒。在所有分词系统中,没有比 Stanford 启动更慢的系统,分词速度也不快。代码优化的空间比较大。

Stanford 系统支持自定义训练,只要用户提供训练数据,该系统可以训练新的模型参数。

Stanford 分词系统只是验证作者论文的一种手段,为了非常微小的分词准确率提升,导致了模型参数膨胀。

在 Demo 环境下可以使用 Stanford 系统,在大规模数据环境下不适合使用该系统。

GPWS 系统

GPWS 是北京语言大学语言信息处理研究所研发的分词系统,2001 年对外发布。该分词系统是 2000 年后唯一一个基于大规模规则 + 统计的分词系统(仅限个人所知),在 2004 年非常低的硬件配置下,分词速度也能达到 3MB-5MB/ 秒,对系统资源的消耗很低。后来授权给了新浪、 微软 等公司使用,被应用在了信息检索中。

GPWS 可以实现中文人名、外国人名、日本人名的识别,其它分词系统几乎都没有做到这个程度;对通用领域的文本切分效果较好,支持自定义词典;很少出现切分“离谱”的情况。该系统适合大规模数据处理的场景。

上述所有系统几乎都依赖于训练数据,而 GPWS 没有这方面的问题。GPWS 依赖于高质量分词词典和歧义切分机制,采用基于可信度的人名识别方法,不依赖于公开的训练数据。

GPWS 最大的问题在于很难复制,代码没有公开;在分词准确率上,GPWS 已经比不上字本位的分词系统;但从分词稳定性上,GPWS 仍然非常出色,比纯统计分词系统明显要好。

分词的难点在哪里?

歧义

歧义问题与词长非常相关,词语越短,发生歧义的可能性越大,词语越长,发生歧义的可能性越低,很少出现成语与其他词发生歧义的情况。歧义问题在分词中不是罪严重的问题,仅占分词错误数的 10% 左右。歧义分类包括:

交集型歧义

abc -> 可以切分为 ab c 和 a bc,占所有歧义总量的 95%,也就是说歧义问题主要是指交集型歧义

例如:

研究生命的起源 | 研究生 命 的起源

这种环境下 工作 | 这种环境 下工 作

化妆 和 服装 | 化妆 和服 装

这群 山里的娃娃 |这 群山 里的娃娃

进书店 跟 进超市一样 | 进书店 跟进 超市一样

组合型歧义

abc ->可以切分为 abc 和 a bc 或 abc。

组合型歧义一般要通过前后邻接搭配的可能性大小来判断。

他从 马上 下来 | 他从 马 上 下来

这个门 把手 坏了 | 这个门 把 手 坏了

基于马尔科夫模型计算邻接搭配可以消除绝大部分歧义。

通过计算词语搭配的概率估计句子的概率,选择概率最大的结果即可。

分词错误的主要来源

未登录词 – 不在词典中的词,该问题在文本中出现频度远远高于歧义。

未登录词的类型包括:人名、地名、机构名、公司名、数字、日期、专业术语、新词、产品名等。一般把人名、地名、机构名、公司名叫命名实体,例如:

卢靖姗一夜爆红 (人名)

在东四十条站台见面 (地点)

银联的小兄弟网联成立了 (机构名)

公元 2017 年 8 月 24 日发生一件大事(日期)

中国外汇储备达到三点 94 万亿美元(数字)

在明略软件做大数据处理 (公司名)

基于暗网数据买牛股 (专业术语)

招行发布了朝朝盈一号的理财产品(产品名)

让你见识什么叫冻龄 (新词)

不同类型的命名实体还可以细分,比如人名可以分为中文人名、藏族人名、维族人名、日本人名、欧美人名等。

地名可以分为典型地名和非典型地名,典型地名如国、省、市、县、乡、村等;非典型地名还包括路、居委会、大厦商场、门牌单元、图书馆、门面等。理论上,只要是有经纬度坐标的实体,都可以纳入地名识别范畴。在实际工作中,这方面的识别需求非常强烈,比如在公安领域的线索或案情信息,往往涉及到这种非典型地名。

机构和公司的类型也多种多样,除了行政机构外,还有各种社团、NGO 组织、基金会、校友会等等;公司名涉及到公司全称和公司简称的识别,例如:

明略软件系统科技有限公司(全称)

明略软件(简称)

明略数据(简称)

全称识别相对容易一点,简称识别非常困难,比如:小米、滴滴、凡客、OFO 等。

机构公司名与地名之间存在很大的交集。理论上,一个机构或公司往往会有办公地点,有时也会用机构公司名来称呼该地点,这样的话机构公司名也就有了地点属性。例如:

小明在明略软件上班(公司名)

把球踢进了明略软件的门前(看做公司名还是地点?)

在实际工作中,命名实体的关注程度最高,因为这些实体往往是知识图谱的节点。其它未登录词中,专业术语的提取会对文本分类和文本理解有重要帮助。

分词中的语料问题

基于统计模型的分词系统,在分词结果上出现差异的一个原因是对语料的预处理差异导致。相当多的分词系统没有对训练数据进行一致性校验,认为训练数据是无差错的。在实际调查时发现,训练数据包含了不少标注不一致的情况。例如人民日报中的例子:

自认倒霉 | 自 认 倒霉

倒霉 鬼 | 倒霉鬼

除了切分一致性外,词性标注的不一致性更严重一些,如:“自认倒霉”有时标注为 l、有时标注为 lv;“难能可贵”有时标注为 i、有时标注为 iv。

分词语料的选择范围有限,主要包括北大人民日报标注语料、微软标注语料、社科院标注语料、CTB 语料、OntoNotes 语料、城市大学繁体语料、中研院繁体语料等。一般选择一种数据即可,数据需要购买。

分词语料之间在词语颗粒度上有一定差异,一般不混用进行训练,例如:

承租人、承租者 (北大) | 承租 商 (微软)

高 清晰度 彩电 (北大) | 高清晰度电视 (微软)

分词的理论解决方案

分词的理论解决方案是采用统计模型,基于切分语料进行训练。该方案在学术界和工程界都很常见,也是学术界的研究热点。方案的差异主要是模型和特征工程不一样。模型差异非常常见,比如隐马尔科夫模型、最大熵模型、条件随机场模型、结构感知机模型、RNN 模型 等。

特征提取

特征提取的第一步是选择单元:基于字还是基于词。从实践来看,基于字的模型对未登录词识别能力较强,但基于词的模型很少会出现切分“离谱”的情况。采用什么颗粒度单元,取决于具体任务。

特征工程会对最终分词结果产生很大影响。字本位分词的常见分词特征是:

Unigram 是单字特征模板,当前字的前一个字、当前字、后一个字。Bigram 是邻接字组合特征模板,包括前一个字与当前字、当前字与后一个字的组合。Jump 是把前一个字与后一个字组合。

其它特征主要是关于字的属性,如是否数字、标点、字母等。这些特征都是形式上的特征,没有歧义。

每一个特征实例在 CRF 模型中有一个权重。由于特征越多,模型参数越大,在实际工程应用中资源消耗越大,因此在实际任务中会有一定取舍。

理论解决方案的问题

训练数据规模有限

北大人民日报的原始语料的词语数为 2800 万;CTB9.0 词语数为 200 万;国家语委数据为 5000 万字。

标注语料是一个非常消耗人力的事情。北大 1998 年人民日报的标注共持续了 3 年时间才完成。CTB1.0 的标注持续了约 2 年时间。

领域迁移性不佳

其他领域实施时,分词准确率下降很快。由于标注语料的词语使用无法覆盖实际语言现象,因此基于标注语料训练的分词系统在差异较大的领域会出现准确率降低的情况,例如基于北大语料训练的分词系统在微博上的切分准确率就不是很高。

模型越来越大,速度越来越慢

早期使用 HMM 模型训练分词系统,在北大数据上训练大概需要 1-2 分钟,内存消耗很小。现在使用 CRF 模型训练大概需要 3 天左右,内存大概需要十几 G。CRF 模型在训练分词系统时,其参数数量跟特征数量直接相关,训练数据越多,特征数量越大,模型也就越来越大。导致系统调用存在困难,运行速度下降。

如何工程解决?

能用规则解决的,就不要靠模型了

针对文本中有规律的部分,可以利用规则或者正则表达式来识别,例如数字、标点、时间、日期、重叠式等,如笑一笑。

扩大训练语料

扩大训练语料的一种办法是购买更多语料;另外一种办法是利用其它分词系统来切分数据,对数据进行清洗,形成新数据。

这些不同的分词系统依赖的训练数据尽量不要相同,例如 Stanford 系统是基于 CTB 语料,LTP 系统是基于人民日报,这两个系统的切分结果就可以考虑混用。在混用前,要进行一定程度的预处理,比如保持切分一致性。

明略的分词系统通过使用多款不同分词系统的分词结果,扩大训练数据,在人名识别上大幅度提高了召回率。

增加词表

增加词表是提高切分准确率“立竿见影”的办法。在自然语言处理中,只要是封闭集合的词语或实体,可以考虑利用词表来切分,例如成语。该方法简单有效。

在明略分词数据中,集成了全国所有的地名、公交站名、路名等,精确到村和居委会,对国内地名识别上有很高的准确度。对机构名和公司名,集成了经常出现的国内行政机构、上市企业等名字。

在 Bosen 系统的演示中,对公司名识别准确率非常高,例如:“明略数据、明略软件”这种公司简称也能识别出来,即使没有上下文也能识别。这应该跟其后台的公司名数据有关。

最大匹配 + 大词表

从诸多实践来看,最大匹配分词策略 + 大词表的方法非常有效。在《中文分词十年回顾》中作者提到了最大匹配和大词表的效果:

Ftop 行表示没有未登录词的情况下,仅使用最大匹配达到的 F 值(准确率 + 召回率)。

实用的分词系统,都带有大量通用词表和领域词表。

收集整理领域词表,对迁移分词系统至关重要。这对统计分词系统比较困难。

结合深度学习?

ACL 2017 年有 3 篇跟分词相关的文章,都是深度学习 (神经网络) 和分词结合的内容。分别是:

Neural Word Segmentation with Rich Pretraining

Adversarial Multi-Criteria Learning for Chinese Word Segmentation

Fast and Accurate Neural Word Segmentation for Chinese

从明略的实践来看,深度学习应用到分词任务中的优点在于:模型非常小。在约 200MB 的语料上训练得到的模型只有 5MB。分词准确率接近历史上最佳评测结果,但是分词速度太慢。

从最新文献来看,利用神经网络来做分词,训练效率和运行效率都比较低,慢得无法忍受,不适合工程上部署,也不适合做 Demo。

在《Fast and Accurate …… for Chinese》中提供了运行速度对比,测试数据为 170k 左右,2015 和 2016 年的 6 项分词结果中,切分测试数据的时间从 28 秒到 125 秒。在传统方法上,比如基于 CRF 分词,运行时间大概只要 1 秒。

根据个人经验,神经网络在 NLP 上的成功应用的领域往往是准确率不高或者运行效率很低的场合,例如问答系统、机器翻译、句法分析。在准确率比较高或者运行效率不错的场景下,利用深度学习会得不偿失。