쿼리 빌드 가이드

개요

이 섹션에서는 이상 감지 쿼리를 올바르게 구성하는 방법을 설명합니다. 개략적으로 조정해야 하는 네 가지 유형의 매개변수가 있습니다.

  • 데이터 선택 매개변수 - 분석에 포함되는 데이터를 지정합니다. 예를 들면 QueryDataSetRequest.dimensionNames, QueryDataSetRequest.pinnedDimensionsQueryDataSetRequest.testedInterval입니다.
  • 집계 매개변수를 사용하면 여러 이벤트가 그룹화되어 슬라이스를 생성하는 데 사용되는 값을 생성합니다. 예를 들면 ForecastParams.aggregatedDimension입니다.
  • 예측 매개변수는 예상 값을 계산하는 데 사용되는 예측 알고리즘을 구성하는 데 사용됩니다. 예를 들면 ForecastParams.holdout, ForecastParams.forecastHistory, ForecastParams.minDensity입니다.
  • 감도 조정 매개변수는 변경 시 비정상 이벤트 수, 지연 시간, 컴퓨팅 리소스의 수를 늘리거나 줄일 수 있습니다. 예를 들면 ForecastParams.maxPositiveRelativeChange, ForecastParams.maxNegativeRelativeChangeForecastParams.forecastExtraWeight입니다.

기본 요건

빠른 시작 가이드의 설정 안내에 따라 이 가이드의 모든 명령어를 실행할 수 있는지 확인합니다.

GELT 프로젝트의 데이터로 미리 로드된 공개 데모 데이터세트를 쿼리하여 각 매개변수가 반환된 결과에 미치는 영향을 설명합니다.

다음 쿼리를 작업 디렉터리에 query.json로 저장합니다.

{
  dimensionNames: ["EntityLOCATION"],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 1.0,
    maxNegativeRelativeChange: 1.0,
    forecastExtraWeight: 200.0
  }
}

빠른 시작 가이드에 설명된 대로 다음 명령어를 사용하여 쿼리를 실행할 수 있습니다.

$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query

이 가이드에서는 query.json가 다양한 매개변수를 변경하여 출력에 미치는 영향을 보여줍니다. 빠른 시작 가이드에서 타원형으로 제거된 위의 gcurl 명령어를 사용하여 사본을 수정하고 쿼리를 재실행하는 방법을 확인할 수 있습니다.

데이터 선택

이상 감지 쿼리는 특정 시간 간격 내에 특정 데이터 세트에서 이상치가 있는지 평가하고 일부 측정기준에서 데이터를 격리하고 선택적으로 일부 측정기준의 일부 값을 필터링합니다. 이 섹션에서는 이러한 데이터 선택 단계를 모두 제어하는 방법을 자세히 설명합니다.

시간 간격 사양

QueryDataSetRequest.tested_interval를 설정하여 불일치를 조사하려는 시간 간격을 지정할 수 있습니다. query.json에서 2019년 4월 15일 동안 발생한 불일치를 감지하도록 지정합니다.

...
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
...

예를 들어 2019년 4월 15일 오후 1시에서 오후 2시 사이에 발생한 불일치를 감지하려면 testedInterval를 다음과 같이 설정합니다.

...
  testedInterval: {
    startTime: "2019-04-15T13:00:00Z",
    length: "3600s"
  },
...

: 시작 시간 및 길이를 다르게 설정하여 testedInterval 값을 재생하여 반환된 비정상 이벤트가 어떻게 다른지 확인하세요.

슬라이싱

특정 시간 간격 내에서 이상치를 감지하면 이벤트가 데이터 슬라이스로 그룹화되는 방식도 지정해야 합니다. 이를 위해 dimensionNames를 데이터세트에서 슬라이스하려는 측정기준 집합으로 설정하면 됩니다.

query.json에서는 데이터를 'EntityLOCATION' 측정기준으로만 격리합니다(dimensionNames: ["EntityLOCATION"]). 결과 목록에서 모든 슬라이스의 값이 'EntityLocation' 측정기준의 값이 서로 다르다는 것을 알 수 있습니다.

대신 데이터를 여러 측정기준으로 분할하려면 다음과 같이 측정기준 이름을 여러 개 지정할 수 있습니다.

{
  dimensionNames: ["EntityLOCATION", "EntityORGANIZATION"],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 1.0,
    maxNegativeRelativeChange: 1.0,
    forecastExtraWeight: 50.0
  }
}

이 쿼리를 실행하면 결과 슬라이스가 두 개의 지정된 측정기준인 'EntityLOCATION'과 'EntityORGANIZATION'에서 값을 가져옵니다(반환되는 첫 번째 이상 슬라이스만 표시됨).

$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query

{
  "name": "projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104",
  "anomalyDetectionResult": {
    "anomalies": [
      {
        "dimensions": [
          {
            "name": "EntityLOCATION",
            "stringVal": "Seine"
          },
          {
            "name": "EntityORGANIZATION",
            "stringVal": "AP"
          }
        ],
        "result": {
          "holdoutErrors": {},
          "trainingErrors": {},
          "forecastStats": {
            "numAnomalies": 1
          },
          "testedIntervalActual": 344
        },
        "status": {}
      },
...

필터링

데이터세트의 하위 집합만 분석하는 데 관심이 있다면 pinnedDimensions를 설정하여 특정 측정기준에 특정 값이 있는 이벤트만 필터링할 수 있습니다.

EntityORGANIZATION를 사용한 필터링과 EntityLOCATION로 분할하는 예시(첫 번째 결과만 표시)

$ cat query.json

{
  dimensionNames: ["EntityLOCATION"],
  pinnedDimensions: [
  {
    name: "EntityORGANIZATION",
    stringVal: "AP"
  }
  ],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 1.0,
    maxNegativeRelativeChange: 1.0,
    forecastExtraWeight: 250.0
  }
}

$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query

{
  "name": "projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104",
  "anomalyDetectionResult": {
    "anomalies": [
      {
        "dimensions": [
          {
            "name": "EntityLOCATION",
            "stringVal": "Seine"
          }
        ],
        "result": {
          "holdoutErrors": {},
          "trainingErrors": {},
          "forecastStats": {
            "numAnomalies": 1
          },
          "testedIntervalActual": 344
        },
        "status": {}
      },
      {
        "dimensions": [
          {
            "name": "EntityLOCATION",
            "stringVal": "Ile de la Cite"
          }
        ],
        "result": {
          "holdoutErrors": {},
          "trainingErrors": {},
          "forecastStats": {
            "numAnomalies": 1
          },
          "testedIntervalActual": 282
        },
        "status": {}
      },
...

집계

기본 집계 방법은 슬라이스의 이벤트 수를 계산합니다.

숫자 차원을 합산하여 이벤트를 집계할 수도 있습니다. ForecastParams.aggregatedDimension를 합산하려는 숫자 측정기준으로 설정하여 지정합니다.

예측 구성

테스트된 시간 간격 동안 예상되는 값을 계산하려면 슬라이스의 이전 값을 기준으로 예측 알고리즘을 사용하며, 이 값이 테스트 대상 간격 중에 어떤 값을 가져야 하는지를 예측합니다.

참고: 슬라이스의 값은 집계 방법으로 지정됩니다.

예측 내역

시계열에 포함된 데이터의 양은 ForecastParams.forecastHistory 매개변수로 지정됩니다.

초기 예에서는 다음과 같이 설명합니다.

  • forecastHistory: "2592000s"를 설정하여 2019년 3월 16일부터 2019년 4월 15일 (30일 ~ 22,000초) 사이의 이벤트를 가져오고 이 2일 사이의 시계열을 형성해야 한다는 것을 알 수 있습니다.
  • 시계열의 각 데이터 포인트에는 테스트 기간의 길이 (예: 86400s - 1일)와 동일한 기간이 포함됩니다.
  • 시계열에는 해당 일의 해당 이벤트에 대해 집계된 값이 있는 각 포인트가 30개 있습니다. 집계 방법으로 계산하면 첫 번째 시계열 포인트는 2019년 3월 16일에 총 이벤트 수를 갖게 되며, 두 번째 지점은 2019년 3월 17일이 되는 두 번째 시점 등으로 계산됩니다.

ForecastResult.history 필드에 반환된 시계열의 이전 값을 확인할 수 있습니다 (요청에서 QueryDataSetRequest.returnTimeseriestrue로 설정된 경우에만 반환됨).

참고 : Google Play에서Timeseries proto를TimeseriesPoint )로 정렬되고 시간 값(예:TimeseriesPoint.value )를 사용하여 슬라이스의 집계된 값이TimeseriesPoint.time ,TimeseriesPoint.time + testedInterval.length ] 시간 간격과 일치해야 합니다.

ForecastParams.forecastHistory를 늘리고 더 긴 기록을 포함하면 특정 시즌 패턴을 포착하고 잠재적으로 더 많은 데이터가 포함되므로 예측의 정확성을 높일 수 있습니다. 예를 들어 월간 계절성 패턴이 있는 경우 forecastHistory을 30일로 설정하면 해당 패턴을 캡처할 수 없으므로 이 경우에는 forecastHistory의 경우 분석된 시계열에 여러 월별 패턴이 있습니다. 예를 들어 월 패턴을 100~300일로 감지할 경우 충분히 오래 걸릴 수 있지만 실제 패턴에 따라 달라져야 합니다.

초기 예시에서 testedInterval.length3600s(1시간)로 줄이고 ForecastParams.forecastHistory8640000s (100일)로 늘립니다. 그러면 history 시계열의 점 수가 2400개로 증가되어 더 세분화되어 더 긴 기간을 포괄합니다.

홀드아웃/테스트 간격

예측의 품질을 평가하기 위해 시계열의 처음 X% 만 학습합니다. 시계열의 마지막 부분은 평가 목적으로 유지되며 ForecastParams.holdout 매개변수로 제어합니다.

ForecastParams.holdout 매개변수는 백분율 (0~100)을 나타내며, 테스트 목적으로 유지해야 하는 데이터의 양을 나타냅니다. 이 예시에서는 holdout: 10.0를 지정했으므로 처음 90% 의 성능을 기준으로 예측 성능을 평가할 수 있는 시계열의 마지막 10% 를 유지합니다.

처음 예시에서는 30개의 시계열 포인트가 있다고 가정합니다. 즉, 처음 27점은 학습용으로, 마지막 3개 항목은 모델 테스트/평가용으로 유지됩니다.

홀드아웃 기간 동안 측정되는 오류는 ForecastResult.holdoutErrors에 반환되며 해당 오류는 예측을 하한 및 상한값 (testedIntervalForecastLowerBoundtestedIntervalForecastUpperBound)으로 계산하는 데 사용됩니다. 홀드아웃 오류가 발생할 경우 예측 범위가 넓어지고, 오류가 적을수록 경계가 더 (하고 ForecastResult.testedIntervalForecast에 가깝습니다.

홀드아웃 값은 낮은 비율 (3%~10%)이어야 하지만 예측 경계 계산에 이러한 오류가 필요하므로 충분한 데이터 포인트가 포함되어야 합니다.

최소 밀도

ForecastParams.minDensity 매개변수가 제공하는 최소 밀도는 하나 이상이 이벤트가 아닌 이상 시계열을 포함해야 하는 시계열을 1개 이상 지정합니다.

홀드아웃과 마찬가지로 0~100 범위의 백분율 값입니다.

포인트 수는 testedInterval.startTime - forecastHistorytestedInterlal.startTime 사이의 예상 포인트 수를 비교합니다.

예를 들어 첫 번째 예시에서 testedInterval.length를 1일로, forecastHistory를 30일로 설정하는 시계열 시계열이 30개이면 minDensity을 설정합니다. 80개 이상의 이벤트가 포함된 시계열만 허용합니다.

참고: 이 예시에서는 minDensity를 0으로 설정하고 급증이 감지되었을 때 0으로 설정하는 것이 좋습니다.

호라이즌

ForecastParams.horizonTime으로 지정된 시간 범위는 간단히 테스트된 시간 간격에서 미래까지 지정합니다. 이전 시계열을 기준으로 값을 예측해야 합니다.

QueryDataSetRequest.returnTimeseries을 true로 설정하면 예측 시계열이 각 슬라이스의 ForecastResult.forecast에 반환되고 testedInterval.startTime + testedInterval.lengthtestedInterval.startTime + testedInterval.length + horizonTime 사이의 예측 값이 포함됩니다.

민감도 미세 조정

슬라이스에 대해 테스트된 간격 동안의 예측 경계와 실제 값을 기반으로 민감도 매개변수에 따라 비정상적인 값으로 분류될 수도 있습니다. 이러한 매개변수는 다음과 같습니다.

  • ForecastParameters.maxPositiveRelativeChangetestedIntervalForecastUpperBound와 비교하여 실제 값이 증가할 수 있는 정도를 지정합니다.
  • ForecastParameters.maxNegativeRelativeChangetestedIntervalForecastLowerBound와 비교하여 실제 값이 줄어들 수 있는 정도를 지정합니다.
  • ForecastParameters.forecastExtraWeight는 실제 크기와 예측 경계를 비교할 때 추가 가중치로 사용됩니다. 추가 가중치는 더 작은 절대 편차를 무시하려는 경우에 유용합니다.

참고: 긍정적 또는 부정적 변경에 대해 각각 다른 매개변수를 사용합니다. 고객이 다양한 스팟과 스 drops을 서로 다르게 설정하거나 setting등을 설정하여 다른 and도에서 떨어트릴 수 있도록 하고 있습니다. 상한

참고: maxNegativeRelativeChange의 최댓값은 실제 시계열의 경우 1.0입니다 (예: 집계 방법으로 이벤트 수를 계산하는 경우). 실제 가치의 100% 를 기준으로 합니다.

모든 민감도 매개변수를 0으로 설정해 보세요.

{
  dimensionNames: ["EntityLOCATION"],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 0.0,
    maxNegativeRelativeChange: 0.0,
    forecastExtraWeight: 0.0
  }
}

이 쿼리는 실행할 수 있는 가장 민감한 쿼리이며 [testedIntervalForecastLowerBound, testedIntervalForecastUpperBound] 경계 외부에 testedIntervalActual가 있는 모든 슬라이스를 비정상으로 표시합니다. 이 방법이 우리가 원하는 일처럼 보일 수 있지만 (일부 애플리케이션에서 유용할 수 있음) 실제로 이러한 잘못된 경우는 대부분 오탐지로 인해 이러한 실수의 대부분은 무시하는 것이 좋습니다.

이 기준 쿼리를 실행하면 약 2500건의 불일치가 발생합니다.

$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query \
    | grep "testedIntervalActual" | wc -l

2520

maxPositiveRelativeChangemaxNegativeRelativeChange를 모두 1.0으로 늘리면 편차가 작은 ~1로 감소되지만, 편차는 작지만 슬라이스의 편차가 줄어듭니다. 이상치로 분류된 여러 조각이 있습니다.

그날의 뉴스에 대한 가장 큰 급증에만 관심이 있다고 생각한다면 forecastExtraWeight를 증가시킬 수 있으며, 그러면 볼륨이 작은 슬라이스가 필터링됩니다. 200.0으로 설정하겠습니다. 그러면 최종 query.json를 제공합니다.

{
  dimensionNames: ["EntityLOCATION"],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 1.0,
    maxNegativeRelativeChange: 1.0,
    forecastExtraWeight: 200.0
  }
}

앞의 쿼리를 실행하면 3가지 비정상 종료가 발생합니다. 모든 대표적인 이슈는 2019년 4월 15일에 보도에서 가장 많이 언급된 사건인 노트르담 화재와 관련이 있습니다.

$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query \
    | grep stringVal

            "stringVal": "Ile de la Cite"
            "stringVal": "Notre Dame"
            "stringVal": "Seine"

쿼리 성능 및 리소스 사용량

노이즈를 줄이고 관련 없는 슬라이스를 필터링하는 것 외에, 이상 감지 민감도를 줄이면 쿼리 지연 시간과 리소스 사용량을 크게 줄일 수 있습니다.

forecastExtraWeight를 늘리면 일반적으로 비정상적인 슬라이스에서 가장 눈에 띄는 감소가 발생하므로 쿼리 성능 향상을 위해 증가해야 하는 기본 민감도 매개변수도 사용됩니다.

다양한 민감도 매개변수를 사용하여 쿼리 성능에 미치는 영향을 확인할 수 있습니다. 예를 들면 다음과 같습니다.

$ cat query.json

{
  dimensionNames: ["EntityLOCATION"],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 0.0,
    maxNegativeRelativeChange: 0.0,
    forecastExtraWeight: 0.0
  }
}

$ time gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query \
    | grep stringVal | wc -l

2580

real 0m26.765s
user 0m0.618s
sys  0m0.132s

가장 민감한 매개변수가 쿼리 결과를 가져오는 데 72.7초 정도 소요된다는 것을 알 수 있습니다. 감도를 줄이면 최대 3.4초까지 가속됩니다.

$ cat query.json

{
  dimensionNames: ["EntityLOCATION"],
  testedInterval: {
    startTime: "2019-04-15T00:00:00Z",
    length: "86400s"
  },
  forecastParams: {
    forecastHistory: "2592000s",
    holdout: 10.0,
    minDensity: 0.0,
    maxPositiveRelativeChange: 1.0,
    maxNegativeRelativeChange: 1.0,
    forecastExtraWeight: 200.0
  }
}

$ time gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/timeseries-insights-api-demo/datasets/webnlp-201901-202104:query \
    | grep stringVal | wc -l

3

real 0m3.412s
user 0m0.681s
sys  0m0.047s

다음 단계