在创建指数平滑的重量时处理浮点不精确



我想创建一个指数平滑权重的数组,就像从这里的公式(7.2(中一样。我知道递归定义,但需要实际的权重。我想到了以下直接实现:

import numpy as np
def create_weights(n, alpha = 1.0):
    wghts = alpha*(1-alpha)**np.arange(n)
    return wghts

重量应总计1.0,但是,如该测试所示,对于较小的alpha并非如此,我猜是由于浮点的印象:

np.set_printoptions(precision=3)
for alpha in np.arange(1.0, 0.0, -0.1):
    print("%.3f, %s, %.3f" % (alpha, create_weights(5, alpha) , create_weights(5, alpha).sum()))
Out:
1.000, [1. 0. 0. 0. 0.], 1.000
0.900, [9.e-01 9.e-02 9.e-03 9.e-04 9.e-05], 1.000
0.800, [0.8   0.16  0.032 0.006 0.001], 1.000
0.700, [0.7   0.21  0.063 0.019 0.006], 0.998
0.600, [0.6   0.24  0.096 0.038 0.015], 0.990
0.500, [0.5   0.25  0.125 0.062 0.031], 0.969
0.400, [0.4   0.24  0.144 0.086 0.052], 0.922
0.300, [0.3   0.21  0.147 0.103 0.072], 0.832
0.200, [0.2   0.16  0.128 0.102 0.082], 0.672
0.100, [0.1   0.09  0.081 0.073 0.066], 0.410

类似于这里的解决方案,我可以简单地"归一化"它,以再次扩展它:

def create_weights(n, alpha = 1.0):
    wghts = alpha*(1-alpha)**np.arange(n)
    wghts /= wghts.sum()
    return wghts

这将导致:

1.000, [1. 0. 0. 0. 0.], 1.000
0.900, [9.e-01 9.e-02 9.e-03 9.e-04 9.e-05], 1.000
0.800, [0.8   0.16  0.032 0.006 0.001], 1.000
0.700, [0.702 0.211 0.063 0.019 0.006], 1.000
0.600, [0.606 0.242 0.097 0.039 0.016], 1.000
0.500, [0.516 0.258 0.129 0.065 0.032], 1.000
0.400, [0.434 0.26  0.156 0.094 0.056], 1.000
0.300, [0.361 0.252 0.177 0.124 0.087], 1.000
0.200, [0.297 0.238 0.19  0.152 0.122], 1.000
0.100, [0.244 0.22  0.198 0.178 0.16 ], 1.000

现在,总和总计高达1.0,对于小alpha而言,第一个权重与其预期值太大(预期与alpha相同(。

是否有另一种实现此功能来实现权重的属性的方法,增加了1.0( -small错误(,而第一个权重为alpha( - 小错误(?

这与浮点精度无关。即使使用Infinite Precision实际数字算术,您生成的阵列也不会总计1。生成的一个无限序列类似地总计为1,但是您的数组停止了5个元素,而不是永远进行。

简单的指数平滑不会在5个元素上任意停止。过去远远足够多的元素将截止物应用于它们的重量很小,但对于每个alpha而没有标准化的每个alpha,都会产生不合理的结果。

最新更新