More like this query
More Like This Queryは、指定された文書のセットに「似た」文書を見つけます。そのために、MLTはこれらの入力文書の代表的な用語のセットを選択し、これらの用語を使用してクエリを形成し、クエリを実行して結果を返します。ユーザーは入力文書、用語の選択方法、およびクエリの形成方法を制御します。
最も単純な使用ケースは、提供されたテキストに似た文書を要求することです。ここでは、「Once upon a time」というテキストが「タイトル」と「説明」フィールドに似ているすべての映画を要求しており、選択される用語の数を12に制限しています。
Python
resp = client.search(
query={
"more_like_this": {
"fields": [
"title",
"description"
],
"like": "Once upon a time",
"min_term_freq": 1,
"max_query_terms": 12
}
},
)
print(resp)
Ruby
response = client.search(
body: {
query: {
more_like_this: {
fields: [
'title',
'description'
],
like: 'Once upon a time',
min_term_freq: 1,
max_query_terms: 12
}
}
}
)
puts response
Js
const response = await client.search({
query: {
more_like_this: {
fields: ["title", "description"],
like: "Once upon a time",
min_term_freq: 1,
max_query_terms: 12,
},
},
});
console.log(response);
Console
GET /_search
{
"query": {
"more_like_this" : {
"fields" : ["title", "description"],
"like" : "Once upon a time",
"min_term_freq" : 1,
"max_query_terms" : 12
}
}
}
より複雑な使用ケースは、インデックスに既に存在する文書とテキストを混合することです。この場合、文書を指定するための構文は、Multi GET APIで使用されるものに似ています。
Python
resp = client.search(
query={
"more_like_this": {
"fields": [
"title",
"description"
],
"like": [
{
"_index": "imdb",
"_id": "1"
},
{
"_index": "imdb",
"_id": "2"
},
"and potentially some more text here as well"
],
"min_term_freq": 1,
"max_query_terms": 12
}
},
)
print(resp)
Ruby
response = client.search(
body: {
query: {
more_like_this: {
fields: [
'title',
'description'
],
like: [
{
_index: 'imdb',
_id: '1'
},
{
_index: 'imdb',
_id: '2'
},
'and potentially some more text here as well'
],
min_term_freq: 1,
max_query_terms: 12
}
}
}
)
puts response
Js
const response = await client.search({
query: {
more_like_this: {
fields: ["title", "description"],
like: [
{
_index: "imdb",
_id: "1",
},
{
_index: "imdb",
_id: "2",
},
"and potentially some more text here as well",
],
min_term_freq: 1,
max_query_terms: 12,
},
},
});
console.log(response);
Console
GET /_search
{
"query": {
"more_like_this": {
"fields": [ "title", "description" ],
"like": [
{
"_index": "imdb",
"_id": "1"
},
{
"_index": "imdb",
"_id": "2"
},
"and potentially some more text here as well"
],
"min_term_freq": 1,
"max_query_terms": 12
}
}
}
最終的に、ユーザーはテキストを混合し、選択した文書のセットを提供することができますが、インデックスに必ずしも存在しない文書を提供することもできます。インデックスに存在しない文書を提供するための構文は、人工文書に似ています。
Python
resp = client.search(
query={
"more_like_this": {
"fields": [
"name.first",
"name.last"
],
"like": [
{
"_index": "marvel",
"doc": {
"name": {
"first": "Ben",
"last": "Grimm"
},
"_doc": "You got no idea what I'd... what I'd give to be invisible."
}
},
{
"_index": "marvel",
"_id": "2"
}
],
"min_term_freq": 1,
"max_query_terms": 12
}
},
)
print(resp)
Ruby
response = client.search(
body: {
query: {
more_like_this: {
fields: [
'name.first',
'name.last'
],
like: [
{
_index: 'marvel',
doc: {
name: {
first: 'Ben',
last: 'Grimm'
},
_doc: "You got no idea what I'd... what I'd give to be invisible."
}
},
{
_index: 'marvel',
_id: '2'
}
],
min_term_freq: 1,
max_query_terms: 12
}
}
}
)
puts response
Js
const response = await client.search({
query: {
more_like_this: {
fields: ["name.first", "name.last"],
like: [
{
_index: "marvel",
doc: {
name: {
first: "Ben",
last: "Grimm",
},
_doc: "You got no idea what I'd... what I'd give to be invisible.",
},
},
{
_index: "marvel",
_id: "2",
},
],
min_term_freq: 1,
max_query_terms: 12,
},
},
});
console.log(response);
Console
GET /_search
{
"query": {
"more_like_this": {
"fields": [ "name.first", "name.last" ],
"like": [
{
"_index": "marvel",
"doc": {
"name": {
"first": "Ben",
"last": "Grimm"
},
"_doc": "You got no idea what I'd... what I'd give to be invisible."
}
},
{
"_index": "marvel",
"_id": "2"
}
],
"min_term_freq": 1,
"max_query_terms": 12
}
}
}
How it Works
特定の入力文書に似たすべての文書を見つけたいと仮定します。明らかに、入力文書自体はそのタイプのクエリに対して最良の一致であるべきです。その理由は、主にLuceneスコアリング公式によるもので、最も高いtf-idfを持つ用語によるものです。したがって、入力文書の中で最も高いtf-idfを持つ用語は、その文書の良い代表者であり、類似の文書を取得するために排他的クエリ(またはOR
)内で使用できます。MLTクエリは、単に入力文書からテキストを抽出し、それを分析し、通常はフィールドで同じアナライザーを使用して、最も高いtf-idfを持つ上位K用語を選択して、これらの用語の排他的クエリを形成します。
MLTを実行するフィールドは、インデックスされており、text
またはkeyword
のタイプである必要があります。さらに、like
を文書と共に使用する場合、_source
が有効であるか、フィールドがstored
であるか、term_vector
を保存する必要があります。分析を高速化するために、インデックス時に用語ベクトルを保存することが役立つ場合があります。
たとえば、「タイトル」と「tags.raw」フィールドでMLTを実行したい場合、インデックス時にそれらのterm_vector
を明示的に保存できます。「説明」と「tags」フィールドでMLTを実行することもできますが、_source
はデフォルトで有効になっているため、これらのフィールドの分析の速度は向上しません。
Python
resp = client.indices.create(
index="imdb",
mappings={
"properties": {
"title": {
"type": "text",
"term_vector": "yes"
},
"description": {
"type": "text"
},
"tags": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keyword",
"term_vector": "yes"
}
}
}
}
},
)
print(resp)
Ruby
response = client.indices.create(
index: 'imdb',
body: {
mappings: {
properties: {
title: {
type: 'text',
term_vector: 'yes'
},
description: {
type: 'text'
},
tags: {
type: 'text',
fields: {
raw: {
type: 'text',
analyzer: 'keyword',
term_vector: 'yes'
}
}
}
}
}
}
)
puts response
Js
const response = await client.indices.create({
index: "imdb",
mappings: {
properties: {
title: {
type: "text",
term_vector: "yes",
},
description: {
type: "text",
},
tags: {
type: "text",
fields: {
raw: {
type: "text",
analyzer: "keyword",
term_vector: "yes",
},
},
},
},
},
});
console.log(response);
Console
PUT /imdb
{
"mappings": {
"properties": {
"title": {
"type": "text",
"term_vector": "yes"
},
"description": {
"type": "text"
},
"tags": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keyword",
"term_vector": "yes"
}
}
}
}
}
}
Parameters
唯一の必須パラメータはlike
であり、他のすべてのパラメータには妥当なデフォルトがあります。パラメータには3つのタイプがあります:1つは文書入力を指定するため、もう1つは用語選択とクエリ形成のためです。
Document Input Parameters
like |
MLTクエリの唯一の必須パラメータはlike であり、柔軟な構文に従います。この構文では、ユーザーは自由形式のテキストおよび/または単一または複数の文書を指定できます(上記の例を参照)。文書を指定するための構文は、Multi GET APIで使用されるものに似ています。文書を指定する際、テキストはfields から取得されますが、各文書リクエストでオーバーライドされる場合があります。テキストはフィールドのアナライザーによって分析されますが、オーバーライドされることもあります。フィールドのアナライザーをオーバーライドするための構文は、Term Vectors APIのper_field_analyzer パラメータの構文に似ています。さらに、インデックスに必ずしも存在しない文書を提供するために、人工文書もサポートされています。 |
unlike |
unlike パラメータは、like と組み合わせて使用され、選択した文書のセットに見つかった用語を選択しないようにします。言い換えれば、like: "Apple" の文書を要求することができますが、unlike: "cake crumble tree" 。構文はlike と同じです。 |
| fields
| テキストを取得して分析するフィールドのリスト。デフォルトはindex.query.default_field
インデックス設定で、デフォルト値は*
です。*
値は、メタデータフィールドを除く用語レベル\
クエリに適格なすべてのフィールドに一致します。
Term Selection Parameters
max_query_terms |
選択されるクエリ用語の最大数。この値を増やすと、クエリ実行速度の代償として精度が向上します。デフォルトは25 です。 |
min_term_freq |
用語が入力文書から無視される最小用語頻度。デフォルトは2 です。 |
min_doc_freq |
用語が入力文書から無視される最小文書頻度。デフォルトは5 です。 |
max_doc_freq |
用語が入力文書から無視される最大文書頻度。これは、ストップワードのような非常に頻繁に使用される単語を無視するために役立つ場合があります。デフォルトは無制限(Integer.MAX_VALUE 、すなわち2^31-1 または2147483647)です。 |
min_word_length |
用語が無視される最小単語長。デフォルトは0 です。 |
max_word_length |
用語が無視される最大単語長。デフォルトは無制限(0 )です。 |
stop_words |
ストップワードの配列。このセット内の任意の単語は「興味がない」と見なされ、無視されます。アナライザーがストップワードを許可する場合、MLTにそれらを明示的に無視するように指示することが望ましいかもしれません。文書の類似性の目的では、「ストップワードは決して興味がない」と仮定するのが合理的です。 |
| analyzer
| 自由形式のテキストを分析するために使用されるアナライザー。デフォルトはfields
の最初のフィールドに関連付けられたアナライザーです。
Query Formation Parameters
minimum_should_match |
排他的クエリが形成された後、このパラメータは一致する必要がある用語の数を制御します。 この構文は、minimum should matchと同じです。 (デフォルトは "30%" です)。 |
fail_on_unsupported_field |
指定されたフィールドのいずれかがサポートされているタイプ(text またはkeyword )でない場合、クエリが失敗するか(例外をスローする)を制御します。これを false に設定すると、フィールドを無視して処理を続行します。デフォルトはtrue です。 |
boost_terms |
形成されたクエリの各用語は、tf-idfスコアによってさらにブーストされる可能性があります。 この機能を使用する際のブースト係数を設定します。デフォルトは無効( 0 )です。他の正の値は、指定されたブースト係数で用語のブーストを有効にします。 |
include |
入力文書も検索結果に含めるべきかどうかを指定します。 デフォルトは false です。 |
| boost
| クエリ全体のブースト値を設定します。デフォルトは1.0
です。
Alternative
類似文書のクエリ構築をより制御するために、選択した用語を例文書からブールクエリに組み立てるカスタムクライアントコードを書くことを検討する価値があります。テキストの一部から「興味のある」単語を選択するmore_like_this
のロジックは、TermVectors APIを介してもアクセス可能です。たとえば、termvectors APIを使用すると、文書のテキストに見つかったトピックキーワードの選択をユーザーに提示し、興味のある単語を選択して掘り下げることができるようになります。more_like_this
によって使用されるマッチングのより「ブラックボックス」アプローチを使用するのではなく。