Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a: ✅Microsoft Fabric✅Azure 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
- Suscripción a Azure. Cree una cuenta de Azure gratuita.
- Un clúster y una base de datos Crean un clúster y una base de datos o una base de datos KQL con permisos y datos de edición.
- El complemento de Python debe estar habilitado en el clúster. Esto es necesario para python insertado que se usa en la función .
- Cree un recurso de Anomaly Detector y obtenga su clave para acceder al servicio.
- Habilite el complemento http_request o el complemento http_request_post en el clúster para acceder al punto de conexión del servicio de detección de anomalías.
- Modifique la directiva de llamada para el tipo
webapi
para acceder al punto de conexión del servicio de detección de anomalías.
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
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.
En el gráfico siguiente se muestran las anomalías detectadas por la función nativa en TS1.