Moving function 집계

Moving function 집계

moving_fn 집계는 슬라이딩 윈도우 위에서 스크립트를 실행하는 부모 파이프라인(parent pipeline) 집계예요. 슬라이딩 윈도우가 히스토그램이나 date_histogram 집계에서 추출한 값 시퀀스를 한 버킷씩 이동하면서 스크립트를 실행해요.

출처: 문서

본문

moving_fn 집계는 슬라이딩 윈도우 위에서 스크립트를 실행하는 부모 파이프라인(parent pipeline) 집계입니다. 슬라이딩 윈도우는 부모 히스토그램 또는 date_histogram 집계에서 추출한 값 시퀀스 위를 이동합니다. 윈도우는 한 번에 한 버킷씩 왼쪽에서 오른쪽으로 이동하며, moving_fn은 윈도우가 이동할 때마다 스크립트를 실행합니다.

moving_fn 집계를 사용하면 슬라이딩 윈도우 안의 데이터에 어떤 숫자 계산이든 스크립트로 처리할 수 있습니다. 예를 들어 다음과 같은 용도로 사용할 수 있습니다.

  • 추세 분석 (Trend analysis)
  • 이상치 탐지 (Outlier detection)
  • 맞춤형 시계열 분석 (Custom time-series analysis)
  • 맞춤형 평활화 알고리즘 (Custom smoothing algorithms)
  • 디지털 신호 처리 (Digital signal processing, DSP)

파라미터

moving_fn 집계는 다음 파라미터를 받습니다.

파라미터 필수/선택 데이터 타입 설명
buckets_path 필수 String 처리할 지표 값을 담고 있는 집계 버킷들의 경로입니다. Buckets path를 참고하세요.
script 필수 String 또는 Object 각 데이터 윈도우에 대한 값을 계산하는 스크립트입니다. 인라인 스크립트, 저장된 스크립트, 스크립트 파일이 될 수 있습니다. 스크립트는 buckets_path 파라미터에 정의된 변수 이름에 접근할 수 있습니다.
window 필수 Integer 슬라이딩 윈도우 안의 버킷 수입니다. 양의 정수여야 합니다.
gap_policy 선택 String 누락된 데이터에 적용할 정책입니다. 유효한 값은 skip과 insert_zeros이며 기본값은 skip입니다. Data gaps를 참고하세요.
format 선택 String DecimalFormat 서식 문자열입니다. 집계의 value_as_string 속성에 서식이 적용된 출력을 반환합니다.
shift 선택 Integer 윈도우를 이동할 버킷 수입니다. 양수(미래 버킷 쪽으로 이동) 또는 음수(과거 버킷 쪽으로 이동)일 수 있습니다. 기본값은 0으로, 현재 버킷의 바로 왼쪽에 윈도우를 배치합니다. Shifting the window를 참고하세요.

이동 함수의 동작 방식

moving_fn 집계는 정렬된 버킷 시퀀스 위의 슬라이딩 윈도우에서 동작합니다. 부모 집계의 첫 번째 버킷에서 시작해 moving_fn은 다음을 수행합니다.

  • window와 shift 파라미터로 지정된 버킷들에서 값의 부분 시퀀스(윈도우)를 수집합니다.
  • 이 값들을 배열로 script가 지정한 함수에 전달합니다.
  • script를 사용해 배열에서 단일 값을 계산합니다.
  • 이 값을 현재 버킷의 결과로 반환합니다.
  • 한 버킷 앞으로 이동하고 이 과정을 반복합니다.

'과거'와 '미래' 값은 이동 윈도우 함수의 가장 일반적인 사용 사례인 시계열 데이터를 가리킵니다. 더 일반적으로는 정렬된 모든 데이터 시퀀스에서 각각 이전 값과 이후 값을 가리킵니다.

moving_fn이 적용하는 스크립트는 사전 정의된 함수이거나 맞춤형 스크립트일 수 있습니다. 버킷 값은 values 배열로 스크립트에 제공됩니다. 스크립트는 double 값을 결과로 반환합니다. 결과 값 NaN과 +/- Inf는 허용되지만 null은 허용되지 않습니다.

윈도우 크기

window 파라미터는 윈도우의 크기를 정의하는 버킷 수를 지정합니다.

스크립트 함수에 전달되는 배열은 0부터 인덱스가 시작됩니다. 배열 값은 스크립트 안에서 values[0]부터 values[n]으로 접근하며, 여기서 n = values.length - 1 입니다.

윈도우 이동(shift)

shift 파라미터는 현재 버킷을 기준으로 이동 윈도우가 어디에 위치하는지를 제어합니다. 분석에 과거 맥락이 필요한지, 현재 데이터가 필요한지, 미래 예측이 필요한지에 따라 shift를 설정하세요. 기본값인 0은 과거 값만 표시합니다(현재 버킷 제외).

자주 사용되는 shift 값은 다음과 같습니다.

shift 윈도우 설명
0 과거 값만. 현재 값을 제외합니다. --[-----]x----
1 현재 값을 포함한 과거 값. --[----x]-----
window/2 현재 값을 중심으로 윈도우를 배치합니다. --[--x--]-----
window 현재 값을 포함한 미래 값. --[x----]-----

윈도우가 시퀀스의 시작이나 끝에서 사용 가능한 데이터를 벗어나면, 윈도우는 사용 가능한 포인트만 쓰도록 자동으로 줄어듭니다.

[x----]--
-[x----]-
--[x----]
---[x---]
----[x--]
-----[x-]
------[x]

사전 정의된 함수

moving_fn 집계는 맞춤형 스크립트 대신 사용할 수 있는 여러 사전 정의된 함수를 지원합니다. 이 함수들은 MovingFunctions 컨텍스트에서 접근할 수 있습니다. 예를 들어 MovingFunctions.max(values)처럼 max 함수에 접근할 수 있습니다.

다음 표는 사전 정의된 함수를 설명합니다.

함수 모델 키워드 설명
Max max 윈도우 안의 최댓값입니다.
Min min 윈도우 안의 최솟값입니다.
Sum sum 윈도우 안의 값들의 합계입니다.
Unweighted average unweightedAvg 윈도우 안의 모든 값의 가중치 없는 평균으로, sum / window와 같습니다.
Linear weighted average linearWeightedAvg 선형 감소 가중치를 사용한 가중 평균으로, 최근 값에 더 많은 중요도를 부여합니다.
Exponentially Weighted Moving Average ewma 지수 감소 가중치를 사용한 가중 평균으로, 최근 값에 더 많은 중요도를 부여합니다.
Holt holt 두 번째 지수 항을 사용해 장기 추세를 완화하는 가중 평균입니다.
Holt-Winters holt_wimnters 세 번째 지수 항을 사용해 주기적(계절적) 효과를 완화하는 가중 평균입니다.
Standard deviation stdDev 윈도우 안의 값들의 합계입니다.

사전 정의된 모든 함수는 values 배열을 첫 번째 파라미터로 받습니다. 추가 파라미터를 받는 함수는 values 뒤에 파라미터를 순서대로 전달하세요. 예를 들어 script 값을 MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))로 설정해 stdDev 함수를 호출할 수 있습니다.

각 모델에 필요한 설정은 다음 표와 같습니다.

함수 추가 파라미터 허용 값 기본값 설명
max 없음 Numeric array None 윈도우의 최댓값입니다.
min 없음 Numeric array None 윈도우의 최솟값입니다.
sum 없음 Numeric array None 윈도우 안의 모든 값의 합계입니다.
unweightedAvg 없음 Numeric array None 윈도우 안의 모든 값의 산술 평균입니다.
linearWeightedAvg 없음 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 유형 모델에서 divide-by-zero 오류를 피하기 위해 0 값에 작은 오프셋을 추가할지 여부입니다.
stdDev avg Any double None 윈도우의 표준 편차입니다. 의미 있는 표준 편차를 계산하려면 슬라이딩 윈도우 배열의 평균을 사용하세요. 일반적으로 MovingFunctions.unweightedAvg(values)입니다.

사전 정의된 함수는 파라미터가 누락된 함수 시그니처를 지원하지 않습니다. 따라서 기본값을 사용하더라도 추가 파라미터를 반드시 제공해야 합니다.

예제: 사전 정의된 함수

다음 예제는 OpenSearch Dashboards logs 샘플 데이터에서 1주일 간격의 날짜 히스토그램을 만듭니다. sum 서브 집계가 매주 기록된 모든 bytes의 합계를 계산하고, 마지막으로 moving_fn 집계가 윈도우 크기 5, 기본 shift 0, 가중치 없는 평균을 사용해 bytes 합계의 표준 편차를 계산합니다.

POST /opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "my_date_histo": {
      "date_histogram": {
        "field": "timestamp",
        "calendar_interval": "week"
      },
      "aggs": {
        "the_sum": {
          "sum": { "field": "bytes" }
        },
        "the_movavg": {
          "moving_fn": {
            "buckets_path": "the_sum",
            "window": 5,
            "script": "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))"
          }
        }
      }
    }
  }
}

예제 응답

응답은 두 번째 버킷에서 0 값으로 시작하는 이동 윈도우의 표준 편차를 보여 줍니다. stdDev 함수는 비어 있거나 잘못된 값(null 또는 NaN)만 포함하는 윈도우에 대해 0을 반환합니다.

{
  "took": 15,
  "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_histo": {
      "buckets": [
        {
          "key_as_string": "2025-03-24T00:00:00.000Z",
          "key": 1742774400000,
          "doc_count": 249,
          "the_sum": {
            "value": 1531493
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-03-31T00:00:00.000Z",
          "key": 1743379200000,
          "doc_count": 1617,
          "the_sum": {
            "value": 9213161
          },
          "the_movavg": {
            "value": 0
          }
        },
        {
          "key_as_string": "2025-04-07T00:00:00.000Z",
          "key": 1743984000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9188671
          },
          "the_movavg": {
            "value": 3840834
          }
        },
        {
          "key_as_string": "2025-04-14T00:00:00.000Z",
          "key": 1744588800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9244851
          },
          "the_movavg": {
            "value": 3615414.498228507
          }
        },
        {
          "key_as_string": "2025-04-21T00:00:00.000Z",
          "key": 1745193600000,
          "doc_count": 1609,
          "the_sum": {
            "value": 9061045
          },
          "the_movavg": {
            "value": 3327358.65618917
          }
        },
        {
          "key_as_string": "2025-04-28T00:00:00.000Z",
          "key": 1745798400000,
          "doc_count": 1554,
          "the_sum": {
            "value": 8713507
          },
          "the_movavg": {
            "value": 3058812.9440705855
          }
        },
        {
          "key_as_string": "2025-05-05T00:00:00.000Z",
          "key": 1746403200000,
          "doc_count": 1710,
          "the_sum": {
            "value": 9544718
          },
          "the_movavg": {
            "value": 195603.33146038183
          }
        },
        {
          "key_as_string": "2025-05-12T00:00:00.000Z",
          "key": 1747008000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9155820
          },
          "the_movavg": {
            "value": 270085.92336040025
          }
        },
        {
          "key_as_string": "2025-05-19T00:00:00.000Z",
          "key": 1747612800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9025078
          },
          "the_movavg": {
            "value": 269477.75659701484
          }
        },
        {
          "key_as_string": "2025-05-26T00:00:00.000Z",
          "key": 1748217600000,
          "doc_count": 895,
          "the_sum": {
            "value": 5047345
          },
          "the_movavg": {
            "value": 267356.5422566652
          }
        }
      ]
    }
  }
}

맞춤형 스크립트

moving_fn 결과를 계산하기 위해 임의의 맞춤형 스크립트를 제공할 수 있습니다. 맞춤형 스크립트는 Painless 스크립팅 언어를 사용합니다. 자세한 내용은 Painless scripting language를 참고하세요.

예제: 맞춤형 스크립트

다음 예제는 OpenSearch Dashboards e-commerce 샘플 데이터에서 1주일 간격의 날짜 히스토그램을 만듭니다. sum 서브 집계가 매주 모든 과세 수익(taxed revenue)의 합계를 계산합니다. 그런 다음 moving_fn 스크립트가 현재 값 바로 앞의 두 값 중 더 큰 값을 반환하고, 두 값이 없으면 NaN을 반환합니다.

POST /opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "my_date_histo": {
      "date_histogram": {
        "field": "order_date",
        "calendar_interval": "week"
      },
      "aggs": {
        "the_sum": {
          "sum": { "field": "taxful_total_price" }
        },
        "the_movavg": {
          "moving_fn": {
            "buckets_path": "the_sum",
            "window": 2,
            "script": "return (values.length values[1] ? values[0] : values[1]))"
          }
        }
      }
    }
  }
}

이 예제는 계산을 수행할 충분한 이전 데이터가 있는 세 번째 버킷부터 계산 결과를 반환합니다.

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4675,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "my_date_histo": {
      "buckets": [
        {
          "key_as_string": "2025-03-24T00:00:00.000Z",
          "key": 1742774400000,
          "doc_count": 582,
          "the_sum": {
            "value": 41455.5390625
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-03-31T00:00:00.000Z",
          "key": 1743379200000,
          "doc_count": 1048,
          "the_sum": {
            "value": 79448.60546875
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-04-07T00:00:00.000Z",
          "key": 1743984000000,
          "doc_count": 1048,
          "the_sum": {
            "value": 78208.4296875
          },
          "the_movavg": {
            "value": 79448.60546875
          }
        },
        {
          "key_as_string": "2025-04-14T00:00:00.000Z",
          "key": 1744588800000,
          "doc_count": 1073,
          "the_sum": {
            "value": 81277.296875
          },
          "the_movavg": {
            "value": 79448.60546875
          }
        },
        {
          "key_as_string": "2025-04-21T00:00:00.000Z",
          "key": 1745193600000,
          "doc_count": 924,
          "the_sum": {
            "value": 70494.2578125
          },
          "the_movavg": {
            "value": 81277.296875
          }
        }
      ]
    }
  }
}

예제: 이동 평균(Moving average)

moving_fn 집계는 더 이상 사용되지 않는(Deprecated) moving_avg 집계를 대체합니다. moving_fn 집계는 moving_avg 집계와 비슷하지만 평균만이 아닌 임의의 함수를 계산하므로 더 다재다능합니다. moving_avg의 모든 사전 정의된 함수는 moving_fn에도 구현되어 있습니다.

holt 모델은 alpha와 beta 파라미터로 제어되는 지수 감쇠 가중치를 사용하는 이동 평균입니다. 다음 예제는 OpenSearch Dashboards logs 샘플 데이터에서 1주일 간격의 날짜 히스토그램을 만듭니다. sum 서브 집계가 매주 모든 bytes의 합계를 계산합니다. 마지막으로 moving_fn 집계가 윈도우 크기 6, 기본 shift 0, alpha 값 0.3, beta 값 0.1을 사용하는 Holt 모델로 bytes 합계의 가중 평균을 계산합니다.

POST /opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "my_date_histogram": {
      "date_histogram": {
        "field": "timestamp",
        "calendar_interval": "week"
      },
      "aggs": {
        "the_sum": {
          "sum": { "field": "bytes" }
        },
        "the_movavg": {
          "moving_fn": {
            "buckets_path": "the_sum",
            "window": 6,
            "script": "MovingFunctions.holt(values, 0.3, 0.1)"
          }
        }
      }
    }
  }
}

집계는 두 번째 버킷부터 이동 holt 평균을 반환합니다.

{
  "took": 16,
  "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,
          "the_sum": {
            "value": 1531493
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-03-31T00:00:00.000Z",
          "key": 1743379200000,
          "doc_count": 1617,
          "the_sum": {
            "value": 9213161
          },
          "the_movavg": {
            "value": 1531493
          }
        },
        {
          "key_as_string": "2025-04-07T00:00:00.000Z",
          "key": 1743984000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9188671
          },
          "the_movavg": {
            "value": 3835993.3999999994
          }
        },
        {
          "key_as_string": "2025-04-14T00:00:00.000Z",
          "key": 1744588800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9244851
          },
          "the_movavg": {
            "value": 5603111.707999999
          }
        },
        {
          "key_as_string": "2025-04-21T00:00:00.000Z",
          "key": 1745193600000,
          "doc_count": 1609,
          "the_sum": {
            "value": 9061045
          },
          "the_movavg": {
            "value": 6964515.302359998
          }
        },
        {
          "key_as_string": "2025-04-28T00:00:00.000Z",
          "key": 1745798400000,
          "doc_count": 1554,
          "the_sum": {
            "value": 8713507
          },
          "the_movavg": {
            "value": 7930766.089341199
          }
        },
        {
          "key_as_string": "2025-05-05T00:00:00.000Z",
          "key": 1746403200000,
          "doc_count": 1710,
          "the_sum": {
            "value": 9544718
          },
          "the_movavg": {
            "value": 8536788.607547803
          }
        },
        {
          "key_as_string": "2025-05-12T00:00:00.000Z",
          "key": 1747008000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9155820
          },
          "the_movavg": {
            "value": 9172269.837272028
          }
        },
        {
          "key_as_string": "2025-05-19T00:00:00.000Z",
          "key": 1747612800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9025078
          },
          "the_movavg": {
            "value": 9166173.88436614
          }
        },
        {
          "key_as_string": "2025-05-26T00:00:00.000Z",
          "key": 1748217600000,
          "doc_count": 895,
          "the_sum": {
            "value": 5047345
          },
          "the_movavg": {
            "value": 9123157.830417283
          }
        }
      ]
    }
  }
}

더 알아보기 (Learn more)