• Elasticsearch 相似度评分模型介绍


    前言

    Elasticsearch 是基于 Lucene 的世界范围内最流行的全文检索框架,其文档相似度算法包含 TF/IDF 和 BM25,从 ES 5.0开始 BM25 算法已经成为 ES 默认的相似度评分模块。

    TF-IDF 与 BM25 的区别

    TF-IDF 和 BM25 都是计算文本相似性的常用算法。TF-IDF 的计算方法简单,计算复杂度低,但对高频词不敏感,参数难以调节。BM25 是在 TF-IDF 的基础上进行改进的,它考虑了文档的长度和查询词在文档中出现的次数,在大多数情况下都能够产生比 TF-IDF 更准确的相关性评分

    TF-IDF 和 BM25 的主要区别在于计算方法的不同。TF-IDF 的计算方法为:

    TF-IDF(t,d) = TF(t,d) * IDF(t)

    其中:

    • TF(t,d) 表示词 t 在文档 d 中的词频
    • IDF(t) 表示词 t 的逆文档频率

    BM25 的计算方法为:

    BM25(t,d) = (k1 + 1) * TF(t,d) / (k1 * (1 - b + b * df / docLength) + TF(t,d))

    其中:

    • k1 是控制词频对权重的贡献的参数
    • b 是控制逆文档频率对权重的贡献的参数
    • d 是控制文档长度对权重的贡献的参数

    TF-IDF 和 BM25 的区别主要体现在以下几个方面:

    • 参数数量:TF-IDF 只需要一个参数,即逆文档频率。BM25 需要三个参数,即 k1、b 和 d,可以根据实际需求进行调节,以提高相关性评分的准确性
    • 计算复杂度:TF-IDF 的计算复杂度为 O(n),其中 n 是文档中的词数。BM25 的计算复杂度与 TF-IDF 相当,即 O(n)。
    • 相关性评分:BM25 在大多数情况下都能够产生比 TF-IDF 更准确的相关性评分。
    评分在查询业务场景中的应用

    在实际业务中,有关查询场景的评分可以分为如下四类:

    不关注评分

    这类场景下,纯粹把 ES 当作检索库使用,不关注相似度评分,那么可以使用 constant query 或者使用 bool query 中的 filter 来进行过滤即可,这样可以提高检索性能

    默认评分

    默认评分,也就是框架默认评分。这类场景下,仅使用最简单的查询方式,比如 查询 name:"tom",并没有人为额外干预评分的机制,仅靠默认的评分算法的得到 rank 列表 ,做为检索结果

    业务评分 + 框架评分

    此种场景下比较常见,比如查询 name:"tom"^10 name:"cat"^5, 或者更加复杂的结合通过 Function Score Query 来完成更加复杂的业务

    仅业务评分

    这种场景下,一般在推荐业务中比较常见,其完全忽略框架的评分策略,而采纳业务方或者产品方定义的评分规则,实现起来一般比较复杂,看一个例子:

    1. GET /pi_ent_work/_search
    2. {
    3. "query": {
    4. "function_score": {
    5. "query": {
    6. "bool": {
    7. "must": [
    8. {
    9. "query_string": {
    10. "boost": 0, # 注意此处禁用框架评分
    11. "query": "prov:(33 OR 36)"
    12. }
    13. }
    14. ],
    15. "must_not": [
    16. {
    17. "terms": {
    18. "id": [
    19. "123"
    20. ]
    21. }
    22. }
    23. ],
    24. "filter": [
    25. {
    26. "term": {
    27. "count": {
    28. "value": "1"
    29. }
    30. }
    31. }
    32. ]
    33. }
    34. },
    35. "score_mode": "sum",
    36. "boost_mode": "replace",
    37. "functions": [
    38. {
    39. "script_score": {
    40. "script": {
    41. "lang": "expression",
    42. # 完全采用自定义评分并与数据中的某个字段关联
    43. "source": " _score*0.8 + doc['custom_score'].value*0.4"
    44. }
    45. }
    46. },
    47. {
    48. "weight": 6,
    49. "filter": {
    50. "query_string": {
    51. "query": "prov:(33 OR 36)"
    52. }
    53. }
    54. },
    55. {
    56. "weight": 4,
    57. "filter": {
    58. "query_string": {
    59. "query": " product_id:112900 "
    60. }
    61. }
    62. },
    63. {
    64. "weight": 2,
    65. "filter": {
    66. "query_string": {
    67. "query": "price:[* TO 3]"
    68. }
    69. }
    70. }
    71. ]
    72. }
    73. },
    74. "size": 100,
    75. "_source": {
    76. "includes": [
    77. "id",
    78. "_score",
    79. "prov",
    80. "product_id",
    81. "custom_score",
    82. "count"
    83. ]
    84. }
    85. }

    上面的例子完全忽略了框架评分,而全部采用自己指定的规则评分,在 ES 中可以结合 Function Score Query来实现

    总结

    在实际工作中,搜索和推荐业务会比较依赖全文检索框架,很多情况下框架的默认的评分机制并不能很好的满足我们的需求,所以需要结合一些自定义评分策略来完善我们的 rank 效果

  • 相关阅读:
    第二十章 多线程
    【python初学者日记】Mac版在pycharm中*.py文件点击run不运行
    使用香橙派 在Linux环境中安装并学习Python
    AppWeb认证绕过漏洞(CVE-2018-8715)
    python实现遗传算法,并绘制训练过程以及参数对比
    uni-app:跨页面传递数组
    20221127-1Spring_day01(资料来自黑马程序)
    【窗口显示不全问题】VMware在安装Linux各系统窗口显示不全导致无法正常安装以及问题
    CI/CD 工具和技术:释放 DevOps 的力量
    计算机毕业设计ssm社区爱心活动网站be83l系统+程序+源码+lw+远程部署
  • 原文地址:https://blog.csdn.net/u010454030/article/details/134697579