Агрегация скользящей функции
Для упорядоченной последовательности данных агрегация скользящей функции сдвигает окно по данным и позволяет пользователю указать пользовательский скрипт, который выполняется для каждого окна данных. Для удобства предусмотрено несколько общих функций, таких как min/max, скользящие средние и т.д.
Синтаксис
Агрегация moving_fn выглядит следующим образом:
{
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.min(values)"
}
} Таблица 66. moving_fn Параметры
| Имя параметра | Описание | Обязательно | Значение по умолчанию |
|---|---|---|---|
| Путь к метрике, представляющей интерес (см. | Обязательно | |
| Размер окна, которое "сдвигается" по гистограмме. | Обязательно | |
| Скрипт, который должен выполняться для каждого окна данных | Обязательно | |
| Политика, которая применяется при обнаружении разрывов в данных. См. Обработка разрывов в данных. | Необязательно |
|
| Сдвиг положения окна. | Необязательно | 0 |
Агрегации moving_fn должны быть вложены в histogram или date_histogram агрегацию. Их можно вкладывать как и другие метрические агрегации:
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movfn": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.unweightedAvg(values)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movfn: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.unweightedAvg(values)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movfn: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.unweightedAvg(values)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movfn": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.unweightedAvg(values)"
}
}
}
}
}
} | Создается | |
| Используется метрика | |
| В заключение, задаётся агрегация |
Скользящие средние строятся путём сначала указания histogram или date_histogram по полю. Затем вы можете необязательно добавить числовые метрики, такие как sum, внутри этой гистограммы. Наконец, агрегация moving_fn вкладывается внутрь гистограммы. Параметр buckets_path используется для указания одной из метрик-сестёр внутри гистограммы (см. buckets_path Синтаксис для описания синтаксиса для buckets_path).
Пример ответа от вышеуказанной агрегации может быть таким:
{
"took": 11,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"my_date_histo": {
"buckets": [
{
"key_as_string": "2015/01/01 00:00:00",
"key": 1420070400000,
"doc_count": 3,
"the_sum": {
"value": 550.0
},
"the_movfn": {
"value": null
}
},
{
"key_as_string": "2015/02/01 00:00:00",
"key": 1422748800000,
"doc_count": 2,
"the_sum": {
"value": 60.0
},
"the_movfn": {
"value": 550.0
}
},
{
"key_as_string": "2015/03/01 00:00:00",
"key": 1425168000000,
"doc_count": 2,
"the_sum": {
"value": 375.0
},
"the_movfn": {
"value": 305.0
}
}
]
}
}
} Настройка пользовательских скриптов
Агрегация функции Moving Function позволяет пользователю указать любой произвольный скрипт для определения пользовательской логики. Скрипт вызывается каждый раз, когда собирается новый набор данных. Эти значения передаются скрипту в переменной values. Скрипт должен выполнить какое-либо вычисление и вывести одно double в качестве результата. Вывод null запрещён, хотя NaN и +/- Inf разрешены.
Например, этот скрипт просто вернёт первое значение из окна или NaN, если доступных значений нет:
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "return values.length > 0 ? values[0] : Double.NaN"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movavg: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'return values.length > 0 ? values[0] : Double.NaN'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movavg: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "return values.length > 0 ? values[0] : Double.NaN",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "return values.length > 0 ? values[0] : Double.NaN"
}
}
}
}
}
} Параметр сдвига
По умолчанию (с shift = 0), окно, предлагаемое для вычисления, содержит последние n значения, за исключением текущего значения. Увеличение shift на 1 сдвигает начальную позицию окна на 1 вправо.
- Чтобы включить текущее значение в окно, используйте
shift = 1. - Для центрирования (
n / 2значений до и после текущего значения), используйтеshift = window / 2. - Для выравнивания по правому краю (
nзначений после текущего значения), используйтеshift = window.
Если любой из краёв окна выходит за пределы ряда данных, окно уменьшается до включения только доступных значений.
Встроенные функции
Для удобства, ряд функций был встроен и доступен в контексте скрипта moving_fn:
-
max() -
min() -
sum() -
stdDev() -
unweightedAvg() -
linearWeightedAvg() -
ewma() -
holt() -
holtWinters()
Функции доступны из пространства имён MovingFunctions. Например, MovingFunctions.max()
Функция max
Эта функция принимает набор значений типа double и возвращает максимальное значение в этом диапазоне. Значения null и NaN игнорируются; максимальное значение вычисляется только для действительных значений. Если диапазон пуст или все значения являются null/NaN, в качестве результата возвращается NaN.
Таблица 67. Параметры функции max(double[] values)
| Имя параметра | Описание |
|---|---|
| Диапазон значений для поиска максимального значения |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_moving_max": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.max(values)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_moving_max: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.max(values)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_moving_max: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.max(values)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_moving_max": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.max(values)"
}
}
}
}
}
} Функция min
Эта функция принимает набор значений типа double и возвращает минимальное значение в этом диапазоне. Значения null и NaN игнорируются; минимальное значение вычисляется только для действительных значений. Если диапазон пуст или все значения являются null/NaN, в качестве результата возвращается NaN.
Таблица 68. Параметры функции min(double[] values)
| Имя параметра | Описание |
|---|---|
| Диапазон значений для поиска минимального значения |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_moving_min": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.min(values)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_moving_min: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.min(values)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_moving_min: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.min(values)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_moving_min": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.min(values)"
}
}
}
}
}
} Функция sum
Эта функция принимает набор значений типа double и возвращает сумму значений в этом диапазоне. Значения null и NaN игнорируются; сумма вычисляется только для действительных значений. Если диапазон пуст или все значения являются null/NaN, в качестве результата возвращается 0.0.
Таблица 69. Параметры функции sum(double[] values)
| Имя параметра | Описание |
|---|---|
| Диапазон значений для вычисления суммы |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_moving_sum": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.sum(values)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_moving_sum: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.sum(values)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_moving_sum: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.sum(values)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_moving_sum": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.sum(values)"
}
}
}
}
}
} Функция stdDev
Эта функция принимает набор значений типа double и среднее значение, а затем возвращает стандартное отклонение значений в этом окне. Значения null и NaN игнорируются; сумма вычисляется только для действительных значений. Если окно пустое или все значения являются null/NaN, в качестве результата возвращается 0.0.
Таблица 70. Параметры функции stdDev(double[] values)
| Имя параметра | Описание |
|---|---|
| Окно значений, для которых нужно вычислить стандартное отклонение |
| Среднее значение окна |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_moving_sum": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_moving_sum: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_moving_sum: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script:
"MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_moving_sum": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))"
}
}
}
}
}
} Параметр avg должен быть предоставлен функции стандартного отклонения, потому что различные типы средних значений могут быть вычислены в окне (простые, взвешенные по линейному закону и т.д.). Различные скользящие средние, описанные ниже, могут быть использованы для вычисления среднего значения для функции стандартного отклонения.
Функция unweightedAvg
Функция unweightedAvg вычисляет сумму всех значений в окне, а затем делит на размер окна. Это эффективно является простым средним арифметическим значением окна. Простое скользящее среднее не выполняет никакого временного взвешивания, что означает, что значения от simple скользящего среднего имеют тенденцию «отставать» от реальных данных.
Значения null и NaN игнорируются; среднее значение вычисляется только для действительных значений. Если окно пустое или все значения являются null/NaN, возвращается NaN. Это означает, что количество, используемое в расчете среднего значения, равно количеству значений, не являющихся null, не являющихся NaN.
Таблица 71. Параметры функции unweightedAvg(double[] values)
| Имя параметра | Описание |
|---|---|
| Окно значений, для которых нужно найти сумму |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.unweightedAvg(values)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movavg: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.unweightedAvg(values)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movavg: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.unweightedAvg(values)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.unweightedAvg(values)"
}
}
}
}
}
} Функция linearWeightedAvg
Функция linearWeightedAvg назначает линейное взвешивание точкам в ряду, так что "более старые" точки данных (например, те, что в начале окна) вносят линейно меньший вклад в общее среднее значение. Линейное взвешивание помогает уменьшить «отставание» от среднего значения данных, так как более старые точки имеют меньшее влияние.
Если окно пустое или все значения являются null/NaN, возвращается NaN.
Таблица 72. Параметры функции linearWeightedAvg(double[] values)
| Имя параметра | Описание |
|---|---|
| Окно значений, для которых нужно найти сумму |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.linearWeightedAvg(values)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movavg: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.linearWeightedAvg(values)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movavg: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.linearWeightedAvg(values)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.linearWeightedAvg(values)"
}
}
}
}
}
} Функция ewma
Функция ewma (также известная как "экспоненциально-взвешенное скользящее среднее") похожа на функцию linearMovAvg, за исключением того, что более старые точки данных становятся экспоненциально менее значимыми, а не линейно. Скорость, с которой важность убывает, можно контролировать с помощью параметра alpha. Малые значения приводят к медленному убыванию весов, обеспечивая большую сглаженность и учитывая большую часть окна. Большие значения приводят к быстрому убыванию весов, что уменьшает влияние более старых значений на скользящее среднее. Это способствует более точному отслеживанию данных, но с меньшей сглаженностью.
Значения null и NaN игнорируются; среднее значение вычисляется только для реальных значений. Если окно пустое или все значения являются null/NaN, результат будет NaN. Это означает, что количество, используемое в расчете среднего значения, — это количество ненулевых, не-null, не-NaN значений.
Таблица 73. Параметры функции ewma(double[] values, double alpha)
| Имя параметра | Описание |
|---|---|
| Окно значений для нахождения суммы |
| Экспоненциальное убывание |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.ewma(values, 0.3)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movavg: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.ewma(values, 0.3)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movavg: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.ewma(values, 0.3)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.ewma(values, 0.3)"
}
}
}
}
}
} Функция holt
Функция holt (также известная как "двойное экспоненциальное скользящее среднее") включает второй экспоненциальный член, который отслеживает тренд данных. Простое экспоненциальное скользящее среднее не работает хорошо, когда данные имеют подлежащий линейный тренд. Двойная экспоненциальная модель вычисляет два значения: "уровень" и "тенденцию".
Вычисление уровня аналогично ewma и представляет собой экспоненциально взвешенное представление данных. Разница в том, что вместо исходного значения используется ранее сглаженное значение, что позволяет ему оставаться близким к исходному ряду. Вычисление тренда рассматривает разницу между текущим и последним значением (например, наклон или тренд сглаженных данных). Значение тренда также экспоненциально взвешено.
Значения получаются путем умножения компонент уровня и тренда.
Значения null и NaN игнорируются; среднее значение вычисляется только для реальных значений. Если окно пустое или все значения являются null/NaN, результат будет NaN. Это означает, что количество, используемое в расчете среднего значения, — это количество ненулевых, не-null, не-NaN значений.
Таблица 74. Параметры функции holt(double[] values, double alpha)
| Имя параметра | Описание |
|---|---|
| Окно значений для нахождения суммы |
| Значение убывания уровня |
| Значение убывания тренда |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.holt(values, 0.3, 0.1)"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movavg: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'MovingFunctions.holt(values, 0.3, 0.1)'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movavg: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script: "MovingFunctions.holt(values, 0.3, 0.1)",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "MovingFunctions.holt(values, 0.3, 0.1)"
}
}
}
}
}
} На практике значение alpha ведет себя очень похоже в holtMovAvg как и ewmaMovAvg: небольшие значения производят больше сглаживания и задержки, а большие значения производят более точное отслеживание и меньшую задержку. Значение beta часто трудно оценить. Малые значения подчеркивают долгосрочные тренды (например, постоянный линейный тренд на всем ряде), а большие значения подчеркивают краткосрочные тренды.
Функция holtWinters
Функция holtWinters (также известная как «тройная экспоненциальная») включает третий экспоненциальный член, который отслеживает сезонную составляющую ваших данных. Таким образом, эта агрегация сглаживается по трём компонентам: «уровень», «тенденция» и «сезонность».
Расчёт уровня и тренда идентичен расчёту в holt. Расчёт сезонности рассматривает разницу между текущей точкой и точкой, предшествующей ей на один период.
Для Holt-Winters требуется немного больше ручного управления, чем для других скользящих средних. Вам нужно указать «периодичность» ваших данных: например, если ваши данные имеют циклические тенденции каждые 7 дней, вы бы установили period = 7. Аналогично, если есть месячная тенденция, вы бы установили её в 30. В настоящее время нет возможности определения периодичности, хотя это запланировано для будущих улучшений.
Значения null и NaN игнорируются; среднее значение рассчитывается только по реальным значениям. Если окно пустое или все значения являются null/NaN, NaN возвращается в качестве результата. Это означает, что количество, используемое в расчёте среднего значения, равно количеству не-null, не-NaN значений.
Таблица 75. Параметры функции holtWinters(double[] values, double alpha)
| Имя параметра | Описание |
|---|---|
| Окно значений для поиска суммы |
| Значение затухания уровня |
| Значение затухания тренда |
| Значение затухания сезонности |
| Периодичность данных |
| Истинно, если вы хотите использовать мультипликативную Holt-Winters, ложно для аддитивной |
resp = client.search(
size=0,
aggs={
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": {
"field": "price"
}
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}"
}
}
}
}
},
)
print(resp) response = client.search(
body: {
size: 0,
aggregations: {
my_date_histo: {
date_histogram: {
field: 'date',
calendar_interval: '1M'
},
aggregations: {
the_sum: {
sum: {
field: 'price'
}
},
the_movavg: {
moving_fn: {
buckets_path: 'the_sum',
window: 10,
script: 'if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}'
}
}
}
}
}
}
)
puts response const response = await client.search({
size: 0,
aggs: {
my_date_histo: {
date_histogram: {
field: "date",
calendar_interval: "1M",
},
aggs: {
the_sum: {
sum: {
field: "price",
},
},
the_movavg: {
moving_fn: {
buckets_path: "the_sum",
window: 10,
script:
"if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}",
},
},
},
},
},
});
console.log(response); POST /_search
{
"size": 0,
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "date",
"calendar_interval": "1M"
},
"aggs": {
"the_sum": {
"sum": { "field": "price" }
},
"the_movavg": {
"moving_fn": {
"buckets_path": "the_sum",
"window": 10,
"script": "if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}"
}
}
}
}
}
} Мультипликативная Holt-Winters работает путём деления каждой точки данных на сезонное значение. Это проблематично, если какие-либо из ваших данных равны нулю или если в данных есть пробелы (поскольку это приводит к делению на ноль). Для решения этой проблемы mult Holt-Winters дополняет все значения очень маленьким значением (1*10-10), чтобы все значения были отличны от нуля. Это влияет на результат, но только незначительно. Если ваши данные не равны нулю или вы предпочитаете видеть NaN при встрече нулевых значений, вы можете отключить это поведение с помощью pad: false
«Холодный старт»
К сожалению, из-за природы Holt-Winters, ему требуется два периода данных для «запуска» алгоритма. Это означает, что ваши данные window всегда должны быть как минимум вдвое больше, чем ваш период. Если это не так, будет выброшено исключение. Это также означает, что Holt-Winters не будет генерировать значение для первых 2 * period блоков; текущий алгоритм не выполняет обратное прогнозирование.
В приведенном выше примере вы заметите оператор if (), проверяющий размер значений. Это проверка, чтобы убедиться, что у нас есть два периода данных (5 * 2, где 5 — период, указанный в функции holtWintersMovAvg), прежде чем вызывать функцию holt-winters.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-aggregations-pipeline-movfn-aggregation.html