Как Elasticsearch вычисляет баллы в этом функциональном запросе? Странное поведение - PullRequest
0 голосов
/ 14 января 2019

Я использую script_score для вычисления оценки на основе значения поля, назовем его likeability, оно имеет тип float.

Сценарий:

_score * (1 + _doc['likeability'].value)

У меня есть несколько идентичных документов, за исключением likeability и идентификатора курса.

Когда я запускаю запрос оценки функции, как показано ниже, я получаю следующие результаты:

id | likeability | score
A  | 3.5         | 56.961056
B  | 2.0         | 37.974037
C  | 1.5         | 31.645031
D  | 0.5         | 18.987019
E  | 1.0         | 16.044298
F  | 0.0         |  8.022149 

Странно, с вероятностью 0.5 документ D получает более высокий балл, чем E с вероятностью 1.0.

Кто-нибудь знает, почему это так?

У меня была эта проблема на моей машине, и она исчезла. Но сейчас происходит на другой машине.

Может ли это быть как-то связано с количеством осколков?

Вот мой запрос:

{
  "from": 0,
  "size": 50,
  "query": {
    "function_score": {
      "query": { ... }
      },
      "functions": [
        {
          "filter": {
            "match_all": {
              "boost": 1.0
            }
          },
          "script_score": {
            "script": {
              "inline": "_score * (1 + doc['likeability'].value)",
              "lang": "painless"
            }
          }
        }
      ],
      "score_mode": "multiply",
      "boost_mode" : "replace",
      "max_boost": 3.4028235E+38,
      "boost": 1.0
    }
  }
}

EDIT:

Я дважды проверил еще раз, и, как мне кажется, он может что-то делать с осколками, потому что если я вычислю _score из скрипта, то получится, что для него есть два значения:

id | likeability | score

_score of 12,65777
A  | 3.5         | 56.961056
B  | 2.0         | 37.974037 
C  | 1.5         | 31.645031 
D  | 0.5         | 18.987019 

_score of 8.022149
E  | 1.0         | 16.044298 
F  | 0.0         |  8.022149

1 Ответ

0 голосов
/ 16 января 2019

Как обсуждалось в комментариях, проблема сводилась к слишком большому количеству осколков и слишком малому количеству данных. Эта проблема подробно описана в https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-is-broken.html, но в целом проблема заключается в том, что IDF является частью TF / IDF. Он хранит статистику, насколько часто используется термин для всех документов (в одном поле). Редкие термины являются более «ценными» и получают более высокий балл. Однако, вопреки интуиции, эта статистика рассчитывается для каждого шарда. Если ваши данные распределены неравномерно, ваши результаты будут отрицательными.

Существует также опция ?search_type=dfs_query_then_fetch для расчета общей статистики, но это действительно не должно быть необходимым. У вас либо достаточно данных, чтобы это не имело значения, либо вы должны использовать один осколок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...