{"id":14956595,"url":"https://github.com/mongodb/signal-processing-algorithms","last_synced_at":"2025-11-11T21:08:05.937Z","repository":{"id":44721914,"uuid":"239863069","full_name":"mongodb/signal-processing-algorithms","owner":"mongodb","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-20T16:55:16.000Z","size":761,"stargazers_count":42,"open_issues_count":4,"forks_count":20,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-28T21:03:36.626Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","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/mongodb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-11T20:57:58.000Z","updated_at":"2025-03-20T16:55:21.000Z","dependencies_parsed_at":"2024-06-21T16:53:45.831Z","dependency_job_id":"93b3e487-129c-4525-92ef-02f60d4e8c03","html_url":"https://github.com/mongodb/signal-processing-algorithms","commit_stats":{"total_commits":33,"total_committers":7,"mean_commits":4.714285714285714,"dds":"0.48484848484848486","last_synced_commit":"9723602af8fcd7b722fc51fa3a53b11ddb29beb7"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fsignal-processing-algorithms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fsignal-processing-algorithms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fsignal-processing-algorithms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongodb%2Fsignal-processing-algorithms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mongodb","download_url":"https://codeload.github.com/mongodb/signal-processing-algorithms/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256110,"owners_count":20909240,"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","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":[],"created_at":"2024-09-24T13:13:11.355Z","updated_at":"2025-11-11T21:08:05.866Z","avatar_url":"https://github.com/mongodb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Signal Processing Algorithms\n\nA suite of algorithms implementing [Energy\nStatistics](https://en.wikipedia.org/wiki/Energy_distance), [E-Divisive with\nMeans](https://arxiv.org/pdf/1306.4933.pdf) and [Generalized ESD Test for\nOutliers](https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h3.htm) in python. See [The Use\nof Change Point Detection to Identify Software Performance Regressions in a Continuous Integration\nSystem](https://dl.acm.org/doi/abs/10.1145/3358960.3375791) and [Creating a Virtuous Cycle in\nPerformance Testing at MongoDB](https://dl.acm.org/doi/pdf/10.1145/3427921.3450234) for background\non the development and use of this library.\n\n## Getting Started - Users\n```\npip install signal-processing-algorithms\n```\n\n## Getting Started - Developers\n\nGetting the code:\n\n```\n$ git clone git@github.com:mongodb/signal-processing-algorithms.git\n$ cd signal-processing-algorithms\n```\n\nInstallation\n```\n$ pip install poetry\n$ poetry install\n```\nTesting/linting:\n```\n$ poetry run pytest\n```\n\nRunning the slow tests:\n```\n$ poetry run pytest --runslow\n```\n\n**Some of the larger tests can take a significant amount of time (more than 2 hours).**\n\n## Energy statistics\n[Energy Statistics](https://en.wikipedia.org/wiki/Energy_distance) is the statistical concept of Energy Distance \nand can be used to measure how similar/different two distributions are.\n\nFor statistical samples from two random variables X and Y:\nx1, x2, ..., xn and y1, y2, ..., yn\n\nE-Statistic is defined as:\n\n\u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=E_{n,m}(X,Y):=2A-B-C\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?E_{n,m}(X,Y):=2A-B-C\" title=\"E_{n,m}(X,Y):=2A-B-C\" /\u003e\u003c/a\u003e\n\nwhere,\n\n\u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=A:={\\frac\u0026space;{1}{nm}}\\sum\u0026space;_{i=1}^{n}\\sum\u0026space;_{j=1}^{m}\\|x_{i}-y_{j}\\|,B:={\\frac\u0026space;{1}{n^{2}}}\\sum\u0026space;_{i=1}^{n}\\sum\u0026space;_{j=1}^{n}\\|x_{i}-x_{j}\\|,C:={\\frac\u0026space;{1}{m^{2}}}\\sum\u0026space;_{i=1}^{m}\\sum\u0026space;_{j=1}^{m}\\|y_{i}-y_{j}\\|\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?A:={\\frac\u0026space;{1}{nm}}\\sum\u0026space;_{i=1}^{n}\\sum\u0026space;_{j=1}^{m}\\|x_{i}-y_{j}\\|,B:={\\frac\u0026space;{1}{n^{2}}}\\sum\u0026space;_{i=1}^{n}\\sum\u0026space;_{j=1}^{n}\\|x_{i}-x_{j}\\|,C:={\\frac\u0026space;{1}{m^{2}}}\\sum\u0026space;_{i=1}^{m}\\sum\u0026space;_{j=1}^{m}\\|y_{i}-y_{j}\\|\" title=\"A:={\\frac {1}{nm}}\\sum _{i=1}^{n}\\sum _{j=1}^{m}\\|x_{i}-y_{j}\\|,B:={\\frac {1}{n^{2}}}\\sum _{i=1}^{n}\\sum _{j=1}^{n}\\|x_{i}-x_{j}\\|,C:={\\frac {1}{m^{2}}}\\sum _{i=1}^{m}\\sum _{j=1}^{m}\\|y_{i}-y_{j}\\|\" /\u003e\u003c/a\u003e\n\nT-statistic is defined as: \n\n\u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=T={\\frac\u0026space;{nm}{n\u0026plus;m}}E_{{n,m}}(X,Y)\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?T={\\frac\u0026space;{nm}{n\u0026plus;m}}E_{{n,m}}(X,Y)\" title=\"T={\\frac {nm}{n+m}}E_{{n,m}}(X,Y)\" /\u003e\u003c/a\u003e\n\nE-coefficient of inhomogeneity is defined as:\n\n\u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=H=\\frac{2E||X-Y||\u0026space;-\u0026space;E||X-X'||\u0026space;-\u0026space;E||Y-Y'||}{2E||X-Y||}\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?H=\\frac{2E||X-Y||\u0026space;-\u0026space;E||X-X'||\u0026space;-\u0026space;E||Y-Y'||}{2E||X-Y||}\" title=\"H=\\frac{2E||X-Y|| - E||X-X'|| - E||Y-Y'||}{2E||X-Y||}\" /\u003e\u003c/a\u003e\n\n\n```\nfrom signal_processing_algorithms.energy_statistics import energy_statistics\nfrom some_module import series1, series2\n\n# To get Energy Statistics of the distributions.\nes = energy_statistics.get_energy_statistics(series1, series2)\n\n# To get Energy Statistics and permutation test results of the distributions.\nes_with_probabilities = energy_statistics.get_energy_statistics_and_probabilities(series1, series2, permutations=100)\n\n```\n\n## Intro to E-Divisive\n\nDetecting distributional changes in a series of numerical values can be surprisingly difficult. Simple systems based on thresholds or\n mean values can be yield false positives due to outliers in the data, and will fail to detect changes in the noise\n profile of the series you are analyzing.\n \nOne robust way of detecting many of the changes missed by other approaches is to use [E-Divisive with Means](https://arxiv.org/pdf/1306.4933.pdf), an energy\n statistic based approach that compares the expected distance (Euclidean norm) between samples of two portions of the\n series with the expected distance between samples within those portions.\n \nThat is to say, assuming that the two portions can each be modeled as i.i.d. samples drawn from distinct random variables\n (X for the first portion, Y for the second portion), you would expect the E-statistic to be non-zero if there is a\n difference between the two portions: \n \n \u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=E_{n,m}(X,Y):=2A-B-C\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?E_{n,m}(X,Y):=2A-B-C\" title=\"E_{n,m}(X,Y):=2A-B-C\" /\u003e\u003c/a\u003e\n where A, B and C are as defined in the Energy Statistics above.\n\nOne can prove that \u003ca href=\"https://www.codecogs.com/eqnedit.php?latex={E_{n,m}(X,Y)\\geq\u0026space;0}\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?{E_{n,m}(X,Y)\\geq\u0026space;0}\" title=\"{E_{n,m}(X,Y)\\geq 0}\" /\u003e\u003c/a\u003e and that the corresponding population value is zero if and only if X and Y have the same distribution. Under this null hypothesis the test statistic\n\n\u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=T={\\frac\u0026space;{nm}{n\u0026plus;m}}E_{{n,m}}(X,Y)\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?T={\\frac\u0026space;{nm}{n\u0026plus;m}}E_{{n,m}}(X,Y)\" title=\"T={\\frac {nm}{n+m}}E_{{n,m}}(X,Y)\" /\u003e\u003c/a\u003e\n\nconverges in distribution to a quadratic form of independent standard normal random variables. Under the alternative hypothesis T tends to infinity. This makes it possible to construct a consistent statistical test, the energy test for equal distributions\n  \nThus for a series Z of length L,\n\n\u003ca href=\"https://www.codecogs.com/eqnedit.php?latex=Z\u0026space;=\u0026space;\\{Z_{1},\u0026space;...,\u0026space;Z_{\\tau}\u0026space;,\u0026space;...\u0026space;,\u0026space;Z_{L}\\},\u0026space;X\u0026space;=\\{Z_{1},...,Z_{\\tau}\\},\u0026space;Y=\\{Z_{\\tau\u0026plus;1}\\,...,Z_{L}\\}\" target=\"_blank\"\u003e\u003cimg src=\"https://latex.codecogs.com/gif.latex?Z\u0026space;=\u0026space;\\{Z_{1},\u0026space;...,\u0026space;Z_{\\tau}\u0026space;,\u0026space;...\u0026space;,\u0026space;Z_{L}\\},\u0026space;X\u0026space;=\\{Z_{1},...,Z_{\\tau}\\},\u0026space;Y=\\{Z_{\\tau\u0026plus;1}\\,...,Z_{L}\\}\" title=\"Z = \\{Z_{1}, ..., Z_{\\tau} , ... , Z_{L}\\}, X =\\{Z_{1},...,Z_{\\tau}\\}, Y=\\{Z_{\\tau+1}\\,...,Z_{L}\\}\" /\u003e\u003c/a\u003e\n\nwe find the most likely change point by solving the following for \u0026tau; such that it has the maximum T statistic value.\n\n### Multiple Change Points\n\nThe algorithm for finding multiple change points is also simple.\n\nAssuming you have some k known change points:\n1. Partition the series into segments between/around these change points.\n2. Find the maximum value of our divergence metric _within_ each partition.\n3. Take the maximum of the maxima we have just found --\u003e this is our k+1th change point.\n4. Return to step 1 and continue until reaching your stopping criterion.\n\n### Stopping Criterion\n\nIn this package we have implemented a permutation based test as a stopping criterion:\n\nAfter step 3 of the multiple change point procedure above, randomly permute all of the data _within_ each cluster, and\n find the most likely change point for this permuted data using the procedure laid out above. \n \nAfter performing this operation z times, count the number of\n permuted change points z' that have higher divergence metrics than the change point you calculated with un-permuted data.\n The significance level of your change point is thus z'/(z+1). \n\nWe allow users to configure a permutation tester with `pvalue`\n and `permutations` representing the significance cutoff for algorithm termination and permutations to perform for each\n test, respectively.\n \n### Example\n```\nfrom signal_processing_algorithms.energy_statistics import energy_statistics\nfrom some_module import series\n\nchange_points = energy_statistics.e_divisive(series, pvalue=0.01, permutations=100)\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongodb%2Fsignal-processing-algorithms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmongodb%2Fsignal-processing-algorithms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongodb%2Fsignal-processing-algorithms/lists"}