移动函数聚合
编辑移动函数聚合
编辑给定一个有序的数据序列,移动函数聚合将在数据上滑动一个窗口,并允许用户指定一个在每个数据窗口上执行的自定义脚本。为方便起见,预定义了许多常用函数,例如最小值/最大值、移动平均值等。
语法
编辑单独的 moving_fn
聚合看起来像这样
{ "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.min(values)" } }
表 67. moving_fn
参数
参数名称 | 描述 | 必填 | 默认值 |
---|---|---|---|
|
目标指标的路径(更多详情参见 |
必填 |
|
|
在直方图上“滑动”的窗口大小。 |
必填 |
|
|
应该在每个数据窗口上执行的脚本 |
必填 |
|
|
在数据中发现间隙时要应用的策略。参见 处理数据中的间隙。 |
可选 |
|
|
可选 |
0 |
moving_fn
聚合必须嵌入在 histogram
或 date_histogram
聚合中。它们可以像任何其他指标聚合一样嵌入。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movfn": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.unweightedAvg(values)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movfn: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.unweightedAvg(values)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movfn: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.unweightedAvg(values)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movfn": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.unweightedAvg(values)" } } } } } }
在“timestamp”字段上构建一个名为“my_date_histo”的 |
|
使用 |
|
最后,我们指定一个 |
移动平均值是通过首先在一个字段上指定 histogram
或 date_histogram
来构建的。然后,您可以选择在该直方图内添加数值度量,例如 sum
。最后,moving_fn
嵌入到直方图中。buckets_path
参数然后用于“指向”直方图内的某个兄弟度量(有关 buckets_path
语法的描述,请参见 buckets_path
语法)。
上述聚合的示例响应可能如下所示
{ "took": 11, "timed_out": false, "_shards": ..., "hits": ..., "aggregations": { "my_date_histo": { "buckets": [ { "key_as_string": "2015/01/01 00:00:00", "key": 1420070400000, "doc_count": 3, "the_sum": { "value": 550.0 }, "the_movfn": { "value": null } }, { "key_as_string": "2015/02/01 00:00:00", "key": 1422748800000, "doc_count": 2, "the_sum": { "value": 60.0 }, "the_movfn": { "value": 550.0 } }, { "key_as_string": "2015/03/01 00:00:00", "key": 1425168000000, "doc_count": 2, "the_sum": { "value": 375.0 }, "the_movfn": { "value": 305.0 } } ] } } }
自定义用户脚本
编辑移动函数聚合允许用户指定任何任意脚本以定义自定义逻辑。每次收集新的数据窗口时都会调用该脚本。这些值在 values
变量中提供给脚本。然后,脚本应该执行某种计算并发出单个 double
作为结果。不允许发出 null
,但允许 NaN
和 +/- Inf
。
例如,此脚本将简单地返回窗口中的第一个值,如果没有任何值可用则返回 NaN
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "return values.length > 0 ? values[0] : Double.NaN" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movavg: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'return values.length > 0 ? values[0] : Double.NaN' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movavg: { moving_fn: { buckets_path: "the_sum", window: 10, script: "return values.length > 0 ? values[0] : Double.NaN", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "return values.length > 0 ? values[0] : Double.NaN" } } } } } }
shift 参数
编辑默认情况下(shift = 0
),用于计算的窗口是最后 n
个值(不包括当前桶)。将 shift
增加 1 会将起始窗口位置向右移动 1
。
- 要将当前桶包含到窗口中,请使用
shift = 1
。 - 对于中心对齐(当前桶之前和之后
n / 2
个值),请使用shift = window / 2
。 - 对于右对齐(当前桶之后
n
个值),请使用shift = window
。
如果任一窗口边缘超出数据序列的边界,则窗口将缩小以仅包含可用值。
预构建函数
编辑为方便起见,许多函数已预先构建,可在 moving_fn
脚本上下文中使用。
-
max()
-
min()
-
sum()
-
stdDev()
-
unweightedAvg()
-
linearWeightedAvg()
-
ewma()
-
holt()
-
holtWinters()
这些函数可从 MovingFunctions
命名空间中获取。例如 MovingFunctions.max()
max 函数
编辑此函数接受一组双精度数并返回该窗口中的最大值。null
和 NaN
值将被忽略;最大值仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_max": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.max(values)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_moving_max: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.max(values)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_moving_max: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.max(values)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_max": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.max(values)" } } } } } }
min 函数
编辑此函数接受一组双精度数并返回该窗口中的最小值。null
和 NaN
值将被忽略;最小值仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_min": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.min(values)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_moving_min: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.min(values)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_moving_min: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.min(values)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_min": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.min(values)" } } } } } }
sum 函数
编辑此函数接受一组双精度数并返回该窗口中值的总和。null
和 NaN
值将被忽略;总和仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 0.0
作为结果。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_sum": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.sum(values)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_moving_sum: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.sum(values)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_moving_sum: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.sum(values)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_sum": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.sum(values)" } } } } } }
stdDev 函数
编辑此函数接受一组双精度数和平均值,然后返回该窗口中值的标准差。null
和 NaN
值将被忽略;总和仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 0.0
作为结果。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_sum": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_moving_sum: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_moving_sum: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_moving_sum": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))" } } } } } }
必须将 avg
参数提供给标准差函数,因为可以在窗口上计算不同类型的平均值(简单平均值、线性加权平均值等)。下面详细介绍的各种移动平均值可用于计算标准差函数的平均值。
unweightedAvg 函数
编辑unweightedAvg
函数计算窗口中所有值的总和,然后除以窗口的大小。它实际上是窗口的简单算术平均值。简单移动平均值不执行任何时间相关的加权,这意味着 simple
移动平均值的值往往会“滞后”于实际数据。
null
和 NaN
值将被忽略;平均值仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。这意味着平均值计算中使用的计数是非 null
、非 NaN
值的计数。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.unweightedAvg(values)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movavg: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.unweightedAvg(values)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movavg: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.unweightedAvg(values)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.unweightedAvg(values)" } } } } } }
linearWeightedAvg 函数
编辑linearWeightedAvg
函数为序列中的点分配线性权重,以便“较旧”的数据点(例如窗口开头的那些数据点)对总平均值的贡献线性减少。线性加权有助于减少数据均值背后的“滞后”,因为较旧的点的影响较小。
如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.linearWeightedAvg(values)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movavg: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.linearWeightedAvg(values)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movavg: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.linearWeightedAvg(values)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.linearWeightedAvg(values)" } } } } } }
ewma 函数
编辑ewma
函数(又名“单指数”)与 linearMovAvg
函数类似,不同之处在于较旧的数据点的权重呈指数下降,而不是线性下降。权重衰减的速度可以用 alpha
设置来控制。较小的值使权重缓慢衰减,这提供了更大的平滑度并考虑了窗口的更大一部分。较大的值使权重快速衰减,这减少了较旧的值对移动平均值的影响。这往往使移动平均值更紧密地跟踪数据,但平滑度较低。
null
和 NaN
值将被忽略;平均值仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。这意味着平均值计算中使用的计数是非 null
、非 NaN
值的计数。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.ewma(values, 0.3)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movavg: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.ewma(values, 0.3)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movavg: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.ewma(values, 0.3)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.ewma(values, 0.3)" } } } } } }
holt 函数
编辑holt
函数(又名“双指数”)包含第二个指数项,用于跟踪数据的趋势。当数据具有潜在的线性趋势时,单指数函数表现不佳。双指数模型在内部计算两个值:“水平”和“趋势”。
水平计算类似于 ewma
,是对数据的指数加权视图。不同之处在于使用先前平滑的值而不是原始值,这使其能够保持接近原始序列。趋势计算查看当前值和最后一个值之间的差异(例如,平滑数据的斜率或趋势)。趋势值也呈指数加权。
通过将水平和趋势分量相乘来生成值。
null
和 NaN
值将被忽略;平均值仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。这意味着平均值计算中使用的计数是非 null
、非 NaN
值的计数。
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.holt(values, 0.3, 0.1)" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movavg: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'MovingFunctions.holt(values, 0.3, 0.1)' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movavg: { moving_fn: { buckets_path: "the_sum", window: 10, script: "MovingFunctions.holt(values, 0.3, 0.1)", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "MovingFunctions.holt(values, 0.3, 0.1)" } } } } } }
实际上,在holtMovAvg
中,alpha
值的行为与ewmaMovAvg
非常相似:较小的值会产生更多的平滑效果和更大的滞后,而较大的值会产生更紧密的跟踪和更小的滞后。beta
的值通常难以观察。较小的值强调长期趋势(例如,整个序列中的恒定线性趋势),而较大的值则强调短期趋势。
Holt-Winters 函数
编辑holtWinters
函数(又称“三重指数平滑”)结合了第三个指数项,用于跟踪数据的季节性方面。因此,这种聚合基于三个组成部分进行平滑:“水平”、“趋势”和“季节性”。
水平和趋势计算与holt
相同。季节性计算查看当前点与前一个周期的点的差异。
Holt-Winters 需要比其他移动平均值更多的手动干预。您需要指定数据的“周期性”:例如,如果您的数据每 7 天出现周期性趋势,则应设置period = 7
。类似地,如果存在月度趋势,则应将其设置为30
。目前尚无周期性检测功能,但这已列入未来增强计划。
null
和 NaN
值将被忽略;平均值仅根据实际值计算。如果窗口为空,或所有值都是 null
/NaN
,则返回 NaN
作为结果。这意味着平均值计算中使用的计数是非 null
、非 NaN
值的计数。
表 76。holtWinters(double[] values, double alpha)
参数
参数名称 | 描述 |
---|---|
|
查找总和的窗口值 |
|
水平衰减值 |
|
趋势衰减值 |
|
季节性衰减值 |
|
数据的周期性 |
|
如果要使用乘法 Holt-Winters,则为 True;如果要使用加法,则为 False |
resp = client.search( size=0, aggs={ "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}" } } } } }, ) print(resp)
response = client.search( body: { size: 0, aggregations: { my_date_histo: { date_histogram: { field: 'date', calendar_interval: '1M' }, aggregations: { the_sum: { sum: { field: 'price' } }, the_movavg: { moving_fn: { buckets_path: 'the_sum', window: 10, script: 'if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}' } } } } } } ) puts response
const response = await client.search({ size: 0, aggs: { my_date_histo: { date_histogram: { field: "date", calendar_interval: "1M", }, aggs: { the_sum: { sum: { field: "price", }, }, the_movavg: { moving_fn: { buckets_path: "the_sum", window: 10, script: "if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}", }, }, }, }, }, }); console.log(response);
POST /_search { "size": 0, "aggs": { "my_date_histo": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "aggs": { "the_sum": { "sum": { "field": "price" } }, "the_movavg": { "moving_fn": { "buckets_path": "the_sum", "window": 10, "script": "if (values.length > 5*2) {MovingFunctions.holtWinters(values, 0.3, 0.1, 0.1, 5, false)}" } } } } } }
乘法 Holt-Winters 通过将每个数据点除以季节性值来工作。如果您的任何数据为零,或者数据中存在间隙(因为这会导致除以零),则会出现问题。为了解决这个问题,mult
Holt-Winters 将所有值填充一个非常小的数值 (1*10-10),以便所有值都不为零。这会影响结果,但影响极小。如果您的数据非零,或者您希望在遇到零时看到NaN
,则可以使用pad: false
禁用此行为。
“冷启动”
编辑不幸的是,由于 Holt-Winters 的性质,它需要两个周期的数据来“引导”算法。这意味着您的window
必须始终至少是您周期大小的两倍。如果不满足此条件,将抛出异常。这也意味着 Holt-Winters 不会为前2 * period
个数据桶发出值;当前算法不进行反向预测。
您会在上面的示例中注意到,我们有一个if ()
语句来检查 values 的大小。这是为了确保在调用 Holt-Winters 函数之前,我们拥有两个周期的数据(5 * 2
,其中 5 是holtWintersMovAvg
函数中指定的周期)。