series_decompose()
Applies a decomposition transformation on a series.
Takes an expression containing a series (dynamic numerical array) as input and decomposes it to seasonal, trend, and residual components.
Syntax
series_decompose(
Series ,
[ Seasonality,
Trend,
Test_points,
Seasonality_threshold ])
Learn more about syntax conventions.
Parameters
Name  Type  Required  Description 

Series  dynamic 
✔️  An array of numeric values, typically the resulting output of makeseries or make_list operators. 
Seasonality  int 
Controls the seasonal analysis. The possible values are:  1 : Autodetect seasonality using series_periods_detect. This is the default value. Period: A positive integer specifying the expected period in number of bins. For example, if the series is in 1  h bins, a weekly period is 168 bins. 0 : No seasonality, so skip extracting this component. 

Trend  string 
Controls the trend analysis. The possible values are:  avg : Define trend component as average(x) . This is the default. linefit : Extract trend component using linear regression. none : No trend, so skip extracting this component. 

Test_points  int 
A positive integer specifying the number of points at the end of the series to exclude from the learning, or regression, process. This parameter should be set for forecasting purposes. The default value is 0.  
Seasonality_threshold  real 
The threshold for seasonality score when Seasonality is set to autodetect. The default score threshold is 0.6. For more information, see series_periods_detect. 
Returns
The function returns the following respective series:
baseline
: the predicted value of the series (sum of seasonal and trend components, see below).seasonal
: the series of the seasonal component: if the period isn't detected or is explicitly set to 0: constant 0.
 if detected or set to positive integer: median of the series points in the same phase
trend
: the series of the trend component.residual
: the series of the residual component (that is, x  baseline).
Note
 Component execution order:
 Extract the seasonal series
 Subtract it from x, generating the deseasonal series
 Extract the trend component from the deseasonal series
 Create the baseline = seasonal + trend
 Create the residual = x  baseline
 Either seasonality and, or trend should be enabled. Otherwise, the function is redundant, and just returns baseline = 0 and residual = x.
More about series decomposition
This method is usually applied to time series of metrics expected to manifest periodic and/or trend behavior. You can use the method to forecast future metric values and/or detect anomalous values. The implicit assumption of this regression process is that apart from seasonal and trend behavior, the time series is stochastic and randomly distributed. Forecast future metric values from the seasonal and trend components while ignoring the residual part. Detect anomalous values based on outlier detection only on the residual part only. Further details can be found in the Time Series Decomposition chapter.
Examples
Weekly seasonality
In the following example, we generate a series with weekly seasonality and without trend, we then add some outliers to it. series_decompose
finds and automatically detects the seasonality, and generates a baseline that is almost identical to the seasonal component. The outliers we added can be clearly seen in the residuals component.
let ts=range t from 1 to 24*7*5 step 1
 extend Timestamp = datetime(20180301 05:00) + 1h * t
 extend y = 2*rand() + iff((t/24)%7>=5, 10.0, 15.0)  (((t%24)/10)*((t%24)/10)) // generate a series with weekly seasonality
 extend y=iff(t==150 or t==200 or t==780, y8.0, y) // add some dip outliers
 extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
 summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts
 extend series_decompose(y)
 render timechart
Weekly seasonality with trend
In this example, we add a trend to the series from the previous example. First, we run series_decompose
with the default parameters. The trend avg
default value only takes the average and doesn't compute the trend. The generated baseline doesn't contain the trend. When observing the trend in the residuals, it becomes apparent that this example is less accurate than the previous example.
let ts=range t from 1 to 24*7*5 step 1
 extend Timestamp = datetime(20180301 05:00) + 1h * t
 extend y = 2*rand() + iff((t/24)%7>=5, 5.0, 15.0)  (((t%24)/10)*((t%24)/10)) + t/72.0 // generate a series with weekly seasonality and ongoing trend
 extend y=iff(t==150 or t==200 or t==780, y8.0, y) // add some dip outliers
 extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
 summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts
 extend series_decompose(y)
 render timechart
Next, we rerun the same example. Since we're expecting a trend in the series, we specify linefit
in the trend parameter. We can see that the positive trend is detected and the baseline is much closer to the input series. The residuals are close to zero, and only the outliers stand out. We can see all the components on the series in the chart.
let ts=range t from 1 to 24*7*5 step 1
 extend Timestamp = datetime(20180301 05:00) + 1h * t
 extend y = 2*rand() + iff((t/24)%7>=5, 5.0, 15.0)  (((t%24)/10)*((t%24)/10)) + t/72.0 // generate a series with weekly seasonality and ongoing trend
 extend y=iff(t==150 or t==200 or t==780, y8.0, y) // add some dip outliers
 extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
 summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts
 extend series_decompose(y, 1, 'linefit')
 render timechart
Related content
 Visualize results with an anomalychart
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for