`
wzhiju
  • 浏览: 140883 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

分词词典的构造机制(一)

阅读更多
对于初步接触分词的朋友们来说,分词词典的构造是一件不可小觑的事情。因为词典的好坏直接影响到算法的性能、运行时间。换句话说,分词词典构造的好,将会极大地改观分词的性能,而各种复杂的分词算法,直接依赖于分词词典的构造机制(是进行分词的根基)。下面将分几个部分进行词典构造机制几种方法的介绍。
在这片文章中,根据我所用过的最基础的方法进行词典的构造,即拼音的索引方法。(也是大家最能直接想到的方法)
下面结合我的应用,分享一下具体的做法。
1. hashMap.java 文件
文件用来将拼音生成一个 LinkedHashMap 表,并对应与相应的键值。如下所示:
hashMap.put("a", 0);
        hashMap.put("ai", 1);
        hashMap.put("an", 2);
        hashMap.put("ang", 3);
        hashMap.put("ao", 4);
        hashMap.put("ba", 5);
        hashMap.put("bai", 6);
hashMap.put("ban", 7);

将拼音“a”放在哈希散列图的第0个位置,依次类推。
2. CnToSpell.java 文件
此文件用于将汉字转化为读音。例如输入“你好”将返回“nihao”。其中用到的getCnAscii() 方法,是根据汉字的国标码将其对应于相应int型的数值。如下:
public static int getCnAscii(char cn) {
byte[] bytes = null;
try {
bytes = (String.valueOf(cn)).getBytes("gbk");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (bytes == null || bytes.length > 2 || bytes.length <= 0) {
return 0;
}
if (bytes.length == 1) {
return bytes[0];
}
if (bytes.length == 2) {
int hightByte = 256 + bytes[0];
int lowByte = 256 + bytes[1];
int ascii = (256 * hightByte + lowByte) - 256 * 256;
// System.out.println("ASCII=" + ascii);
return ascii;
}
return 0;
}

而initialize()方法则将对应的数值和拼音的对应关系存入哈希散列图中。
(LinkedHashMap<String, Integer>spellMap = new LinkedHashMap<String, Integer>(400);)
spellPut("a", -20319);
spellPut("ai", -20317);
spellPut("an", -20304);
spellPut("ang", -20295);
spellPut("ao", -20292);
spellPut("ba", -20283);
spellPut("bai", -20265);
spellPut("ban", -20257);
spellPut("bang", -20242);
spellPut("bao", -20230);
spellPut("bei", -20051);
spellPut("ben", -20036);
spellPut("beng", -20032);
……

所以对于一个要转化为拼音的汉字而言,首先用getCnAscii() 方法获得int型数值,而后根据哈希散列图寻找相应的读音。
特别地,对于多音字的部分词汇将归为排在前面的第一个拼音。此外,其他情况,例如某些复杂汉字无法找到其对应的拼音,将要单独归为一类。(因为此种情况的汉字不算太多,所以对于性能而言,没有影响)
3. Dictionary.java文件
遍历一个txt 词典文件,根据第一个汉字的读音,将它们按照读音的不同归为不同的类中。
public void makeDictionary() throws IOException {// 打开一个到文件WordTable.txt的一个流
BufferedReader bf = new BufferedReader(new FileReader("stopword.txt"));
String dicItem = "";// 每一行的词语
int currentZiYinIndex = 0;// 当期字音的键值
while ((dicItem = bf.readLine()) != null) {
String firstCharacter = dicItem.substring(0, 1);// 获取第一个字
String ziYin = CnToSpell.getFullSpell(firstCharacter);// 获取第一个字的字音
if (hashMap.get(ziYin) != null) {
currentZiYinIndex = hashMap.get(ziYin).intValue(); // 获得第一个字音对应的键值
if (dicStr[currentZiYinIndex] == null) {
dicStr[currentZiYinIndex] = dicItem + " ";
} else {
dicStr[currentZiYinIndex] += dicItem + " ";
}
}// 否则存入未能识别的数组
else {// unknownWords 每次都叠加
if (dicStr[395] == null) {
dicStr[395] = dicItem + " ";
} else {
dicStr[395] += dicItem + " ";
}
}
}
}
同样的道理,查找某一个词条时,首先根据首字转化为拼音,然后,根据该拼音缩小查找范围,提高查询速率。程序如下:
public boolean lookDictionary(String words) {
boolean flag = false;// 定义布尔型变量用来标志是否找到
String firstWord = "";
if (words.length() > 1) {
firstWord = words.substring(0, 1);
} else if (words.length() == 1) {
firstWord = String.valueOf(words.charAt(0));
}
// System.out.println(firstWord);
String ziYin = CnToSpell.getFullSpell(firstWord);// 获取第一个字的字音
int index = 0;// 用来标记键值
if (hashMap.get(ziYin) != null) {
index = hashMap.get(ziYin).intValue();// 获得键值,找到相应的数组
} else {
index = 395;
}
if (dicStr[index] == null)
return false;
String singleWord[] = dicStr[index].split(" ");// 将一个长的字符串按照空格划分为多个单词
int numOfSpace = 0;// 定义一个变量来统计空格的个数,从而来确定划分完后的数组个数
for (int i = 0; i < dicStr[index].length(); i++) {// 统计有多少个空格,从而确定数组的个数
if (dicStr[index].charAt(i) == ' ') {
numOfSpace++;
}
}
// 在划分完的数组中查找该词,如果找到将flag设为true
for (int ind = 0; ind < (numOfSpace); ind++) {
if (singleWord[ind].equals(words)) {
flag = true;
break;
}
}
return flag;
}
当然,分词词典的构成机制还有其他的集中主流方法,在下面的文档中将会和大家一起交流。
  • dic.rar (6.9 KB)
  • 下载次数: 28
0
0
分享到:
评论

相关推荐

    中文分词工具word-1.0,Java实现的中文分词组件多种基于词典的分词算法

    3、中文分词算法 之 词典机制性能优化与测试 4、中文分词算法 之 基于词典的正向最小匹配算法 5、中文分词算法 之 基于词典的逆向最小匹配算法 5、Java开源项目cws_evaluation:中文分词器分词效果评估

    分词辅助类.zip

    类中可能包含一个词典成员变量,用于存储词汇,以及一个或多个方法,如`Tokenize()`用于执行分词操作,`LoadDictionary()`用于加载词典文件,`AddCustomRule()`用于添加用户自定义的分词规则等。 7. **文件I/O操作*...

    基于双数组Trie_树中文分词研究

    对于给定的字符串α1, α2, …, αn,在Trie树中搜索最多只需要经过n次匹配即可完成一次查找,这使得它成为中文匹配分词算法中词典的一种常见实现方式。然而,Trie树的空间利用率通常较低。 双数组Trie树是对Trie树...

    lucene2.0与其分词工具包

    "je-analysis"可能是一个早期的中文分析器,用于对中文文本进行预处理,包括词典匹配、分词、去除停用词等步骤,以便于Lucene理解并处理中文内容。这在处理大量中文文档时尤其关键,因为中文没有明显的词边界,传统...

    Lucene2.1 Source Code,分词源码

    例如,IK 分词器就是一种常用的基于词典的中文分词器,它支持动态加载词典,能较好地处理常见词汇。 - **统计语言模型分词**:这种方法利用概率统计模型,如隐马尔可夫模型(HMM)或条件随机场(CRF),根据词语...

    分词工具 IKAnalyzer2012_SRC

    3. **创建Analyzer实例**:通过`org.wltea.analyzer.lucene.IKAnalyzer`类的构造函数创建分词器实例。 4. **执行分词**:使用Analyzer的`TokenStream`方法对文本进行分词。 5. **处理分词结果**:遍历返回的`...

    盘古分词最全demo,和对应的依赖文件

    此外,为了优化性能和内存占用,盘古分词支持词典动态加载和缓存机制。当系统内存有限时,可以选择延迟加载词典,只在需要时才加载到内存,以减少启动时的资源消耗。 总结来说,盘古分词与Lucene.Net 3.0.3的集成...

    Maven构造Alice支持中文及自定义标签

    开发者不仅对Alice的源码进行了深度定制,还充分利用了Maven的构建机制和IK分词器的特性,实现了对中文输入的高效处理和对话流程的灵活控制。这对于提升Alice与中文用户的交互体验具有重要意义。

    WordSeg.zip

    然后,设计一个分词函数,该函数利用MFC的消息处理机制,接收输入文本,调用最大匹配算法进行分词,并将结果输出。 在MFC项目中,可以创建一个C++类,比如`CWordSeg`,来封装分词逻辑。类的成员变量可能包括词典、...

    solr ik源码详细解析

    本文将深入探讨IKAnalyzer的源码,剖析其核心的词典处理、分词处理和歧义处理机制。 首先,我们来看IKAnalyzer的词典处理。词典是分词的基础,IKAnalyzer的词典主要分为两大部分:一是内置的主词典`main2012.dic`,...

    TRSDatabaseServer用户手册

    - 附加分词词典是对主分词词典的补充,用于处理特定领域的专业词汇。 - 停用词典包含了一些常见但无意义的词汇,如“的”、“和”等,避免这些词汇干扰搜索结果。 - 附加停用词典同样是对主停用词典的扩展,针对特定...

    lucene-2.9.2.jar包+源码

    在源码中,你可以看到分词器的实现细节,包括词典加载、动态扩展和词语切分策略。 接下来,我们关注TF-IDF(Term Frequency-Inverse Document Frequency)算法。TF-IDF是一种在信息检索和文本挖掘领域常用的评分...

    lucene3.0.0jar及IKAnalyzer

    2. **动态词典**:IKAnalyzer 支持动态加载词典,用户可以根据需要自行扩展或更新词典,增强了分词的灵活性。 3. **用户自定义分析**:除了内置的分词规则,IKAnalyzer 还允许用户自定义分析器,实现特定的分词逻辑...

    双数组Trie树算法优化及其应用研究.pdf

    作者基于该优化策略实现了一个词典管理程序,并将其与其他索引机制进行对比实验。实验结果显示,利用优化后的双数组Trie树算法的词典不仅在查询速度上优于使用其他索引机制的词典,而且在存储数据的空间占用方面也...

    DotLucene演示源码

    DotLucene提供了一个高效的索引机制,能够快速地对大量文本数据进行预处理,生成可以高效查询的索引。这个过程包括分析文本(分词)、建立倒排索引以及存储各种元数据。索引构建完成后,用户可以通过输入关键词进行...

    《自己动手写搜索引擎》光盘资料(第3章)

    这部分可能讲解了中文分词算法,如基于词典的分词、统计模型的分词等。同时,去重机制确保每个网页只被索引一次,防止重复信息。 4. **倒排索引**:倒排索引是搜索引擎的核心数据结构,使得快速查找包含特定关键词...

    Lucene原理与代码分析完整版以及找的一些资料

    Lucene的查询解析过程包括了分词、语法分析、查询构造等多个步骤。用户输入的文本首先经过查询解析器(QueryParser)转化为一系列的查询条款(Query Terms),这些条款可以是单个词汇,也可以是复杂的布尔表达式。...

    双数组Trie优化算法及其应用研究

    本文主要探讨了双数组Trie树(Double-Array Trie)算法的一种优化方法,并详细分析了其在实际应用中的表现,特别是在词典管理和自动分词领域。双数组Trie树作为一种高效的字符串搜索算法,在诸多场景下具有重要的应用...

Global site tag (gtag.js) - Google Analytics