【Java开源代码栏目提醒】:网学会员Java开源代码为您提供【论文范文】基于Java的搜索引擎Nutch中文搜索技术研究 - 其它管理文献参考,解决您在【论文范文】基于Java的搜索引擎Nutch中文搜索技术研究 - 其它管理文献学习中工作中的难题,参考学习。
论文范文 题目基于Java的搜索引擎Nutch中文搜索技术研究 编辑司马小 摘要Nutch是一个优秀的基于Java的开放源码搜索引擎为了使它能够支持中文搜索本文在分析了Nutch结构的基础上采用词表分词技术和前向匹配分词算法对中文信息进行分词以JavaCC脚本实现上下文相关文法中文分析模块成功实现了Nutch中文搜索功能。
关键词搜索引擎 分词 正规 Abstract: In order to enable Chinese search in Nutch which is an excellent Java-based open source search engine this paper analyses the structure of Nutch and separates words in Chinese information based on Chinese dictionary and forward matching algorithm. Chinese analysis module is generated by JavaCC script that results in supporting Chinese search in Nutch. Key
words: Search Engine Word Segmentation Regular Expression 1 前言 搜索引擎是当今
网络应用的核心问题已经受到各企业和研究部门的广泛关注。
Lucene和Nutch是针对国外英文系统环境的搜索引擎本文在研究了中文分词技术和JavaCC技术的基础上成功地实现了Lucene和Nucth的中文分析模块使Lucene和Nucth能够实现中文信息检索。
2 Nutch分析 Lucene是开放源码的基于Java的全文检索引擎其贡献者Doug Cutting是一位资深全文索引/检索专家。
作为一个全文检索系统在进行检索之前需要建立索引索引的过程是先读取文章中的词语然后一一存放在称为倒排索引文件的索引数据库Index Database中。
索引数据库记录了词语出现的位臵频率等相关信息以备后面读取。
Nutch是Cutting创建的另一个
Java开源项目目的是提供全功能的搜索引擎其底层借助了Lucene的部分功能并且索引结构与Lucene兼容。
Lucene和Nutch并没有规定数据源的格式而只提供了一个通用的结构Document对象来接受索引的输入因此输入的数据源可以是数据库、WORD文档、PDF
文档和
HTML文档只要能够设计相应的解析转换器将数据源构造成Docuement对象即可进行索引。
对于大批量的数据索引还可以通过调整IndexerWrite的文件合并频率属性MergeFactor来提高批量索引的效率。
用户输入查询字符串Query String然后经过分析器的分析就会产生一个Query对象。
真正
搜索时使用IndexSearcher类的search方法它返回Hits对象。
通过遍历Hits对象的所有文档document就可以找到所有被搜索到的文章页面。
查询字符串的语法定义为 Query :: Clause Clause :: - : Query 中间的逻辑包括and or - 等符号而且还有短语查询和针对西文的前缀/模糊查询等。
总的来说这是其他很多搜索引擎都不具备的功能。
通过修改QueryParser的语法生成脚本还可以修改或扩展查询分析器的功能使它更加适用于中文环境。
所有的问题都通过一个额外抽象层来方便以后的扩展和重用通过重新实现来达到自己的目的而对其他模块而不需要。
可以简单的应用入口Searcher Indexer并调用底层一系列组件协同的完成搜索任务。
所有的对象的任务都非常专一比如搜索过程QueryParser分析将查询语句转换成一系列的精确查询的组合Query通过底层的索引读取结构IndexReader进行索引的读取并用相应的打分器给搜索结果进行打分/排序等。
所有的功能模块原子化程度非常高因此可以通过重新实现而不需要修改其他模块。
除了灵活的应用接口设计Lucene和Nutch还提供了一些适合大多数应用的语言分析器实现SimpleAnalyserStandardAnalyser这也是新用户能够很快上手的重要原因之一。
3 Nutch中文搜索 3.1 中文分词 在搜索引擎和各种语言处理的需要中分词可以说是最基本的操作。
汉语句子是由词语组成的人们在使用汉语时可以直接理解并使用它。
对于计算机是不可能达到人类的智能的也不能理解人类语言。
但是由于人类仍然希望计算机能理解人类的语言并且迫切的希望使用在各种商业和技术领域中因此提出了计算机形式文法。
但是现有形式文法是建立在事先分词的基础上的。
对于某些语言单词之间有特定的符号隔开一般是空格所以没有任何分词的困难。
而汉语与其他语言都有很大的不同汉字之间没有空格。
如果想继续沿用西方的形式文法理论处理汉语那么必然涉及到中文分词问题。
在系统实现中使用词表分词。
词表中文分词的原理是根据现有词库进行字符串模式匹配把长的字符串分割为若干个词库中已经存在的词语即可。
因此制作词库成为必须的词库中词语的选择也要慎重。
系统选择的是一个大小为53301个中文词语按照拼音顺序排列的文本格式的词库词语之间使用回车符隔开。
这个词库在使用时要全部调入内存。
为此使用哈希表来实现。
这是因为词库是使用最频繁的公有资源把词库的调入和查词工作封装到WordDataBase类中这是一个静态类作为公有资源使用不允许产生多个实例。
分词系统同时为Lucene索引器、Lucene
查询分析器和Nutch分析器提供服务。
词库选择的好坏直接影响着Lucene和Nutch的表现。
对于Lucene来说是否收入长词语并没有多大关系。
因为Lucene可以将相对短的词语进行索引查询时不会造成什么影响。
例如“中华人民共和国”这个词语并不存在于词库中而是“中华”“人民”“共和国”三个词语存在。
在索引时这三个词语被连续的索引。
Lucene查询分析器将“中华人民共和国”解释为一个短语查询对象PhraseQuery由三个TermQuery组成分别是“中华”“人民”“共和国”。
由于PhraseQuery查询要求索引中的词语顺序必须与组成它的TermQuery的顺序一致且必须连续因此在查询时同样能正确的查到。
如此一来似乎可以不再需要词库直接对每一个汉字做索引就可以了。
这样做当然没有任何问题有些搜索引擎就是这么做的。
但是为了查准率这样做就有一个缺点即分词中的交叉歧义和包含歧义问题。
由于是在无语义的情况下分词只能作某些字符串运算实际上是字符串模式匹配来进行分词因此出现了不同的分词策略。
每一种策略的分词结果可能不同这完全依赖于词库。
所有的分词方法为前向递增最大匹配分词、前向递减最大匹配分词、前向递增最小匹配分词、前向递减最小匹配分词、后向递增最大匹配分词、后向递减最大匹配分词、后向递增最小匹配分词和后向递减最小匹配分词共计8种方法。
系统实现了4种前向分词方法基本上就可以满足需要。
由于现代汉语文章中充斥着大量的英文单词甚至句子尤其是
计算机方面。
鉴于英文是世界上使用最广泛的语言中文文章中含有另外的语言的可能性不大。
英文分词是很简单的根据空格作为分隔符即可。
但是还有一些特殊的单词必须要考虑。
另外涉及到一个重要
问题也是最复杂的一个问题就是汉字之间的空格如何处理。
一般来讲汉字之间不可能出现空格。
在计算机中有时候为明确区分汉字也人为地加上空格。
处理方法是决不可以把空格当作中文的词语分隔符因为空格一般恰恰是出现在词语的中间。
对于整个分词
系统来说还应该允许用户自由选择需要的词语即提供过滤功能。
系统允许用户设臵中文词语英文词语中文停止词英文停止词分别是否要加入结果Word
列表中。
停止词表示一种语言中的大量出现且无关紧要的通用词语例如助词、叹词和介词等。
这些信息预先定义在WordDataBase中。
对于中文来说“的”“地”“得”等都可以作为停止词。
对于英文则有“this”“are”“the”等。
3.2 JavaCC分析 JavaCC是集分词和语法分析与一身的针对Java语言的文本自动分词
软件包类似于Unix系统中的LEX和YACC工具。
JavaCC把这两者的功能结合形成了一个功能强大的分析工具。
用户只需写出分析脚本JavaCC就会生成符合用户要求的类用来进行词法和语法分析。
JavaCC使用了自动机的理论而不是递归下降分析Lucene和Nutch正是利用
JavaCC这个十分强大的工具生成系统的分词器。
JavaCC的语法定义是由正规式Regular Expression来完成的。
在这里指的是上下文无关文法。
理解形式文法的定义才能更好的理解和使用JavaCC。
在一种语言中存在非终结符和终结符两种单词。
正规式就定义了一个非终结符怎样被替换为另一个字符串。
正规式可以描述一种语言符合该正规式定义的所有句子都是这个语言的句子。
或者正规式描述了正规文法又称线性文法或上下文无关文法。
称为线性是因为这种文法可以从前到后顺序的被指定为一个句子。
JavaCC的语法定义功能十分强大可以做几乎所有的限制和指定。
它提供了四种正规式类型 regexpr_kind :: TOKEN SPECIAL_TOKEN SKIP MORE TOKEN: 它表示语法中的单词Token这个段中的正规式规定了这种语言中单词的语法即分词的依据。
单词管理器TokenManager依据每一个正规式来匹配下一个单词这是按照最大匹配规则进行的。
如果有多个匹配那么选择最长的单词返回。
如果有几种正规式产生了相同长度的最长单词那么以较笨重正规式的顺序返回最先定义的正规式产生的单词。
单词管理器匹配出要返回的单词后即返回给语法分析器。
SPECIAL_TOKEN: 在SPECIAL_TOKEN段写出的正规式规定了特殊单词。
特殊单词也是一种单词但是并不起实际的作用也不能从getNextToken中访问到。
它的访问方式是从Token类的specialToken属性来读取。
对于一种语言如果某些单词不起语法的作用但也是句子的一部分那么可以使用特殊单词。
例如编程语言中的注释。
SKIP: 由SKIP段产生的单词被跳过即忽略。
当我们不惜望出现某种模式的单词时即可使用SKIP段。
MORE: 当一个单词不能一次被产生而必须逐渐产生时则使用MORE。
未完成的Token被存储在一个StringBuffer对象中我们可以任意修改。
所谓正规式实际就是产生式。
它的语法格式如下 javacode_production :: JAVACODE java_return_type java_identifier java_parameter_list java_block JAVACODE产生式可以写入任何Java
代码也可以写EBNF扩展的Backus-Naur范式。
实际上在某种程度上上下文无关语言就变成了上下文相关语言因为Java
代码可以处理有关语境的信息。
例如在修改的脚本加入了
代码以后就是一个上下文相关语言。
有时候当EBNF无法自行描述语法时也可以借助“无所不能的”Java
代码。
例如下面的
代码非终结符 skip_to_matching_brace的作用是跳过完整匹配的括号。
实际上这个
工作是EBNF无法完成的因为它描述的不是线性文法。
但是使用Java
代码可以很容易的解决 JAVACODE void skip_to_matching_brace Token tok int nesting 1 while true tok getToken1 if tok.kind LBRACE nesting if tok.kind RBRACE nesting-- if nesting 0 break tok getNextToken 3.2利用JavaCC构造中文分析模块 JavaCC是根据西方语言的形式文法理论
设计的不能直接解决中文问题。
当仔细研究后发现所谓的“中文问题”实际上就是如何把上下文无关文法转变为上下文相关文法。
EBNF当然不能解决这个问题。
通过写入Java
代码用各种对象和标志变量制作特殊的“上下文”环境就可以实现JavaCC的中文分词。
Lucene和Nutch原来的脚本在TOKEN段进行了精细的刻画对于英文单词、主机地址、电子邮件地址、数字、缩写等各种格式都进行了考虑。
只需利用中文分词功能直接传入中文句子得到ArrayList类型的返回结果。
因此唯一的工作就是事先分出一个全部是中文的字符串这一点通过下面的定义实现 CJK: u3040-u318f u3300-u337f u3400-u3d2d u4e00-u9fff uf900-ufaff 上面的CHINESE的定义为由汉字开头包含汉字或空格的最长的字符串而汉字则定义为CJK。
CJK即中国、日本、朝鲜和韩国使用的中国汉字的总称全称为CJK IdeographsCJK象形文字这是Unicode标准所定义的。
在Lucene中一旦实现了中文字符串的提取就可以把它进行分词然后在next方法中返回。
但是在Nutch中QueryParser已经取消与NutchAnalysis合并到一起这样就增加了修改的难度。
因为next方法也被取消需要取词时直接通过调用TokenManager的getNextToken方法来取得而这个方法是JavaCC自动产生的无法自行定制。
解决的办法是利用JavaCC语法提供的TOKEN_MGR_DECLS段在TokenManager中加入用户定义的
代码通过重写getNextToken方法来判断返回的单词的种类。
如果不是CHINESE中文类型则直接返回否则进行分词分别返回分词的结果。
与英文分词不同的是中文分词有多种方式。
例如有前向递增最大分词前向递增最小分词等8种方法适用的范围是不相同的。
在Lucene或Nutch中如果是为了制作索引那么应该使用全部的4种前向分词即前向递增最大分词、前向递增最小分词、前向递减最大分词、前向递减最小分词。
这是因为索引词库要尽量全使用全部的分词可以保证所有的词都被提取出来。
还有一种情况是为了使用查询分析器即对查询字符串进行分析这时只需使用前向递增最大分词。
4 结论 JavaCC是一个强大的词法和语法分析工具Lucene和Nutch利用JavaCC构造语言分析模块的设计架构使系统具有良好的可扩展性为构造不同语种的语言分析模块奠定了基础。
实验表明利用JavaCC和中文词表分词技术实现的中文分析模块与原系统具有良好的兼容性相对于商用的搜索引擎 Nutch作为开放源
代码搜索引擎将会更加透明从而更值得广大Internet用户信赖。
参考文献: 徐宝文 张卫丰. 搜索引擎与信息获取技术M.北京: 清华大学出版社 2003. Xue Bao-wen Zhang Wei-feng. Search Engine and Information Acquire Technology M. Beijing: Tsinghua University Press 2003. 姚天顺 朱靖波 张琍. 自然语言理解M. 北京: 清华大学出版社 2002. Yao Tian-sun Zhu Jing-bo Zhang Li. Natural Language Comprehension M. Beijing: Tsinghua University Press 2002. 丁承 邵志清. 基于字表的中文搜索引擎分词系统J.计算机工程20012:191-193. Ding Cheng Shao Zhi-qing. Word Segmentation System Based on Character Table for Chinese Search Engine: Design and Implementation J. Journal of Computer Engineering20012:191-193. 姚砺 束永安. 用JavaCC构造编译器的方法J.计算机工程20039: 39-41. Yao Li Su Yong-an. Method of Constructing Compiler with JavaCC J. Journal of Computer Engineering 20039: 39-41. 吕映芝 张素琴 蒋维杜. 编译原理M. 北京: 清华大学出版社 1998. Lǜ Ying-zhi Zhang Su-qin Jiang Wei-du. Compiling Principle M. Beijing: Tsinghua University Press 1998.