`
单眼皮大娘
  • 浏览: 112790 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

paoding基于词典如何分词

阅读更多
    上次介绍了Paoding的字典数据结构,这次介绍下paoding是如何对待分词文本依据词典分词的。paoding在查找字典时依据两个类: BinaryDictionary 和 HashBinaryDictionary。上次也已经介绍过这两个数据结构,这里不再重复。

    HashBinaryDictionary其实就是把大块数据词典切分成小块的词典,并用BinaryDictionary存储。在用HashBinaryDictionary的search方法查找时,其采用的是递归方法,最终还是会进入BinaryDictionary中。看代码便知道
public Hit search(CharSequence input, int begin, int count) {
		SubDictionaryWrap subDic = (SubDictionaryWrap) subs.get(keyOf(input
				.charAt(hashIndex + begin)));
		if (subDic == null) {
			return Hit.UNDEFINED;
		}
		Dictionary dic = subDic.dic;
		// 对count==hashIndex + 1的处理
		if (count == hashIndex + 1) {
			Word header = dic.get(0);
			if (header.length() == hashIndex + 1) {
				if (subDic.wordIndexOffset + 1 < this.ascWords.length) {
					return new Hit(subDic.wordIndexOffset, header,
							this.ascWords[subDic.wordIndexOffset + 1]);
				} else {
					return new Hit(subDic.wordIndexOffset, header, null);
				}
			} else {
				return new Hit(Hit.UNCLOSED_INDEX, null, header);
			}
		}
		// count > hashIndex + 1
		Hit word = dic.search(input, begin, count);
		if (word.isHit()) {
			int index = subDic.wordIndexOffset + word.getIndex();
			word.setIndex(index);
			if (word.getNext() == null && index < size()) {
				word.setNext(get(index + 1));
			}
		}
		return word;
	}


可以看出确实是递归调用Search方法(在构建该结构的时候也是采用递归构造)。
而在BinaryDictionary的search方法中,采用的是二分查找(一会解释为何使用二分查找方法)。代码如下:
public Hit search(CharSequence input, int begin, int count) {
		int left = this.start;
		int right = this.end - 1;
		int pointer = 0;
		Word word = null;
		int relation;
		//
		while (left <= right) {
			pointer = (left + right) >> 1;
			word = ascWords[pointer];
			relation = compare(input, begin, count, word);
			if (relation == 0) {
				// System.out.println(new String(input,begin, count)+"***" +
				// word);
				int nextWordIndex = pointer + 1;
				if (nextWordIndex >= ascWords.length) {
					return new Hit(pointer, word, null);
				}
				else {
					return new Hit(pointer, word, ascWords[nextWordIndex]);
				}
			}
			if (relation < 0)
				right = pointer - 1;
			else
				left = pointer + 1;
		}
		//
		if (left >= ascWords.length) {
			return Hit.UNDEFINED;
		}
		//
		boolean asPrex = true;
		Word nextWord = ascWords[left];
		if (nextWord.length() < count) {
			asPrex = false;
		}
		for (int i = begin, j = 0; asPrex && j < count; i++, j++) {
			if (input.charAt(i) != nextWord.charAt(j)) {
				asPrex = false;
			}
		}
		return asPrex ? new Hit(Hit.UNCLOSED_INDEX, null, nextWord) : Hit.UNDEFINED;
	}


这里很佩服Paoding的作者,这样的结构绝不逊色于中科院字典的数据结构。中科院的字典是人为排好序的,而这里paoding的字典没有排好序列为何还能跟中科院的查找方法类似,采用二分查找法?

主要是其在构造字典数据时调用了
Arrays.sort(array);
这个方法,sort的解释如下:
Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. All elements in the array must implement the Comparable interface. Furthermore, all elements in the array must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the array).

This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.

The sorting algorithm is a modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n*log(n) performance.


为解除疑惑,也做了相应的测试:
public class TestArraySort {
	public static void main(String[] args) {
		HashSet<String> set = new HashSet<String>();
		set.add("三心二意");
		set.add("五谷丰登");
		set.add("六六大顺");
		set.add("三个人");
		set.add("五个人");
		set.add("六个人");
		Object[] array = set.toArray();
		Arrays.sort(array);
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}
}

结果如下:

三个人
三心二意
五个人
五谷丰登
六个人
六六大顺

public class TestCharactor {
	public static void main(String[] args)  {
		int c1 = '三';
		int c2 = '五';
		
		System.out.println("The category of c1 is: " + c1);
		System.out.println("The category of c2 is: " + c2);
	}
}

结果如下:

The category of c1 is: 19977
The category of c2 is: 20116

public class TestCharactor {
	public static void main(String[] args)  {
		int c1 = '个';
		int c2 = '心';
		
		System.out.println("The category of c1 is: " + c1);
		System.out.println("The category of c2 is: " + c2);
	}
}


The category of c1 is: 20010
The category of c2 is: 24515


这个充分说明了sort确实是把词典中的词按照汉字对应的值按升序排好序列,这个为二分查找埋下伏笔。

    paoding在进行切分时采用的双重循环方式,这就可以切分尽可能多的词,外层循环相当于一个游标,逐个扫面带切分的文本,内层循环尽可能的切词,把切出的词丢到一个专门接受词的类中,这就是所谓的细粒度切分。
分享到:
评论

相关推荐

    paoding 分词

    **中文分词技术详解——以paoding为例** 中文分词是自然语言处理中的基础步骤,对于中文文本的理解和分析至关重要。在Java领域中,paoding(又称“庖丁”)是一个高效、灵活的中文分词库,专为处理大规模中文文本而...

    PaoDing.zip_java paoding_java 分词_paoding_中文文本分词_文本 检索

    2. 初始化分词器:创建PaoDing的实例,可能需要指定词典路径等配置。 3. 进行分词:调用分词器提供的方法,如`cut()`,传入待分词的文本,返回分词结果。 4. 处理分词结果:根据业务需求,可以对分词结果进行进一步...

    Lucene建立索引jar包和Paoding分词jar包

    它的特点包括支持多种分词模式(精确、全模式、简明模式等),内置丰富的词典,以及高效的分词算法。在Lucene中,我们可以通过集成paoding-analysis.jar来利用Paoding进行中文分词,提升索引质量和检索效果。 四、...

    Paoding中文分词

    标题“Paoding中文分词”指的是一个专门用于处理中文文本的分词工具,名为“庖丁解牛中文分词”。在自然语言处理领域,分词是预处理的重要步骤,它将连续的汉字序列切分成有意义的词汇单元,便于后续的文本分析和...

    paoding中文分词

    2. **灵活性**:Paoding支持自定义词典,用户可以根据实际需求添加或修改词汇,以适应特定领域的分词工作。 3. **丰富的分词模式**:除了基本的精确模式,Paoding还提供了全模式、搜索引擎模式等多种分词策略,以...

    Solr3.2 + Paoding中文分词的搜索引擎

    Apache Solr是基于Lucene的开源搜索服务器,提供了更高级别的API和配置选项,而Paoding则是一款专门针对中文的高性能分词工具,能准确地对中文文本进行切词,提升搜索的精确度。 首先,Apache Solr 3.2是Solr的一个...

    paoding 中文分词

    "Paoding 中文分词"是一款专为处理中文文本而设计的开源分词工具,它在中文信息处理领域具有较高的知名度。"庖丁"是它的别名,来源于中国古代庖丁解牛的故事,寓意其在处理复杂中文文本时,能够如庖丁解牛般游刃有余...

    paoding analysis 3.0.1 jar (庖丁解牛分词器)

    由于庖丁官方目前提供可下载尚不...先下载2.0.4的版本(h t t p : / /code.google.com/p/paoding/),配置好环境后,引用paoding analysis 3.0.1 jar 代替paoding analysis 2.0.4 jar 即可,其他配置如词典等都不变。

    lucene中文分词器(paoding解牛)

    3. **模糊匹配**:对于未出现在词典中的新词或错别字,Paoding采用了基于概率模型的模糊匹配算法,能够在一定程度上识别和处理。 4. **自学习能力**:Paoding具备一定的自学习功能,通过对用户搜索行为的学习,不断...

    paoding-analysis-2.0.4-alpha2.zip_java 分词_paoding

    Paoding Analysis的核心组件包括分词器(Tokenizer)、过滤器(Filter)和词典(Dictionary)。分词器负责对输入的中文文本进行初步切分,过滤器则在分词结果的基础上进行进一步处理,如去除停用词、词性标注等,...

    基于Lucene的中文分词器代码paoding,IK,imdict,mmseg4j

    本文将深入探讨基于Lucene的四种中文分词器:Paoding、IK、Imdict和Mmseg4j,它们都是针对Java开发的高效、开源的中文分词工具。 1. Paoding(庖丁)分词器: Paoding是一款高性能的中文分词器,设计目标是提供...

    基于Lucene的搜索系统-客户端调用

    Paoding在处理中文分词时,采用了多种策略,如基于词典的精确分词、基于统计的模糊分词等,提高了分词的准确率。在与Lucene结合使用时,Paoding的分词结果会被Lucene用于构建查询,并在索引中查找匹配的文档。 在...

    paoding.rar_paoding_paoding analyzer.

    常见的分词算法有基于词典的匹配法、最大匹配法、正向最大匹配法、逆向最大匹配法以及结合统计模型的HMM(隐马尔科夫模型)和CRF(条件随机场)等。 - **Paoding Analyzer**:作为一个优秀的中文分词工具,它集成了...

    lucene-4.8.1 + paoding-analysis-master

    本篇文章将深入探讨基于Lucene 4.8.1的中文分词系统,以及Paoding Analysis这一强大的中文分词库。 Lucene是一个高性能、全文检索库,由Apache软件基金会开发,提供了一个可扩展的搜索和索引框架。在版本4.8.1中,...

    paoding+lucene实现全文检索功能简单实例

    Paoding提供了丰富的配置选项,如自定义词典,可以让你根据具体需求调整分词结果,比如添加专有名词、缩写或者行业术语。自定义词典允许你在分词过程中包含特定的词汇,提高分词的准确性。 接着,我们来谈谈Lucene...

    paoding_analysis.rar_PaodingAnalysis_lucene paoding_paodi

    在实际应用中,"paoding_analysis.rar"这个压缩包很可能包含了实现这一功能所需的全部资源和配置文件,例如分词词典、样例代码以及相关的文档说明。文件名中的"lucene paoding paodi"标签,暗示了这是关于Lucene使用...

    paoding查询关键字匹配到的个数的实例

    Paoding的配置主要涉及分词器的选择、词典文件等。可以创建一个Properties对象,设置相应的参数,例如: ```java Properties props = new Properties(); props.setProperty("paoding.analysis.analyzer", "smart");...

    solr 5.x 和 6.x 最新中文分词器

    3. Paoding Analyzer:基于词典的分词器,拥有较高的分词准确率,支持用户自定义词典,适合专业领域的搜索需求。 二、Solr配置中文分词器 在Solr中使用中文分词器需要在配置文件中指定。通常在`schema.xml`或`...

    庖丁解牛分词 java包

    5. `dic`: 这个目录可能包含了分词词典,词典是分词器的基础,包含了大量的词汇及其相关信息,用于识别和处理文本中的词汇。 6. `src` 和 `classes`: 这两个目录分别存放源代码和编译后的字节码文件,对于深入理解...

    lucene简单教程poading中文分词.pdf

    Paoding 是一个面向中文的分词器,它支持中文分词、自动识别词性、支持多种自定义词典和扩展字典等特性。在 Lucene 中集成 Paoding 分词器可以使得中文搜索更加准确和高效。Paoding 提供了易于使用的接口,可以在 ...

Global site tag (gtag.js) - Google Analytics