中文分词--词典分词--最长匹配
(个人学习笔记,慎重参考)
1 基本概念
中文分词
指的是将一段文本拆分为一系列单词的过程,这些单词顺序拼接后等于原文本。
作为中文信息处理的第一站,是后续nlp任务的基础,中文分词算法大致可分为词典规则与统计学习,针对具体问题往往会以统计学习为主、词典规则为辅。
2 正向最长匹配
最长匹配算法
就是在以某个下标为起点递增查词的过程中,优先输出更长的单词,这种规则被称为最长匹配算法。从前往后匹配则称为正向最长匹配,反之则称为逆向最长匹配。
# -*- coding:utf-8 -*-from tests.book.ch02.utility import load_dictionarydef forward_segment(text, dic):word_list = []i = 0while i < len(text):longest_word = text[i] # 当前扫描位置的单字for j in range(i + 1, len(text) + 1): # 所有可能的结尾word = text[i:j] # 从当前位置到结尾的连续字符串if word in dic: # 在词典中if len(word) > len(longest_word): # 并且更长longest_word = word # 则更优先输出word_list.append(longest_word) # 输出最长词i += len(longest_word) # 正向扫描return word_listif __name__ == '__main__':dic = load_dictionary()print(forward_segment('就读北京大学', dic))print(forward_segment('研究生命起源', dic))
运行结果:
['就读', '北京大学']
['研究生', '命', '起源']
- 从代码逻辑可以看出,在匹配到字典中的最长字符串优先输出,若以该起点的字符中都不在字典中,则该起点的单字作为分词输出;
- [‘研究生’, ‘命’, ‘起源’]产生误差的原因在于,正向最长匹配“研究生”的优先级大于“研究”,下面采用逆向最长匹配解决这个问题;
3 逆向最长匹配
# -*- coding:utf-8 -*-
# Author:hankcs
# Date: 2018-05-22 21:05
# 《自然语言处理入门》2.3.3 逆向最长匹配
# 配套书籍:http://nlp.hankcs.com/book.php
# 讨论答疑:https://bbs.hankcs.com/
from tests.book.ch02.utility import load_dictionarydef backward_segment(text, dic):word_list = []i = len(text) - 1while i >= 0: # 扫描位置作为终点longest_word = text[i] # 扫描位置的单字for j in range(0, i): # 遍历[0, i]区间作为待查询词语的起点word = text[j: i + 1] # 取出[j, i]区间作为待查询单词if word in dic:if len(word) > len(longest_word): # 越长优先级越高longest_word = wordbreakword_list.insert(0, longest_word) # 逆向扫描,所以越先查出的单词在位置上越靠后i -= len(longest_word)return word_listif __name__ == '__main__':dic = load_dictionary()print(backward_segment('研究生命起源', dic))print(backward_segment('项目的研究计划', dic))
运行结果:
['研究', '生命', '起源']
['项', '目的', '研究计划']
- [‘研究’, ‘生命’, ‘起源’]分词正确了,但是[‘项’, ‘目的’, ‘研究计划’]又错了,后者用正向最长匹配可以正确分词;
4 双向最长匹配
- 清华大学的孙茂松教授曾经做过统计,在随机挑选的3680个句子中,正向匹配错误而逆向匹配正确的句子占比9.24%9.24\%9.24%,正向匹配正确而逆向匹配错误的情况则没有。
- 基于类似上面观察到的一些经验,人们继续提出了双向最长匹配,具体规则如下:
(1)同时执行正向和逆向最长匹配,若两者的词数不同,则返回词数更少的那一个;
(2)否则,返回两者中单字更少的那一个。当单字数也相同时,优先返回逆向最长匹配的结果;
# -*- coding:utf-8 -*-from tests.book.ch02.backward_segment import backward_segment
from tests.book.ch02.forward_segment import forward_segment
from tests.book.ch02.utility import load_dictionarydef count_single_char(word_list: list): # 统计单字成词的个数return sum(1 for word in word_list if len(word) == 1)def bidirectional_segment(text, dic):f = forward_segment(text, dic)b = backward_segment(text, dic)if len(f) < len(b): # 词数更少优先级更高return felif len(f) > len(b):return belse:if count_single_char(f) < count_single_char(b): # 单字更少优先级更高return felse:return b # 都相等时逆向匹配优先级更高if __name__ == '__main__':dic = load_dictionary()print(bidirectional_segment('研究生命起源', dic))
运行结果:
['研究', '生命', '起源']
5 三种算法对比
- 上图显示,双向最长匹配的确在2、3、5这3种情况下选择出了最好的结果,但在4号句子上选择了错误的结果,使得最终正确率 3/6 反而小于逆向最长匹配的 4/6 , 由此,规则系统的脆弱可见一斑。规则集的维护有时是拆东墙补西墙,有时是帮倒忙。
6 参考文献
- 何晗《自然语言处理入门》;
中文分词--词典分词--最长匹配相关推荐
- 词典分词算法实现详解
1.概述 中文分词指的是将一段文本拆分为一系列单词的过程,这是中文信息处理的第一站,中文分词备受关注.中文分词大致分为以下两类: 基于词典规则 基于机器学习 这里我们主要介绍词典分词 2.词典分词 词 ...
- NPL系列之分词和分词框架(二)
如果要从事NPL的相关技术工作,那么最基础的工作就是分词工作,这个也是所有技术的第一步,当然 这里讨论的中文的分词,因为英文的分词技术是比较单一,基本上按照空格进行标准分词就可以了,但是中文就比较复杂 ...
- 中文分词词典构造简述
中文分词词典构造简述 在分词系统中常用的分词词典机制有:(1)基于整词二分;(2)基于TRIE索引树;(3)基于逐字二分. 一.基于整词二分的分词词典机制 这是一种广为使用的分词词典机制.其结构通常分 ...
- 与自定义词典 分词_使用jieba库进行中文分词、关键词提取、添加自定义的词典进行分词...
jieba库在中文分词中很常用,做一个简单的介绍和运用~ 需求1:打开本地的十九大报告文本,并采用jieba分词器进行分词,最后将分词结果存入名为segresult的文本文件中. 注释:①jieba库 ...
- NPL基于词典分词(二)
前言 <NPL基于词典分词(一)>中我们实现了块儿不准的词典分词,词典分词无法消歧.给定两种分词结果"商品 和服 务"以及"商品 和 服务",词典分 ...
- 中文开源汉语分词工具
本文转载自:http://www.scholat.com/vpost.html?pid=4477 由于中文文本词与词之间没有像英文那样有空格分隔,因此很多时候中文文本操作都涉及切词,这里整理了一些中文 ...
- NPL基于词典分词(一)
前言 自然数据处理里很重要的一环节就是中文分词,它指的是将一段文本拆分为一系列单词的过程,这些单词顺序拼接后等于原文本.而中文分词算法大致分为基于词典规则与基于机器学习这两大派. 什么是词 在基于词典 ...
- NLP入门(1)-词典分词方法及实战
分词是自然语言处理中最基本的任务之一,而词典分词是最简单.最常见的分词算法,仅需一部词典和一套查词典的规则即可. 利用词典分词,最主要的是定制合适的切分规则.规则主要有正向最长匹配.逆向最长匹配和双向 ...
- 大数据语义分析:灵玖中文分词的分词处理
在中文自然语言处理中,词是最小的能够独立活动的有意义的语言成分.汉语是以字为基本书写单位,词语之间没有明显的区分标记,因此进行中文自然语言处理通常是先将汉语文本中的字符串切分成合理的词语序列,然后再在 ...
最新文章
- win 下 安装 iphone 环境
- (转载)自然语言处理中的Attention Model:是什么及为什么
- vue 模板字符串循环_使用React四年后转而使用Vue,是一种什么样的体验?
- maven 主pom 配置不同环境指定不同配置文件以及打包参数
- JetBrains 加入 .NET 基金会
- java 字母金字塔_LeetCode756:金字塔转换矩阵(JAVA题解)
- 小米9 Pro 5G评测:史上最低价5G手机
- PHP String
- win10下安装pytorch,torchvision遇到的bug
- C++学习(一零九)Resource Hacker工具介绍
- win7更新_今天,Win7正式终止更新,扫雷成为历史
- 汽车EMI/EMC测试标准ISO7637-2详解
- CodeBlock的安装、配置和运行
- 惠普传真服务器位置,惠普传真机的使用方法
- 基于51单片机蓝牙直流电机控制(IR2104S驱动H桥)
- RecyclerView三种布局下的上拉加载 下拉刷新
- git 遇到The remote end hung up unexpectedly
- 解决了bridge到blender的2个问题(导入+材质)
- Centos7操作系统搭建Snipe-IT资产管理系统
- Scene(场景)的使用
热门文章
- 前端学习(3):vs code编辑器
- 第七期:Python 从入门到精通:一个月就够了!
- 玩转oracle 11g(11):开启归档模式
- Ubuntu 和 Centos 的一点差别
- CSS之Screen视图属性
- 判断一个java对象中的属性是否都未赋值_100道Java基础面试题(一)
- Dubbo中的监控和管理
- MySQL数据库select语句的使用方法
- mysql中max_allowed_packet参数的配置方法(避免大数据写入或者更新失败)
- VMware 报错“Intel VT-x处于禁止状态”