Add performance test for LeastSquares (#263)

* Install phpbench 🚀

* Add first benchmark for LeastSquares

* Update README and CONTRIBUTING guide

* Fix typo
This commit is contained in:
Arkadiusz Kondas 2018-03-10 21:48:16 +01:00 committed by GitHub
parent af2d732194
commit a36fe086d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 526 additions and 15 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/vendor/
.php_cs.cache
/build
/tests/Performance/Data/*.csv

View File

@ -8,7 +8,7 @@ code base clean, unified and future proof.
You should only open pull requests against the `master` branch.
## Unit-Tests
## Unit Tests
Please try to add a test for your pull-request. You can run the unit-tests by calling:
@ -16,6 +16,22 @@ Please try to add a test for your pull-request. You can run the unit-tests by ca
vendor/bin/phpunit
```
## Performance Tests
Before first run bootstrap script will download all necessary datasets from public repository `php-ai/php-ml-datasets`.
Time performance tests:
```bash
vendor/bin/phpbench run --report=time
```
Memory performance tests:
```bash
vendor/bin/phpbench run --report=memory
```
## Travis
GitHub automatically run your pull request through Travis CI.
@ -23,21 +39,21 @@ If you break the tests, I cannot merge your code, so please make sure that your
## Merge
Please allow me time to review your pull requests. I will give my best to review everything as fast as possible, but cannot always live up to my own expectations.
Please give me time to review your pull requests. I will give my best to review everything as fast as possible, but cannot always live up to my own expectations.
## Coding Standards & Static Analysis
When contributing code to PHP-ML, you must follow its coding standards. To do that, just run:
```bash
vendor/bin/ecs check src tests --fix
composer fix-cs
```
[More about EasyCodingStandard](https://github.com/Symplify/EasyCodingStandard)
Code has to also pass static analysis by [PHPStan](https://github.com/phpstan/phpstan):
```bash
vendor/bin/phpstan.phar analyse src tests --level max --configuration phpstan.neon
composer phpstan
```

View File

@ -9,11 +9,9 @@
[![Coverage Status](https://coveralls.io/repos/github/php-ai/php-ml/badge.svg?branch=master)](https://coveralls.io/github/php-ai/php-ml?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/php-ai/php-ml/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/php-ai/php-ml/?branch=master)
<a href="http://www.yegor256.com/2016/10/23/award-2017.html">
<img src="http://www.yegor256.com/images/award/2017/winner-itcraftsmanpl.png"
style="width:203px;height:45px;"/></a>
![PHP-ML - Machine Learning library for PHP](docs/assets/php-ml-logo.png)
<p align="center">
<img src="https://github.com/php-ai/php-ml/blob/master/docs/assets/php-ml-logo.png" />
</p>
Fresh approach to Machine Learning in PHP. Algorithms, Cross Validation, Neural Network, Preprocessing, Feature Extraction and much more in one library.
@ -35,6 +33,11 @@ echo $classifier->predict([3, 2]);
// return 'b'
```
## Awards
<a href="http://www.yegor256.com/2016/10/23/award-2017.html">
<img src="http://www.yegor256.com/images/award/2017/winner-itcraftsmanpl.png" width="400"/></a>
## Documentation
To find out how to use PHP-ML follow [Documentation](http://php-ml.readthedocs.org/).
@ -51,6 +54,10 @@ composer require php-ai/php-ml
Example scripts are available in a separate repository [php-ai/php-ml-examples](https://github.com/php-ai/php-ml-examples).
## Datasets
Public datasets are available in a separate repository [php-ai/php-ml-datasets](https://github.com/php-ai/php-ml-datasets).
## Features
* Association rule learning
@ -120,6 +127,7 @@ Example scripts are available in a separate repository [php-ai/php-ml-examples](
## Contribute
- [Guide: CONTRIBUTING.md](https://github.com/php-ai/php-ml/blob/master/CONTRIBUTING.md)
- [Issue Tracker: github.com/php-ai/php-ml](https://github.com/php-ai/php-ml/issues)
- [Source Code: github.com/php-ai/php-ml](https://github.com/php-ai/php-ml)

View File

@ -23,6 +23,7 @@
"php": "^7.1"
},
"require-dev": {
"phpbench/phpbench": "^0.14.0",
"phpstan/phpstan-phpunit": "^0.9.4",
"phpstan/phpstan-shim": "^0.9",
"phpstan/phpstan-strict-rules": "^0.9.0",

406
composer.lock generated
View File

@ -4,9 +4,64 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "9135b3dece8c6938922f757123274e95",
"content-hash": "fc88078118714e9fb6b13a02dba0bd00",
"packages": [],
"packages-dev": [
{
"name": "beberlei/assert",
"version": "v2.9.2",
"source": {
"type": "git",
"url": "https://github.com/beberlei/assert.git",
"reference": "2d555f72f3f4ff9e72a7bc17cb8a53c86737c8a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/beberlei/assert/zipball/2d555f72f3f4ff9e72a7bc17cb8a53c86737c8a0",
"reference": "2d555f72f3f4ff9e72a7bc17cb8a53c86737c8a0",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=5.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.1.1",
"phpunit/phpunit": "^4.8.35|^5.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Assert\\": "lib/Assert"
},
"files": [
"lib/Assert/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de",
"role": "Lead Developer"
},
{
"name": "Richard Quadling",
"email": "rquadling@gmail.com",
"role": "Collaborator"
}
],
"description": "Thin assertion library for input validation in business models.",
"keywords": [
"assert",
"assertion",
"validation"
],
"time": "2018-01-25T13:33:16+00:00"
},
{
"name": "composer/semver",
"version": "1.4.2",
@ -375,6 +430,144 @@
],
"time": "2017-08-23T07:46:41+00:00"
},
{
"name": "lstrojny/functional-php",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/lstrojny/functional-php.git",
"reference": "7c2091ddea572e012aa980e5d19d242d3a06ad5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lstrojny/functional-php/zipball/7c2091ddea572e012aa980e5d19d242d3a06ad5b",
"reference": "7c2091ddea572e012aa980e5d19d242d3a06ad5b",
"shasum": ""
},
"require": {
"php": "~7"
},
"require-dev": {
"phpunit/phpunit": "~6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"psr-4": {
"Functional\\": "src/Functional"
},
"files": [
"src/Functional/Average.php",
"src/Functional/Capture.php",
"src/Functional/ConstFunction.php",
"src/Functional/CompareOn.php",
"src/Functional/CompareObjectHashOn.php",
"src/Functional/Compose.php",
"src/Functional/Concat.php",
"src/Functional/Contains.php",
"src/Functional/Curry.php",
"src/Functional/CurryN.php",
"src/Functional/Difference.php",
"src/Functional/DropFirst.php",
"src/Functional/DropLast.php",
"src/Functional/Each.php",
"src/Functional/Equal.php",
"src/Functional/ErrorToException.php",
"src/Functional/Every.php",
"src/Functional/False.php",
"src/Functional/Falsy.php",
"src/Functional/Filter.php",
"src/Functional/First.php",
"src/Functional/FirstIndexOf.php",
"src/Functional/FlatMap.php",
"src/Functional/Flatten.php",
"src/Functional/Flip.php",
"src/Functional/GreaterThan.php",
"src/Functional/GreaterThanOrEqual.php",
"src/Functional/Group.php",
"src/Functional/Head.php",
"src/Functional/Id.php",
"src/Functional/IfElse.php",
"src/Functional/Identical.php",
"src/Functional/IndexesOf.php",
"src/Functional/Intersperse.php",
"src/Functional/Invoke.php",
"src/Functional/InvokeFirst.php",
"src/Functional/InvokeIf.php",
"src/Functional/InvokeLast.php",
"src/Functional/Invoker.php",
"src/Functional/Last.php",
"src/Functional/LastIndexOf.php",
"src/Functional/LessThan.php",
"src/Functional/LessThanOrEqual.php",
"src/Functional/LexicographicCompare.php",
"src/Functional/Map.php",
"src/Functional/Match.php",
"src/Functional/Maximum.php",
"src/Functional/Memoize.php",
"src/Functional/Minimum.php",
"src/Functional/None.php",
"src/Functional/Not.php",
"src/Functional/PartialAny.php",
"src/Functional/PartialLeft.php",
"src/Functional/PartialMethod.php",
"src/Functional/PartialRight.php",
"src/Functional/Partition.php",
"src/Functional/Pick.php",
"src/Functional/Pluck.php",
"src/Functional/Poll.php",
"src/Functional/Product.php",
"src/Functional/Ratio.php",
"src/Functional/ReduceLeft.php",
"src/Functional/ReduceRight.php",
"src/Functional/Reindex.php",
"src/Functional/Reject.php",
"src/Functional/Retry.php",
"src/Functional/Select.php",
"src/Functional/SelectKeys.php",
"src/Functional/SequenceConstant.php",
"src/Functional/SequenceExponential.php",
"src/Functional/SequenceLinear.php",
"src/Functional/Some.php",
"src/Functional/Sort.php",
"src/Functional/Sum.php",
"src/Functional/SuppressError.php",
"src/Functional/Tap.php",
"src/Functional/Tail.php",
"src/Functional/TailRecursion.php",
"src/Functional/True.php",
"src/Functional/Truthy.php",
"src/Functional/Unique.php",
"src/Functional/With.php",
"src/Functional/Zip.php",
"src/Functional/ZipAll.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lars Strojny",
"email": "lstrojny@php.net",
"homepage": "http://usrportage.de"
},
{
"name": "Max Beutel",
"email": "nash12@gmail.com"
}
],
"description": "Functional primitives for PHP",
"keywords": [
"functional"
],
"time": "2018-01-03T10:08:50+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.7.0",
@ -1072,6 +1265,168 @@
],
"time": "2017-10-19T09:58:18+00:00"
},
{
"name": "phpbench/container",
"version": "1.2",
"source": {
"type": "git",
"url": "https://github.com/phpbench/container.git",
"reference": "c0e3cbf1cd8f867c70b029cb6d1b0b39fe6d409d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpbench/container/zipball/c0e3cbf1cd8f867c70b029cb6d1b0b39fe6d409d",
"reference": "c0e3cbf1cd8f867c70b029cb6d1b0b39fe6d409d",
"shasum": ""
},
"require": {
"psr/container": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.36"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"PhpBench\\DependencyInjection\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Leech",
"email": "daniel@dantleech.com"
}
],
"description": "Simple, configurable, service container.",
"time": "2018-02-12T08:08:59+00:00"
},
{
"name": "phpbench/dom",
"version": "0.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpbench/dom.git",
"reference": "b135378dd0004c05ba5446aeddaf0b83339c1c4c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpbench/dom/zipball/b135378dd0004c05ba5446aeddaf0b83339c1c4c",
"reference": "b135378dd0004c05ba5446aeddaf0b83339c1c4c",
"shasum": ""
},
"require": {
"ext-dom": "*",
"php": "^5.4|^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"PhpBench\\Dom\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Leech",
"email": "daniel@dantleech.com"
}
],
"description": "DOM wrapper to simplify working with the PHP DOM implementation",
"time": "2016-02-27T12:15:56+00:00"
},
{
"name": "phpbench/phpbench",
"version": "0.14.0",
"source": {
"type": "git",
"url": "https://github.com/phpbench/phpbench.git",
"reference": "ea2c7ca1cdbfa952b8d50c4f36fc233dbfabe3c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpbench/phpbench/zipball/ea2c7ca1cdbfa952b8d50c4f36fc233dbfabe3c9",
"reference": "ea2c7ca1cdbfa952b8d50c4f36fc233dbfabe3c9",
"shasum": ""
},
"require": {
"beberlei/assert": "^2.4",
"doctrine/annotations": "^1.2.7",
"ext-dom": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"lstrojny/functional-php": "1.0|^1.2.3",
"php": "^7.0",
"phpbench/container": "~1.0",
"phpbench/dom": "~0.2.0",
"seld/jsonlint": "^1.0",
"symfony/console": "^2.6|^3.0|^4.0",
"symfony/debug": "^2.4|^3.0|^4.0",
"symfony/filesystem": "^2.4|^3.0|^4.0",
"symfony/finder": "^2.4|^3.0|^4.0",
"symfony/options-resolver": "^2.6|^3.0|^4.0",
"symfony/process": "^2.1|^3.0|^4.0"
},
"require-dev": {
"doctrine/dbal": "^2.4",
"liip/rmt": "^1.2",
"padraic/phar-updater": "^1.0",
"phpstan/phpstan": "^0.8.5",
"phpunit/phpunit": "^6.0"
},
"suggest": {
"ext-xdebug": "For XDebug profiling extension."
},
"bin": [
"bin/phpbench"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"PhpBench\\": "lib/",
"PhpBench\\Extensions\\Dbal\\": "extensions/dbal/lib/",
"PhpBench\\Extensions\\XDebug\\": "extensions/xdebug/lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Leech",
"email": "daniel@dantleech.com"
}
],
"description": "PHP Benchmarking Framework",
"time": "2017-12-05T15:55:57+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "1.0.1",
@ -2457,6 +2812,55 @@
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2016-10-03T07:35:21+00:00"
},
{
"name": "seld/jsonlint",
"version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/jsonlint.git",
"reference": "d15f59a67ff805a44c50ea0516d2341740f81a38"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38",
"reference": "d15f59a67ff805a44c50ea0516d2341740f81a38",
"shasum": ""
},
"require": {
"php": "^5.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
},
"bin": [
"bin/jsonlint"
],
"type": "library",
"autoload": {
"psr-4": {
"Seld\\JsonLint\\": "src/Seld/JsonLint/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "JSON Linter",
"keywords": [
"json",
"linter",
"parser",
"validator"
],
"time": "2018-01-24T12:46:19+00:00"
},
{
"name": "slevomat/coding-standard",
"version": "4.2.1",

View File

@ -9,11 +9,9 @@
[![Coverage Status](https://coveralls.io/repos/github/php-ai/php-ml/badge.svg?branch=master)](https://coveralls.io/github/php-ai/php-ml?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/php-ai/php-ml/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/php-ai/php-ml/?branch=master)
<a href="http://www.yegor256.com/2016/10/23/award-2017.html">
<img src="http://www.yegor256.com/images/award/2017/winner-itcraftsmanpl.png"
style="width:203px;height:45px;"/></a>
![PHP-ML - Machine Learning library for PHP](assets/php-ml-logo.png)
<p align="center">
<img src="https://github.com/php-ai/php-ml/blob/master/docs/assets/php-ml-logo.png" />
</p>
Fresh approach to Machine Learning in PHP. Algorithms, Cross Validation, Neural Network, Preprocessing, Feature Extraction and much more in one library.
@ -35,6 +33,11 @@ $classifier->predict([3, 2]);
// return 'b'
```
## Awards
<a href="http://www.yegor256.com/2016/10/23/award-2017.html">
<img src="http://www.yegor256.com/images/award/2017/winner-itcraftsmanpl.png" width="400"/></a>
## Documentation
To find out how to use PHP-ML follow [Documentation](http://php-ml.readthedocs.org/).
@ -105,6 +108,7 @@ Example scripts are available in a separate repository [php-ai/php-ml-examples](
## Contribute
- Guide: [CONTRIBUTING.md](https://github.com/php-ai/php-ml/blob/master/CONTRIBUTING.md)
- Issue Tracker: [github.com/php-ai/php-ml/issues](https://github.com/php-ai/php-ml/issues)
- Source Code: [github.com/php-ai/php-ml](https://github.com/php-ai/php-ml)

17
phpbench.json Normal file
View File

@ -0,0 +1,17 @@
{
"bootstrap": "tests/Performance/bootstrap.php",
"path": "tests/Performance",
"reports": {
"time": {
"extends": "aggregate",
"title": "The Consumation of Time",
"cols": [ "subject", "mode", "mean", "rstdev", "diff"]
},
"memory": {
"extends": "aggregate",
"title": "The Memory Usage",
"cols": [ "subject", "mem_real", "mem_final", "mem_peak", "diff"],
"diff_col": "mem_peak"
}
}
}

View File

View File

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace Phpml\Tests\Performance\Regression;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
use PhpBench\Benchmark\Metadata\Annotations\Iterations;
use PhpBench\Benchmark\Metadata\Annotations\OutputTimeUnit;
use PhpBench\Benchmark\Metadata\Annotations\Revs;
use Phpml\Dataset\CsvDataset;
use Phpml\Dataset\Dataset;
use Phpml\Regression\LeastSquares;
/**
* @BeforeMethods({"init"})
* @OutputTimeUnit("seconds")
*/
final class LeastSquaresBench
{
/**
* @var Dataset
*/
private $dataset;
public function init(): void
{
$this->dataset = new CsvDataset(__DIR__.'/../Data/bike-sharing-hour.csv', 14);
}
/**
* @Revs(1)
* @Iterations(5)
*/
public function benchLeastSquaresTrain(): void
{
$leastSqueares = new LeastSquares();
$leastSqueares->train($this->dataset->getSamples(), $this->dataset->getTargets());
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
require __DIR__.'/../../vendor/autoload.php';
$dataDir = __DIR__.'/Data';
$datasets = [
'https://github.com/php-ai/php-ml-datasets/raw/0.1.0/datasets/bike-sharing-hour.csv',
];
foreach ($datasets as $dataset) {
$path = $dataDir.'/'.basename($dataset);
if (!file_exists($path)) {
if (!copy($dataset, $path)) {
die(sprintf('Failed to download %s', $dataset));
}
}
}