加重平均集計
文書から抽出された数値の加重平均を計算する single-value
メトリクス集計です。これらの値は、文書内の特定の数値フィールドから抽出できます。
通常の平均を計算する場合、各データポイントは等しい「重み」を持ち、最終値に等しく寄与します。一方、加重平均は各データポイントに異なる重みを付けます。各データポイントが最終値に寄与する量は文書から抽出されます。
数式として、加重平均は ∑(value * weight) / ∑(weight)
です。
通常の平均は、すべての値が暗黙の重み 1
を持つ加重平均と考えることができます。
パラメータ名 | 説明 | 必須 | デフォルト値 |
---|---|---|---|
value |
値を提供するフィールドまたはスクリプトの設定 | 必須 | |
weight |
重みを提供するフィールドまたはスクリプトの設定 | 必須 | |
format |
数値応答フォーマッタ | オプション |
value
および weight
オブジェクトには、フィールドごとの特定の設定があります:
パラメータ名 | 説明 | 必須 | デフォルト値 |
---|---|---|---|
field |
値を抽出するフィールド | 必須 | |
missing |
フィールドが完全に欠落している場合に使用する値 | オプション |
パラメータ名 | 説明 | 必須 | デフォルト値 |
---|---|---|---|
field |
重みを抽出するフィールド | 必須 | |
missing |
フィールドが完全に欠落している場合に使用する重み | オプション |
例
文書に 0-100 の数値スコアを保持する "grade"
フィールドと、任意の数値重みを保持する "weight"
フィールドがある場合、次のように加重平均を計算できます:
Python
resp = client.search(
index="exams",
size=0,
aggs={
"weighted_grade": {
"weighted_avg": {
"value": {
"field": "grade"
},
"weight": {
"field": "weight"
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'exams',
body: {
size: 0,
aggregations: {
weighted_grade: {
weighted_avg: {
value: {
field: 'grade'
},
weight: {
field: 'weight'
}
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "exams",
size: 0,
aggs: {
weighted_grade: {
weighted_avg: {
value: {
field: "grade",
},
weight: {
field: "weight",
},
},
},
},
});
console.log(response);
コンソール
POST /exams/_search
{
"size": 0,
"aggs": {
"weighted_grade": {
"weighted_avg": {
"value": {
"field": "grade"
},
"weight": {
"field": "weight"
}
}
}
}
}
コンソール-結果
{
...
"aggregations": {
"weighted_grade": {
"value": 70.0
}
}
}
フィールドごとに複数の値が許可されますが、重みは1つだけ許可されます。集計が複数の重みを持つ文書に遭遇した場合(例:重みフィールドが多値フィールドの場合)、検索は中止されます。この状況がある場合は、ランタイムフィールドを構築して、それらの値を単一の重みに結合する必要があります。
この単一の重みは、value
フィールドから抽出された各値に独立して適用されます。
この例は、複数の値を持つ単一の文書が単一の重みで平均化される方法を示しています:
Python
resp = client.index(
index="exams",
refresh=True,
document={
"grade": [
1,
2,
3
],
"weight": 2
},
)
print(resp)
resp1 = client.search(
index="exams",
size=0,
aggs={
"weighted_grade": {
"weighted_avg": {
"value": {
"field": "grade"
},
"weight": {
"field": "weight"
}
}
}
},
)
print(resp1)
Ruby
response = client.index(
index: 'exams',
refresh: true,
body: {
grade: [
1,
2,
3
],
weight: 2
}
)
puts response
response = client.search(
index: 'exams',
body: {
size: 0,
aggregations: {
weighted_grade: {
weighted_avg: {
value: {
field: 'grade'
},
weight: {
field: 'weight'
}
}
}
}
}
)
puts response
Js
const response = await client.index({
index: "exams",
refresh: "true",
document: {
grade: [1, 2, 3],
weight: 2,
},
});
console.log(response);
const response1 = await client.search({
index: "exams",
size: 0,
aggs: {
weighted_grade: {
weighted_avg: {
value: {
field: "grade",
},
weight: {
field: "weight",
},
},
},
},
});
console.log(response1);
コンソール
POST /exams/_doc?refresh
{
"grade": [1, 2, 3],
"weight": 2
}
POST /exams/_search
{
"size": 0,
"aggs": {
"weighted_grade": {
"weighted_avg": {
"value": {
"field": "grade"
},
"weight": {
"field": "weight"
}
}
}
}
}
3つの値(1
、2
、および 3
)は、すべて 2
の重みを持つ独立した値として含まれます:
コンソール-結果
{
...
"aggregations": {
"weighted_grade": {
"value": 2.0
}
}
}
集計は 2.0
を結果として返し、手動で計算した場合に期待されるものと一致します: ((1*2) + (2*2) + (3*2)) / (2+2+2) == 2
ランタイムフィールド
インデックスされた値と完全に一致しない値を合計または重み付けする必要がある場合は、ランタイムフィールドで集計を実行します。
Python
resp = client.index(
index="exams",
refresh=True,
document={
"grade": 100,
"weight": [
2,
3
]
},
)
print(resp)
resp1 = client.index(
index="exams",
refresh=True,
document={
"grade": 80,
"weight": 3
},
)
print(resp1)
resp2 = client.search(
index="exams",
filter_path="aggregations",
size=0,
runtime_mappings={
"weight.combined": {
"type": "double",
"script": "\n double s = 0;\n for (double w : doc['weight']) {\n s += w;\n }\n emit(s);\n "
}
},
aggs={
"weighted_grade": {
"weighted_avg": {
"value": {
"script": "doc.grade.value + 1"
},
"weight": {
"field": "weight.combined"
}
}
}
},
)
print(resp2)
Ruby
response = client.index(
index: 'exams',
refresh: true,
body: {
grade: 100,
weight: [
2,
3
]
}
)
puts response
response = client.index(
index: 'exams',
refresh: true,
body: {
grade: 80,
weight: 3
}
)
puts response
response = client.search(
index: 'exams',
filter_path: 'aggregations',
body: {
size: 0,
runtime_mappings: {
'weight.combined' => {
type: 'double',
script: "\n double s = 0;\n for (double w : doc['weight']) {\n s += w;\n }\n emit(s);\n "
}
},
aggregations: {
weighted_grade: {
weighted_avg: {
value: {
script: 'doc.grade.value + 1'
},
weight: {
field: 'weight.combined'
}
}
}
}
}
)
puts response
Js
const response = await client.index({
index: "exams",
refresh: "true",
document: {
grade: 100,
weight: [2, 3],
},
});
console.log(response);
const response1 = await client.index({
index: "exams",
refresh: "true",
document: {
grade: 80,
weight: 3,
},
});
console.log(response1);
const response2 = await client.search({
index: "exams",
filter_path: "aggregations",
size: 0,
runtime_mappings: {
"weight.combined": {
type: "double",
script:
"\n double s = 0;\n for (double w : doc['weight']) {\n s += w;\n }\n emit(s);\n ",
},
},
aggs: {
weighted_grade: {
weighted_avg: {
value: {
script: "doc.grade.value + 1",
},
weight: {
field: "weight.combined",
},
},
},
},
});
console.log(response2);
コンソール
POST /exams/_doc?refresh
{
"grade": 100,
"weight": [2, 3]
}
POST /exams/_doc?refresh
{
"grade": 80,
"weight": 3
}
POST /exams/_search?filter_path=aggregations
{
"size": 0,
"runtime_mappings": {
"weight.combined": {
"type": "double",
"script": """
double s = 0;
for (double w : doc['weight']) {
s += w;
}
emit(s);
"""
}
},
"aggs": {
"weighted_grade": {
"weighted_avg": {
"value": {
"script": "doc.grade.value + 1"
},
"weight": {
"field": "weight.combined"
}
}
}
}
}
コンソール-結果
{
"aggregations": {
"weighted_grade": {
"value": 93.5
}
}
}
欠落した値
デフォルトでは、集計は null
または value
または weight
フィールドの値が欠落している文書を除外します。これらの文書に対してデフォルト値を指定するには、missing
パラメータを使用します。
Python
resp = client.search(
index="exams",
size=0,
aggs={
"weighted_grade": {
"weighted_avg": {
"value": {
"field": "grade",
"missing": 2
},
"weight": {
"field": "weight",
"missing": 3
}
}
}
},
)
print(resp)
Js
const response = await client.search({
index: "exams",
size: 0,
aggs: {
weighted_grade: {
weighted_avg: {
value: {
field: "grade",
missing: 2,
},
weight: {
field: "weight",
missing: 3,
},
},
},
},
});
console.log(response);
コンソール
POST /exams/_search
{
"size": 0,
"aggs": {
"weighted_grade": {
"weighted_avg": {
"value": {
"field": "grade",
"missing": 2
},
"weight": {
"field": "weight",
"missing": 3
}
}
}
}
}