• Elasticsearch - IK分词器;文档得分机制(十一)


    阅读本文前可先参考

    Elasticsearch - Kibana(四)_MinggeQingchun的博客-CSDN博客

    https://blog.csdn.net/MinggeQingchun/article/details/126768243

    一、IK分词器

    中文分词

    ES 的默认分词器无法识别中文中测试、单词这样的词汇,而是简单的将每个字拆完分为一 个词

    解决方案: 采用IK分词器

    (一)IK分词器下载安装

    官网下载地址:

    Releases · medcl/elasticsearch-analysis-ik · GitHub

    找到对应Elasticsearch对应版本下载即可

    将解压后的后的文件夹放入 ES 根目录下的 plugins 目录下,重启 ES 即可使用

    (二)IK分词器使用

    IK 分词器提供了两个分词算法

    ik_smart:最少切分

    Ik_max_word:最细粒度划分

    1、使用 ik_smart 算法对之前得中文内容进行分词

    2、ik_max_word 算法分词

     (三)自定义分词器

    1、首先进入 ES 根目录中的 plugins 文件夹下的 ik 文件夹,进入 config 目录,创建 custom.dic 文件,写入"一个学生"

     

    2、打开 IKAnalyzer.cfg.xml 文件,将新建的 custom.dic 配置其中, 重启 ES 服务器

    重启服务器,测试效果

    二、文档得分机制

    Lucene 和 ES 的得分机制是一个基于词频和逆文档词频的公式,简称为 TF-IDF(term frequency–inverse document frequency 公式

    TF-IDF(term frequency–inverse document frequency)是一种用于信息检索数据挖掘的常用加权技术。TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency)

    TF (词频)

    Term Frequency : 搜索文本中的各个词条(term)在查询文本中出现了多少次,出现次数越多,就越相关,得分会比较高

    IDF(逆文档频率)

    Inverse Document Frequency : 搜索文本中的各个词条(term)在整个索引的所有文档中出现了多少次,出现的次数越多,说明越不重要,也就越不相关,得分就比较低

    TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)。TF表示词条在文档d中出现的频率。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处.

    词频(term frequency,TF)指的是某一个给定的词语在该文件中出现的频率

    这个数字是对词数(term count)的归一化,以防止它偏向长的文

    (一)打分机制

    1、基础数据

    1. # 创建索引
    2. PUT /myindex
    3. # 增加文档数据
    4. # 此时索引中只有这一条数据
    5. PUT /myindex/_doc/1
    6. {
    7. "text":"hello"
    8. }

    2、查询匹配条件的文档数据 

    1. GET /myindex/_search
    2. {
    3. "query": {
    4. "match": {
    5. "text": "hello"
    6. }
    7. } }

     这里文档的得分为:0.2876821

    3、分析文档数据打分过程

    1. # 增加分析参数
    2. GET /myindex/_search?explain=true
    3. {
    4. "query": {
    5. "match": {
    6. "text": "hello"
    7. }
    8. }
    9. }

    返回输出

    1. {
    2. "took" : 2,
    3. "timed_out" : false,
    4. "_shards" : {
    5. "total" : 1,
    6. "successful" : 1,
    7. "skipped" : 0,
    8. "failed" : 0
    9. },
    10. "hits" : {
    11. "total" : {
    12. "value" : 1,
    13. "relation" : "eq"
    14. },
    15. "max_score" : 0.2876821,
    16. "hits" : [
    17. {
    18. "_shard" : "[myindex][0]",
    19. "_node" : "cbR5pVsVS1q0NR3kt24wzg",
    20. "_index" : "myindex",
    21. "_type" : "_doc",
    22. "_id" : "1",
    23. "_score" : 0.2876821,
    24. "_source" : {
    25. "text" : "hello"
    26. },
    27. "_explanation" : {
    28. "value" : 0.2876821,
    29. "description" : "weight(text:hello in 0) [PerFieldSimilarity], result of:",
    30. "details" : [
    31. {
    32. "value" : 0.2876821,
    33. "description" : "score(freq=1.0), computed as boost * idf * tf from:",
    34. "details" : [
    35. {
    36. "value" : 2.2,
    37. "description" : "boost",
    38. "details" : [ ]
    39. },
    40. {
    41. "value" : 0.2876821,
    42. "description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
    43. "details" : [
    44. {
    45. "value" : 1,
    46. "description" : "n, number of documents containing term",
    47. "details" : [ ]
    48. },
    49. {
    50. "value" : 1,
    51. "description" : "N, total number of documents with field",
    52. "details" : [ ]
    53. }
    54. ]
    55. },
    56. {
    57. "value" : 0.45454544,
    58. "description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
    59. "details" : [
    60. {
    61. "value" : 1.0,
    62. "description" : "freq, occurrences of term within document",
    63. "details" : [ ]
    64. },
    65. {
    66. "value" : 1.2,
    67. "description" : "k1, term saturation parameter",
    68. "details" : [ ]
    69. },
    70. {
    71. "value" : 0.75,
    72. "description" : "b, length normalization parameter",
    73. "details" : [ ]
    74. },
    75. {
    76. "value" : 1.0,
    77. "description" : "dl, length of field",
    78. "details" : [ ]
    79. },
    80. {
    81. "value" : 1.0,
    82. "description" : "avgdl, average length of field",
    83. "details" : [ ]
    84. }
    85. ]
    86. }
    87. ]
    88. }
    89. ]
    90. }
    91. }
    92. ]
    93. }
    94. }

    打分机制中有 2 个重要阶段:计算 TF 值和 IDF

    最后的分数

    4、计算TF值

     5、计算IDF值

    6、计算文档得分

    7、增加新的文档,测试得分

    (1)增加一个毫无关系的文档

    1. # 增加文档
    2. PUT /myindex/_doc/2
    3. {
    4. "text" : "spark"
    5. }
    6. # 因为新文档无词条相关信息,所以匹配的文档数据得分就应该较高:
    7. # 0.6931741
    8. GET /myindex/_search
    9. {
    10. "query": {
    11. "match": {
    12. "text": "hello"
    13. }
    14. } }

    (2)增加一个完全一样的文档

    1. # 增加文档
    2. PUT /myindex/_doc/2
    3. {
    4. "text" : "hello"
    5. }
    6. # 因为新文档含词条相关信息,且多个文件含有词条,所以显得不是很重要,得分会变低
    7. # 0.18232156
    8. GET /myindex/_search
    9. {
    10. "query": {
    11. "match": {
    12. "text": "hello"
    13. }
    14. } }

    (3)增加一个含有词条,但是内容较多的文档

    1. # 增加文档
    2. PUT /myindex/_doc/2
    3. {
    4. "text" : "hello elasticsearch" }
    5. # 因为新文档含词条相关信息,但只是其中一部分,所以查询文档的分数会变得更低一些。
    6. # 0.14874382
    7. GET /myindex/_search
    8. {
    9. "query": {
    10. "match": {
    11. "text": "hello"
    12. }
    13. } }

    8、测试

    查询文档标题中含有“Hadoop”,“Elasticsearch”,“Spark”的内容;优先选择“Spark”的内容

    (1)准备数据

    1. # 准备数据
    2. PUT /testscore/_doc/1001
    3. {
    4. "title" : "Hadoop is a Framework",
    5. "content" : "Hadoop 是一个大数据基础框架"
    6. }
    7. PUT /testscore/_doc/1002
    8. {
    9. "title" : "Hive is a SQL Tools",
    10. "content" : "Hive 是一个 SQL 工具"
    11. }
    12. PUT /testscore/_doc/1003
    13. {
    14. "title" : "Spark is a Framework",
    15. "content" : "Spark 是一个分布式计算引擎"
    16. }

    (2)查询数据,Spark 的结果并不会放置在最前面

  • 相关阅读:
    Java:为什么使用Java开发Web和移动应用
    SpringBoot--中间件技术-2:整合redis,redis实战小案例,springboot cache,cache简化redis的实现,含代码
    MySQL缓存策略详解
    一个C#跨平台的机器视觉和机器学习的开源库
    如何在vue3+vite中优雅的使用iconify图标
    docker出现Cannot connect to the Docker daemon at unix:///var/run/docker.sock....
    1、HTML——初识HTML、HTML的定义、HTML5
    [EFI]华硕 Asus VivoBook S510UA 电脑 Hackintosh 黑苹果efi引导文件
    vite4+vue3使用Tailwind.css
    十六、Java 数组
  • 原文地址:https://blog.csdn.net/MinggeQingchun/article/details/126855747