Moving average 집계
Moving average 집계
moving_avg 집계는 정렬된 데이터셋의 윈도우(인접한 부분 집합) 안에 들어 있는 지표의 평균 시퀀스를 계산하는 부모 파이프라인(parent pipeline) 집계예요. 주로 시계열 데이터의 노이즈를 완화하거나 추세를 파악하는 데 사용해요.
출처: 문서
본문
Deprecated(사용 중단 예정):
moving_avg집계는moving_fn집계를 대신 사용하도록 권장되어 더 이상 사용되지 않습니다.
moving_avg 집계는 정렬된 데이터셋의 윈도우(인접한 부분 집합) 안에 들어 있는 지표의 평균 시퀀스를 계산하는 부모 파이프라인(parent pipeline) 집계입니다.
moving_avg 집계를 만들려면 먼저 히스토그램 또는 date_histogram 집계를 만듭니다. 선택적으로 히스토그램 집계 안에 지표(metric) 집계를 임베드합니다. 마지막으로 히스토그램 안에 moving_avg 집계를 임베드하고, buckets_path 파라미터를 추적하려는 임베드된 지표로 설정합니다.
윈도우의 크기는 윈도우 안에 들어 있는 연속된 데이터 값의 개수입니다. 각 반복에서 알고리즘은 윈도우 안의 모든 데이터 포인트에 대한 평균을 계산한 다음, 이전 윈도우의 첫 번째 값을 빼고 다음 윈도우의 첫 번째 값을 포함하면서 한 데이터 값씩 앞으로 밀어냅니다.
예를 들어 데이터가 [1, 5, 8, 23, 34, 28, 7, 23, 20, 19]일 때 윈도우 크기가 5인 이동 평균은 다음과 같습니다.
(1 + 5 + 8 + 23 + 34) / 5 = 14.2
(5 + 8 + 23 + 34 + 28) / 5 = 19.6
(8 + 23 + 34 + 28 + 7) / 5 = 20
and so on ...
moving_avg 집계는 일반적으로 시계열 데이터에 적용해 노이즈나 단기 변동을 완화하고 추세를 파악하는 데 사용합니다. 작은 윈도우 크기를 지정하면 소규모 변동을 완화할 수 있고, 더 큰 윈도우 크기를 지정하면 고주파 변동이나 무작위 노이즈를 완화해 저주파 추세를 더 잘 드러낼 수 있습니다.
이동 평균에 대한 자세한 내용은 Wikipedia를 참고하세요.
파라미터
moving_avg 집계는 다음 파라미터를 받습니다.
| 파라미터 | 필수/선택 | 데이터 타입 | 설명 |
|---|---|---|---|
buckets_path |
필수 | String | 집계할 버킷들의 경로입니다. Buckets path를 참고하세요. |
gap_policy |
선택 | String | 누락된 데이터에 적용할 정책입니다. 유효한 값은 skip과 insert_zeros이며 기본값은 skip입니다. Data gaps를 참고하세요. |
format |
선택 | String | DecimalFormat 서식 문자열입니다. 집계의 value_as_string 속성에 서식이 적용된 출력을 반환합니다. |
window |
선택 | Numerical | 윈도우 안에 들어 있는 데이터 포인트의 개수입니다. 기본값은 5입니다. |
model |
선택 | String | 사용할 가중 이동 평균 모델입니다. 옵션은 ewma, holt, holt_winters, linear, simple이며 기본값은 simple입니다. Models를 참고하세요. |
settings |
선택 | Object | 윈도우를 조정하기 위한 파라미터입니다. Models를 참고하세요. |
predict |
선택 | Numerical | 결과 끝에 추가할 예측 값의 개수입니다. 기본값은 0입니다. |
예제
다음 예제는 OpenSearch Dashboards logs 샘플 데이터에서 한 달 간격의 날짜 히스토그램을 만듭니다. sum 서브 집계가 매달 모든 bytes의 합계를 계산하고, 마지막으로 moving_avg 집계가 이 합계들에서 월별 bytes의 이동 평균을 계산합니다.
GET opensearch_dashboards_sample_data_logs/_search
{
"size": 0,
"aggs": {
"my_date_histogram": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "month"
},
"aggs": {
"sum_of_bytes": {
"sum": { "field": "bytes" }
},
"moving_avg_of_sum_of_bytes": {
"moving_avg": {
"buckets_path": "sum_of_bytes"
}
}
}
}
}
}
예제 응답
집계는 두 번째 버킷부터 moving_avg 값을 반환합니다. 첫 번째 버킷에는 이전 데이터 포인트가 충분하지 않아 이동 평균 값이 없습니다.
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"my_date_histogram": {
"buckets": [
{
"key_as_string": "2025-03-01T00:00:00.000Z",
"key": 1740787200000,
"doc_count": 480,
"sum_of_bytes": {
"value": 2804103
}
},
{
"key_as_string": "2025-04-01T00:00:00.000Z",
"key": 1743465600000,
"doc_count": 6849,
"sum_of_bytes": {
"value": 39103067
},
"moving_avg_of_sum_of_bytes": {
"value": 2804103
}
},
{
"key_as_string": "2025-05-01T00:00:00.000Z",
"key": 1746057600000,
"doc_count": 6745,
"sum_of_bytes": {
"value": 37818519
},
"moving_avg_of_sum_of_bytes": {
"value": 20953585
}
}
]
}
}
}
예제: 예측(Prediction)
moving_avg 집계를 사용해 미래 버킷을 예측할 수 있습니다.
다음 예제는 이전 예제의 간격을 1주일로 줄이고, 응답 끝에 5개의 예측된 1주일 버킷을 추가합니다.
GET opensearch_dashboards_sample_data_logs/_search
{
"size": 0,
"aggs": {
"my_date_histogram": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "week"
},
"aggs": {
"sum_of_bytes": {
"sum": {
"field": "bytes"
}
},
"moving_avg_of_sum_of_bytes": {
"moving_avg": {
"buckets_path": "sum_of_bytes",
"predict": 5
}
}
}
}
}
}
응답에는 5개의 예측이 포함됩니다. 예측된 버킷의 doc_count가 0이라는 점에 유의하세요.
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"my_date_histogram": {
"buckets": [
{
"key_as_string": "2025-03-24T00:00:00.000Z",
"key": 1742774400000,
"doc_count": 249,
"sum_of_bytes": {
"value": 1531493
}
},
{
"key_as_string": "2025-03-31T00:00:00.000Z",
"key": 1743379200000,
"doc_count": 1617,
"sum_of_bytes": {
"value": 9213161
},
"moving_avg_of_sum_of_bytes": {
"value": 1531493
}
},
{
"key_as_string": "2025-04-07T00:00:00.000Z",
"key": 1743984000000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9188671
},
"moving_avg_of_sum_of_bytes": {
"value": 5372327
}
},
{
"key_as_string": "2025-04-14T00:00:00.000Z",
"key": 1744588800000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9244851
},
"moving_avg_of_sum_of_bytes": {
"value": 6644441.666666667
}
},
{
"key_as_string": "2025-04-21T00:00:00.000Z",
"key": 1745193600000,
"doc_count": 1609,
"sum_of_bytes": {
"value": 9061045
},
"moving_avg_of_sum_of_bytes": {
"value": 7294544
}
},
{
"key_as_string": "2025-04-28T00:00:00.000Z",
"key": 1745798400000,
"doc_count": 1554,
"sum_of_bytes": {
"value": 8713507
},
"moving_avg_of_sum_of_bytes": {
"value": 7647844.2
}
},
{
"key_as_string": "2025-05-05T00:00:00.000Z",
"key": 1746403200000,
"doc_count": 1710,
"sum_of_bytes": {
"value": 9544718
},
"moving_avg_of_sum_of_bytes": {
"value": 9084247
}
},
{
"key_as_string": "2025-05-12T00:00:00.000Z",
"key": 1747008000000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9155820
},
"moving_avg_of_sum_of_bytes": {
"value": 9150558.4
}
},
{
"key_as_string": "2025-05-19T00:00:00.000Z",
"key": 1747612800000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9025078
},
"moving_avg_of_sum_of_bytes": {
"value": 9143988.2
}
},
{
"key_as_string": "2025-05-26T00:00:00.000Z",
"key": 1748217600000,
"doc_count": 895,
"sum_of_bytes": {
"value": 5047345
},
"moving_avg_of_sum_of_bytes": {
"value": 9100033.6
}
},
{
"key_as_string": "2025-06-02T00:00:00.000Z",
"key": 1748822400000,
"doc_count": 0,
"moving_avg_of_sum_of_bytes": {
"value": 8297293.6
}
},
{
"key_as_string": "2025-06-09T00:00:00.000Z",
"key": 1749427200000,
"doc_count": 0,
"moving_avg_of_sum_of_bytes": {
"value": 8297293.6
}
},
{
"key_as_string": "2025-06-16T00:00:00.000Z",
"key": 1750032000000,
"doc_count": 0,
"moving_avg_of_sum_of_bytes": {
"value": 8297293.6
}
},
{
"key_as_string": "2025-06-23T00:00:00.000Z",
"key": 1750636800000,
"doc_count": 0,
"moving_avg_of_sum_of_bytes": {
"value": 8297293.6
}
},
{
"key_as_string": "2025-06-30T00:00:00.000Z",
"key": 1751241600000,
"doc_count": 0,
"moving_avg_of_sum_of_bytes": {
"value": 8297293.6
}
}
]
}
}
}
모델(Models)
moving_avg 집계는 이동 윈도우의 값에 가중치를 부여하는 방식이 서로 다른 5가지 모델을 지원합니다. model 파라미터로 어떤 모델을 사용할지 지정합니다.
| 모델 | 모델 키워드 | 가중치 방식 |
|---|---|---|
| Simple | simple |
윈도우 안의 모든 값의 가중치 없는 평균입니다. |
| Linear | linear |
선형 감소 가중치를 사용해 최근 값에 더 많은 중요도를 부여합니다. |
| Exponentially Weighted Moving Average | ewma |
지수 감소 가중치를 사용해 최근 값에 더 많은 중요도를 부여합니다. |
| Holt | holt |
두 번째 지수 항을 사용해 장기 추세를 완화합니다. |
| Holt-Winters | holt_winters |
세 번째 지수 항을 사용해 주기적(계절적) 효과를 완화합니다. |
settings 객체를 사용해 모델의 속성을 설정합니다. 각 모델에 사용 가능한 설정은 다음 표와 같습니다.
| 모델 | 파라미터 | 허용 값 | 기본값 | 설명 |
|---|---|---|---|---|
simple |
없음 | Numeric array | None | 윈도우 안의 모든 값의 산술 평균입니다. |
linear |
없음 | Numeric array | None | 윈도우 안의 모든 값의 가중 평균으로, 최근 값에 더 큰 가중치를 부여합니다. |
ewma |
alpha |
[0, 1] | 0.3 | 감쇠 파라미터입니다. 값이 클수록 최근 데이터 포인트에 더 많은 가중치를 부여합니다. |
holt |
alpha |
[0, 1] | 0.3 | 레벨(level) 구성 요소의 감쇠 파라미터입니다. |
beta |
[0, 1] | 0.1 | 추세(trend) 구성 요소의 감쇠 파라미터입니다. | |
holt_winters |
alpha |
[0, 1] | 0.3 | 레벨(level) 구성 요소의 감쇠 파라미터입니다. |
beta |
[0, 1] | 0.3 | 추세(trend) 구성 요소의 감쇠 파라미터입니다. | |
gamma |
[0, 1] | 0.3 | 계절(seasonal) 구성 요소의 감쇠 파라미터입니다. | |
type |
add, mult |
add |
계절성이 모델링되는 방식을 정의합니다. 가산(additive) 또는 승산(multiplicative)입니다. | |
period |
Integer | 1 | 한 주기를 구성하는 버킷의 개수입니다. | |
pad |
Boolean | true | mult 유형 모델에서 0 값을 나눗셈 오류(divide-by-zero)를 피하기 위해 0 값에 작은 오프셋을 추가할지 여부입니다. |
이 모델들과 파라미터에 대한 논의는 Wikipedia를 참고하세요.
예제: Holt 모델
holt 모델은 alpha와 beta 파라미터로 제어되는 지수 감쇠로 가중치를 계산합니다.
다음 요청은 윈도우 크기 6, alpha 값 0.4, beta 값 0.2를 사용하는 Holt 모델로 주간 총 bytes 데이터의 이동 평균을 계산합니다.
GET opensearch_dashboards_sample_data_logs/_search
{
"size": 0,
"aggs": {
"my_date_histogram": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "week"
},
"aggs": {
"sum_of_bytes": {
"sum": {
"field": "bytes"
}
},
"moving_avg_of_sum_of_bytes": {
"moving_avg": {
"buckets_path": "sum_of_bytes",
"window": 6,
"model": "holt",
"settings": { "alpha": 0.4, "beta": 0.2 }
}
}
}
}
}
}
이동 평균은 두 번째 버킷부터 시작됩니다.
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"my_date_histogram": {
"buckets": [
{
"key_as_string": "2025-03-24T00:00:00.000Z",
"key": 1742774400000,
"doc_count": 249,
"sum_of_bytes": {
"value": 1531493
}
},
{
"key_as_string": "2025-03-31T00:00:00.000Z",
"key": 1743379200000,
"doc_count": 1617,
"sum_of_bytes": {
"value": 9213161
},
"moving_avg_of_sum_of_bytes": {
"value": 1531493
}
},
{
"key_as_string": "2025-04-07T00:00:00.000Z",
"key": 1743984000000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9188671
},
"moving_avg_of_sum_of_bytes": {
"value": 4604160.2
}
},
{
"key_as_string": "2025-04-14T00:00:00.000Z",
"key": 1744588800000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9244851
},
"moving_avg_of_sum_of_bytes": {
"value": 6806684.584000001
}
},
{
"key_as_string": "2025-04-21T00:00:00.000Z",
"key": 1745193600000,
"doc_count": 1609,
"sum_of_bytes": {
"value": 9061045
},
"moving_avg_of_sum_of_bytes": {
"value": 8341230.127680001
}
},
{
"key_as_string": "2025-04-28T00:00:00.000Z",
"key": 1745798400000,
"doc_count": 1554,
"sum_of_bytes": {
"value": 8713507
},
"moving_avg_of_sum_of_bytes": {
"value": 9260724.7236736
}
},
{
"key_as_string": "2025-05-05T00:00:00.000Z",
"key": 1746403200000,
"doc_count": 1710,
"sum_of_bytes": {
"value": 9544718
},
"moving_avg_of_sum_of_bytes": {
"value": 9657431.903375873
}
},
{
"key_as_string": "2025-05-12T00:00:00.000Z",
"key": 1747008000000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9155820
},
"moving_avg_of_sum_of_bytes": {
"value": 9173999.55240704
}
},
{
"key_as_string": "2025-05-19T00:00:00.000Z",
"key": 1747612800000,
"doc_count": 1610,
"sum_of_bytes": {
"value": 9025078
},
"moving_avg_of_sum_of_bytes": {
"value": 9172040.511275519
}
},
{
"key_as_string": "2025-05-26T00:00:00.000Z",
"key": 1748217600000,
"doc_count": 895,
"sum_of_bytes": {
"value": 5047345
},
"moving_avg_of_sum_of_bytes": {
"value": 9108804.964619776
}
}
]
}
}
}