Compartir a través de


series_uv_anomalies_fl()

Se aplica a: ✅Microsoft FabricAzure Data Explorer

La función series_uv_anomalies_fl() es una función definida por el usuario (UDF) que detecta anomalías en series temporales mediante una llamada a la API de detección de anomalías univariante, parte de Azure Cognitive Services. La función acepta un conjunto limitado de series temporales como matrices dinámicas numéricas y el nivel de confidencialidad de detección de anomalías necesario. Cada serie temporal se convierte al formato JSON necesario y lo envía al punto de conexión de servicio de Anomaly Detector. La respuesta del servicio contiene matrices dinámicas de anomalías altas o bajas, la serie temporal de línea base modelada, sus límites normales altos y bajos (un valor por encima o por debajo del límite alto o bajo es una anomalía) y la estacionalidad detectada.

Nota:

Considere la posibilidad de usar la función nativa series_decompose_anomalies(), que es más escalable y se ejecuta más rápido.

Requisitos previos

En el ejemplo de función siguiente, reemplace YOUR-AD-RESOURCE-NAME en el URI y YOUR-KEY en el del encabezado por el Ocp-Apim-Subscription-Key nombre y la clave del recurso de Anomaly Detector.

Sintaxis

T | invoke series_uv_anomalies_fl( y_series [ , sensibilidad [, tsid]])

Obtenga más información sobre las convenciones de sintaxis.

Parámetros

Nombre Type Obligatorio Descripción
y_series string ✔️ Nombre de la columna de tabla de entrada que contiene los valores de la serie que se van a detectar.
sensibilidad integer Entero en el intervalo [0-100] que especifica la sensibilidad de detección de anomalías. 0 es la detección menos sensible, mientras que 100 es la más sensible que indica incluso una pequeña desviación de la línea base esperada se etiquetaría como anomalía. Valor predeterminado: 85
tsid string Nombre de la columna de tabla de entrada que contiene el identificador de serie temporal. Se puede omitir al analizar una sola serie temporal.

Definición de función

Puede definir la función insertando su código como una función definida por la consulta o creandola como una función almacenada en la base de datos, como se indica a continuación:

Defina la función mediante la siguiente instrucción let. No se requieren permisos.

Importante

Una instrucción let no se puede ejecutar por sí sola. Debe ir seguido de una instrucción de expresión tabular. Para ejecutar un ejemplo de trabajo de series_uv_anomalies_fl(), vea Ejemplos.

let series_uv_anomalies_fl=(tbl:(*), y_series:string, sensitivity:int=85, tsid:string='_tsid')
{
    let uri = 'https://YOUR-AD-RESOURCE-NAME.cognitiveservices.azure.com/anomalydetector/v1.0/timeseries/entire/detect';
    let headers=dynamic({'Ocp-Apim-Subscription-Key': h'YOUR-KEY'});
    let kwargs = bag_pack('y_series', y_series, 'sensitivity', sensitivity);
    let code = ```if 1:
        import json
        y_series = kargs["y_series"]
        sensitivity = kargs["sensitivity"]
        json_str = []
        for i in range(len(df)):
            row = df.iloc[i, :]
            ts = [{'value':row[y_series][j]} for j in range(len(row[y_series]))]
            json_data = {'series': ts, "sensitivity":sensitivity}     # auto-detect period, or we can force 'period': 84. We can also add 'maxAnomalyRatio':0.25 for maximum 25% anomalies
            json_str = json_str + [json.dumps(json_data)]
        result = df
        result['json_str'] = json_str
    ```;
    tbl
    | evaluate python(typeof(*, json_str:string), code, kwargs)
    | extend _tsid = column_ifexists(tsid, 1)
    | partition by _tsid (
       project json_str
       | evaluate http_request_post(uri, headers, dynamic(null))
       | project period=ResponseBody.period, baseline_ama=ResponseBody.expectedValues, ad_ama=series_add(0, ResponseBody.isAnomaly), pos_ad_ama=series_add(0, ResponseBody.isPositiveAnomaly)
       , neg_ad_ama=series_add(0, ResponseBody.isNegativeAnomaly), upper_ama=series_add(ResponseBody.expectedValues, ResponseBody.upperMargins), lower_ama=series_subtract(ResponseBody.expectedValues, ResponseBody.lowerMargins)
       | extend _tsid=toscalar(_tsid)
      )
};
// Write your query to use the function here.

Ejemplos

En los ejemplos siguientes se usa el operador invoke para ejecutar la función .

Uso series_uv_anomalies_fl() para detectar anomalías

Para usar una función definida por la consulta, invoquela después de la definición de función incrustada.

let series_uv_anomalies_fl=(tbl:(*), y_series:string, sensitivity:int=85, tsid:string='_tsid')
{
    let uri = 'https://YOUR-AD-RESOURCE-NAME.cognitiveservices.azure.com/anomalydetector/v1.0/timeseries/entire/detect';
    let headers=dynamic({'Ocp-Apim-Subscription-Key': h'YOUR-KEY'});
    let kwargs = bag_pack('y_series', y_series, 'sensitivity', sensitivity);
    let code = ```if 1:
        import json
        y_series = kargs["y_series"]
        sensitivity = kargs["sensitivity"]
        json_str = []
        for i in range(len(df)):
            row = df.iloc[i, :]
            ts = [{'value':row[y_series][j]} for j in range(len(row[y_series]))]
            json_data = {'series': ts, "sensitivity":sensitivity}     # auto-detect period, or we can force 'period': 84. We can also add 'maxAnomalyRatio':0.25 for maximum 25% anomalies
            json_str = json_str + [json.dumps(json_data)]
        result = df
        result['json_str'] = json_str
    ```;
    tbl
    | evaluate python(typeof(*, json_str:string), code, kwargs)
    | extend _tsid = column_ifexists(tsid, 1)
    | partition by _tsid (
       project json_str
       | evaluate http_request_post(uri, headers, dynamic(null))
       | project period=ResponseBody.period, baseline_ama=ResponseBody.expectedValues, ad_ama=series_add(0, ResponseBody.isAnomaly), pos_ad_ama=series_add(0, ResponseBody.isPositiveAnomaly)
       , neg_ad_ama=series_add(0, ResponseBody.isNegativeAnomaly), upper_ama=series_add(ResponseBody.expectedValues, ResponseBody.upperMargins), lower_ama=series_subtract(ResponseBody.expectedValues, ResponseBody.lowerMargins)
       | extend _tsid=toscalar(_tsid)
      )
};
let etime=datetime(2017-03-02);
let stime=datetime(2017-01-01);
let dt=1h;
let ts = requests
| make-series value=avg(value) on timestamp from stime to etime step dt
| extend _tsid='TS1';
ts
| invoke series_uv_anomalies_fl('value')
| lookup ts on _tsid
| render anomalychart with(xcolumn=timestamp, ycolumns=value, anomalycolumns=ad_ama)

Salida

Gráfico que muestra anomalías en una serie temporal.

Comparación series_uv_anomalies_fl() y nativo series_decompose_anomalies()

En el ejemplo siguiente se compara la API de detección de anomalías univariante con la función nativa series_decompose_anomalies() en tres series temporales y se supone que la series_uv_anomalies_fl() función ya está definida en la base de datos:

Para usar una función definida por la consulta, invoquela después de la definición de función incrustada.

let series_uv_anomalies_fl=(tbl:(*), y_series:string, sensitivity:int=85, tsid:string='_tsid')
{
    let uri = 'https://YOUR-AD-RESOURCE-NAME.cognitiveservices.azure.com/anomalydetector/v1.0/timeseries/entire/detect';
    let headers=dynamic({'Ocp-Apim-Subscription-Key': h'YOUR-KEY'});
    let kwargs = bag_pack('y_series', y_series, 'sensitivity', sensitivity);
    let code = ```if 1:
        import json
        y_series = kargs["y_series"]
        sensitivity = kargs["sensitivity"]
        json_str = []
        for i in range(len(df)):
            row = df.iloc[i, :]
            ts = [{'value':row[y_series][j]} for j in range(len(row[y_series]))]
            json_data = {'series': ts, "sensitivity":sensitivity}     # auto-detect period, or we can force 'period': 84. We can also add 'maxAnomalyRatio':0.25 for maximum 25% anomalies
            json_str = json_str + [json.dumps(json_data)]
        result = df
        result['json_str'] = json_str
    ```;
    tbl
    | evaluate python(typeof(*, json_str:string), code, kwargs)
    | extend _tsid = column_ifexists(tsid, 1)
    | partition by _tsid (
       project json_str
       | evaluate http_request_post(uri, headers, dynamic(null))
       | project period=ResponseBody.period, baseline_ama=ResponseBody.expectedValues, ad_ama=series_add(0, ResponseBody.isAnomaly), pos_ad_ama=series_add(0, ResponseBody.isPositiveAnomaly)
       , neg_ad_ama=series_add(0, ResponseBody.isNegativeAnomaly), upper_ama=series_add(ResponseBody.expectedValues, ResponseBody.upperMargins), lower_ama=series_subtract(ResponseBody.expectedValues, ResponseBody.lowerMargins)
       | extend _tsid=toscalar(_tsid)
      )
};
let ts = demo_make_series2
| summarize TimeStamp=make_list(TimeStamp), num=make_list(num) by sid;
ts
| invoke series_uv_anomalies_fl('num', 'sid', 90)
| join ts on $left._tsid == $right.sid
| project-away _tsid
| extend (ad_adx, score_adx, baseline_adx)=series_decompose_anomalies(num, 1.5, -1, 'linefit')
| project-reorder num, *
| render anomalychart with(series=sid, xcolumn=TimeStamp, ycolumns=num, baseline_adx, baseline_ama, lower_ama, upper_ama, anomalycolumns=ad_adx, ad_ama)

Salida

En el gráfico siguiente se muestran las anomalías detectadas por la API de detección de anomalías univariante en TS1. También puede seleccionar TS2 o TS3 en el cuadro de filtro del gráfico.

Gráfico que muestra anomalías mediante la A P I univariante en una serie temporal.

En el gráfico siguiente se muestran las anomalías detectadas por la función nativa en TS1.

Gráfico que muestra anomalías mediante la función nativa en una serie temporal.