PHPackages                             gtjamesa/php-zscore - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. gtjamesa/php-zscore

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

gtjamesa/php-zscore
===================

Smoothed z-score peak detection algorithm (https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data/22640362#22640362)

v1.1.0(4y ago)21.0k1MITPHPPHP ^7.4|^8.0

Since Jul 6Pushed 2y ago1 watchersCompare

[ Source](https://github.com/gtjamesa/php-zscore)[ Packagist](https://packagist.org/packages/gtjamesa/php-zscore)[ Docs](https://github.com/gtjamesa/php-zscore)[ RSS](/packages/gtjamesa-php-zscore/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

PHP smoothed peak detection algorithm (ZScore)
==============================================

[](#php-smoothed-peak-detection-algorithm-zscore)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1dc5e6502ffb4082b7b5765db90c1a8e71d6f288585a90986ed703e35efbe3e4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f67746a616d6573612f7068702d7a73636f72652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gtjamesa/php-zscore)[![Total Downloads](https://camo.githubusercontent.com/85899807eab3936d2786182258b8042bc49a9d44c10f8c7b401546ac8e978b39/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f67746a616d6573612f7068702d7a73636f72652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gtjamesa/php-zscore)

This package is the implementation of the "[Robust peak detection algorithm (using z-scores)](https://stackoverflow.com/a/22640362/6029703)" algorithm by [Jean-Paul](https://www.linkedin.com/in/jpgvb).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require gtjamesa/php-zscore
```

Usage
-----

[](#usage)

Parameters to configure the algorithm can be set using a fluent interface, or optionally be specified as the second parameter when creating the object.

```
// Create object using fluent interface
$zScore = (new ZScore())->lag(30)
    ->threshold(5)
    ->influence(0);

// Create object using options as an array
$zScore = new ZScore([
    'lag'       => 30,
    'threshold' => 5,
    'influence' => 0,
]);

// Calculate peak signals for the supplied dataset
// Returns [0, 1, 0, 0, ..., -1, 0, 0, 1]
$results = $zScore->calculate($data);
```

The algorithm will iterate the entire supplied dataset on first calculation. This will be inefficient to run on a real-time stream of incoming data, as it will recalculate every signal for the dataset.

Additional signals for incoming datapoints can be added to the dataset after it's creation by calling the `add()` method:

```
$signal = $zScore->add(155); // returns -1, 0 or 1
```

#### Saving/loading

[](#savingloading)

The `ZScore` class can be serialized/unserialized so that the previously calculated data may be saved to disk or cache, to be reloaded at a later time. You may optionally call the `shrink()` method before serialization to ignore the dataset, as it is unnecessary for future signal calculations.

```
$serialized = serialize($zScore); // 3766 bytes
$serializedSmall = serialize($zScore->shrink()); // 3081 bytes
```

#### Algorithm configuration parameters

[](#algorithm-configuration-parameters)

***`lag`***: the lag parameter determines how much your data will be smoothed and how adaptive the algorithm is to changes in the long-term average of the data. The more [stationary](https://en.wikipedia.org/wiki/Stationary_process) your data is, the more lags you should include (this should improve the robustness of the algorithm). If your data contains time-varying trends, you should consider how quickly you want the algorithm to adapt to these trends. i.e., if you put `lag` at 10, it takes 10 'periods' before the algorithm's threshold is adjusted to any systematic changes in the long-term average. So choose the `lag` parameter based on the trending behaviour of your data and how adaptive you want the algorithm to be.

***`influence`***: this parameter determines the influence of signals on the algorithm's detection threshold. If put at 0, signals have no influence on the threshold, such that future signals are detected based on a threshold that is calculated with a mean and standard deviation that is not influenced by past signals. Another way to think about this is that if you put the influence at 0, you implicitly assume stationarity (i.e. no matter how many signals there are, the time series always returns to the same average over the long term). If this is not the case, you should put the influence parameter somewhere between 0 and 1, depending on the extent to which signals can systematically influence the time-varying trend of the data. e.g., if signals lead to a [structural break](https://en.wikipedia.org/wiki/Structural_break) of the long-term average of the time series, the influence parameter should be put high (close to 1) so the threshold can adjust to these changes quickly.

***`threshold`***: the threshold parameter is the number of standard deviations from the moving mean above which the algorithm will classify a new datapoint as being a signal. For example, if a new datapoint is 4.0 standard deviations above the moving mean and the threshold parameter is set as 3.5, the algorithm will identify the datapoint as a signal. This parameter should be set based on how many signals you expect. For example, if your data is normally distributed, a threshold (or: z-score) of 3.5 corresponds to a signalling probability of 0.00047 (from [this table](https://imgur.com/a/UJlXNJo)), which implies that you expect a signal once every 2128 datapoints (1/0.00047). The threshold therefore directly influences how sensitive the algorithm is and thereby also how often the algorithm signals. Examine your own data and determine a sensible threshold that makes the algorithm signal when you want it to (some trial-and-error might be needed here to get to a good threshold for your purpose).

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

### Security

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [James](https://github.com/gtjamesa)
- [Jean-Paul](https://stackoverflow.com/a/22640362/6029703)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity23

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~527 days

Total

2

Last Release

1615d ago

PHP version history (2 changes)v1.0.0PHP ^7.4

v1.1.0PHP ^7.4|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/9e2a5e45322004ebc65fcfc1b13bb0a51bb3a0f75cd97dbe33b1cbb3bca74681?d=identicon)[gtjamesa](/maintainers/gtjamesa)

---

Top Contributors

[![gtjamesa](https://avatars.githubusercontent.com/u/2078364?v=4)](https://github.com/gtjamesa "gtjamesa (8 commits)")

---

Tags

zscorephp-zscore

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/gtjamesa-php-zscore/health.svg)

```
[![Health](https://phpackages.com/badges/gtjamesa-php-zscore/health.svg)](https://phpackages.com/packages/gtjamesa-php-zscore)
```

###  Alternatives

[madewithlove/laravel-nova-uuid-support

Adds uuid and other string identifier support to Laravel Nova

28132.9k](/packages/madewithlove-laravel-nova-uuid-support)[delight-im/ids

Short, obfuscated and efficient IDs for PHP

289.5k1](/packages/delight-im-ids)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
