`
sealbird
  • 浏览: 590841 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

CLucene加入ICTCLAS中文分词

    博客分类:
  • C++
阅读更多
  
 最近,我在开发桌面搜索软件,其中桌面搜索最核心的部分就是全文检索。之前已经完成了一个初始版本。全文检索是使用的中科院计算所郭博士的Firtex,后来有位老师说Firtex最近没人在维护,建议使用CLucene,于是我老板就提议再开发另一个版本——CLucene版的桌面搜索。

CLucene是C++版的Lucene,提供全文检索的功能。在网上找了部分资料,主要都是如何在CLucene中加入中文分词。于是我根据网上的资料和自己在开发过程中对CLucene的理解,开始向CLucene加入中文分词。听说ICTCLAS的中文分词很出名,就拿来试试。

CLucene使用的是0.9.21版,同时通过svn更新到最新的文件,下载地址是

http://sourceforge.net/projects/clucene/。

ICTCLAS中文分词使用是ICTCLAS3.0,这是共享版,但不开源,可以增加用户自定义词典,下载地址

http://www.ictclas.org/Download.html。

CLucene只支持Unicode的编码,所以对需要对输入的字符串都要进行转换。在Windows下可以使用api WideCharToMultiByte和MultiByteToWideChar。在Linux下,可以使用linux下有著名的iconv。

我的开发平台是windows,vs2005。在CLucene中加入中文分词,分三步完成。

1、把项目设置为Use Unicode Character Set。因为使用ANSI时,汉字存在与其他语言编码重叠的问题,不能准确判断是否为汉字。一般下载的CLucene默认就是设置好的。

2、 \src\CLucene\util\Misc.cpp中有个Misc::_cpycharToWide函数,这个函数是CLucene中用来将char字符串转换为wchar_t字符串的,但原代码中使用的是不考虑编码的转换,把汉字从ANSI编码转到UCS2编码会失效,所以需要使用MultiByteToWideChar进行转换。同样的在同一个文件中,有这样一个函数Misc::_cpywideToChar,是将wchar_t转换成char,同理使用WideCharToMultiByte进行转换。

3、也是最麻烦的一步。如果了解Lucene结构的开发者,应该知道Lucene进行索引前需要对文本进行分词,就是需要使用Analyzer类进行分词。在CLucene中有一个StandardAnalyzer类,它本意是可以处理亚洲语言(包括中日韩),但不完善。可以通过改写 \src\CLucene\analysis\standard\StandardTokenizer.cpp文件来达到目的。因此,在这一步有二种方法,一是上面所说的,修改StandardTokenizer,让它支持中文分词。另一个就是自己写一个ChineseTokenizer和ChineseAnalyzer,在索引的时候调用它就好了,同样查询的时候也要ChineseAnalyzer进行分析。

第一种方法:在StandardTokenizer中有一个StandardTokenizer::next()方法,用来获取下一个token。Token可以简单看成是索引文件中的一个项。在原代码中,先判断是否为ALPHA,再判断是否为_CJK,而在中文windows系统上,将一个UCS2编码的汉字(正好一个wchar_t)作为参数传给 iswalpha函数时,返回值是true。所以任何CJK字符都会被处理成ALPHA。因此,项目修改为使用Unicode编码后,ReadCJK函数 不会被调用到。所以需要将原代码中的if(_CJK)的判断分支放到if(ALPHA)前面,这样遇到CJK字符时就会调用 StandardTokenizer::ReadCJK。ReadCJK函数用于读取一个CJK的token。这个函数不能处理中文分词,它遇到CJK字符时一直向后读取,直到遇到非CJK字符或文件结束才跳出,把读取到的整个字符串作为索引中的一个项。所以需要重写这个函数。我个人认为这个方法需要修改原代码地方太多,而且代码重用率低,所以我选择了第二种方法。

第二种方法:就是自己重新写一个ChineseAnalyzer和ChineseTokenizer。这样对原代码修改少,改错也方便,最重要可以将它应用其他需要的程序中。其实这两个类也并不难写,只要根据StandardTokenizer和StandardAnalyzer的结构,模仿一下就行了。ChineseTokenizer是继承Tokenizer类的,必须实现Tokenizer类的next()虚成员函数。这个成员函数就是要输入下一个分词的字符串。所以在这里将ICTCLAS加入,每次将一个分词输出就好。因此ICTCLAS只支持char类型分词,所以还要将Unicode转换成char,分词使用ParagraphProcess函数。关键代码如下:
  

str=STRDUP_TtoA(ioBuffer); //将输入字符串转换成char
  
   pResult=STRDUP_AtoT(ICTCLAS_ParagraphProcess(str,0)); //ICTCLAS中文分词函数调用
   _CLDELETE_ARRAY(str);// 回收内存

pResult保存了分词后的结构,每个词是空格分隔,所以每次调用next()时,都从pResult里取下一个词,直接取完,则从Reader里读入下一段,继续分词,直接Reader已经到达尾部。代码如下

TCHAR word[LUCENE_MAX_WORD_LEN]={0}; //保存单个词的临时空间
while(pResult[end] !=_T(' ') && end <nCount) //查找空间,找到单词的结束位置
{
   word[end-start]=pResult[end];
   end++;
}
word[end-start]=0;
while(pResult[end]==_T(' ') && end<nCount) end++;   //查找下一个词的开始位置
start=end;
token->setText(word); //输出到token

这个完成之后,ChineseTokenizer也就完成了。不过在这过程中,发现ICTCLAS分词速度并没想象中的快。不知道是不是因为这个是共享版的问题。


ChineseTokenizer完成后,接着就实现ChineseAnalyzer类。这个更加简单,只要完全模仿StandardAnalyzer就好了。ChineseAnalyzer是继承于Analyzer的,同样必须实现TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader)就可以了。这个只要生成一个ChineseTokenizer,返回就行了。代码如下:

TokenStream* ChineseAnalyzer::tokenStream(const TCHAR* fieldName, Reader* reader) {
   TokenStream* ret= _CLNEW ChineseTokenizer(reader); //中文分词ChineseTokenizer
   ret = _CLNEW LowerCaseFilter(ret,true);   //英文大小变换,统一成小写
   ret = _CLNEW StopFilter(ret,true, &stopSet); //停用词过滤,如“的”,“这”,“an”

   return ret;
}

关于停用词的过滤,可以修改\src\CLucene\analysis\Analyzers.cpp里关于StopAnalyzer的定义。我个人加入了中文的停用词表

static const TCHAR* CHINESE_STOP_WORDS[];

在ChineseAnalyzer的构造函数里,将停用词表加入到映射中,先在ChineseAnalyzer里定义这个成员
   CL_NS(util)::CLSetList<const TCHAR*> stopSet;用于保存停用词表,再加构造函数里加入下面这句:

StopFilter::fillStopTable( &stopSet,CL_NS(analysis)::StopAnalyzer::CHINESE_STOP_WORDS);

这样就完成了ChineseAnalyzer类。

接着就可以在索引里使用这个ChineseAnalyzer。
索引时需要生成ChineseAnalyzer的一个实例,将它传给IndexWriter。

查询时也是一样的道理,只不过是将它传给QueryParser。

这样就完成了CLucene加入ICTCLAS中文分词,但是发现ICTCLAS的分词速度不行,我只使用65K的文件就需要至少10秒的时间才完成。我正在寻找能替换ICTCLAS的中文分词。
分享到:
评论

相关推荐

    clucene中文处理

    总的来说,"clucene中文处理"是一个综合性的任务,它涵盖了中文分词、索引构建、查询解析、编码处理等多个技术领域。开发者需要对C++编程、自然语言处理、信息检索等领域有深入的理解,才能有效地实现和优化Clucene...

    CLucene源代码-Lucene的C++版本

    分析器负责分词、去除停用词、词形还原等任务,以确保索引的质量。CLucene和CLucene都支持自定义分析器,可以根据具体需求调整分析过程。 3. **文档(Document)**:在CLucene中,文档是信息的基本单元,可以包含多...

    C++搜索引擎Clucene源码

    在Clucene的源码中,我们可以看到这些组件的具体实现,例如`TokenStream`接口定义了分词流的行为,`Analyzer`类负责整个分词过程,`IndexWriter`类处理索引的建立和更新,`IndexReader`用于读取索引,`QueryParser`...

    luceneDemo_pure1aa_DEMO_clucene_

    1. **索引创建**:DEMO首先会读取文本数据,使用Clucene的Analyzer进行分词,然后创建IndexWriter对象,将分词后的文档写入索引。 2. **索引优化**:创建索引后,可能需要进行优化操作,以提高检索效率。这通常通过...

    CLucene

    1. **分词和分析**:CLucene内建了对文本的分词处理,支持多种语言的分词器。它提供了Tokenization(分词)和Analyzer(分析器)的概念,允许用户自定义文本处理流程,以适应不同语言和应用场景。 2. **索引构建**:...

    搜索引擎 CLucene 源代码

    4. **分词支持**:CLucene 内置了对多种语言的分词支持,可以处理英文、中文等不同语言的文本。 5. **索引和存储**:CLucene 可以创建倒排索引,将文本数据转化为可快速查询的结构。同时,它还提供了对原始数据的...

    C++搜索引擎 CLucene源码

    4. **文本分析**:CLucene支持多种语言的文本分析,包括分词、去除停用词、词干化等,这些预处理步骤对于提高搜索精度至关重要。 5. **倒排索引**:CLucene采用了倒排索引这一高效的数据结构,通过记录每个词在哪些...

    Clucene库以及自己封装好的Clucene方法库

    1. **建立索引**:Clucene允许开发者对大量文本数据进行索引,这个过程包括分词、建立倒排索引等步骤。分词是将文本拆分成独立的词语,倒排索引则是将每个词语对应的文档位置信息存储起来,以便于快速查找。 2. **...

    CLucene 最新源码

    1. **分词器(Tokenizer)**:CLucene提供了一系列的分词器,如StandardAnalyzer,用于将输入的文本分解成可搜索的关键词。分词器可以根据不同的语言进行定制,以适应各种文本处理需求。 2. **文档(Document)**:...

    clucene源码

    大名鼎鼎的clucene,是lucene的c++ 版; CLucene README ============== ------------------------------------------------------ CLucene is a C++ port of Lucene. It is a high-performance, full-featured ...

    Clucene使用示例

    Clucene 使用示例 Clucene 是一个基于 Lucene 搜索引擎的 C++ 实现,它提供了一个简单而强大的搜索引擎解决方案。本文将通过一个示例程序,展示如何使用 Clucene 创建索引、编译程序和使用搜索引擎。 一、创建索引...

    lucene及分词工具说明

    ### Lucene及分词工具说明 #### 一、概述 Lucene是一款高性能的全文...通过以上内容,我们可以了解到如何使用CLucene支持中文处理以及如何利用分词工具进行中文文本的分词。这对于中文搜索引擎的开发具有重要的意义。

    clucene2.3.3.4源码 windows下vs2013工程

    《CLucene 2.3.3.4源码在Windows环境下使用Visual Studio 2013的工程实践》 CLucene是一款开源的全文搜索引擎库,它基于C++编写,为开发者提供了一种高效、可扩展的全文检索解决方案。在本文中,我们将详细探讨如何...

    clucene-0.9.10.tar

    1. 分词和分析:Clucene能够对输入的文本进行分词处理,去除停用词,进行词干化等,以便于建立有效的索引。 2. 倒排索引:这是Clucene的核心,它将每个单词映射到包含该词的文档列表,使得搜索操作可以在极短的时间...

    搜索引擎开源代码Clucene-core-0.9.21

    1. **分词和索引**:Clucene使用了高效的分词算法,将文本分解成有意义的单词或短语(称为术语),并创建一个索引,使得可以快速查找包含特定术语的文档。 2. **倒排索引**:这是搜索引擎最核心的数据结构。Clucene...

    CLUCENE资料合集+代码源码

    这是我学CLUCENE时期整理出来的几个不错的资料,我觉得里面总有一款会适合你,而且你所需要知道的技术里面基本上都是涵盖的,所以可以当作教材或者参考手册使用。(里面有CLUCENE,可以用的)

    Clucene库以及自己封装的方法库(补充)——对应的头文件和.lib索引文件

    Clucene库是一个开源的全文搜索引擎库,它是Lucene的一个C++版本,旨在提供与Java Lucene相似的功能。在IT行业中,全文搜索引擎对于处理大量文本数据的检索和查询至关重要,尤其在内容管理和信息检索系统中应用广泛...

    CLucene结构文档

    CLucene类结构文档 内嵌源代码及各类关系图

    clucene-core-2.3.3.4

    《关于Clucene-core-2.3.3.4在Visual Studio 2005环境下的构建与修改》 Clucene-core-2.3.3.4是一款基于C++的全文搜索引擎库,它是Lucene的C++版本。Lucene是Java语言实现的一个全文检索库,而Clucene则为那些更...

    clucene-core-2.3.3.4 cmake可生产vs2005工程

    标题"clucene-core-2.3.3.4 cmake可生产vs2005工程"指的是一个开源全文搜索引擎库Clucene的特定版本2.3.3.4,它已经配置为使用CMake构建系统,能够生成适用于Visual Studio 2005的工程文件。CMake是一个跨平台的开源...

Global site tag (gtag.js) - Google Analytics