Elasticsearch常见分词器对比区别,并讲解一下其各自使用方法

介绍:ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

Elasticsearch 中,内置了很多分词器(analyzers)。下面来进行比较下系统默认分词器和常用的中文分词器之间的区别。

系统默认分词器:

1、standard 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html

如何使用:http://www.yiibai.com/lucene/lucene_standardanalyzer.html

英文的处理能力同于 StopAnalyzer. 支持中文采用的方法为单字切分。他会将词汇单元转换成小写形式,并去除停用词和标点符号。

/**StandardAnalyzer分析器*/
    public void standardAnalyzer(String msg){
        StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
        this.getTokens(analyzer, msg);
    }

2、simple 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-simple-analyzer.html

如何使用: http://www.yiibai.com/lucene/lucene_simpleanalyzer.html

功能强于 WhitespaceAnalyzer, 首先会通过非字母字符来分割文本信息,然后将词汇单元统一为小写形式。该分析器会去掉数字类型的字符。

/**SimpleAnalyzer分析器*/
    public void simpleAnalyzer(String msg){
        SimpleAnalyzer analyzer = new SimpleAnalyzer(Version.LUCENE_36);
        this.getTokens(analyzer, msg);
    }

3、Whitespace 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-whitespace-analyzer.html

如何使用:http://www.yiibai.com/lucene/lucene_whitespaceanalyzer.html

仅仅是去除空格,对字符没有 lowcase 化, 不支持中文;并且不对生成的词汇单元进行其他的规范化处理。

/**WhitespaceAnalyzer分析器*/
    public void whitespaceAnalyzer(String msg){
        WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer(Version.LUCENE_36);
        this.getTokens(analyzer, msg);
    }

4、Stop 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stop-analyzer.html

如何使用:http://www.yiibai.com/lucene/lucene_stopanalyzer.html

StopAnalyzer 的功能超越了 SimpleAnalyzer,在 SimpleAnalyzer 的基础上增加了去除英文中的常用单词(如 the,a 等),也可以更加自己的需要设置常用单词;不支持中文

/**StopAnalyzer分析器*/
   public void stopAnalyzer(String msg){
       StopAnalyzer analyzer = new StopAnalyzer(Version.LUCENE_36);
       this.getTokens(analyzer, msg);
   }

5、keyword 分词器

KeywordAnalyzer 把整个输入作为一个单独词汇单元,方便特殊类型的文本进行索引和检索。针对邮政编码,地址等文本信息使用关键词分词器进行索引项建立非常方便。

6、pattern 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-pattern-analyzer.html

一个 pattern 类型的 analyzer 可以通过正则表达式将文本分成 "terms"(经过 token Filter 后得到的东西)。接受如下设置:

一个 pattern analyzer 可以做如下的属性设置:

lowercaseterms 是否是小写. 默认为 true 小写.
pattern正则表达式的 pattern, 默认是 W+.
flags正则表达式的 flags
stopwords一个用于初始化 stop filter 的需要 stop 单词的列表. 默认单词是空的列表

7、language 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lang-analyzer.html

一个用于解析特殊语言文本的 analyzer 集合。( arabic,armenian, basque, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, finnish, french,galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian,persian, portuguese, romanian, russian, sorani, spanish, swedish, turkish, thai.)可惜没有中文。不予考虑

8、snowball 分词器

一个 snowball 类型的 analyzer 是由 standard tokenizer 和 standard filter、lowercase filter、stop filter、snowball filter 这四个 filter 构成的。

snowball analyzer 在 Lucene 中通常是不推荐使用的。

9、Custom 分词器

是自定义的 analyzer。允许多个零到多个 tokenizer,零到多个 Char Filters. custom analyzer 的名字不能以 "_" 开头.

The following are settings that can be set for a custom analyzer type:

SettingDescription
tokenizer通用的或者注册的 tokenizer.
filter通用的或者注册的 token filters
char_filter通用的或者注册的 character filters
position_increment_gap距离查询时,最大允许查询的距离,默认是 100

自定义的模板:

index :
    analysis :
        analyzer :
            myAnalyzer2 :
                type : custom
                tokenizer : myTokenizer1
                filter : [myTokenFilter1, myTokenFilter2]
                char_filter : [my_html]
                position_increment_gap: 256
        tokenizer :
            myTokenizer1 :
                type : standard
                max_token_length : 900
        filter :
            myTokenFilter1 :
                type : stop
                stopwords : [stop1, stop2, stop3, stop4]
            myTokenFilter2 :
                type : length
                min : 0
                max : 2000
        char_filter :
              my_html :
                type : html_strip
                escaped_tags : [xxx, yyy]
                read_ahead : 1024

10、fingerprint 分词器

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-fingerprint-analyzer.html

中文分词器:

1、ik-analyzer

https://github.com/wks/ik-analyzer

IKAnalyzer 是一个开源的,基于 java 语言开发的轻量级的中文分词工具包。

采用了特有的 “正向迭代最细粒度切分算法 “,支持细粒度和最大词长两种切分模式;具有 83 万字 / 秒(1600KB/S)的高速处理能力。

采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符

优化的词典存储,更小的内存占用。支持用户词典扩展定义

针对 Lucene 全文检索优化的查询分析器 IKQueryParser(作者吐血推荐);引入简单搜索表达式,采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高 Lucene 检索的命中率。

Maven 用法:

<dependency>
    <groupId>org.wltea.ik-analyzer</groupId>
    <artifactId>ik-analyzer</artifactId>
    <version>3.2.8</version>
</dependency>

在 IK Analyzer 加入 Maven Central Repository 之前,你需要手动安装,安装到本地的 repository,或者上传到自己的 Maven repository 服务器上。

要安装到本地 Maven repository,使用如下命令,将自动编译,打包并安装:mvn install -Dmaven.test.skip=true

Elasticsearch 添加中文分词
安装 IK 分词插件

https://github.com/medcl/elasticsearch-analysis-ik

进入 elasticsearch-analysis-ik-master

更多安装请参考博客:

1、为 elastic 添加中文分词
http://blog.csdn.net/dingzfang/article/details/42776693

2、如何在 Elasticsearch 中安装中文分词器 (IK+pinyin) http://www.cnblogs.com/xing901022/p/5910139.html

3、Elasticsearch 中文分词器 IK 配置和使用 http://blog.csdn.net/jam00/article/details/52983056

2、结巴中文分词

特点:

1、支持三种分词模式:

  • 精确模式,试图将句子最精确地切开,适合文本分析;

  • 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;

  • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

2、支持繁体分词

3、支持自定义词典

3、THULAC

THULAC(THU Lexical Analyzer for Chinese)由清华大学自然语言处理与社会人文计算实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能。THULAC 具有如下几个特点:

能力强。利用我们集成的目前世界上规模最大的人工分词和词性标注中文语料库(约含 5800 万字)训练而成,模型标注能力强大。

准确率高。该工具包在标准数据集 Chinese Treebank(CTB5)上分词的 F1 值可达 97.3%,词性标注的 F1 值可达到 92.9%,与该数据集上最好方法效果相当。

速度较快。同时进行分词和词性标注速度为 300KB/s,每秒可处理约 15 万字。只进行分词速度可达到 1.3MB/s。

中文分词工具 thulac4j 发布

1、规范化分词词典,并去掉一些无用词;

2、重写 DAT(双数组 Trie 树)的构造算法,生成的 DAT size 减少了 8% 左右,从而节省了内存;

3、优化分词算法,提高了分词速率。

<dependency>
  <groupId>io.github.yizhiru</groupId>
  <artifactId>thulac4j</artifactId>
  <version>${thulac4j.version}</version>
</dependency>

http://www.cnblogs.com/en-heng/p/6526598.html

thulac4j 支持两种分词模式:

SegOnly 模式,只分词没有词性标注;

SegPos 模式,分词兼有词性标注。

// SegOnly mode
String sentence = "滔滔的流水,向着波士顿湾无声逝去";
SegOnly seg = new SegOnly("models/seg_only.bin");
System.out.println(seg.segment(sentence));
// [滔滔, 的, 流水, ,, 向着, 波士顿湾, 无声, 逝去]

// SegPos mode
SegPos pos = new SegPos("models/seg_pos.bin");
System.out.println(pos.segment(sentence));
//[滔滔/a, 的/u, 流水/n, ,/w, 向着/p, 波士顿湾/ns, 无声/v, 逝去/v]

4、NLPIR

中科院计算所 NLPIR:http://ictclas.nlpir.org/nlpir/ (可直接在线分析中文)

下载地址:https://github.com/NLPIR-team/NLPIR

中科院分词系统 (NLPIR)JAVA 简易教程: http://www.cnblogs.com/wukongjiuwo/p/4092480.html

5、ansj 分词器

https://github.com/NLPchina/ansj_seg

这是一个基于 n-Gram+CRF+HMM 的中文分词的 java 实现.

分词速度达到每秒钟大约 200 万字左右(mac air 下测试),准确率能达到 96% 以上

目前实现了. 中文分词. 中文姓名识别 .

用户自定义词典, 关键字提取,自动摘要,关键字标记等功能 可以应用到自然语言处理等方面, 适用于对分词效果要求高的各种项目.

maven 引入:

<dependency>
            <groupId>org.ansj</groupId>
            <artifactId>ansj_seg</artifactId>
            <version>5.1.1</version>
</dependency>

调用 demo

String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我.我一定尽我所能.帮助大家.ansj_seg更快,更准,更自由!" ;
 System.out.println(ToAnalysis.parse(str));

 欢迎/v,使用/v,ansj/en,_,seg/en,,,(,ansj/en,中文/nz,分词/n,),在/p,这里/r,如果/c,你/r,遇到/v,什么/r,问题/n,都/d,可以/v,联系/v,我/r,./m,我/r,一定/d,尽我所能/l,./m,帮助/v,大家/r,./m,ansj/en,_,seg/en,更快/d,,,更/d,准/a,,,更/d,自由/a,!

6、哈工大的 LTP

https://link.zhihu.com/?target=https%3A//github.com/HIT-SCIR/ltp

LTP 制定了基于 XML 的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等 6 项中文处理核心技术),以及基于动态链接库(Dynamic Link Library, DLL)的应用程序接口、可视化工具,并且能够以网络服务(Web Service)的形式进行使用。

关于 LTP 的使用,请参考: http://ltp.readthedocs.io/zh_CN/latest/

7、庖丁解牛

下载地址:http://pan.baidu.com/s/1eQ88SZS

使用分为如下几步:

  1. 配置 dic 文件:修改 paoding-analysis.jar 中的 paoding-dic-home.properties 文件,将 “#paoding.dic.home=dic” 的注释去掉,并配置成自己 dic 文件的本地存放路径。eg:/home/hadoop/work/paoding-analysis-2.0.4-beta/dic

  2. 把 Jar 包导入到项目中:将 paoding-analysis.jar、commons-logging.jar、lucene-analyzers-2.2.0.jar 和 lucene-core-2.2.0.jar 四个包导入到项目中,这时就可以在代码片段中使用庖丁解牛工具提供的中文分词技术,例如:

Analyzer analyzer = new PaodingAnalyzer(); //定义一个解析器
String text = "庖丁系统是个完全基于lucene的中文分词系统,它就是重新建了一个analyzer,叫做PaodingAnalyzer,这个analyer的核心任务就是生成一个可以切词TokenStream。"; <span style="font-family: Arial, Helvetica, sans-serif;">//待分词的内容</span>
TokenStream tokenStream = analyzer.tokenStream(text, new StringReader(text)); //得到token序列的输出流
try {
    Token t;
    while ((t = tokenStream.next()) != null)
    {
           System.out.println(t); //输出每个token
    }
} catch (IOException e) {
    e.printStackTrace();
}

8、sogo 在线分词

sogo 在线分词采用了基于汉字标注的分词方法,主要使用了线性链链 CRF(Linear-chain CRF)模型。词性标注模块主要基于结构化线性模型(Structured Linear Model)

在线使用地址为:http://www.sogou.com/labs/webservice/

9、word 分词

地址:https://github.com/ysc/word

word 分词是一个 Java 实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用 ngram 模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过自定义配置文件来改变组件行为,能自定义用户词库、自动检测词库变化、支持大规模分布式环境,能灵活指定多种分词算法,能使用 refine 功能灵活控制分词结果,还能使用词频统计、词性标注、同义标注、反义标注、拼音标注等功能。提供了 10 种分词算法,还提供了 10 种文本相似度算法,同时还无缝和 Lucene、Solr、ElasticSearch、Luke 集成。注意:word1.3 需要 JDK1.8

maven 中引入依赖:

<dependencies>
    <dependency>
        <groupId>org.apdplat</groupId>
        <artifactId>word</artifactId>
        <version>1.3</version>
    </dependency>
</dependencies>

ElasticSearch 插件:

1、打开命令行并切换到elasticsearch的bin目录
cd elasticsearch-2.1.1/bin

2、运行plugin脚本安装word分词插件:
./plugin install http://apdplat.org/word/archive/v1.4.zip

安装的时候注意:
    如果提示:
        ERROR: failed to download
    或者
        Failed to install word, reason: failed to download
    或者
        ERROR: incorrect hash (SHA1)
    则重新再次运行命令,如果还是不行,多试两次

如果是elasticsearch1.x系列版本,则使用如下命令:
./plugin -u http://apdplat.org/word/archive/v1.3.1.zip -i word

3、修改文件elasticsearch-2.1.1/config/elasticsearch.yml,新增如下配置:
index.analysis.analyzer.default.type : "word"
index.analysis.tokenizer.default.type : "word"

4、启动ElasticSearch测试效果,在Chrome浏览器中访问:
http://localhost:9200/_analyze?analyzer=word&text=杨尚川是APDPlat应用级产品开发平台的作者

5、自定义配置
修改配置文件elasticsearch-2.1.1/plugins/word/word.local.conf

6、指定分词算法
修改文件elasticsearch-2.1.1/config/elasticsearch.yml,新增如下配置:
index.analysis.analyzer.default.segAlgorithm : "ReverseMinimumMatching"
index.analysis.tokenizer.default.segAlgorithm : "ReverseMinimumMatching"

这里segAlgorithm可指定的值有:
正向最大匹配算法:MaximumMatching
逆向最大匹配算法:ReverseMaximumMatching
正向最小匹配算法:MinimumMatching
逆向最小匹配算法:ReverseMinimumMatching
双向最大匹配算法:BidirectionalMaximumMatching
双向最小匹配算法:BidirectionalMinimumMatching
双向最大最小匹配算法:BidirectionalMaximumMinimumMatching
全切分算法:FullSegmentation
最少词数算法:MinimalWordCount
最大Ngram分值算法:MaxNgramScore
如不指定,默认使用双向最大匹配算法:BidirectionalMaximumMatching

10、jcseg 分词器

https://code.google.com/archive/p/jcseg/

11、stanford 分词器

Stanford 大学的一个开源分词工具,目前已支持汉语。

首先,去【1】下载 Download Stanford Word Segmenter version 3.5.2,取得里面的 data 文件夹,放在 maven project 的 src/main/resources 里。

然后,maven 依赖添加:

<properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <corenlp.version>3.6.0</corenlp.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>edu.stanford.nlp</groupId>
            <artifactId>stanford-corenlp</artifactId>
            <version>${corenlp.version}</version>
        </dependency>
        <dependency>
            <groupId>edu.stanford.nlp</groupId>
            <artifactId>stanford-corenlp</artifactId>
            <version>${corenlp.version}</version>
            <classifier>models</classifier>
        </dependency>
        <dependency>
            <groupId>edu.stanford.nlp</groupId>
            <artifactId>stanford-corenlp</artifactId>
            <version>${corenlp.version}</version>
            <classifier>models-chinese</classifier>
        </dependency>
    </dependencies>

测试:

import java.util.Properties;

import edu.stanford.nlp.ie.crf.CRFClassifier;

public class CoreNLPSegment {

    private static CoreNLPSegment instance;
    private CRFClassifier         classifier;

    private CoreNLPSegment(){
        Properties props = new Properties();
        props.setProperty("sighanCorporaDict", "data");
        props.setProperty("serDictionary", "data/dict-chris6.ser.gz");
        props.setProperty("inputEncoding", "UTF-8");
        props.setProperty("sighanPostProcessing", "true");
        classifier = new CRFClassifier(props);
        classifier.loadClassifierNoExceptions("data/ctb.gz", props);
        classifier.flags.setProperties(props);
    }

    public static CoreNLPSegment getInstance() {
        if (instance == null) {
            instance = new CoreNLPSegment();
        }

        return instance;
    }

    public String[] doSegment(String data) {
        return (String[]) classifier.segmentString(data).toArray();
    }

    public static void main(String[] args) {

        String sentence = "他和我在学校里常打桌球。";
        String ret[] = CoreNLPSegment.getInstance().doSegment(sentence);
        for (String str : ret) {
            System.out.println(str);
        }

    }

}

博客:

https://blog.sectong.com/blog/corenlp_segment.html

http://blog.csdn.net/lightty/article/details/51766602

12、Smartcn

Smartcn 为 Apache2.0 协议的开源中文分词系统,Java 语言编写,修改的中科院计算所 ICTCLAS 分词系统。很早以前看到 Lucene 上多了一个中文分词的 contribution,当时只是简单的扫了一下. class 文件的文件名,通过文件名可以看得出又是一个改的 ICTCLAS 的分词系统。

http://lucene.apache.org/core/5_1_0/analyzers-smartcn/org/apache/lucene/analysis/cn/smart/SmartChineseAnalyzer.html

自定义分词器

虽然 Elasticsearch 带有一些现成的分析器,然而在分析器上 Elasticsearch 真正的强大之处在于,你可以通过在一个适合你的特定数据的设置之中组合字符过滤器、分词器、词汇单元过滤器来创建自定义的分析器。

字符过滤器:

字符过滤器 用来 整理 一个尚未被分词的字符串。例如,如果我们的文本是 HTML 格式的,它会包含像 <p> 或者 <div> 这样的 HTML 标签,这些标签是我们不想索引的。我们可以使用 html 清除 字符过滤器 来移除掉所有的 HTML 标签,并且像把 &Aacute; 转换为相对应的 Unicode 字符 Á 这样,转换 HTML 实体。

一个分析器可能有 0 个或者多个字符过滤器。

分词器:

一个分析器 必须 有一个唯一的分词器。分词器把字符串分解成单个词条或者词汇单元。标准 分析器里使用的 标准 分词器 把一个字符串根据单词边界分解成单个词条,并且移除掉大部分的标点符号,然而还有其他不同行为的分词器存在。

词单元过滤器:

经过分词,作为结果的 词单元流 会按照指定的顺序通过指定的词单元过滤器 。

词单元过滤器可以修改、添加或者移除词单元。我们已经提到过 lowercase 和 stop 词过滤器 ,但是在 Elasticsearch 里面还有很多可供选择的词单元过滤器。词干过滤器 把单词 遏制 为 词干。ascii_folding 过滤器移除变音符,把一个像 "très" 这样的词转换为 "tres" 。ngram 和 edge_ngram 词单元过滤器 可以产生 适合用于部分匹配或者自动补全的词单元。

创建一个自定义分析器

我们可以在 analysis 下的相应位置设置字符过滤器、分词器和词单元过滤器:

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { ...   custom token filters   ... },
            "analyzer":    { ...    custom analyzers      ... }
        }
    }
}

这个分析器可以做到下面的这些事:

1、使用 html 清除 字符过滤器移除 HTML 部分。

2、使用一个自定义的 映射 字符过滤器把 & 替换为 "和" :

"char_filter": {
    "&_to_and": {
        "type":       "mapping",
        "mappings": [ "&=> and "]
    }
}

3、使用 标准 分词器分词。

4、小写词条,使用 小写 词过滤器处理。

5、使用自定义 停止 词过滤器移除自定义的停止词列表中包含的词:

"filter": {
    "my_stopwords": {
        "type":        "stop",
        "stopwords": [ "the", "a" ]
    }
}

我们的分析器定义用我们之前已经设置好的自定义过滤器组合了已经定义好的分词器和过滤器:

"analyzer": {
    "my_analyzer": {
        "type":           "custom",
        "char_filter":  [ "html_strip", "&_to_and" ],
        "tokenizer":      "standard",
        "filter":       [ "lowercase", "my_stopwords" ]
    }
}

汇总起来,完整的 创建索引 请求 看起来应该像这样:


PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": {
                "&_to_and": {
                    "type":       "mapping",
                    "mappings": [ "&=> and "]
            }},
            "filter": {
                "my_stopwords": {
                    "type":       "stop",
                    "stopwords": [ "the", "a" ]
            }},
            "analyzer": {
                "my_analyzer": {
                    "type":         "custom",
                    "char_filter":  [ "html_strip", "&_to_and" ],
                    "tokenizer":    "standard",
                    "filter":       [ "lowercase", "my_stopwords" ]
            }}
}}}

索引被创建以后,使用 analyze API 来 测试这个新的分析器:

GET /my_index/_analyze?analyzer=my_analyzer
The quick & brown fox

下面的缩略结果展示出我们的分析器正在正确地运行:

{
  "tokens" : [
      { "token" :   "quick",    "position" : 2 },
      { "token" :   "and",      "position" : 3 },
      { "token" :   "brown",    "position" : 4 },
      { "token" :   "fox",      "position" : 5 }
    ]
}

这个分析器现在是没有多大用处的,除非我们告诉 Elasticsearch 在哪里用上它。我们可以像下面这样把这个分析器应用在一个 string 字段上:

PUT /my_index/_mapping/my_type
{
    "properties": {
        "title": {
            "type":      "string",
            "analyzer":  "my_analyzer"
        }
    }
}

作者:zhisheng

来源链接:

https://segmentfault.com/a/1190000011065897?utm_source=sf-related

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值