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
          }
        }
      ]
    }
  }
}

더 알아보기 (Learn more)