【问题标题】:Elasticsearch low fuzzy scoreElasticsearch 低模糊分数
【发布时间】:2017-04-04 19:22:05
【问题描述】:

我有一个包含大约 300,000 个姓名和地址的数据库。有很多名字的拼写略有不同,但地址相同。 我一直在尝试将这些名称组合在一起。 这是我的数据示例。

POST /_bulk
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SREE SAI MAHILA PODUPU SANGHAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SREE ANJANEYA MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SREE BANGARAMMA MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SREE SAI MAHILA PODUPU SANGHAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI SAI MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI BANGARAMMA MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI ANJANEYA MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI RAMA MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI PYDITHALLAMMA MAHIALA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI RAMA MAHILA PODUPU SANGHAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI PYDIMAMBA MAHILA PODUPU SANGAM KANNAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }
{ "index":  { "_index": "test", "_type": "test" }}
{ "name":"SRI PYDITHALAMMA MAHILA PODUPU SANGAM", "address":"KSR PURAM", "city":"VIZIANAGARAM" }

当我尝试模糊匹配名称时,我的匹配分数非常低。 这是我正在使用的查询示例:

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": {
              "query": "SREE BANGARAMMA MAHILA PODUPU SANGAM",
              "fuzziness": 2,
              "operator": "and"            

            }
          }
        }
      ]
    }
  }
}

当我查询这个小样本集时,对于 SREE BANGARAMMA MAHILA PODUPU SANGAM,我得到一个 max_score1.1982819 和模糊匹配的文档:SRI BANGARAMMA MAHILA PODUPU SANGAM 有一个 score0.2869133。这表示23% 匹配。他们的第一个词略有不同:SRI vs SREE

SRISREE 在我的数据集中出现了很多。这些可以等同于诸如Sir 之类的标题。查询的最后一部分,MAHILA PODUPU SANGAM 在我的数据集中也重复了很多次。字符串中唯一的唯一实体是BANGARAMMA。 词频/逆文档频率会是结果偏斜的原因吗?

当我查询这个小样本集时,我确实得到了我想要的结果。 但是,当我在我的 300,000 个主要数据集上运行相同的查询时,我只能得到与文档 100% 匹配的结果,并且没有显示模糊匹配。

我尝试过使用boost,但这似乎也没有产生我想要的结果。

我想知道这个问题是否是因为模糊匹配分数低。如果模糊匹配在样本集中仅 12 个数据点的得分如此之低,那么与 300,000 相比,它的得分可能要低得多。我想知道在查询主数据集时如何显示模糊匹配。坦率地说,我不知道问题出在哪里。有人可以指出我正确的方向吗?

样本集的结果如下所示:

  "hits": {
    "total": 2,
    "max_score": 1.1982819,
    "hits": [
      {
        "_index": "test",
        "_type": "test",
        "_id": "AViGh5xU276qVT8pqAHz",
        "_score": 1.1982819,
        "_source": {
          "name": "SREE BANGARAMMA MAHILA PODUPU SANGAM",
          "address": "KSR PURAM",
          "city": "VIZIANAGARAM"
        }
      },
      {
        "_index": "test",
        "_type": "test",
        "_id": "AViGh5xU276qVT8pqAH2",
        "_score": 0.2869133,
        "_source": {
          "name": "SRI BANGARAMMA MAHILA PODUPU SANGAM",
          "address": "KSR PURAM",
          "city": "VIZIANAGARAM"
        }
      }
    ]
  }

【问题讨论】:

  • 你确定没有结果吗?还是没有显示?您的查询既没有大小也没有建议的页面,然后默认为一个值。附带说明:你 23% 匹配的方程式并不是真正可以指望的东西。您只能看到查询集之间的差异。但是你不应该以任何方式使用百分比。
  • 大小默认为10。但是,只有两个文档与上面的查询匹配。一个是查询本身中的文档,它与自身具有 100% 的匹配。另一个是模糊匹配检索的。当我查询上面给出的样本集时,模糊匹配只检索另一个文档。当我在 300,000 个数据点中搜索它时,它不会检索到相同的文档。它只是没有显示。它只匹配自身并返回一个结果。

标签: elasticsearch fuzzy-search


【解决方案1】:

我不会依赖 tf-idf 和模糊查询来满足您的需求。模糊查询在编辑距离为 2 时最大。因此,“sri”可能匹配“sree”,但不匹配“shree”。

阅读 SimHash 算法(字符串的局部敏感散列函数 :: 意味着相似的字符串具有彼此接近的散列值)。

如果您在索引之前使用名称的 SimHash 向源数据添加另一个字段,则可以使用该值来限制为给定地址返回的“相似名称”范围。

您可能仍需要进行一些手动重复数据删除工作以使您的列表可靠,但至少 SimHashing 名称将使此过程不那么痛苦(例如,按地址排序,然后按名称哈希)。

您还可以决定使用停用词过滤器从搜索索引中简单地删除“sri”之类的敬语(如果它在您的收藏中出现 1000 次,它真的可以帮助您找到人吗?还是有人单独搜索“sri”? )

我还建议使用常见的次大陆昵称/名称变体列表(如果你能找到的话)作为同义词列表来规范化(例如 Hari, Hariram => Hari)*

*如果您找到/创建此列表,请分享!很多项目都需要这个!

【讨论】:

  • 谢谢!这是一个非常有趣的答案。我检查了 SimHash,我肯定会实现它。我确实在很多这样的数据集上工作,所以我想我最终需要为此获得一个同义词列表。如果我找到一个或者我们碰巧自己创造了一个,我会告诉你的。干杯! :)
【解决方案2】:

试试下面的查询

{
          "query": {
            "multi_match": {
                      "query": "SREE BANGARAMMA MAHILA PODUPU SANGAM",
                'fuzziness': 2,
                'prefix_length': 1
            }
          }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多