Analisi delle serie temporali

I servizi cloud e i dispositivi IoT generano dati di telemetria che possono essere usati per ottenere informazioni dettagliate, ad esempio il monitoraggio dell'integrità del servizio, i processi di produzione fisici e le tendenze di utilizzo. L'esecuzione dell'analisi delle serie temporali è un modo per identificare le deviazioni nel modello di queste metriche rispetto al modello di baseline tipico.

Linguaggio di query Kusto (KQL) contiene il supporto nativo per la creazione, la manipolazione e l'analisi di più serie temporali. In questo articolo viene illustrato come viene usato KQL per creare e analizzare migliaia di serie temporali in secondi, consentendo soluzioni e flussi di lavoro di monitoraggio quasi in tempo reale.

Creazione di serie temporali

In questa sezione si creerà un ampio set di serie temporali regolari in modo semplice e intuitivo usando l'operatore make-series e specificando eventuali valori mancanti in base alle esigenze. Il primo passaggio nell'analisi delle serie temporali consiste nel partizionare la tabella dei dati di telemetria originale e trasformarla in un set di serie temporali. La tabella contiene in genere una colonna di timestamp, dimensioni contestuali e metriche facoltative. Le dimensioni vengono usate per partizionare i dati. L'obiettivo è quello di creare migliaia di serie temporali per ogni partizione a intervalli regolari.

La tabella di input demo_make_series1 contiene 600.000 record del traffico di servizi Web arbitrario. Usare il comando seguente per eseguire l'esempio di 10 record:

demo_make_series1 | take 10 

La tabella risultante contiene una colonna di timestamp e tre colonne di dimensioni contestuali, ma non sono incluse metriche:

TimeStamp BrowserVer OsVer Paese/Area geografica
2016-08-25 09:12:35.4020000 Chrome 51.0 Windows 7 Regno Unito
2016-08-25 09:12:41.1120000 Chrome 52.0 Windows 10
2016-08-25 09:12:46.2300000 Chrome 52.0 Windows 7 Regno Unito
2016-08-25 09:12:46.5100000 Chrome 52.0 Windows 10 Regno Unito
2016-08-25 09:12:46.5570000 Chrome 52.0 Windows 10 Repubblica di Lituania
2016-08-25 09:12:47.0470000 Chrome 52.0 Windows 8.1 India
2016-08-25 09:12:51.3600000 Chrome 52.0 Windows 10 Regno Unito
2016-08-25 09:12:51.6930000 Chrome 52.0 Windows 7 Paesi Bassi
2016-08-25 09:12:56.4240000 Chrome 52.0 Windows 10 Regno Unito
2016-08-25 09:13:08.7230000 Chrome 52.0 Windows 10 India

Poiché non sono presenti metriche, è possibile creare solo un set di serie temporali che rappresenta il traffico totale, partizionato in base al sistema operativo, usando la query seguente:

let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| render timechart 
  • Usare l'operatore make-series per creare un set di tre serie temporali, dove:
    • num=count(): la serie temporale del traffico
    • from min_t to max_t step 1h: la serie temporale viene creata in base a intervalli di un'ora nell'intero periodo di tempo (il timestamp meno recente e quello più recente dei record della tabella)
    • default=0: specificare il metodo di riempimento per gli intervalli mancanti per creare serie temporali regolari In alternativa, usare series_fill_const(), series_fill_backward()series_fill_forward()e series_fill_linear() per le modifiche
    • by OsVer: partizione per sistema operativo
  • L'effettiva struttura di dati di una serie temporale è una matrice numerica del valore aggregato per ogni intervallo temporale. Per la visualizzazione viene usato render timechart.

Nella tabella precedente sono presenti tre partizioni. È possibile creare una serie temporale distinta per ogni versione del sistema operativo, ovvero Windows 10 (rosso), 7 (blu) e 8.1 (verde), come illustrato nel grafico:

Partizione serie temporali.

Funzioni di analisi delle serie temporali

In questa sezione si eseguiranno tipiche funzioni di elaborazione delle serie temporali. Dopo aver creato un set di serie temporali, KQL supporta un elenco crescente di funzioni da elaborare e analizzare. Verranno descritte alcune funzioni rappresentative per l'elaborazione e l'analisi delle serie temporali.

Filtro

L'applicazione di filtri è una pratica comune nell'elaborazione dei segnali ed è utile per le attività di elaborazione delle serie temporali, ad esempio lo smorzamento di un segnale di disturbo o il rilevamento di modifiche.

  • Sono presenti due funzioni di filtro generiche:
    • series_fir(): Applicazione del filtro FIR. Usato per il calcolo semplice della media mobile e della differenziazione della serie temporale per il rilevamento di modifiche.
    • series_iir(): Applicazione del filtro IIR. Usato per lo smorzamento esponenziale e la somma cumulativa.
  • Extend viene usato per estendere il set di serie temporali aggiungendo alla query una nuova serie a media mobile costituita da cinque intervalli (denominata ma_num):
let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| extend ma_num=series_fir(num, repeat(1, 5), true, true)
| render timechart

Filtro serie temporali.

Analisi di regressione

Azure Esplora dati supporta l'analisi della regressione lineare segmentata per stimare la tendenza della serie temporale.

  • Usare series_fit_line() per individuare la linea che meglio si adatta a una serie temporale per il rilevamento della tendenza generale.
  • Usare series_fit_2lines per rilevare le variazioni della tendenza, rispetto alla linea di base, che sono utili negli scenari di monitoraggio.

Esempio di series_fit_line() funzioni e series_fit_2lines() in una query di serie temporali:

demo_series2
| extend series_fit_2lines(y), series_fit_line(y)
| render linechart with(xcolumn=x)

Regressione della serie temporale.

  • Blu: serie temporale originale
  • Verde: linea adattata
  • Rosso: due linee adattate

Nota

La funzione ha rilevato correttamente il punto di variazione del livello.

Rilevamento della stagionalità

Molte metriche seguono modelli stagionali (periodici). Il traffico degli utenti dei servizi cloud contiene in genere modelli giornalieri e settimanali che sono più alti nella parte centrale della giornata lavorativa e più bassi di notte o durante il fine settimana. I sensori IoT eseguono misurazioni in base a intervalli periodici. Le misure fisiche, ad esempio temperatura, pressione o umidità, possono mostrare anche un comportamento stagionale.

L'esempio seguente applica il rilevamento della stagionalità al traffico di un servizio Web nel corso di un mese (intervalli di 2 ore):

demo_series3
| render timechart 

Stagionalità delle serie temporali.

  • Usare series_periods_detect() per rilevare automaticamente i periodi nella serie temporale.
  • Usare series_periods_validate() se si è conoscenza del fatto che una metrica dovrebbe avere specifici periodi distinti e si vuole verificare che esistano effettivamente.

Nota

Se non esistono specifici periodi distinti è presente un'anomalia.

demo_series3
| project (periods, scores) = series_periods_detect(num, 0., 14d/2h, 2) //to detect the periods in the time series
| mv-expand periods, scores
| extend days=2h*todouble(periods)/1d
periodi scores days
84 0.820622786055595 7
12 0.764601405803502 1

La funzione rileva la stagionalità giornaliera e settimanale. La prima ha un punteggio minore rispetto alla seconda perché i giorni del fine settimana sono diversi dai normali giorni della settimana.

Funzioni relative a elementi

È possibile eseguire operazioni aritmetiche e logiche su una serie temporale. Usando series_subtract() si può calcolare una serie temporale residua, ovvero la differenza tra una metrica originale non elaborata e una metrica smorzata e cercare eventuali anomalie nel segnale residuo:

let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp in from min_t to max_t step 1h by OsVer
| extend ma_num=series_fir(num, repeat(1, 5), true, true)
| extend residual_num=series_subtract(num, ma_num) //to calculate residual time series
| where OsVer == "Windows 10"   // filter on Win 10 to visualize a cleaner chart 
| render timechart

Operazioni di serie temporali.

  • Blu: serie temporale originale
  • Rosso: serie temporale smorzata
  • Verde: serie temporale residua

Flusso di lavoro di serie temporali su larga scala

L'esempio seguente illustra come queste funzioni possono essere eseguite su larga scala su migliaia di serie temporali in secondi per il rilevamento di anomalie. Per visualizzare alcuni record di telemetria di esempio di una metrica di conteggio delle letture di un servizio di database in un periodo di quattro giorni, eseguire la query seguente:

demo_many_series1
| take 4 
timestamp Loc Op DB DataRead
2016-09-11 21:00:00.0000000 Loc 9 5117853934049630089 262 0
2016-09-11 21:00:00.0000000 Loc 9 5117853934049630089 241 0
2016-09-11 21:00:00.0000000 Loc 9 -865998331941149874 262 279862
2016-09-11 21:00:00.0000000 Loc 9 371921734563783410 255 0

E statistiche semplici:

demo_many_series1
| summarize num=count(), min_t=min(TIMESTAMP), max_t=max(TIMESTAMP) 
num min_t max_t
2177472 2016-09-08 00:00:00.0000000 2016-09-11 23:00:00.0000000

La creazione di una serie temporale con intervalli di un'ora della metrica di lettura (quattro giorni totali * 24 ore = 96 punti) ha come risultato una fluttuazione del modello normale:

let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));  
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));  
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h
| render timechart with(ymin=0) 

Serie temporale su larga scala.

Il comportamento sopra illustrato è fuorviante perché la singola serie temporale normale risulta dall'aggregazione di migliaia di istanze diverse che possono avere modelli anomali. È pertanto opportuno creare una serie temporale per ogni istanza. Un'istanza è definita da Loc (posizione), Op (operazione) e DB (computer specifico).

Quante serie temporali è possibile creare?

demo_many_series1
| summarize by Loc, Op, DB
| count
Conteggio
18339

A questo punto, si crea un set di 18339 serie temporali della metrica di conteggio delle letture. Si aggiunge la clausola by all'istruzione make-series, si applica la regressione lineare e si selezionano le prime due serie temporali che risultano avere la tendenza decrescente più significativa:

let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));  
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));  
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h by Loc, Op, DB
| extend (rsquare, slope) = series_fit_line(reads)
| top 2 by slope asc 
| render timechart with(title='Service Traffic Outage for 2 instances (out of 18339)')

Serie temporale top due.

Visualizzare le istanze:

let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));  
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));  
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h by Loc, Op, DB
| extend (rsquare, slope) = series_fit_line(reads)
| top 2 by slope asc
| project Loc, Op, DB, slope 
Loc Op DB slope
Loc 15 37 1151 -102743.910227889
Loc 13 37 1249 -86303.2334644601

In meno di due minuti, sono state analizzate quasi 20.000 serie temporali e sono state rilevate due serie temporali anomale in cui il conteggio di lettura è stato improvvisamente eliminato.

Queste funzionalità avanzate combinate con prestazioni veloci forniscono una soluzione unica e potente per l'analisi delle serie temporali.