分词介绍

一个 tokenizer(分词器)接收一个字符流,将之分割为独立的 tokens(词元,通常是独立的单词),然后输出 tokens 流。

例如 whitespace tokenizer 遇到空白字符时分割文本。它会将文本“Quick brown fox!”分割为 [Quick,brown,fox!]

tokenizer(分词器)还负责记录各个 terms(词条) 的顺序或 position 位置(用于phrase短语和word proximity词近邻查询),以及 term(词条)所代表的原始word(单词)的 start(起始)和 end(结束)的 character offsets(字符串偏移量)(用于高亮显示搜索的内容)。

Elasticsearch 提供了很多内置的分词器,可以用来构建 custom analyzers(自定义分词器)。

测试分词器

POST _analyze
{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}
{
  "tokens" : [
    {
      "token" : "The",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "quick",
      "start_offset" : 4,
      "end_offset" : 9,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "brown",
      "start_offset" : 10,
      "end_offset" : 15,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "fox.",
      "start_offset" : 16,
      "end_offset" : 20,
      "type" : "word",
      "position" : 3
    }
  ]
}

注意:所有的语言分词,默认使用的都是 “Standard Analyzer”,但是这些分词器针对于中文的分词,并不友好。为此需要安装中文的分词器。

IK分词器

基本介绍使用

IK 分词器解决了这一问题,GitHub文档:https://github.com/medcl/elasticsearch-analysis-ik

K Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。

安装时不能用 elasticsearch-plugin install xxx.zip 进行自动安装

必须到 https://github.com/medcl/elasticsearch-analysis-ik/releases/download 对应es版本然后手动安装

我的版本是7.4.2,所以我需要找到跟我一一对应的版本。

在前面安装的 elasticsearch 时,我们已经将 elasticsearch 容器的 /usr/share/elasticsearch/plugins 目录,映射到宿主机的 /mydata/elasticsearch/plugins 目录下,所以比较方便的做法就是下载 elasticsearch-analysis-ik-7.4.2.zip 文件,然后解压到该文件夹下即可。

安装完毕后,需要重启 elasticsearch 容器。

查看版本

curl http://localhost:9200

进入目录

cd /mydata/elasticsearch/plugins

下载压缩包

yum -y install wget
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip

解压并删除压缩包,必须删除压缩包,否则会被当作插件导致 elasticsearch 启动失败

yum install -y unzip zip
unzip elasticsearch-analysis-ik-7.4.2.zip -d ik
rm -rf elasticsearch-analysis-ik-7.4.2.zip

重启容器

docker restart elasticsearch

测试使用

ik 分词器有两种常用的分词,分别是 ik_smartik_max_word

ik_smart

POST _analyze
{
  "analyzer": "ik_smart", 
  "text":"我是中国人"
}

// 结果

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中国人",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}

ik_max_word

POST _analyze
{
  "analyzer": "ik_max_word", 
  "text":"我是乐心湖"
}

//结果

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "乐心",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "湖",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 3
    }
  ]
}

从结果来看,它没有把“乐心湖”当做一个整体,这显然是不合理的,所以接下来我们肯定是要可以自定义词库了。

自定义扩展词库

由于经常会有一些新的热点词或者流行词出现,自定义扩展词库是非常有必要的。例如 "乐心湖" 就是一个词。

在 ik 的配置文件夹 es/plugins/ik/config

  • IKAnalyzer.cfg.xml:用来配置自定义词库
  • main.dic:ik原生内置的中文词库,总共有27万多条,只要是这些单词,都会被分在一起
  • quantifier.dic:放了一些单位相关的词
  • suffix.dic:放了一些后缀
  • surname.dic:中国的姓氏
  • stopword.dic:英文停用词

我们可以在这里创建一个自定义词库文件 fenci.dic,写入 乐心湖,然后我们去编辑 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">./fenci.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

根据提示,写入文件路径,<entry key="ext_dict">./fenci.dic</entry>

修改完配置文件后,需要重启 Elasticsearch。

POST _analyze
{
  "analyzer": "ik_max_word",
  "text": ["我是乐心湖"]
}

// 结果

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "乐心湖",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "乐心",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "湖",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 4
    }
  ]
}

可以看到分词结果:“乐心湖”就单独成一个词了。


腾讯云社区邀请各位技术博主加入,福利多多噢!
Last modification:January 28th, 2021 at 09:01 pm
如果觉得我的文章对你有用,请随意赞赏