Lucene中的分词器概述

分词器概述

在对Document中的内容进行索引之前,需要使用分词器(Analyzer)进行分词,分词的目的是为了搜索。分词的主要过程就是先分词后过滤。

  • 分词:采集到的数据会存储到document对象的Field域中,分词就是将Document中Field的value值切分成一个一个的词。
  • 过滤:包括去除标点符号过滤、去除停用词过滤(的、是、a、an. the等)、大写转小写、词的形还原(复数形式转成单数形参、过去式转成现在式。。。)等。

停用词: 停用词是为节省存储空间和提高搜索效率,搜索引擎在索引页面或处理搜索请求时会自动忽略某些字或词,这些字或词即被称为Stop Words(停用词)。比如语气助词、副词、介词、连接词等,通常自身并无明确的意义,只有将其放入一个完整的句子中才有一定作用,如常见的“的”、“在”、“是”、“啊”等。

对于分词来说,不同的语言,分词规则不同。Lucene作为一个工具包提供不同语言的分词器。

不论是建立索引还是查询的时候都要使用分词器,而且最好是使用同一个分词器。

Lucene原生分词器

StandardAnalyzer

特点: Lucene提供的标准分词器, 可以对用英文进行分词, 对中文是单字分词, 也就是一个字就认为是一个词。

@Override
protected TokenStreamComponents createComponents(final String fieldName) {
    final StandardTokenizer src = new StandardTokenizer();
    src.setMaxTokenLength(maxTokenLength);
    TokenStream tok = new LowerCaseFilter(src);
    tok = new StopFilter(tok, stopwords);
    return new TokenStreamComponents(src, tok) {
        @Override
        protected void setReader(final Reader reader) {
            // So that if maxTokenLength was changed, the change takes
            // effect next time tokenStream is called:
            src.setMaxTokenLength(StandardAnalyzer.this.maxTokenLength);
            super.setReader(reader);
        }
    };
}

Tokenizer 就是分词器,负责将reader转换为语汇单元即进行分词处理,Lucene提供了很多的分词器,也可以使用第三方的分词,比如IKAnalyzer一个中文分词器。

TokenFilter是分词过滤器,负责对语汇单元进行过滤,TokenFilter可以是一个过滤器链,Lucene提供了很多的分词器过滤器,比如大小写转换、去除停用词等。

如下图是语汇单元的生成过程:

Lucene中的分词器概述

从一个 Reader字符流开始,创建一个基于Reader的Tokenizer分词器,经过三个TokenFilter生成语汇单元Token。

WhitespaceAnalyzer

特点: 仅仅是去掉了空格,没有其他任何操作,不支持中文。

SimpleAnalyzer

特点: 将除了字母以外的符号全部去除,并且将所有字母变为小写,需要注意的是这个分词器同样把数字也去除了,同样不支持中文。

CJKAnalyzer

特点: 这个支持中日韩文字,前三个字母也就是这三个国家的缩写。对中文是二分法分词, 去掉空格, 去掉标点符号。个人感觉对中文支持依旧很烂。

第三方分词器简介

  • paoding : 庖丁解牛最新版在 https://code.google.com/p/paoding/ 中最多支持Lucene 3.0,且最新提交的代码在 2008-06-03,在svn中最新也是2010年提交,已经过时,不予考虑。
  • mmseg4j :最新版已从 https://code.google.com/p/mmseg4j/ 移至 https://github.com/chenlb/mmseg4j-solr,支持Lucene 4.10,且在github中最新提交代码是2017年1月,从09年~14年一共有18个版本,也就是一年几乎有3个大小版本,有较大的活跃度,用了mmseg算法。
  • IK-analyzer : 最新版在 https://code.google.com/p/ik-analyzer/上,支持Lucene 4.10从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。 但是也就是2012年12月后没有再更新。
  • ansj_seg :最新版本在 https://github.com/NLPchina/ansj_seg tags仅有1.1版本,从2012年到2014年更新了大小6次,但是作者本人在2014年10月10日说明:“可能我以后没有精力来维护ansj_seg了”,现在由”nlp_china”管理。2014年11月有更新。并未说明是否支持Lucene,是一个由CRF(条件随机场)算法所做的分词算法。
  • imdict-chinese-analyzer :最新版在 https://code.google.com/p/imdict-chinese-analyzer/ , 最新更新也在2009年5月,下载源码,不支持Lucene 4.10 。是利用HMM(隐马尔科夫链)算法。
  • Jcseg :最新版本在git.oschina.net/lionsoul/jcseg,支持Lucene 4.10,作者有较高的活跃度。利用mmseg算法。

ik分词器用户可自定义拓展:

  • 扩展词典:
    放专有名词,或者是我们认为需要强制将某一些字分成一个词。凡是出现在扩展词典中的词,就会被强制分成一个词。
  • 停用词典:
    凡是出现在停用词典中的词,都会被过滤掉.

先建立配置文件IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>IK Analyzer 扩展配置</comment>
    <!--用户可以在这里配置自己的扩展字典 -->
    <entry key="ext_dict">ext.dic;</entry>

    <!--用户可以在这里配置自己的扩展停止词字典-->
    <entry key="ext_stopwords">stopword.dic;</entry>

</properties>

ext.dic为拓展词典,每个词单独占一行:

华为
手机
华为手机
森马
南极人
三星
苹果

stopword.dic为拓展词典,每个词单独占一行:

a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
of
on
...

测试:

@Test
public void TestIKAnalyzer() throws Exception{
    // 1. 创建分词器,分析文档,对文档进行分词
    Analyzer analyzer = new IKAnalyzer();
    // 2. 创建Directory对象,声明索引库的位置
    Directory directory = FSDirectory.open(Paths.get("E:\\dir"));
    // 3. 创建IndexWriteConfig对象,写入索引需要的配置
    IndexWriterConfig config = new IndexWriterConfig(analyzer);
    // 4.创建IndexWriter写入对象
    IndexWriter indexWriter = new IndexWriter(directory, config);
    // 5.写入到索引库,通过IndexWriter添加文档对象document
    Document doc = new Document();
    doc.add(new TextField("name", "vivo X23 8GB+128GB 幻夜蓝,水滴屏全面屏,游戏手机.移
    动联通电信全网通4G手机", Field.Store.YES));
    indexWriter.addDocument(doc);
    // 6.释放资源
    indexWriter.close();
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/lucene%e4%b8%ad%e7%9a%84%e5%88%86%e8%af%8d%e5%99%a8%e6%a6%82%e8%bf%b0/

发表评论

电子邮件地址不会被公开。