Repository navigation
Fixing double and triple exponential smoothing algorithms, and adding an accompanying test suite - #2629
Fixing double and triple exponential smoothing algorithms, and adding an accompanying test suite#2629john-on-line27 wants to merge 5 commits into
Conversation
Previously, the variables which created the exponential smoothing had no validation, so a mistake or malicious actor could easily break the algorithm by using an invalid alpha, beta or gamma. In order to fix this issue, I created a helper function to validate the range of the smoothing variables. This function is optimal, because it lends itself to reuse amongst simple, double and exponential smoothing.
Firstly, the exception handling, which was previously in the main function, was moved into the helper functions. This was done to fit with best practices in exception handling. Secondly, a new helper function was implemented, so that the frequencies being put into the triple exponential are not zero or smaller, as a lower bound, or larger than half of the size of the incoming data array (as the algorithm uses double the size of the frequency to initialize the variables). The first aspect of this test is trivially beneficial, as it makes sure that no invalid values can be input into the algorithm. The second one is also best practice for this specific instance of the algorithm, as it currently fits to the initialization process of the TES algorithm, but is not applicable to all instances of TES. Thirdly, an error was found in the triple exponential smoothing algorithm, where the application of the centered moving average filter would result in an indexOutOfBoundsException for frequencies with an odd number, as the for loop was incorrectly declared. The downside to this is the assumption that the current workflow for the initialization of the starting variables is either valid or optimal. Finally, I have added comments to the exponential smoothing algorithms, so that future contributors have a better understanding of what is happening in underneath the hood.
In order to ensure the full correctness of the Java double and triple exponential smoothing algorithms, the current Java file is being tested by a new EMAUtils.java file, which then proceeds to get reference results from R. The reason why this was the option taken, was that there had been many issues when running the original code, so testing was needed. This includes three main cases, the regular double exponential smoothing algorithm, as well as the odd and even frequency cases for triple exponential smoothing. The reason why I split the last two, is due to the centered moving average used for the initialization, there is two different workflows for the even and odd cases, and in previous iterations of the program, the odd case would crash due to an exception. The reasoning behind the JUnit/R set up comes from the fact that R has prebuilt DES/TES functions, so the correctness of the R reference results can be assumed. The downsides to this approach are two-fold. Firstly, the sample of test data is very small. This is so that the testing does not last a long amount of time, however some may say the length is insufficient. Secondly, the inbuilt reference functions seek to find the optimal alpha, beta and gamma to minimize the RMSE, but since this is irrelevant to what is being tested, it slows down the actual testing. Assisted by: AI AI contributions include the generation of test data, as well as debugging the connection between the JUnit tests and the R tests. The specific AI used was ChatGPT, by OpenAI, and the specific model was GPT-6.1 Sol.
EMAUtils Tests
Initially the default had been set to search for the optimal alpha, beta and gamma values, the testing was much slower than needed, now I have just added a fixed value for all values across the JUnit and R tests.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2629 +/- ##
=============================================
+ Coverage 71.80% 75.56% +3.75%
=============================================
Files 2078 454 -1624
Lines 222401 29799 -192602
Branches 38306 0 -38306
=============================================
- Hits 159698 22518 -137180
+ Misses 51616 7281 -44335
+ Partials 11087 0 -11087
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ywcb00
left a comment
There was a problem hiding this comment.
Thank you very much for addressing this issue @john-on-line27. :)
I added some comments in-line. Could you please have a look at them?
All the best,
David
| } | ||
|
|
||
|
|
||
| Container javaFittedValues = double_exponential_smoothing(TS_DATA, 0.3, 0.1); |
There was a problem hiding this comment.
Could we change this test to perform exponential smoothing by calling a DML script rather than calling the Java method directly. Examples for such tests can be found in BuiltinPowerTransformTest.java and BuiltinEMATest.java.
Also, what is the difference between this test class and the BuiltinEMATest.java. Can we merge these two test classes?
| ts_data <- c( | ||
| 112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, | ||
| 115, 126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140, | ||
| 145, 150, 178, 163, 172, 178, 199, 199, 184, 162, 146, 166, | ||
| 171, 180, 193, 181, 183, 218, 230, 242, 209, 191, 172, 194, | ||
| 196, 196, 236, 235, 229, 243, 264, 272, 237, 211, 180, 201 | ||
| ) |
There was a problem hiding this comment.
Try to pass these data from the java test class instead of hard-coding it inside the R script.
The main task of this pull request was to prove the correctness of this code, and this entailed building out a test suite. Since there is no inbuilt function for double and triple exponential smoothing (DES and TES), the best way to validate the algorithm was to create a reference output from the built R functions.
However in doing this, two issues were found. For the double exponential smoothing, the there was an issue with the offset of the function, creating more predictions than the R function with the same amount of data, so this issue was remedied by changing the amount of data being added to the predictions array. The second issue was that the TES function would not run if the frequency was set to an odd number. This was causing an indexing exception in one of the if statements, so the range within the if function was updated to fix this issue.
Additionally, other things have been added to the EMAUtils.java file, more specifically, exception/error handling, as well as comments. This should lead to an easier time for future maintainers of this code.
The shortcomings to this code include the small sample size for the testing data. This was done so that the program does not run too slowly, but if more data is required to assure quality of the code, that is also something that I am willing to include.
Assisted by: AI
AI contributions include the generation of test data, as well as debugging the connection between the JUnit tests and the R tests. The specific AI used was ChatGPT, by OpenAI, and the specific model was GPT-6.1 Sol.