Lucene笔记17-Lucene的分词-中文分词介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36059561/article/details/83404331

一、分词器的作用

分词器的作用就是得到一个TokenStream流,这个流中存储了分词相关的一些信息,可以通过属性获取到分词的详细信息。

二、自定义Stop分词器

package com.wsy;

import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.apache.lucene.util.Version;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Set;

public class MyStopAnalyzer extends Analyzer {
    private Set set;

    public MyStopAnalyzer(String[] stopWords) {
        // 查看StopAnalyzer中的英文停用词
        System.out.println(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
        set = StopFilter.makeStopSet(Version.LUCENE_35, stopWords, true);
        // 加入原来的停用词
        set.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
    }

    public MyStopAnalyzer() {
        set = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
    }

    @Override
    public TokenStream tokenStream(String fieldName, Reader reader) {
        return new StopFilter(Version.LUCENE_35, new LowerCaseFilter(Version.LUCENE_35, new LetterTokenizer(Version.LUCENE_35, reader)), set);
    }

    public static void displayAllToken(String string, Analyzer analyzer) {
        try {
            TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(string));
            // 放入属性信息,为了查看流中的信息
            // 位置增量信息,语汇单元之间的距离
            PositionIncrementAttribute positionIncrementAttribute = tokenStream.addAttribute(PositionIncrementAttribute.class);
            // 每个语汇单元的位置偏移量信息
            OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
            // 每一个语汇单元的分词信息
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
            // 使用的分词器的类型信息
            TypeAttribute typeAttribute = tokenStream.addAttribute(TypeAttribute.class);
            while (tokenStream.incrementToken()) {
                System.out.println(positionIncrementAttribute.getPositionIncrement() + ":" + charTermAttribute + "[" + offsetAttribute.startOffset() + "-" + offsetAttribute.endOffset() + "]-->" + typeAttribute.type());
            }
            System.out.println("----------------------------");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 自定义的停用词分词器
        Analyzer analyzer1 = new MyStopAnalyzer(new String[]{"I", "you", "hate"});
        // 默认的停用词分词器
        Analyzer analyzer2 = new StopAnalyzer(Version.LUCENE_35);
        String string = "how are you, thank you. I hate you.";
        MyStopAnalyzer.displayAllToken(string, analyzer1);
        MyStopAnalyzer.displayAllToken(string, analyzer2);
    }
}

下面这条语句非常重要,用于给分词器设置过滤链和Tokenizer,如果还需要添加,继续向里面添加即可。

new StopFilter(Version.LUCENE_35, new LowerCaseFilter(Version.LUCENE_35, new LetterTokenizer(Version.LUCENE_35, reader)), set);

三、中文分词器

说道中文分词器,种类还是不少的,paoding分词,mmseg分词,IK分词等等。不过有些已经不更新了。

这里拿mmseg做演示,mmseg是基于搜狗的词库的,下载mmseg4j-1.8.5的压缩包。打开查看里面的内容,其中data中存放的是分词的词库,将jar包导入进项目,mmseg-all有两个jar包,一个是带dic的,一个是不带dic的,这里我们使用不带dic的。使用默认的分词词库测试了一下这样一段话“我来自山东聊城,我叫王劭阳。”,发现“聊城”被分成了“聊”和“城”,不服啊,竟然没有我大聊城?那么我们自己加上吧,打开data文件夹中的words-my.dic,添加上“聊城”,再次去看分词,“聊城”就会被分成“聊城”啦。

public static void main(String[] args) {
    // mmseg分词器
    // 没有指定分词库时候,一个字一个字的分词
    Analyzer analyzer3 = new MMSegAnalyzer();
    // 指定本地分词库后,根据分词器分词
    Analyzer analyzer4 = new MMSegAnalyzer(new File("E:\\Lucene\\mmseg4j-1.8.5\\data"));
    String string2 = "我来自山东聊城,我叫王劭阳。";
    MyStopAnalyzer.displayAllToken(string2, analyzer3);
    MyStopAnalyzer.displayAllToken(string2, analyzer4);
}

猜你喜欢

转载自blog.csdn.net/qq_36059561/article/details/83404331