Calculation of the weighted moving average with exponential adjustment

Asked

Viewed 455 times

4

How could I calculate the a in the following java formula:

inserir a descrição da imagem aqui

I did the following : Df = Df + a(1 -a) xx i

I generalized the formula I just don’t know how to calculate the a, like making a formula where the a = ...

This formula is known as the weighted moving average with exponential adjustment. I searched on English sites in google with the following search : "exponential Smoothing formula" but I was not successful.

  • Dt is a finite sequence?

  • What do these variables mean?

  • 1

    It is a time sequence where each month has its quantity sold of a given product. A is the exponential factor or alpha Df is the quantity in a given month i is an exponential. The formula works as follows given an alpha I calculate the amount sold of a product in the following month. What I want to calculate now is the alpha

1 answer

3


Looking at the formula, I think the solution would be this:

public static double smooth(double a, double... d) {
    double soma = 0.0;
    double potencia = 1.0;
    for (int i = d.length - 1; i >= 0; i--) {
        soma += a * potencia * d[i];
        potencia *= 1.0 - a;
    }
    return soma;
}

I performed a test:

System.out.println(smooth(0.05, 10, 40, 50, 20, 35));

That is the result:

7.078253125000002

To find the term a (supposing it is between 0.0 and 1.0), we search through iterations, the global maximum of the function, knowing that there are no local maxima:

public static double bestSmooth(double... d) {
    double v1 = 0.0;
    double v5 = 1.0;
    while (true) {
        double v3 = (v1 + v5) / 2;
        if (v3 == v1 || v3 == v5) return v3;
        double s1 = smooth(v1, d);
        double s3 = smooth(v3, d);
        double s5 = smooth(v5, d);
        if (s5 >= s3 && s5 >= s1) {
            v1 = v3;
        } else if (s1 >= s3 && s1 >= s5) {
            v5 = v3;
        } else {
            double v2 = (v1 + v3) / 2;
            double v4 = (v3 + v5) / 2;
            double s2 = smooth(v2, d);
            double s4 = smooth(v4, d);
            if (s4 >= s3 && s4 >= s5) {
                v1 = v3;
                v3 = v4;
            } else if (s2 >= s3 && s2 >= s1) {
                v5 = v3;
                v3 = v2;
            } else if (s3 >= s2 && s3 >= s4) {
                v1 = v2;
                v5 = v4;
            }
        }
    }
}

To find the term a on the basis of soma and in the d, there is no way to reverse the formula of smooth directly, then we need to find the corresponding value iteratively:

private static boolean ordered(double a, double b, double c) {
    return (a <= b && b <= c) || (c <= b && b <= a);
}

public static double smoothRatio(double total, double... d) {
    double minA = 0.0;
    double maxA = bestSmooth(d);
    double smoothMin = smooth(minA, d);
    double smoothMax = smooth(maxA, d);
    if (!ordered(smoothMin, total, smoothMax)) throw new IllegalArgumentException();

    while (true) {
        if (total == smoothMin) return minA;
        if (total == smoothMax) return maxA;
        double mid = minA + (maxA - minA) / 2;
        if (mid == minA) return minA;
        if (mid == maxA) return maxA;
        double smoothMid = smooth(mid, d);
        if (ordered(smoothMid, total, smoothMax)) {
            minA = mid;
            smoothMin = smoothMid;
        } else if (ordered(smoothMid, total, smoothMin)) {
            maxA = mid;
            smoothMax = smoothMid;
        }
    }
}

I performed a test:

System.out.println(smoothRatio(7.078253125000002, 10, 40, 50, 20, 35));

And I got that answer:

0.05

Complete examples of tests (the last three are in the figure):

public static void main(String[] args) {
    testar(0.05, 10, 40, 50, 20, 35);
    testar(0.34, 22, 18);
    testar(0.25, 260, 350, 430, 280, 640, 650, 240, 430, 320, 585, 385, 450, 760, 690, 400);
    testar(null, 128, 180, 96, 108, 130, 150, 165, 139, 140, 165, 290, 190, 210, 240, 235);
    testar(null, 36, 48, 26, 31, 57, 42, 26, 23, 18, 25, 18, 36, 41, 18, 22);
}

private static void testar(Double a, double... d) {
    System.out.println("Valores: " + java.util.Arrays.toString(d));
    if (a != null) {
        double r = smooth(a, d);
        System.out.println("Taxa: " + a + " - resultado: " + r);
        double b = smoothRatio(r, d);
        System.out.println("Taxa (prova real): " + b);
    }
    double p = bestSmooth(d);
    System.out.println("Melhor taxa: " + p + " - resultado: " + smooth(p, d));
    System.out.println();
}

Here’s the way out:

Valores: [10.0, 40.0, 50.0, 20.0, 35.0]
Taxa: 0.05 - resultado: 7.078253125000002
Taxa (prova real): 0.05
Melhor taxa: 1.0 - resultado: 35.0

Valores: [22.0, 18.0]
Taxa: 0.34 - resultado: 11.056799999999999
Taxa (prova real): 0.33999999999999997
Melhor taxa: 0.9090909212827682 - resultado: 18.18181818181818

Valores: [260.0, 350.0, 430.0, 280.0, 640.0, 650.0, 240.0, 430.0, 320.0, 585.0, 385.0, 450.0, 760.0, 690.0, 400.0]
Taxa: 0.25 - resultado: 514.275442045182
Taxa (prova real): 0.24999999999999967
Melhor taxa: 0.3844731971623787 - resultado: 529.8357007856109

Valores: [128.0, 180.0, 96.0, 108.0, 130.0, 150.0, 165.0, 139.0, 140.0, 165.0, 290.0, 190.0, 210.0, 240.0, 235.0]
Melhor taxa: 0.9200836578384042 - resultado: 235.20144008802336

Valores: [36.0, 48.0, 26.0, 31.0, 57.0, 42.0, 26.0, 23.0, 18.0, 25.0, 18.0, 36.0, 41.0, 18.0, 22.0]
Melhor taxa: 0.21615071594715118 - resultado: 26.222890515272397

In these last three examples (as in the figure), the first of them (line 3 of the spreadsheet, marked with C) gives the answer 514.275442045182 (which is the same value as cells Q3-S3, if rounded) using a rate of 0.25 (cell U3). If you used an ideal rate of 0.3844731971623787, the answer would be as high as possible for these data: 529.8357007856109

For the other examples, you don’t have a value of a. Different values of a produce different results. Probably the value of a what matters most is the one that produces the best result, which is calculated by means of the function bestSmooth. Thus, in the case of your line 5 of the spreadsheet (marked with B), the best possible result is 235.20144008802336 at an ideal rate of 0.9200836578384042. In the case of your worksheet line 7 (marked with A), the best possible result is 26.222890515272397 at an ideal rate of 0.21615071594715118.

In real life, not always the best result or optimal rate is achievable, but the closer the actual rate gets to the optimal rate provided by the function bestSmooth, the higher the expected value.

See here working on ideone.

  • is right there but the power would be an i that increases. and in case I would like to calculate the alpha I will make the modifications to see if I get there.

  • I already have in the case the sum value that in the example is 22. how I could calculate the a?

  • @user2509556 You want also another formula where based on the d and in sum, you find the a?

  • As for the power variable, the deal is that it starts with the value 1, then it will be (1 - a), afterward (1 - a)^2, afterward (1 - a)^3...

  • Even if you can help me ... thank you

  • @user2509556 I edited the answer.

  • in reality what I want is to calculate the alpha or variable "a" I made a test with the best alpha (0.34) and two quantity of sales taken from the spreadsheet in the case of the month of June with 22 and May with 18. System.out.println(Smooth(0.34, 22,18)); = 11.056799999999 System.out.println(smoothRatio(11.056799999999999, 22,18)); = 0.09933183964086101 yet did not. I think the formula is not that . We are passing the a as parameter and it is he that I want to calculate.

  • @user2509556 For me, smoothRatio(11.056799999999999, 22, 18) gave 0.33999999999999997.

  • Ah, another thing, you prefer the elements d ordered in reverse chronological or chronological order? Why would I imagine May = 22 and June = 18, and not the other way around.

  • is blz. the calculation is correct. but where would I get this sum ? at first I only have d and the elements are received as parameters in reverse form in the figure [https://snag.gy/DGKr80.jpg] you can see the months jun, mai, abr, mar,... in descending form for the product A B and C

  • @user2509556 o a is what is in your cell U3. The d is what is in B3-P3 cells in order (note that the for of smooth is already back to front). So if you have the a and the values of d, just call the smooth. In the example of line C of this figure, smooth(0.25, 260, 350, 430, 280, 640, 650, 240, 430, 320, 585, 385, 450, 760, 690, 400) resulted in 514.275442045182, which is what is in Q3 (after rounding). The reverse process is to find U3 with Q3 and values of d.

  • yes you are right at one point but the a is a value that I want to calculate despite being in excel, through this formula even Smooth, what happens is that I could not see a formula yet to calculate it a = result

  • @user2509556 I edited the answer again. I think what you want is the bestSmooth.

  • As you can see, the more you sell (input values - quantity) the greater the alpha. I used an example with the months of January to May to calculate the June which in the case is 22. I got the following values Best rate: 0.498 - result: 26 I can consider 26 instead of 22 by the variation between the real and the predicted. Since the sale is unpredictable what I want is to have the predictable as close to the real as possible.

  • Thanks for the help your calculation was great.

Show 11 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.