mirror of
https://github.com/Llewellynvdm/php-ml.git
synced 2024-11-25 06:17:34 +00:00
Update dev dependencies (#187)
* composer: update dev dependencies * phpstan fixes * phpstan fixes * phpstan fixes * phpstan fixes * drop probably forgotten humbug configs * apply cs * fix cs bug * compsoer: add coding standard and phsptan dev friendly scripts * ecs: add skipped errors * cs: fix PHP 7.1 * fix cs * ecs: exclude strict fixer that break code * ecs: cleanup commented sets * travis: use composer scripts for testing to prevent duplicated setup
This commit is contained in:
parent
a348111e97
commit
6660645ecd
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
/vendor/
|
/vendor/
|
||||||
humbuglog.*
|
|
||||||
.php_cs.cache
|
.php_cs.cache
|
||||||
/build
|
/build
|
||||||
|
@ -30,8 +30,8 @@ install:
|
|||||||
|
|
||||||
script:
|
script:
|
||||||
- vendor/bin/phpunit $PHPUNIT_FLAGS
|
- vendor/bin/phpunit $PHPUNIT_FLAGS
|
||||||
- if [[ $STATIC_ANALYSIS != "" ]]; then vendor/bin/ecs check src tests; fi
|
- if [[ $STATIC_ANALYSIS != "" ]]; then composer check-cs; fi
|
||||||
- if [[ $STATIC_ANALYSIS != "" ]]; then vendor/bin/phpstan.phar analyse src tests --level max --configuration phpstan.neon; fi
|
- if [[ $STATIC_ANALYSIS != "" ]]; then composer phpstan; fi
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- |
|
- |
|
||||||
|
@ -15,11 +15,10 @@
|
|||||||
"php": "^7.1"
|
"php": "^7.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^6.4",
|
"phpunit/phpunit": "^6.5",
|
||||||
"symplify/easy-coding-standard": "v3.0.0-RC3",
|
"symplify/easy-coding-standard": "^3.1",
|
||||||
"symplify/coding-standard": "v3.0.0-RC3",
|
"symplify/coding-standard": "^3.1",
|
||||||
"symplify/package-builder": "v3.0.0-RC3",
|
"phpstan/phpstan-shim": "^0.9"
|
||||||
"phpstan/phpstan-shim": "^0.8"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@ -30,5 +29,10 @@
|
|||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Phpml\\Tests\\": "tests/Phpml"
|
"Phpml\\Tests\\": "tests/Phpml"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"check-cs": "vendor/bin/ecs check src tests bin",
|
||||||
|
"fix-cs": "vendor/bin/ecs check src tests bin --fix",
|
||||||
|
"phpstan": "vendor/bin/phpstan.phar analyse src tests bin --level max --configuration phpstan.neon"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
744
composer.lock
generated
744
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,8 @@
|
|||||||
includes:
|
includes:
|
||||||
- vendor/symplify/easy-coding-standard/config/psr2.neon
|
- vendor/symplify/easy-coding-standard/config/psr2.neon
|
||||||
- vendor/symplify/easy-coding-standard/config/php70.neon
|
- vendor/symplify/easy-coding-standard/config/php71.neon
|
||||||
- vendor/symplify/easy-coding-standard/config/clean-code.neon
|
- vendor/symplify/easy-coding-standard/config/clean-code.neon
|
||||||
- vendor/symplify/easy-coding-standard/config/common/array.neon
|
- vendor/symplify/easy-coding-standard/config/common.neon
|
||||||
- vendor/symplify/easy-coding-standard/config/common/docblock.neon
|
|
||||||
- vendor/symplify/easy-coding-standard/config/common/namespaces.neon
|
|
||||||
- vendor/symplify/easy-coding-standard/config/common/control-structures.neon
|
|
||||||
|
|
||||||
# many errors, need help
|
|
||||||
#- vendor/symplify/easy-coding-standard/config/common/strict.neon
|
|
||||||
|
|
||||||
checkers:
|
checkers:
|
||||||
# spacing
|
# spacing
|
||||||
@ -33,13 +27,16 @@ checkers:
|
|||||||
- Symplify\CodingStandard\Fixer\Import\ImportNamespacedNameFixer
|
- Symplify\CodingStandard\Fixer\Import\ImportNamespacedNameFixer
|
||||||
- Symplify\CodingStandard\Fixer\Php\ClassStringToClassConstantFixer
|
- Symplify\CodingStandard\Fixer\Php\ClassStringToClassConstantFixer
|
||||||
- Symplify\CodingStandard\Fixer\Property\ArrayPropertyDefaultValueFixer
|
- Symplify\CodingStandard\Fixer\Property\ArrayPropertyDefaultValueFixer
|
||||||
- Symplify\CodingStandard\Fixer\ClassNotation\PropertyAndConstantSeparationFixer
|
|
||||||
- Symplify\CodingStandard\Fixer\ArrayNotation\StandaloneLineInMultilineArrayFixer
|
- Symplify\CodingStandard\Fixer\ArrayNotation\StandaloneLineInMultilineArrayFixer
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
exclude_checkers:
|
exclude_checkers:
|
||||||
# from strict.neon
|
# from strict.neon
|
||||||
- PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer
|
- PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer
|
||||||
|
- PhpCsFixer\Fixer\Strict\StrictComparisonFixer
|
||||||
|
# personal prefference
|
||||||
|
- PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
PhpCsFixer\Fixer\Alias\RandomApiMigrationFixer:
|
PhpCsFixer\Fixer\Alias\RandomApiMigrationFixer:
|
||||||
# random_int() breaks code
|
# random_int() breaks code
|
||||||
@ -47,6 +44,15 @@ parameters:
|
|||||||
SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff:
|
SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff:
|
||||||
# magic calls
|
# magic calls
|
||||||
- src/Phpml/Preprocessing/Normalizer.php
|
- src/Phpml/Preprocessing/Normalizer.php
|
||||||
|
PhpCsFixer\Fixer\StringNotation\ExplicitStringVariableFixer:
|
||||||
|
# bugged
|
||||||
|
- src/Phpml/Classification/DecisionTree/DecisionTreeLeaf.php
|
||||||
|
Symplify\CodingStandard\Fixer\Commenting\RemoveUselessDocBlockFixer:
|
||||||
|
# bug in fixer
|
||||||
|
- src/Phpml/Math/LinearAlgebra/LUDecomposition.php
|
||||||
|
PhpCsFixer\Fixer\FunctionNotation\VoidReturnFixer:
|
||||||
|
# covariant return types
|
||||||
|
- src/Phpml/Classification/Linear/Perceptron.php
|
||||||
|
|
||||||
skip_codes:
|
skip_codes:
|
||||||
# missing typehints
|
# missing typehints
|
||||||
@ -56,3 +62,4 @@ parameters:
|
|||||||
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingTraversableReturnTypeHintSpecification
|
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingTraversableReturnTypeHintSpecification
|
||||||
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingPropertyTypeHint
|
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingPropertyTypeHint
|
||||||
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingTraversablePropertyTypeHintSpecification
|
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingTraversablePropertyTypeHintSpecification
|
||||||
|
- PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\AssignmentInConditionSniff.Found
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"source": {
|
|
||||||
"directories": [
|
|
||||||
"src"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"timeout": 10,
|
|
||||||
"logs": {
|
|
||||||
"text": "humbuglog.txt"
|
|
||||||
}
|
|
||||||
}
|
|
18
phpstan.neon
18
phpstan.neon
@ -1,19 +1,15 @@
|
|||||||
parameters:
|
parameters:
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
- '#Phpml\\Dataset\\FilesDataset::__construct\(\) does not call parent constructor from Phpml\\Dataset\\ArrayDataset#'
|
- '#Phpml\\Dataset\\FilesDataset::__construct\(\) does not call parent constructor from Phpml\\Dataset\\ArrayDataset#'
|
||||||
- '#Parameter \#2 \$predictedLabels of static method Phpml\\Metric\\Accuracy::score\(\) expects mixed\[\], mixed\[\]\|string given#'
|
|
||||||
|
|
||||||
# should be always defined
|
# mocks
|
||||||
- '#Undefined variable: \$j#'
|
- '#PHPUnit_Framework_MockObject_MockObject#'
|
||||||
|
|
||||||
# bugged
|
# wide range cases
|
||||||
- '#expects [a-z\\\|\[\]]*, [a-z\\\|\(\)\[\]]*\[\] given#'
|
- '#Call to function count\(\) with argument type array<int>\|Phpml\\Clustering\\KMeans\\Point will always result in number 1#'
|
||||||
|
- '#Parameter \#1 \$coordinates of class Phpml\\Clustering\\KMeans\\Point constructor expects array, array<int>\|Phpml\\Clustering\\KMeans\\Point given#'
|
||||||
# mock
|
|
||||||
- '#Parameter \#1 \$node of class Phpml\\NeuralNetwork\\Node\\Neuron\\Synapse constructor expects Phpml\\NeuralNetwork\\Node, Phpml\\NeuralNetwork\\Node\\Neuron\|PHPUnit_Framework_MockObject_MockObject given#'
|
|
||||||
- '#Parameter \#1 \$(activationFunction|synapse) of class Phpml\\NeuralNetwork\\Node\\Neuron constructor expects Phpml\\NeuralNetwork\\ActivationFunction|null, Phpml\\NeuralNetwork\\ActivationFunction\\BinaryStep|PHPUnit_Framework_MockObject_MockObject given#'
|
|
||||||
|
|
||||||
# probably known value
|
# probably known value
|
||||||
|
- '#Variable \$j might not be defined#'
|
||||||
- '#Method Phpml\\Classification\\DecisionTree::getBestSplit\(\) should return Phpml\\Classification\\DecisionTree\\DecisionTreeLeaf but returns Phpml\\Classification\\DecisionTree\\DecisionTreeLeaf\|null#'
|
- '#Method Phpml\\Classification\\DecisionTree::getBestSplit\(\) should return Phpml\\Classification\\DecisionTree\\DecisionTreeLeaf but returns Phpml\\Classification\\DecisionTree\\DecisionTreeLeaf\|null#'
|
||||||
- '#Method Phpml\\Classification\\Linear\\DecisionStump::getBestNumericalSplit\(\) should return mixed\[\] but returns \(float\|int\|mixed\|string\)\[\]\|null#'
|
- '#Call to an undefined method Phpml\\Helper\\Optimizer\\Optimizer::getCostValues\(\)#'
|
||||||
- '#Method Phpml\\Classification\\Linear\\DecisionStump::getBestNominalSplit\(\) should return mixed\[\] but returns mixed\[\]\|null#'
|
|
||||||
|
@ -64,9 +64,9 @@ class DecisionTree implements Classifier
|
|||||||
private $featureImportances;
|
private $featureImportances;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array|null
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $columnNames;
|
private $columnNames = [];
|
||||||
|
|
||||||
public function __construct(int $maxDepth = 10)
|
public function __construct(int $maxDepth = 10)
|
||||||
{
|
{
|
||||||
@ -89,7 +89,7 @@ class DecisionTree implements Classifier
|
|||||||
|
|
||||||
// If column names are given or computed before, then there is no
|
// If column names are given or computed before, then there is no
|
||||||
// need to init it and accidentally remove the previous given names
|
// need to init it and accidentally remove the previous given names
|
||||||
if ($this->columnNames === null) {
|
if ($this->columnNames === []) {
|
||||||
$this->columnNames = range(0, $this->featureCount - 1);
|
$this->columnNames = range(0, $this->featureCount - 1);
|
||||||
} elseif (count($this->columnNames) > $this->featureCount) {
|
} elseif (count($this->columnNames) > $this->featureCount) {
|
||||||
$this->columnNames = array_slice($this->columnNames, 0, $this->featureCount);
|
$this->columnNames = array_slice($this->columnNames, 0, $this->featureCount);
|
||||||
@ -380,9 +380,9 @@ class DecisionTree implements Classifier
|
|||||||
$median = Mean::median($values);
|
$median = Mean::median($values);
|
||||||
foreach ($values as &$value) {
|
foreach ($values as &$value) {
|
||||||
if ($value <= $median) {
|
if ($value <= $median) {
|
||||||
$value = "<= $median";
|
$value = "<= ${median}";
|
||||||
} else {
|
} else {
|
||||||
$value = "> $median";
|
$value = "> ${median}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ class DecisionTreeLeaf
|
|||||||
public function getHTML($columnNames = null): string
|
public function getHTML($columnNames = null): string
|
||||||
{
|
{
|
||||||
if ($this->isTerminal) {
|
if ($this->isTerminal) {
|
||||||
$value = "<b>$this->classValue</b>";
|
$value = "<b>${this}->classValue</b>";
|
||||||
} else {
|
} else {
|
||||||
$value = $this->value;
|
$value = $this->value;
|
||||||
if ($columnNames !== null) {
|
if ($columnNames !== null) {
|
||||||
@ -132,13 +132,13 @@ class DecisionTreeLeaf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!preg_match('/^[<>=]{1,2}/', (string) $value)) {
|
if (!preg_match('/^[<>=]{1,2}/', (string) $value)) {
|
||||||
$value = "=$value";
|
$value = "=${value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = "<b>$col $value</b><br>Gini: ".number_format($this->giniIndex, 2);
|
$value = "<b>${col} ${value}</b><br>Gini: ".number_format($this->giniIndex, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$str = "<table ><tr><td colspan=3 align=center style='border:1px solid;'>$value</td></tr>";
|
$str = "<table ><tr><td colspan=3 align=center style='border:1px solid;'>${value}</td></tr>";
|
||||||
|
|
||||||
if ($this->leftLeaf || $this->rightLeaf) {
|
if ($this->leftLeaf || $this->rightLeaf) {
|
||||||
$str .= '<tr>';
|
$str .= '<tr>';
|
||||||
|
@ -86,7 +86,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
|
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return "IF $this->column $this->operator $this->value ".
|
return "IF ${this}->column ${this}->operator ${this}->value ".
|
||||||
'THEN '.$this->binaryLabels[0].' '.
|
'THEN '.$this->binaryLabels[0].' '.
|
||||||
'ELSE '.$this->binaryLabels[1];
|
'ELSE '.$this->binaryLabels[1];
|
||||||
}
|
}
|
||||||
@ -176,14 +176,14 @@ class DecisionStump extends WeightedClassifier
|
|||||||
$maxValue = max($values);
|
$maxValue = max($values);
|
||||||
$stepSize = ($maxValue - $minValue) / $this->numSplitCount;
|
$stepSize = ($maxValue - $minValue) / $this->numSplitCount;
|
||||||
|
|
||||||
$split = null;
|
$split = [];
|
||||||
|
|
||||||
foreach (['<=', '>'] as $operator) {
|
foreach (['<=', '>'] as $operator) {
|
||||||
// Before trying all possible split points, let's first try
|
// Before trying all possible split points, let's first try
|
||||||
// the average value for the cut point
|
// the average value for the cut point
|
||||||
$threshold = array_sum($values) / (float) count($values);
|
$threshold = array_sum($values) / (float) count($values);
|
||||||
[$errorRate, $prob] = $this->calculateErrorRate($targets, $threshold, $operator, $values);
|
[$errorRate, $prob] = $this->calculateErrorRate($targets, $threshold, $operator, $values);
|
||||||
if ($split == null || $errorRate < $split['trainingErrorRate']) {
|
if ($split === [] || $errorRate < $split['trainingErrorRate']) {
|
||||||
$split = [
|
$split = [
|
||||||
'value' => $threshold,
|
'value' => $threshold,
|
||||||
'operator' => $operator,
|
'operator' => $operator,
|
||||||
@ -218,13 +218,13 @@ class DecisionStump extends WeightedClassifier
|
|||||||
$valueCounts = array_count_values($values);
|
$valueCounts = array_count_values($values);
|
||||||
$distinctVals = array_keys($valueCounts);
|
$distinctVals = array_keys($valueCounts);
|
||||||
|
|
||||||
$split = null;
|
$split = [];
|
||||||
|
|
||||||
foreach (['=', '!='] as $operator) {
|
foreach (['=', '!='] as $operator) {
|
||||||
foreach ($distinctVals as $val) {
|
foreach ($distinctVals as $val) {
|
||||||
[$errorRate, $prob] = $this->calculateErrorRate($targets, $val, $operator, $values);
|
[$errorRate, $prob] = $this->calculateErrorRate($targets, $val, $operator, $values);
|
||||||
|
|
||||||
if ($split === null || $split['trainingErrorRate'] < $errorRate) {
|
if ($split === [] || $split['trainingErrorRate'] < $errorRate) {
|
||||||
$split = [
|
$split = [
|
||||||
'value' => $val,
|
'value' => $val,
|
||||||
'operator' => $operator,
|
'operator' => $operator,
|
||||||
|
@ -34,7 +34,7 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
protected $featureCount = 0;
|
protected $featureCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array|null
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $weights = [];
|
protected $weights = [];
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
$this->labels = [];
|
$this->labels = [];
|
||||||
$this->optimizer = null;
|
$this->optimizer = null;
|
||||||
$this->featureCount = 0;
|
$this->featureCount = 0;
|
||||||
$this->weights = null;
|
$this->weights = [];
|
||||||
$this->costValues = [];
|
$this->costValues = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
* Executes a Gradient Descent algorithm for
|
* Executes a Gradient Descent algorithm for
|
||||||
* the given cost function
|
* the given cost function
|
||||||
*/
|
*/
|
||||||
protected function runGradientDescent(array $samples, array $targets, Closure $gradientFunc, bool $isBatch = false): void
|
protected function runGradientDescent(array $samples, array $targets, Closure $gradientFunc, bool $isBatch = false)
|
||||||
{
|
{
|
||||||
$class = $isBatch ? GD::class : StochasticGD::class;
|
$class = $isBatch ? GD::class : StochasticGD::class;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class FuzzyCMeans implements Clusterer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array|Point[] $samples
|
* @param Point[]|int[][] $samples
|
||||||
*/
|
*/
|
||||||
public function cluster(array $samples): array
|
public function cluster(array $samples): array
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ class StopWords
|
|||||||
|
|
||||||
public static function factory(string $language = 'English'): self
|
public static function factory(string $language = 'English'): self
|
||||||
{
|
{
|
||||||
$className = __NAMESPACE__."\\StopWords\\$language";
|
$className = __NAMESPACE__."\\StopWords\\${language}";
|
||||||
|
|
||||||
if (!class_exists($className)) {
|
if (!class_exists($className)) {
|
||||||
throw InvalidArgumentException::invalidStopWordsLanguage($language);
|
throw InvalidArgumentException::invalidStopWordsLanguage($language);
|
||||||
|
@ -164,7 +164,7 @@ trait OneVsRest
|
|||||||
*/
|
*/
|
||||||
private function binarizeTargets(array $targets, $label): array
|
private function binarizeTargets(array $targets, $label): array
|
||||||
{
|
{
|
||||||
$notLabel = "not_$label";
|
$notLabel = "not_${label}";
|
||||||
foreach ($targets as $key => $target) {
|
foreach ($targets as $key => $target) {
|
||||||
$targets[$key] = $target == $label ? $label : $notLabel;
|
$targets[$key] = $target == $label ? $label : $notLabel;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ abstract class Optimizer
|
|||||||
public function setInitialTheta(array $theta)
|
public function setInitialTheta(array $theta)
|
||||||
{
|
{
|
||||||
if (count($theta) != $this->dimensions) {
|
if (count($theta) != $this->dimensions) {
|
||||||
throw new Exception("Number of values in the weights array should be $this->dimensions");
|
throw new Exception("Number of values in the weights array should be ${this}->dimensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->theta = $theta;
|
$this->theta = $theta;
|
||||||
|
@ -10,7 +10,7 @@ use IteratorAggregate;
|
|||||||
class Set implements IteratorAggregate
|
class Set implements IteratorAggregate
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string[]|int[]|float[]
|
* @var string[]|int[]|float[]|bool[]
|
||||||
*/
|
*/
|
||||||
private $elements = [];
|
private $elements = [];
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ class Set implements IteratorAggregate
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[]|int[]|float[]
|
* @return string[]|int[]|float[]|bool[]
|
||||||
*/
|
*/
|
||||||
public function toArray(): array
|
public function toArray(): array
|
||||||
{
|
{
|
||||||
@ -160,9 +160,9 @@ class Set implements IteratorAggregate
|
|||||||
/**
|
/**
|
||||||
* Removes duplicates and rewrites index.
|
* Removes duplicates and rewrites index.
|
||||||
*
|
*
|
||||||
* @param string[]|int[]|float[] $elements
|
* @param string[]|int[]|float[]|bool[] $elements
|
||||||
*
|
*
|
||||||
* @return string[]|int[]|float[]
|
* @return string[]|int[]|float[]|bool[]
|
||||||
*/
|
*/
|
||||||
private static function sanitize(array $elements): array
|
private static function sanitize(array $elements): array
|
||||||
{
|
{
|
||||||
|
@ -15,14 +15,14 @@ class Backpropagation
|
|||||||
private $learningRate;
|
private $learningRate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array|null
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $sigmas;
|
private $sigmas = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array|null
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $prevSigmas;
|
private $prevSigmas = [];
|
||||||
|
|
||||||
public function __construct(float $learningRate)
|
public function __construct(float $learningRate)
|
||||||
{
|
{
|
||||||
@ -57,8 +57,8 @@ class Backpropagation
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clean some memory (also it helps make MLP persistency & children more maintainable).
|
// Clean some memory (also it helps make MLP persistency & children more maintainable).
|
||||||
$this->sigmas = null;
|
$this->sigmas = [];
|
||||||
$this->prevSigmas = null;
|
$this->prevSigmas = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getSigma(Neuron $neuron, int $targetClass, int $key, bool $lastLayer): float
|
private function getSigma(Neuron $neuron, int $targetClass, int $key, bool $lastLayer): float
|
||||||
|
@ -10,6 +10,7 @@ use Phpml\Math\Matrix;
|
|||||||
class LeastSquares implements Regression
|
class LeastSquares implements Regression
|
||||||
{
|
{
|
||||||
use Predictable;
|
use Predictable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace tests\Phpml\Classification\Linear;
|
namespace Phpml\Tests\Classification\Linear;
|
||||||
|
|
||||||
use Phpml\Classification\Linear\LogisticRegression;
|
use Phpml\Classification\Linear\LogisticRegression;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -55,12 +55,12 @@ class LogisticRegressionTest extends TestCase
|
|||||||
|
|
||||||
$zero = $method->invoke($predictor, [0.1, 0.1], 0);
|
$zero = $method->invoke($predictor, [0.1, 0.1], 0);
|
||||||
$one = $method->invoke($predictor, [0.1, 0.1], 1);
|
$one = $method->invoke($predictor, [0.1, 0.1], 1);
|
||||||
$this->assertEquals(1, $zero + $one, null, 1e-6);
|
$this->assertEquals(1, $zero + $one, '', 1e-6);
|
||||||
$this->assertTrue($zero > $one);
|
$this->assertTrue($zero > $one);
|
||||||
|
|
||||||
$zero = $method->invoke($predictor, [0.9, 0.9], 0);
|
$zero = $method->invoke($predictor, [0.9, 0.9], 0);
|
||||||
$one = $method->invoke($predictor, [0.9, 0.9], 1);
|
$one = $method->invoke($predictor, [0.9, 0.9], 1);
|
||||||
$this->assertEquals(1, $zero + $one, null, 1e-6);
|
$this->assertEquals(1, $zero + $one, '', 1e-6);
|
||||||
$this->assertTrue($zero < $one);
|
$this->assertTrue($zero < $one);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ class LogisticRegressionTest extends TestCase
|
|||||||
$two = $method->invoke($predictor, [3.0, 9.5], 2);
|
$two = $method->invoke($predictor, [3.0, 9.5], 2);
|
||||||
$not_two = $method->invoke($predictor, [3.0, 9.5], 'not_2');
|
$not_two = $method->invoke($predictor, [3.0, 9.5], 'not_2');
|
||||||
|
|
||||||
$this->assertEquals(1, $zero + $not_zero, null, 1e-6);
|
$this->assertEquals(1, $zero + $not_zero, '', 1e-6);
|
||||||
$this->assertEquals(1, $one + $not_one, null, 1e-6);
|
$this->assertEquals(1, $one + $not_one, '', 1e-6);
|
||||||
$this->assertEquals(1, $two + $not_two, null, 1e-6);
|
$this->assertEquals(1, $two + $not_two, '', 1e-6);
|
||||||
$this->assertTrue($zero < $two);
|
$this->assertTrue($zero < $two);
|
||||||
$this->assertTrue($one < $two);
|
$this->assertTrue($one < $two);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class AccuracyTest extends TestCase
|
|||||||
$classifier = new SVC(Kernel::RBF);
|
$classifier = new SVC(Kernel::RBF);
|
||||||
$classifier->train($dataset->getTrainSamples(), $dataset->getTrainLabels());
|
$classifier->train($dataset->getTrainSamples(), $dataset->getTrainLabels());
|
||||||
|
|
||||||
$predicted = $classifier->predict($dataset->getTestSamples());
|
$predicted = (array) $classifier->predict($dataset->getTestSamples());
|
||||||
|
|
||||||
$accuracy = Accuracy::score($dataset->getTestLabels(), $predicted);
|
$accuracy = Accuracy::score($dataset->getTestLabels(), $predicted);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace tests\Phpml\NeuralNetwork\Network;
|
namespace Phpml\Tests\NeuralNetwork\Network;
|
||||||
|
|
||||||
use Phpml\NeuralNetwork\Network\MultilayerPerceptron;
|
use Phpml\NeuralNetwork\Network\MultilayerPerceptron;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@ -11,6 +11,7 @@ class MultilayerPerceptronTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testLearningRateSetter(): void
|
public function testLearningRateSetter(): void
|
||||||
{
|
{
|
||||||
|
/** @var MultilayerPerceptron $mlp */
|
||||||
$mlp = $this->getMockForAbstractClass(
|
$mlp = $this->getMockForAbstractClass(
|
||||||
MultilayerPerceptron::class,
|
MultilayerPerceptron::class,
|
||||||
[5, [3], [0, 1], 1000, null, 0.42]
|
[5, [3], [0, 1], 1000, null, 0.42]
|
||||||
|
Loading…
Reference in New Issue
Block a user