• ElasticSearch学习(五): 分词器


    1、什么是Analysis 

            顾名思义,文本分析就是把全文本转换成一系列单词(term/token)的过程,也叫分词

            在 ES 中,Analysis 是通过分词器(Analyzer) 来实现的,可使用 ES 内置的分析器或者按需定制化分析器。

    2、分词器的组成:

            再简单了解了 Analysis 与 Analyzer 之后,让我们来看下分词器的组成:

       分词器Analyzer是专门处理分词的组件,分词器由以下三部分组成:

    1. Character Filters:针对原始文本处理,比如去除 html 标签;
    2. Tokenizer:按照规则将文本切分为单词,比如按照空格切分;
    3. Token Filters:将切分的单词进行加工,比如大写转小写,删除 stopwords,增加同义语。

    执行流程如下:

     

          从图中可以看出,从左到右次经过 Character FiltersTokenizer 以及 Token Filters,这个顺序比较好理解,一个文本进来肯定要先对文本数据进行处理,再去分词,最后对分词的结果进行过滤。

    其中,ES 内置了许多分词器:

    • Standard Analyzer - 默认分词器,按词切分,小写处理
    • Simple Analyzer - 按照非字母切分(符号被过滤),小写处理
    • Stop Analyzer - 小写处理,停用词过滤(the ,a,is)
    • Whitespace Analyzer - 按照空格切分,不转小写
    • Keyword Analyzer - 不分词,直接将输入当做输出
    • Pattern Analyzer - 正则表达式,默认 \W+
    • Language - 提供了 30 多种常见语言的分词器
    • Customer Analyzer - 自定义分词器

    3、Analyzer API

    3.1、直接指定 Analyzer 进行测试

    1. GET _analyze
    2. {
    3. "analyzer": "standard",
    4. "text" : "Mastering Elasticsearch , elasticsearch in Action"
    5. }

    3.2、指定索引的字段进行测试

    1. POST user/_analyze
    2. {
    3. "field": "address",
    4. "text": "北京市"
    5. }

    3.3、自定义分词进行测试

    1. POST _analyze
    2. {
    3. "tokenizer": "standard",
    4. "filter": ["lowercase"],
    5. "text": "Mastering Elasticesearch"
    6. }

    4、ES分词器

    4.1、Stamdard Analyzer

    1.  默认分词器
    2. 按词切分(基于词典)
    3. 切分后全部转换为小写
    4. 保留StopWords(停止词,如英文的in a the 等)

            它是 ES 默认的分词器,它会对输入的文本按词的方式进行切分,切分好以后会进行转小写处理默认的 stopwords 是关闭的

            stopwords说明:

            在信息检索中,停用词是为节省存储空间和提高搜索效率,处理文本时自动过滤掉某些字或词,这些字或词即被称为Stop Words(停用词)。停用词大致分为两类:

            一类是语言中的功能词,这些词极其普遍而无实际含义,比如“the”、“is“、“which“、“on”等。

            另一类是词汇词,比如'want'等,这些词应用广泛,但搜索引擎无法保证能够给出真正相关的搜索结果,难以缩小搜索范围,还会降低搜索效率。实践中,通常把这些词从问题中过滤,从而节省索引的存储空间、提高搜索性能。

            但是在实际语言环境中,停用词有时也有用的。比如,莎士比亚的名句:“To be or not to be.”所有的词都是停用词。特别当停用词和通配符(*)同时使用的时候,问题就来了:“the”、“is“、“on”还是停用词?

     4.1.1、英文分词

    1. GET _analyze
    2. {
    3. "analyzer": "standard",
    4. "text": "In 2022, Java is the best language in the world."
    5. }

    结果:

            可以看出是按词切分的方式对输入的文本进行了转换,比如对 Java 做了转小写,对一些停用词也没有去掉,比如 in

            其中 token 为分词结果;start_offset 为起始偏移;end_offset 为结束偏移;position 为分词位置。

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "in",
    5. "start_offset" : 0,
    6. "end_offset" : 2,
    7. "type" : "",
    8. "position" : 0
    9. },
    10. {
    11. "token" : "2022",
    12. "start_offset" : 3,
    13. "end_offset" : 7,
    14. "type" : "",
    15. "position" : 1
    16. },
    17. {
    18. "token" : "java",
    19. "start_offset" : 9,
    20. "end_offset" : 13,
    21. "type" : "",
    22. "position" : 2
    23. },
    24. {
    25. "token" : "is",
    26. "start_offset" : 14,
    27. "end_offset" : 16,
    28. "type" : "",
    29. "position" : 3
    30. },
    31. {
    32. "token" : "the",
    33. "start_offset" : 17,
    34. "end_offset" : 20,
    35. "type" : "",
    36. "position" : 4
    37. },
    38. {
    39. "token" : "best",
    40. "start_offset" : 21,
    41. "end_offset" : 25,
    42. "type" : "",
    43. "position" : 5
    44. },
    45. {
    46. "token" : "language",
    47. "start_offset" : 26,
    48. "end_offset" : 34,
    49. "type" : "",
    50. "position" : 6
    51. },
    52. {
    53. "token" : "in",
    54. "start_offset" : 35,
    55. "end_offset" : 37,
    56. "type" : "",
    57. "position" : 7
    58. },
    59. {
    60. "token" : "the",
    61. "start_offset" : 38,
    62. "end_offset" : 41,
    63. "type" : "",
    64. "position" : 8
    65. },
    66. {
    67. "token" : "world",
    68. "start_offset" : 42,
    69. "end_offset" : 47,
    70. "type" : "",
    71. "position" : 9
    72. }
    73. ]
    74. }

    4.1.2、中文分词

            中文分词的效果,只是将中文语句分解为单个中文文字,没有词的概念,因此

    Stamdard Analyzer分词器无法应对中文分词 。

    1. GET _analyze
    2. {
    3. "analyzer": "standard",
    4. "text" : "北京市"
    5. }

    分词结果:

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "北",
    5. "start_offset" : 0,
    6. "end_offset" : 1,
    7. "type" : "",
    8. "position" : 0
    9. },
    10. {
    11. "token" : "京",
    12. "start_offset" : 1,
    13. "end_offset" : 2,
    14. "type" : "",
    15. "position" : 1
    16. },
    17. {
    18. "token" : "市",
    19. "start_offset" : 2,
    20. "end_offset" : 3,
    21. "type" : "",
    22. "position" : 2
    23. }
    24. ]
    25. }

    4.2、Simple Analyzer

    1.  使用非英文字母进行分词;
    2. 分词后,非英文字母被删除;
    3. 切分后全部转换为小写;
    4. 保留StopWords。

    4.2.1、英文分词示例

    1. GET _analyze
    2. {
    3. "analyzer": "simple",
    4. "text": "In 2022, Java is the best language in the world."
    5. }

    英文分词效果: (非英文字母被删除

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "in",
    5. "start_offset" : 0,
    6. "end_offset" : 2,
    7. "type" : "word",
    8. "position" : 0
    9. },
    10. {
    11. "token" : "java",
    12. "start_offset" : 9,
    13. "end_offset" : 13,
    14. "type" : "word",
    15. "position" : 1
    16. },
    17. {
    18. "token" : "is",
    19. "start_offset" : 14,
    20. "end_offset" : 16,
    21. "type" : "word",
    22. "position" : 2
    23. },
    24. {
    25. "token" : "the",
    26. "start_offset" : 17,
    27. "end_offset" : 20,
    28. "type" : "word",
    29. "position" : 3
    30. },
    31. {
    32. "token" : "best",
    33. "start_offset" : 21,
    34. "end_offset" : 25,
    35. "type" : "word",
    36. "position" : 4
    37. },
    38. {
    39. "token" : "language",
    40. "start_offset" : 26,
    41. "end_offset" : 34,
    42. "type" : "word",
    43. "position" : 5
    44. },
    45. {
    46. "token" : "in",
    47. "start_offset" : 35,
    48. "end_offset" : 37,
    49. "type" : "word",
    50. "position" : 6
    51. },
    52. {
    53. "token" : "the",
    54. "start_offset" : 38,
    55. "end_offset" : 41,
    56. "type" : "word",
    57. "position" : 7
    58. },
    59. {
    60. "token" : "world",
    61. "start_offset" : 42,
    62. "end_offset" : 47,
    63. "type" : "word",
    64. "position" : 8
    65. }
    66. ]
    67. }

    4.2.3、中文分词示例

            中文分词的效果,其对于连接在一起的中文语句不做任何切分,完整输出该分词器无法应对中文分词。

    1. GET _analyze
    2. {
    3. "analyzer": "simple",
    4. "text" : "北京市"
    5. }
    6. # 分词后的效果:
    7. {
    8. "tokens" : [
    9. {
    10. "token" : "北京市",
    11. "start_offset" : 0,
    12. "end_offset" : 3,
    13. "type" : "word",
    14. "position" : 0
    15. }
    16. ]
    17. }

    4.3、Whitespace Analyzer

    它非常简单,根据名称也可以看出是按照空格进行切分的。

    1. 使用空白字符进行分词;
    2. 切分后不做大小写处理;
    3. 保留StopWords。

    4.3.1、英文分词

            可以看出,只是按照空格进行切分,2022 数字还是在的,Java 的首字母还是大写的,in 还是保留的。

    1. GET _analyze
    2. {
    3. "analyzer": "whitespace",
    4. "text": "In 2022, Java is the best language in the world."
    5. }

    结果:

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "In",
    5. "start_offset" : 0,
    6. "end_offset" : 2,
    7. "type" : "word",
    8. "position" : 0
    9. },
    10. {
    11. "token" : "2022,",
    12. "start_offset" : 3,
    13. "end_offset" : 8,
    14. "type" : "word",
    15. "position" : 1
    16. },
    17. {
    18. "token" : "Java",
    19. "start_offset" : 9,
    20. "end_offset" : 13,
    21. "type" : "word",
    22. "position" : 2
    23. },
    24. {
    25. "token" : "is",
    26. "start_offset" : 14,
    27. "end_offset" : 16,
    28. "type" : "word",
    29. "position" : 3
    30. },
    31. {
    32. "token" : "the",
    33. "start_offset" : 17,
    34. "end_offset" : 20,
    35. "type" : "word",
    36. "position" : 4
    37. },
    38. {
    39. "token" : "best",
    40. "start_offset" : 21,
    41. "end_offset" : 25,
    42. "type" : "word",
    43. "position" : 5
    44. },
    45. {
    46. "token" : "language",
    47. "start_offset" : 26,
    48. "end_offset" : 34,
    49. "type" : "word",
    50. "position" : 6
    51. },
    52. {
    53. "token" : "in",
    54. "start_offset" : 35,
    55. "end_offset" : 37,
    56. "type" : "word",
    57. "position" : 7
    58. },
    59. {
    60. "token" : "the",
    61. "start_offset" : 38,
    62. "end_offset" : 41,
    63. "type" : "word",
    64. "position" : 8
    65. },
    66. {
    67. "token" : "world.",
    68. "start_offset" : 42,
    69. "end_offset" : 48,
    70. "type" : "word",
    71. "position" : 9
    72. }
    73. ]
    74. }

    4.3.2、中文分词

            中文分词的效果,依然只会针对空白字符进行分词,无空白字符的串会被完整输出,该分词器无法应对中文分词。

    1. GET _analyze
    2. {
    3. "analyzer": "whitespace",
    4. "text" : "北京市"
    5. }

    结果:

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "北京市",
    5. "start_offset" : 0,
    6. "end_offset" : 3,
    7. "type" : "word",
    8. "position" : 0
    9. }
    10. ]
    11. }

    4.4、Stop Analyzer

    1. 使用非英文字母进行分词
    2. 分词后,非英文字母被删除
    3. 切分后全部转换为小写
    4. 删除StopWords

    4.4.1、英文分词示例

            相较于刚才提到的 Simple Analyzer删除了非英文字母多了 stop 过滤,stop 就是会把 theais 等修饰词去除。

    1. GET _analyze
    2. {
    3. "analyzer": "stop",
    4. "text": "In 2022, Java is the best language in the world."
    5. }

    结果:

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "java",
    5. "start_offset" : 9,
    6. "end_offset" : 13,
    7. "type" : "word",
    8. "position" : 1
    9. },
    10. {
    11. "token" : "best",
    12. "start_offset" : 21,
    13. "end_offset" : 25,
    14. "type" : "word",
    15. "position" : 4
    16. },
    17. {
    18. "token" : "language",
    19. "start_offset" : 26,
    20. "end_offset" : 34,
    21. "type" : "word",
    22. "position" : 5
    23. },
    24. {
    25. "token" : "world",
    26. "start_offset" : 42,
    27. "end_offset" : 47,
    28. "type" : "word",
    29. "position" : 8
    30. }
    31. ]
    32. }

    4.4.2、中文分词示例

            中文分词的效果,其对于连接在一起的中文语句不做任何切分,完整输出,该分词器无法应对中文分词

    1. GET _analyze
    2. {
    3. "analyzer": "stop",
    4. "text" : "北京市"
    5. }
    6. # 結果:
    7. {
    8. "tokens" : [
    9. {
    10. "token" : "北京市",
    11. "start_offset" : 0,
    12. "end_offset" : 3,
    13. "type" : "word",
    14. "position" : 0
    15. }
    16. ]
    17. }

    4.5、Keyword Analyzer

            它其实不做分词处理,只是将输入作为 Term 输出。

    4.6、Pattern Analyzer

            它可以通过正则表达式的方式进行分词默认是用 \W+ 进行分割的,也就是非字母进行切分的,由于运行结果和 Stamdard Analyzer 一样,就不展示了。

    4.7、Language Analyzer

            ES 为不同国家语言的输入提供了 Language Analyzer 分词器,在里面可以指定不同的语言,

    我们用 english 进行分词看下:

            可以看出 language 被改成了 languag,同时它也是有 stop 过滤器的,比如 in,is 等词也被去除了。

    1. GET _analyze
    2. {
    3. "analyzer": "english",
    4. "text": "In 2022, Java is the best language in the world."
    5. }

    结果:

    1. {
    2. "tokens" : [
    3. {
    4. "token" : "2022",
    5. "start_offset" : 3,
    6. "end_offset" : 7,
    7. "type" : "",
    8. "position" : 1
    9. },
    10. {
    11. "token" : "java",
    12. "start_offset" : 9,
    13. "end_offset" : 13,
    14. "type" : "",
    15. "position" : 2
    16. },
    17. {
    18. "token" : "best",
    19. "start_offset" : 21,
    20. "end_offset" : 25,
    21. "type" : "",
    22. "position" : 5
    23. },
    24. {
    25. "token" : "languag",
    26. "start_offset" : 26,
    27. "end_offset" : 34,
    28. "type" : "",
    29. "position" : 6
    30. },
    31. {
    32. "token" : "world",
    33. "start_offset" : 42,
    34. "end_offset" : 47,
    35. "type" : "",
    36. "position" : 9
    37. }
    38. ]
    39. }

  • 相关阅读:
    6种自媒体赚钱方法!
    Chrome为什么不用COOKIE
    章节一: RASA开源引擎介绍
    高校学生消费行为分析系统
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    Elementui的tabs标签页添加右键关闭所有标签页的按钮
    江江文具店铺运营方案设计
    JavaScript 62 JavaScript 版本 62.2 JavaScript ES5
    百度测开面试题分享
    数字IC前端设计流程及详细解释
  • 原文地址:https://blog.csdn.net/weixin_40482816/article/details/126924409