series_uv_anomalies_fl()
Aplica-se a: ✅Microsoft Fabric✅Azure Data Explorer
A função series_uv_anomalies_fl()
é uma UDF (função definida pelo usuário) que detecta anomalias em séries temporais chamando a API de Detecção de Anomalias Univariadas, parte dos Serviços Cognitivos do Azure. A função aceita um conjunto limitado de séries temporais como matrizes dinâmicas numéricas e o nível de confidencialidade de detecção de anomalias necessário. Cada série temporal é convertida no formato JSON necessário e a posta no ponto de extremidade de serviço do Detector de Anomalias. A resposta de serviço contém matrizes dinâmicas de anomalias altas/baixas/todas, a série temporal de linha de base modelada, seus limites normais, alto/baixo (um valor acima ou abaixo do limite alto/baixo é uma anomalia) e a sazonalidade detectada.
Observação
Considere usar a função nativa series_decompose_anomalies(), que é mais escalável e é executada mais rapidamente.
Pré-requisitos
- Uma assinatura do Azure. Criar uma conta gratuita do Azure.
- Um cluster e um banco de dados Crie um cluster e um banco de dados ou um banco de dados KQL com permissões de edição e dados.
- O plug-in Python deve ser habilitado no cluster. Isso é necessário para o Python embutido usado na função.
- Crie um recurso Detector de Anomalias e obtenha sua chave para acessar o serviço.
- Habilite o plug-in http_request/plug-in http_request_post no cluster para acessar o ponto de extremidade do serviço de detecção de anomalias.
- Modifique a política de texto explicativo para o tipo
webapi
para acessar o ponto de extremidade do serviço de detecção de anomalias.
No exemplo de função a seguir, substitua YOUR-AD-RESOURCE-NAME
no uri e YOUR-KEY
no Ocp-Apim-Subscription-Key
cabeçalho pelo nome e pela chave do recurso do Detector de Anomalias.
Sintaxe
T | invoke series_uv_anomalies_fl(
y_series [ ,
sensibilidade [,
tsid]])
Saiba mais sobre as convenções de sintaxe.
Parâmetros
Nome | Digitar | Obrigatória | Descrição |
---|---|---|---|
y_series | string |
✔️ | O nome da coluna da tabela de entrada que contém os valores da série a ser detectada por anomalias. |
sensibilidade | Número inteiro | Um número inteiro no intervalo [0-100] que especifica a sensibilidade de detecção de anomalias. 0 é a detecção menos sensível, enquanto 100 é a mais sensível, indicando que mesmo um pequeno desvio da linha de base esperada seria marcado como anomalia. Valor padrão: 85 | |
tsid | string |
O nome da coluna da tabela de entrada que contém a ID da série temporal. Pode ser omitido ao analisar uma única série temporal. |
Definição de função
Você pode definir a função inserindo seu código como uma função definida por consulta ou criando-a como uma função armazenada em seu banco de dados, da seguinte maneira:
Defina a função usando a instrução let a seguir. Nenhuma permissão é necessária.
Importante
Uma instrução let não pode ser executada sozinha. Ele deve ser seguido por uma instrução de expressão tabular. Para executar um exemplo funcional de series_uv_anomalies_fl()
, consulte Exemplos.
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.
Exemplos
Os exemplos a seguir usam o operador invoke para executar a função.
Use series_uv_anomalies_fl()
para detectar anomalias
Para usar uma função definida por consulta, invoque-a após a definição da função inserida.
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)
Saída
Compare series_uv_anomalies_fl()
e nativo series_decompose_anomalies()
O exemplo a seguir compara a API de Detecção de Anomalias Univariadas com a função nativa em três séries temporais series_decompose_anomalies()
e pressupõe que a series_uv_anomalies_fl()
função já esteja definida no banco de dados:
Para usar uma função definida por consulta, invoque-a após a definição da função inserida.
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)
Saída
O gráfico a seguir mostra anomalias detectadas pela API de Detecção de Anomalias Univariadas no TS1. Você também pode selecionar TS2 ou TS3 na caixa de filtro de gráfico.
O gráfico a seguir mostra as anomalias detectadas pela função nativa no TS1.