`

【分词】正向最大匹配中文分词算法

阅读更多

中文分词一直都是中文自然语言处理领域的基础研究。目前,网络上流行的很多中文分词软件都可以在付出较少的代价的同时,具备较高的正确率。而且不少中文分词软件支持Lucene扩展。但不管实现如何,目前而言的分词系统绝大多数都是基于中文词典的匹配算法。

 

在这里我想介绍一下中文分词的一个最基础算法:最大匹配算法 (Maximum Matching,以下简称MM算法) 。MM算法有两种:一种正向最大匹配,一种逆向最大匹配。

 

● 算法思想

 

正向最大匹配算法:从左到右将待分词文本中的几个连续字符与词表匹配,如果匹配上,则切分出一个词。但这里有一个问题:要做到最大匹配,并不是第一次匹配到就可以切分的 。我们来举个例子:

           待分词文本:   content[]={"中","华","民","族","从","此","站","起","来","了","。"}

           词表:   dict[]={"中华", "中华民族" , "从此","站起来"}

(1) 从content[1]开始,当扫描到content[2]的时候,发现"中华"已经在词表dict[]中了。但还不能切分出来,因为我们不知道后面的词语能不能组成更长的词(最大匹配)。

(2) 继续扫描content[3],发现"中华民"并不是dict[]中的词。但是我们还不能确定是否前面找到的"中华"已经是最大的词了。因为"中华民"是dict[2]的前缀。

(3) 扫描content[4],发现"中华民族"是dict[]中的词。继续扫描下去:

(4) 当扫描content[5]的时候,发现"中华民族从"并不是词表中的词,也不是词的前缀。因此可以切分出前面最大的词——"中华民族"。

 

由此可见,最大匹配出的词必须保证下一个扫描不是词表中的词或词的前缀才可以结束。

 

 

● 算法实现

 

词表的内存表示: 很显然,匹配过程中是需要找词前缀的,因此我们不能将词表简单的存储为Hash结构。在这里我们考虑一种高效的字符串前缀处理结构——Trie树《Trie Tree 串集合查找 》。这种结构使得查找每一个词的时间复杂度为O(word.length),而且可以很方便的判断是否匹配成功或匹配到了字符串的前缀。

 

下图是我们建立的Trie结构词典的部分,(词语例子:"中华","中华名族","中间","感召","感召力","感受")。

          

(1) 每个结点都是词语中的一个汉字。

(2) 结点中的指针指向了该汉字在某一个词中的下一个汉字。这些指针存放在以汉字为key的hash结构中。

(3) 结点中的"#"表示当前结点中的汉字是从根结点到该汉字结点所组成的词的最后一个字。

 

TrieNode源代码如下:

import java.util.HashMap;
/**
 * 构建内存词典的Trie树结点
 * 
 * @author single(宋乐)
 * @version 1.01, 10/11/2009
 */
public class TrieNode {

	/**结点关键字,其值为中文词中的一个字*/
	public char key=(char)0;
	/**如果该字在词语的末尾,则bound=true*/
	public boolean bound=false;
	/**指向下一个结点的指针结构,用来存放当前字在词中的下一个字的位置*/
	public HashMap<Character,TrieNode> childs=new HashMap<Character,TrieNode>();
	
	public TrieNode(){
	}
	
	public TrieNode(char k){
		this.key=k;
	}
}

 

这套分词代码的优点是:

(1) 分词效率高。纯内存分词速度大约240.6ms/M,算上IO读取时间平均1.6s/M。测试环境:Pentium(R)  4 CPU  3.06GHZ、1G内存。

(2) 传统的最大匹配算法需要实现确定一个切分的最大长度maxLen。如果maxLen过大,则大大影响分词效率。而且超过maxLen的词语将无法分出来。但本算法不需要设置maxLen。只要词表中有的词,不管多长,都能够切分。

(3) 对非汉字的未登录词具备一定的切分能力。比如英文单词[happy, steven],产品型号[Nokia-7320],网址[http://www.sina.com]等。

 

缺点也很明显:

(1) 暂时无词性标注功能,对中文汉字的未登录词无法识别,比如某个人名。

(2) 内存占用稍大,目前词表为86725个词。如果继续扩展词表,很有可能内存Trie树将非常庞大。

 

代码的进一步优化方案:

(1) 想在内存占用空间上降低代价。实际上Trie树主要的空间消耗在每个结点的指针HashMap上。我使用的是JDK中的HashMap,其加载因子为 loadFactor= 0.75,初始化空间大小为DEFAULT_INITIAL_CAPACITY= 16。每次存储数据量超过 loadFactor* DEFAULT_INITIAL_CAPACITY的时候,整个Map空间将翻倍。 因此会照成一定的空间浪费。

 

      但目前还没有想到很好的办法,即能够随机定位到下一个结点的指针,又降低Hash结构的空间代价?

 

 

下面是我实现的基于Trie词典结构的正向最大匹配算法的源代码包和分词词表,可供大家学习下载。但绝对不允许任何商业性质的传播,违者必究。

分享到:
评论
5 楼 Ivar__ 2015-03-15  
楼主这个很不错啊  可惜包里是class文件  能不能发源码学习下啊   Ivarsen@163.com  谢谢
4 楼 xnd09 2014-12-17  
我也是ccnu的, 包里是.class文件,博主给将源码传至gjbh09@qq.com吗?学习一下,拜谢
3 楼 ainihong001 2011-11-25  
包里是.class文件,博主给将源码传至ainihong001@126.com吗?
方便学习啊。多谢。
2 楼 wmm890122 2011-11-12  
问个问题,结点中的指针指向了该汉字在某一个词中的下一个汉字,如果此汉字下面有两个词,如上例中的,中,那它的指针,怎么判断是指向那个汉字?
1 楼 浣熊市市长 2011-06-10  
good
能不能再出个逆向最大匹配的例子

相关推荐

    正向最大匹配算法 分词算法

    正向最大匹配(Forward Maximum Matching,FMM)算法是一种在自然语言处理中广泛使用的中文分词方法。在中文文本处理中,由于汉字不带有明显的边界标识,因此需要借助特定的算法来将连续的汉字序列切分成有意义的...

    分词匹配算法:正向最大匹配和反向最大匹配

    分词匹配算法:正向最大匹配和反向最大匹配 分词匹配算法是自然语言处理领域中的一种重要技术,它的主要目的是将汉字串切分为单个词语,以便于进一步的语言处理。分词匹配算法有多种类型,其中机械分词方法是最基本...

    正向最大匹配算法实现中文分词

    MM算法有三种:一种正向最大匹配,一种逆向最大匹配和双向匹配。本程序实现了正向最大匹配算法。 本程序还可以从我的github上面下载:https://github.com/Zehua-Zeng/Maximum-Matching-Algorithm

    正向最大匹配中文分词算法

    中文分词一直都是中文自然语言处理领域的基础研究。目前,网络上流行的很多中文分词软件都可以在付出较少的代价的同时...MM算法有三种:一种正向最大匹配,一种逆向最大匹配和双向匹配。本程序实现了正向最大匹配算法。

    中文分词程序-正向最大匹配算法及逆向最大匹配算法

    在这个“中文分词程序”中,包含了两种常见的分词算法:正向最大匹配算法(Forward Maximum Matching, FMM)和逆向最大匹配算法(Backward Maximum Matching, BMM)。 正向最大匹配算法是一种自左向右的分词策略。...

    python正向最大匹配分词和逆向最大匹配分词

    在本文中,我们将讨论 Python 实现的正向最大匹配分词和逆向最大匹配分词算法,并提供完整的源代码。 正向最大匹配分词 正向最大匹配分词是一种常用的分词算法,它从左到右扫描输入字符串,并尽可能地找到最长的...

    基于正向、逆向的最大分词算法实现

    本文将深入探讨“基于正向、逆向的最大分词算法实现”的相关知识。 首先,我们要理解什么是分词。分词,也称为词汇化或切词,是指将连续的汉字序列切分成具有独立含义的词语。在中文处理中,由于没有明显的空格分隔...

    中文分词-正向最大匹配法和逆向最大匹配法的实现

    需要注意的是,Python提供了许多现成的中文分词库,如jieba,它们已经实现了包括正向、逆向匹配在内的多种分词算法,并且优化了性能。但在学习和理解分词原理时,自己动手实现这些方法是非常有益的。 总的来说,...

    改进的正向最大匹配分词算法

    ### 改进的正向最大匹配分词算法 #### 概述 本文旨在介绍一种改进的正向最大匹配分词算法(MMSEG),该算法针对传统最大匹配算法存在的不足进行了优化,特别是在处理交集型歧义字段方面有所创新。通过引入预处理、互...

    正向最大匹配(FMM)和逆向最大匹配(BMM)的分词系统

    正向最大匹配(Forward Maximum Matching, 简称FMM)和逆向最大匹配(Backward Maximum Matching, 简称BMM)是两种广泛应用的分词算法,它们在C#环境下被实现并封装在一个名为"FMM&BMM_WordDivise"的压缩包中。...

    matlab中文分词——最大正向匹配法.rar

    本项目以"matlab中文分词——最大正向匹配法.rar"为主题,重点讨论了如何在MATLAB环境中实现最大正向匹配算法进行中文分词。 MATLAB是一种广泛使用的数学计算和编程环境,其强大的数值计算和可视化功能使其成为科研...

    中文分词的正向和反向最大匹配算法

    在处理新闻文本时,除了基本的分词算法,还需要考虑新闻特点,如时间敏感性、事件相关性和专业术语。因此,可能需要定期更新词典,增加新出现的专有名词,或者利用命名实体识别技术来精确识别人名、地名、机构名等。...

    中文分词最大正向匹配

    【中文分词最大正向匹配】是一种常见的中文自然语言处理技术,主要应用于文本处理和信息检索领域。在中文文本中,由于没有明显的空格作为单词的分隔符,因此需要通过特定的算法来识别和分割出单个词汇,这一过程就被...

    Java实现分词(正向最大匹配和逆向最大匹配)两种方法实现

    本文将详细介绍如何利用Java编程语言来实现两种常见的分词算法——正向最大匹配法(FMM)和逆向最大匹配法(BMM),并给出具体的代码示例。 #### 二、正向最大匹配法(FMM) 正向最大匹配法的基本思路是从待分析...

    正向最大匹配分词算法 perl版

    perl 写的正向最大匹配分词模块。 # #正向最大分词 #eg: my $seg = new Segmenter($list); # my $list_arrref = $seg-&gt;segment($line); #

    最新逆向最大匹配分词算法 盘古分词 分词算法 中文分词 源码

    逆向最大匹配分词算法(Reverse Maximum Matching,RMM)是一种常见的中文分词技术,广泛应用于自然语言处理、搜索引擎和信息检索等领域。该算法的基本思想是从待分词文本的末尾开始,向前寻找最长的已存在于词典中...

    java中文分词之正向最大匹配法实例代码

    中文分词应用很广泛,网上也有很多开源项目,下面这篇文章主要给大家介绍了关于java中文分词之正向最大匹配法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。

    一个简单的分词系统(可以选择正向最大匹配分词或逆向最大匹配)

    在这个简单的分词系统中,提供了两种主要的分词算法:正向最大匹配(Forward Maximum Matching, FMM)和逆向最大匹配(Backward Maximum Matching, BMM)。下面我们将详细探讨这两种方法及其应用。 首先,正向最大...

    正向最大匹配算法

    正向最大匹配算法(Forward Maximum Matching Algorithm,简称FMM)是一种广泛应用于自然语言处理领域中的分词技术。该算法的核心思想是根据事先构建好的词典,从左到右扫描待分析的文本,并尽可能匹配出词典中存在...

    基于分词的正向最大匹配和反向最大匹配算法

    正向最大匹配(Forward Maximum Matching, FMM)和反向最大匹配(Backward Maximum Matching, BMM)是两种常见的中文分词算法,它们基于词典进行操作,旨在提高分词的准确性和效率。 **正向最大匹配算法(FMM)** ...

Global site tag (gtag.js) - Google Analytics