movavg-aggregation.asciidoc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. [[search-aggregations-pipeline-movavg-aggregation]]
  2. === Moving Average Aggregation
  3. Given an ordered series of data, the Moving Average aggregation will slide a window across the data and emit the average
  4. value of that window. For example, given the data `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]`, we can calculate a simple moving
  5. average with windows size of `5` as follows:
  6. - (1 + 2 + 3 + 4 + 5) / 5 = 3
  7. - (2 + 3 + 4 + 5 + 6) / 5 = 4
  8. - (3 + 4 + 5 + 6 + 7) / 5 = 5
  9. - etc
  10. Moving averages are a simple method to smooth sequential data. Moving averages are typically applied to time-based data,
  11. such as stock prices or server metrics. The smoothing can be used to eliminate high frequency fluctuations or random noise,
  12. which allows the lower frequency trends to be more easily visualized, such as seasonality.
  13. ==== Syntax
  14. A `moving_avg` aggregation looks like this in isolation:
  15. [source,js]
  16. --------------------------------------------------
  17. {
  18. "moving_avg": {
  19. "buckets_path": "the_sum",
  20. "model": "holt",
  21. "window": 5,
  22. "gap_policy": "insert_zero",
  23. "settings": {
  24. "alpha": 0.8
  25. }
  26. }
  27. }
  28. --------------------------------------------------
  29. .`moving_avg` Parameters
  30. |===
  31. |Parameter Name |Description |Required |Default Value
  32. |`buckets_path` |Path to the metric of interest (see <<bucket-path-syntax, `buckets_path` Syntax>> for more details |Required |
  33. |`model` |The moving average weighting model that we wish to use |Optional |`simple`
  34. |`gap_policy` |Determines what should happen when a gap in the data is encountered. |Optional |`insert_zero`
  35. |`window` |The size of window to "slide" across the histogram. |Optional |`5`
  36. |`settings` |Model-specific settings, contents which differ depending on the model specified. |Optional |
  37. |===
  38. `moving_avg` aggregations must be embedded inside of a `histogram` or `date_histogram` aggregation. They can be
  39. embedded like any other metric aggregation:
  40. [source,js]
  41. --------------------------------------------------
  42. {
  43. "my_date_histo":{ <1>
  44. "date_histogram":{
  45. "field":"timestamp",
  46. "interval":"day"
  47. },
  48. "aggs":{
  49. "the_sum":{
  50. "sum":{ "field": "lemmings" } <2>
  51. },
  52. "the_movavg":{
  53. "moving_avg":{ "buckets_path": "the_sum" } <3>
  54. }
  55. }
  56. }
  57. }
  58. --------------------------------------------------
  59. <1> A `date_histogram` named "my_date_histo" is constructed on the "timestamp" field, with one-day intervals
  60. <2> A `sum` metric is used to calculate the sum of a field. This could be any metric (sum, min, max, etc)
  61. <3> Finally, we specify a `moving_avg` aggregation which uses "the_sum" metric as its input.
  62. Moving averages are built by first specifying a `histogram` or `date_histogram` over a field. You can then optionally
  63. add normal metrics, such as a `sum`, inside of that histogram. Finally, the `moving_avg` is embedded inside the histogram.
  64. The `buckets_path` parameter is then used to "point" at one of the sibling metrics inside of the histogram (see
  65. <<bucket-path-syntax>> for a description of the syntax for `buckets_path`.
  66. ==== Models
  67. The `moving_avg` aggregation includes four different moving average "models". The main difference is how the values in the
  68. window are weighted. As data-points become "older" in the window, they may be weighted differently. This will
  69. affect the final average for that window.
  70. Models are specified using the `model` parameter. Some models may have optional configurations which are specified inside
  71. the `settings` parameter.
  72. ===== Simple
  73. The `simple` model calculates the sum of all values in the window, then divides by the size of the window. It is effectively
  74. a simple arithmetic mean of the window. The simple model does not perform any time-dependent weighting, which means
  75. the values from a `simple` moving average tend to "lag" behind the real data.
  76. [source,js]
  77. --------------------------------------------------
  78. {
  79. "the_movavg":{
  80. "moving_avg":{
  81. "buckets_path": "the_sum",
  82. "model" : "simple"
  83. }
  84. }
  85. }
  86. --------------------------------------------------
  87. A `simple` model has no special settings to configure
  88. The window size can change the behavior of the moving average. For example, a small window (`"window": 10`) will closely
  89. track the data and only smooth out small scale fluctuations:
  90. [[movavg_10window]]
  91. .Moving average with window of size 10
  92. image::images/pipeline_movavg/movavg_10window.png[]
  93. In contrast, a `simple` moving average with larger window (`"window": 100`) will smooth out all higher-frequency fluctuations,
  94. leaving only low-frequency, long term trends. It also tends to "lag" behind the actual data by a substantial amount:
  95. [[movavg_100window]]
  96. .Moving average with window of size 100
  97. image::images/pipeline_movavg/movavg_100window.png[]
  98. ==== Linear
  99. The `linear` model assigns a linear weighting to points in the series, such that "older" datapoints (e.g. those at
  100. the beginning of the window) contribute a linearly less amount to the total average. The linear weighting helps reduce
  101. the "lag" behind the data's mean, since older points have less influence.
  102. [source,js]
  103. --------------------------------------------------
  104. {
  105. "the_movavg":{
  106. "moving_avg":{
  107. "buckets_path": "the_sum",
  108. "model" : "linear"
  109. }
  110. }
  111. --------------------------------------------------
  112. A `linear` model has no special settings to configure
  113. Like the `simple` model, window size can change the behavior of the moving average. For example, a small window (`"window": 10`)
  114. will closely track the data and only smooth out small scale fluctuations:
  115. [[linear_10window]]
  116. .Linear moving average with window of size 10
  117. image::images/pipeline_movavg/linear_10window.png[]
  118. In contrast, a `linear` moving average with larger window (`"window": 100`) will smooth out all higher-frequency fluctuations,
  119. leaving only low-frequency, long term trends. It also tends to "lag" behind the actual data by a substantial amount,
  120. although typically less than the `simple` model:
  121. [[linear_100window]]
  122. .Linear moving average with window of size 100
  123. image::images/pipeline_movavg/linear_100window.png[]
  124. ==== EWMA (Exponentially Weighted)
  125. The `ewma` model (aka "single-exponential") is similar to the `linear` model, except older data-points become exponentially less important,
  126. rather than linearly less important. The speed at which the importance decays can be controlled with an `alpha`
  127. setting. Small values make the weight decay slowly, which provides greater smoothing and takes into account a larger
  128. portion of the window. Larger valuers make the weight decay quickly, which reduces the impact of older values on the
  129. moving average. This tends to make the moving average track the data more closely but with less smoothing.
  130. The default value of `alpha` is `0.5`, and the setting accepts any float from 0-1 inclusive.
  131. [source,js]
  132. --------------------------------------------------
  133. {
  134. "the_movavg":{
  135. "moving_avg":{
  136. "buckets_path": "the_sum",
  137. "model" : "ewma",
  138. "settings" : {
  139. "alpha" : 0.5
  140. }
  141. }
  142. }
  143. --------------------------------------------------
  144. [[single_0.2alpha]]
  145. .Single Exponential moving average with window of size 10, alpha = 0.2
  146. image::images/pipeline_movavg/single_0.2alpha.png[]
  147. [[single_0.7alpha]]
  148. .Single Exponential moving average with window of size 10, alpha = 0.7
  149. image::images/pipeline_movavg/single_0.7alpha.png[]
  150. ==== Holt-Linear
  151. The `holt` model (aka "double exponential") incorporates a second exponential term which
  152. tracks the data's trend. Single exponential does not perform well when the data has an underlying linear trend. The
  153. double exponential model calculates two values internally: a "level" and a "trend".
  154. The level calculation is similar to `ewma`, and is an exponentially weighted view of the data. The difference is
  155. that the previously smoothed value is used instead of the raw value, which allows it to stay close to the original series.
  156. The trend calculation looks at the difference between the current and last value (e.g. the slope, or trend, of the
  157. smoothed data). The trend value is also exponentially weighted.
  158. Values are produced by multiplying the level and trend components.
  159. The default value of `alpha` and `beta` is `0.5`, and the settings accept any float from 0-1 inclusive.
  160. [source,js]
  161. --------------------------------------------------
  162. {
  163. "the_movavg":{
  164. "moving_avg":{
  165. "buckets_path": "the_sum",
  166. "model" : "holt",
  167. "settings" : {
  168. "alpha" : 0.5,
  169. "beta" : 0.5
  170. }
  171. }
  172. }
  173. --------------------------------------------------
  174. In practice, the `alpha` value behaves very similarly in `holt` as `ewma`: small values produce more smoothing
  175. and more lag, while larger values produce closer tracking and less lag. The value of `beta` is often difficult
  176. to see. Small values emphasize long-term trends (such as a constant linear trend in the whole series), while larger
  177. values emphasize short-term trends. This will become more apparently when you are predicting values.
  178. [[double_0.2beta]]
  179. .Double Exponential moving average with window of size 100, alpha = 0.5, beta = 0.2
  180. image::images/pipeline_movavg/double_0.2beta.png[]
  181. [[double_0.7beta]]
  182. .Double Exponential moving average with window of size 100, alpha = 0.5, beta = 0.7
  183. image::images/pipeline_movavg/double_0.7beta.png[]
  184. ==== Prediction
  185. All the moving average model support a "prediction" mode, which will attempt to extrapolate into the future given the
  186. current smoothed, moving average. Depending on the model and parameter, these predictions may or may not be accurate.
  187. Predictions are enabled by adding a `predict` parameter to any moving average aggregation, specifying the nubmer of
  188. predictions you would like appended to the end of the series. These predictions will be spaced out at the same interval
  189. as your buckets:
  190. [source,js]
  191. --------------------------------------------------
  192. {
  193. "the_movavg":{
  194. "moving_avg":{
  195. "buckets_path": "the_sum",
  196. "model" : "simple",
  197. "predict" 10
  198. }
  199. }
  200. --------------------------------------------------
  201. The `simple`, `linear` and `ewma` models all produce "flat" predictions: they essentially converge on the mean
  202. of the last value in the series, producing a flat:
  203. [[simple_prediction]]
  204. .Simple moving average with window of size 10, predict = 50
  205. image::images/pipeline_movavg/simple_prediction.png[]
  206. In contrast, the `holt` model can extrapolate based on local or global constant trends. If we set a high `beta`
  207. value, we can extrapolate based on local constant trends (in this case the predictions head down, because the data at the end
  208. of the series was heading in a downward direction):
  209. [[double_prediction_local]]
  210. .Double Exponential moving average with window of size 100, predict = 20, alpha = 0.5, beta = 0.8
  211. image::images/pipeline_movavg/double_prediction_local.png[]
  212. In contrast, if we choose a small `beta`, the predictions are based on the global constant trend. In this series, the
  213. global trend is slightly positive, so the prediction makes a sharp u-turn and begins a positive slope:
  214. [[double_prediction_global]]
  215. .Double Exponential moving average with window of size 100, predict = 20, alpha = 0.5, beta = 0.1
  216. image::images/pipeline_movavg/double_prediction_global.png[]