{"id":31753810,"url":"https://github.com/servicenow/stl-decomp-4j","last_synced_at":"2025-10-09T17:54:41.554Z","repository":{"id":54423773,"uuid":"80868140","full_name":"ServiceNow/stl-decomp-4j","owner":"ServiceNow","description":"Java implementation of Seasonal-Trend-Loess time-series decomposition algorithm.","archived":false,"fork":false,"pushed_at":"2024-01-23T17:00:36.000Z","size":4069,"stargazers_count":115,"open_issues_count":2,"forks_count":46,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-01-23T18:24:45.155Z","etag":null,"topics":["java","seasonal-adjustment","seasonal-trend-loess","time-series","timeseries"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ServiceNow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-02-03T20:51:08.000Z","updated_at":"2024-01-23T18:24:46.536Z","dependencies_parsed_at":"2022-08-13T15:10:48.685Z","dependency_job_id":"c3a10072-7276-4797-86b1-e111a9195dce","html_url":"https://github.com/ServiceNow/stl-decomp-4j","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/ServiceNow/stl-decomp-4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceNow%2Fstl-decomp-4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceNow%2Fstl-decomp-4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceNow%2Fstl-decomp-4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceNow%2Fstl-decomp-4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ServiceNow","download_url":"https://codeload.github.com/ServiceNow/stl-decomp-4j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceNow%2Fstl-decomp-4j/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001804,"owners_count":26083197,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","seasonal-adjustment","seasonal-trend-loess","time-series","timeseries"],"created_at":"2025-10-09T17:54:34.606Z","updated_at":"2025-10-09T17:54:41.545Z","avatar_url":"https://github.com/ServiceNow.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Seasonal Decomposition of Time Series by Loess\n\n[![travis-ci-status](https://travis-ci.org/ServiceNow/stl-decomp-4j.svg?branch=master)](https://travis-ci.org/ServiceNow/stl-decomp-4j)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\nThe Seasonal-Trend-Loess (STL) algorithm decomposes a time series into seasonal, trend and residual components. The algorithm uses [Loess interpolation](https://en.wikipedia.org/wiki/Local_regression) (original paper [here](https://pdfs.semanticscholar.org/414e/5d1f5a75e2327d99b5bbb93f2e4e241c5acc.pdf)) to smooth the cyclic sub-series (e.g. all January values in the CO\u003csub\u003e2\u003c/sub\u003e data shown in the example below). After removing the seasonality from the signal, the remainder is smoothed (in multiple steps) to find the trend. This process is repeated and may include robustness iterations that take advantage of the weighted-least-squares underpinnings of Loess to remove the effects of outliers. The details are described in [STL: A Seasonal-Trend Decomposition Procedure Based on Loess](http://www.wessa.net/download/stl.pdf).   \n\n**_stl-decomp-4j_** is a Java port of the original Ratfor/Fortran available from [Netlib](http://netlib.org) ([original source here](http://netlib.org/a/stl); also included as part of `examples/StlPerfTest/fortran_benchmark`), extended to support local quadratic interpolation. **_stl-decomp-4j_** expects equally spaced data with no missing values, similar to the original  Fortran version (and the [R](https://stat.ethz.ch/R-manual/R-devel/library/stats/html/stl.html) and [Python](https://github.com/jcrotinger/pyloess) versions, which both use the original Fortran version under the hood).\n\nCheck out the [the **_stl-decomp-4j_** wiki](https://github.com/ServiceNow/stl-decomp-4j/wiki) for TODOs, etc.\n\n## Example\n\nAt a minimum, the STL algorithm requires specifying the periodicity of the data (e.g. 12 for monthly) and the width of the Loess smoother used to smooth the cyclic seasonal sub-series. In general, there are three Loess smoothers that each require three parameters: a width, a degree, and a jump. The width specifies the number of data points that the local interpolation uses to smooth each point, the degree specifies the degree of the local polynomial that is fit to the data, and the jump specifies how many points are skipped between Loess interpolations, with linear interpolation being done between these points. Because of this complexity, construction is done via `Builder` objects, as shown in this simple example.\n\n```java\ndouble[] values = getSomeMonthlyData(); // Monthly time-series data\n\nSeasonalTrendLoess.Builder builder = new SeasonalTrendLoess.Builder();\nSeasonalTrendLoess smoother = builder.\n\t\t\tsetPeriodLength(12).    // Data has a period of 12\n\t\t\tsetSeasonalWidth(35).   // Monthly data smoothed over 35 years\n\t\t\tsetNonRobust().         // Not expecting outliers, so no robustness iterations\n\t\t\tbuildSmoother(values);\n\nSeasonalTrendLoess.Decomposition stl = smoother.decompose();\ndouble[] seasonal = stl.getSeasonal();\ndouble[] trend = stl.getTrend();\ndouble[] residual = stl.getResidual();\n```\n\nThe [StlDemoRestServer example](examples/StlDemoRestServer) includes a copy of the [Monthly CO\u003csub\u003e2\u003c/sub\u003e Measurement Data](http://www.esrl.noaa.gov/gmd/ccgg/trends/) and a simple REST server that reads this data, performs an STL decomposition on the data, and serves up the results to `http://localhost:4567/stldemo`. The `examples/StlDemoRestServer/index.html` file loads the data from this server and plots the resulting decomposition. The code that does the actual decomposition is identical to that shown above, resulting in the following decomposition:\n\n![CO2 Plot](examples/StlDemoRestServer/co2_stl_highchart.jpg)\n\n## Benchmarking\n\nThe [StlPerfTest example](examples/StlPerfTest) times the STL running on the CO\u003csub\u003e2\u003c/sub\u003e data mentioned above or on a time-series of 10 years of random hourly data. The same benchmark is implemented in the original Fortran [here](examples/StlPerfTest/fortran_benchmark). See [Performance Tests](examples/StlPerfTest/PerformanceTest.md) for instructions on running these tests. \n\nLimited testing show the Java to be about half the speed of the Fortran. A comparison of the resulting decompositions is shown in the [StlJavaFortranComparison notebook](examples/StlPerfTest/StlJavaFortranComparison.ipynb).\n\n## Extension to include exogenous inputs \n\nThe STL method is extended to incorporate exogenous inputs where details can be found in the [StlExogenous example](https://github.com/ServiceNow/stl-decomp-4j/tree/master/examples/StlExogenous). \nTo apply exogenous inputs, build the smoother with them (`double[][] exogenousinputs` with each row being one exogenous input) as shown in the example below. After calling the `.decompose()` method, you can get the STL components. Note that the `.getTrend()` method now extracts the combined effect of the trend and exogenous inputs. \n\n```java \nSeasonalTrendLoess smoother = builder.buildSmoother(values, exogenousinputs);\n```\n\n## Documentation\n\nThe implementation of the quadratic extension of `LoessInterpolator` is described, mathematically, in [ImplementationNotes](stl-decomp-4j/docs/ImplementationNotes.pdf).\n\n`TODO: JavaDoc link goes here`\n\n## Build Dependencies\nTo include **_stl-decomp-4j_** in your maven project, add the following to your pom file:\n\n```xml\n        \u003cdependency\u003e\n          \u003cgroupId\u003ecom.github.servicenow.stl4j\u003c/groupId\u003e\n          \u003cartifactId\u003estl-decomp-4j\u003c/artifactId\u003e\n          \u003cversion\u003e1.0.5\u003c/version\u003e\n        \u003c/dependency\u003e\n```\n\nThe **_stl-decomp-4j_** implementation has no external dependencies.\n\nThe unit tests depend on `junit`, `commons-math3` and `slf4j-simple`.\n\nThe examples have further dependencies on `commons-cli`, `opencsv`, `spark-core`, and `jackson-mapper-asl`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fservicenow%2Fstl-decomp-4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fservicenow%2Fstl-decomp-4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fservicenow%2Fstl-decomp-4j/lists"}