From 3e23ef45f45cbe029c9713b1fea8f1d13d657223 Mon Sep 17 00:00:00 2001 From: Andrew DalPino <me@andrewdalpino.com> Date: Tue, 6 Dec 2022 16:59:52 -0600 Subject: [PATCH 1/6] Fix Grid Search best model selection --- CHANGELOG.md | 3 +++ composer.json | 5 ++++- src/GridSearch.php | 2 +- tests/GridSearchTest.php | 8 ++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 383416759..f1d291251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +- 1.3.5 + - Fix Grid Search best model selection + - 1.3.4 - Fix Decision Tree max height terminating condition diff --git a/composer.json b/composer.json index 43b6e605f..7268c22bf 100644 --- a/composer.json +++ b/composer.json @@ -92,7 +92,10 @@ "config": { "preferred-install": "dist", "sort-packages": true, - "process-timeout": 3000 + "process-timeout": 3000, + "allow-plugins": { + "phpstan/extension-installer": true + } }, "funding": [ { diff --git a/src/GridSearch.php b/src/GridSearch.php index fd32414cb..eb3ad3de4 100644 --- a/src/GridSearch.php +++ b/src/GridSearch.php @@ -284,7 +284,7 @@ public function train(Dataset $dataset) : void $scores = $this->backend->process(); - array_multisort($scores, $combinations, SORT_DESC); + array_multisort($scores, SORT_DESC, $combinations); $best = reset($combinations) ?: []; diff --git a/tests/GridSearchTest.php b/tests/GridSearchTest.php index b03e07282..c593f6714 100644 --- a/tests/GridSearchTest.php +++ b/tests/GridSearchTest.php @@ -140,5 +140,13 @@ public function trainPredictBest() : void $score = $this->metric->score($predictions, $testing->labels()); $this->assertGreaterThanOrEqual(self::MIN_SCORE, $score); + + $expectedBest = [ + 'k' => 10, + 'weighted' => true, + 'kernel' => new Manhattan(), + ]; + + $this->assertEquals($expectedBest, $this->estimator->base()->params()); } } From 48ec79b2ecae73247646d63e8b164565651c8b9a Mon Sep 17 00:00:00 2001 From: Andrew DalPino <me@andrewdalpino.com> Date: Tue, 6 Dec 2022 17:31:30 -0600 Subject: [PATCH 2/6] Add deltas to floating point assertions --- tests/GridSearchTest.php | 4 ++-- tests/Kernels/Distance/CosineTest.php | 2 +- .../HyperbolicTangentTest.php | 4 ++-- .../NeuralNet/ActivationFunctions/SiLUTest.php | 4 ++-- .../ActivationFunctions/SoftmaxTest.php | 4 ++-- .../CostFunctions/CrossEntropyTest.php | 4 ++-- .../NeuralNet/CostFunctions/HuberLossTest.php | 4 ++-- .../CostFunctions/RelativeEntropyTest.php | 4 ++-- tests/NeuralNet/Layers/BatchNormTest.php | 12 ++++++------ tests/NeuralNet/Layers/BinaryTest.php | 6 +++--- tests/NeuralNet/Layers/ContinuousTest.php | 6 +++--- tests/NeuralNet/Layers/DenseTest.php | 6 +++--- tests/NeuralNet/Layers/MulticlassTest.php | 6 +++--- tests/NeuralNet/Layers/NoiseTest.php | 18 +++++++++--------- tests/NeuralNet/Optimizers/AdaMaxTest.php | 2 +- .../GaussianRandomProjectorTest.php | 2 +- tests/Transformers/MinMaxNormalizerTest.php | 2 +- .../Transformers/SparseRandomProjectorTest.php | 2 +- tests/Transformers/ZScaleStandardizerTest.php | 2 +- 19 files changed, 47 insertions(+), 47 deletions(-) diff --git a/tests/GridSearchTest.php b/tests/GridSearchTest.php index c593f6714..a2a2c736a 100644 --- a/tests/GridSearchTest.php +++ b/tests/GridSearchTest.php @@ -27,9 +27,9 @@ */ class GridSearchTest extends TestCase { - protected const TRAIN_SIZE = 300; + protected const TRAIN_SIZE = 512; - protected const TEST_SIZE = 10; + protected const TEST_SIZE = 256; protected const MIN_SCORE = 0.9; diff --git a/tests/Kernels/Distance/CosineTest.php b/tests/Kernels/Distance/CosineTest.php index 035722dad..a576b69d8 100644 --- a/tests/Kernels/Distance/CosineTest.php +++ b/tests/Kernels/Distance/CosineTest.php @@ -48,7 +48,7 @@ public function compute(array $a, array $b, float $expected) : void $distance = $this->kernel->compute($a, $b); $this->assertGreaterThanOrEqual(0.0, $distance); - $this->assertEquals($expected, $distance); + $this->assertEqualsWithDelta($expected, $distance, 1e-8); } /** diff --git a/tests/NeuralNet/ActivationFunctions/HyperbolicTangentTest.php b/tests/NeuralNet/ActivationFunctions/HyperbolicTangentTest.php index 322305175..063f892ce 100644 --- a/tests/NeuralNet/ActivationFunctions/HyperbolicTangentTest.php +++ b/tests/NeuralNet/ActivationFunctions/HyperbolicTangentTest.php @@ -47,7 +47,7 @@ public function activate(Matrix $input, array $expected) : void { $activations = $this->activationFn->activate($input)->asArray(); - $this->assertEquals($expected, $activations); + $this->assertEqualsWithDelta($expected, $activations, 1e-8); } /** @@ -90,7 +90,7 @@ public function differentiate(Matrix $input, Matrix $activations, array $expecte { $derivatives = $this->activationFn->differentiate($input, $activations)->asArray(); - $this->assertEquals($expected, $derivatives); + $this->assertEqualsWithDelta($expected, $derivatives, 1e-8); } /** diff --git a/tests/NeuralNet/ActivationFunctions/SiLUTest.php b/tests/NeuralNet/ActivationFunctions/SiLUTest.php index 4728f69ab..b44aa94d2 100644 --- a/tests/NeuralNet/ActivationFunctions/SiLUTest.php +++ b/tests/NeuralNet/ActivationFunctions/SiLUTest.php @@ -47,7 +47,7 @@ public function compute(Matrix $input, array $expected) : void { $activations = $this->activationFn->activate($input)->asArray(); - $this->assertEquals($expected, $activations); + $this->assertEqualsWithDelta($expected, $activations, 1e-8); } /** @@ -90,7 +90,7 @@ public function differentiate(Matrix $input, Matrix $activations, array $expecte { $derivatives = $this->activationFn->differentiate($input, $activations)->asArray(); - $this->assertEquals($expected, $derivatives); + $this->assertEqualsWithDelta($expected, $derivatives, 1e-8); } /** diff --git a/tests/NeuralNet/ActivationFunctions/SoftmaxTest.php b/tests/NeuralNet/ActivationFunctions/SoftmaxTest.php index 0f0419b5e..b0165742b 100644 --- a/tests/NeuralNet/ActivationFunctions/SoftmaxTest.php +++ b/tests/NeuralNet/ActivationFunctions/SoftmaxTest.php @@ -47,7 +47,7 @@ public function activate(Matrix $input, array $expected) : void { $activations = $this->activationFn->activate($input)->asArray(); - $this->assertEquals($expected, $activations); + $this->assertEqualsWithDelta($expected, $activations, 1e-8); } /** @@ -94,7 +94,7 @@ public function differentiate(Matrix $input, Matrix $activations, array $expecte { $derivatives = $this->activationFn->differentiate($input, $activations)->asArray(); - $this->assertEquals($expected, $derivatives); + $this->assertEqualsWithDelta($expected, $derivatives, 1e-8); } /** diff --git a/tests/NeuralNet/CostFunctions/CrossEntropyTest.php b/tests/NeuralNet/CostFunctions/CrossEntropyTest.php index bdfff5069..f03341a65 100644 --- a/tests/NeuralNet/CostFunctions/CrossEntropyTest.php +++ b/tests/NeuralNet/CostFunctions/CrossEntropyTest.php @@ -48,7 +48,7 @@ public function compute(Matrix $output, Matrix $target, float $expected) : void { $loss = $this->costFn->compute($output, $target); - $this->assertEquals($expected, $loss); + $this->assertEqualsWithDelta($expected, $loss, 1e-8); } /** @@ -113,7 +113,7 @@ public function differentiate(Matrix $output, Matrix $target, array $expected) : { $gradient = $this->costFn->differentiate($output, $target)->asArray(); - $this->assertEquals($expected, $gradient); + $this->assertEqualsWithDelta($expected, $gradient, 1e-8); } /** diff --git a/tests/NeuralNet/CostFunctions/HuberLossTest.php b/tests/NeuralNet/CostFunctions/HuberLossTest.php index 6cd929aad..eeba46db5 100644 --- a/tests/NeuralNet/CostFunctions/HuberLossTest.php +++ b/tests/NeuralNet/CostFunctions/HuberLossTest.php @@ -48,7 +48,7 @@ public function compute(Matrix $output, Matrix $target, float $expected) : void { $loss = $this->costFn->compute($output, $target); - $this->assertEquals($expected, $loss); + $this->assertEqualsWithDelta($expected, $loss, 1e-8); } /** @@ -107,7 +107,7 @@ public function differentiate(Matrix $output, Matrix $target, array $expected) : { $gradient = $this->costFn->differentiate($output, $target)->asArray(); - $this->assertEquals($expected, $gradient); + $this->assertEqualsWithDelta($expected, $gradient, 1e-8); } /** diff --git a/tests/NeuralNet/CostFunctions/RelativeEntropyTest.php b/tests/NeuralNet/CostFunctions/RelativeEntropyTest.php index 459d9e453..6318ae97d 100644 --- a/tests/NeuralNet/CostFunctions/RelativeEntropyTest.php +++ b/tests/NeuralNet/CostFunctions/RelativeEntropyTest.php @@ -48,7 +48,7 @@ public function compute(Matrix $output, Matrix $target, float $expected) : void { $loss = $this->costFn->compute($output, $target); - $this->assertEquals($expected, $loss); + $this->assertEqualsWithDelta($expected, $loss, 1e-8); } /** @@ -113,7 +113,7 @@ public function differentiate(Matrix $output, Matrix $target, array $expected) : { $gradient = $this->costFn->differentiate($output, $target)->asArray(); - $this->assertEquals($expected, $gradient); + $this->assertEqualsWithDelta($expected, $gradient, 1e-8); } /** diff --git a/tests/NeuralNet/Layers/BatchNormTest.php b/tests/NeuralNet/Layers/BatchNormTest.php index 05beff7d0..53513c3d6 100644 --- a/tests/NeuralNet/Layers/BatchNormTest.php +++ b/tests/NeuralNet/Layers/BatchNormTest.php @@ -51,9 +51,9 @@ protected function setUp() : void $this->fanIn = 3; $this->input = Matrix::quick([ - [1., 2.5, -0.1], - [0.1, 0., 3.], - [0.002, -6., -0.5], + [1.0, 2.5, -0.1], + [0.1, 00., 3.0], + [0.002, -6.0, -0.5], ]); $this->prevGrad = new Deferred(function () { @@ -98,7 +98,7 @@ public function initializeForwardBackInfer() : void $forward = $this->layer->forward($this->input); $this->assertInstanceOf(Matrix::class, $forward); - $this->assertEquals($expected, $forward->asArray()); + $this->assertEqualsWithDelta($expected, $forward->asArray(), 1e-8); $gradient = $this->layer->back($this->prevGrad, $this->optimizer)->compute(); @@ -109,7 +109,7 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $gradient); - $this->assertEquals($expected, $gradient->asArray()); + $this->assertEqualsWithDelta($expected, $gradient->asArray(), 1e-8); $expected = [ [-0.12607831595417437, 1.2804902385302876, -1.1575619225761131], @@ -120,6 +120,6 @@ public function initializeForwardBackInfer() : void $infer = $this->layer->infer($this->input); $this->assertInstanceOf(Matrix::class, $infer); - $this->assertEquals($expected, $infer->asArray()); + $this->assertEqualsWithDelta($expected, $infer->asArray(), 1e-8); } } diff --git a/tests/NeuralNet/Layers/BinaryTest.php b/tests/NeuralNet/Layers/BinaryTest.php index 9ad32a13a..ec3b89ba4 100644 --- a/tests/NeuralNet/Layers/BinaryTest.php +++ b/tests/NeuralNet/Layers/BinaryTest.php @@ -83,7 +83,7 @@ public function initializeForwardBackInfer() : void $forward = $this->layer->forward($this->input); $this->assertInstanceOf(Matrix::class, $forward); - $this->assertEquals($expected, $forward->asArray()); + $this->assertEqualsWithDelta($expected, $forward->asArray(), 1e-8); [$computation, $loss] = $this->layer->back($this->labels, $this->optimizer); @@ -97,7 +97,7 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $gradient); - $this->assertEquals($expected, $gradient->asArray()); + $this->assertEqualsWithDelta($expected, $gradient->asArray(), 1e-8); $expected = [ [0.7310585786300049, 0.9241418199787566, 0.47502081252106], @@ -106,6 +106,6 @@ public function initializeForwardBackInfer() : void $infer = $this->layer->infer($this->input); $this->assertInstanceOf(Matrix::class, $infer); - $this->assertEquals($expected, $infer->asArray()); + $this->assertEqualsWithDelta($expected, $infer->asArray(), 1e-8); } } diff --git a/tests/NeuralNet/Layers/ContinuousTest.php b/tests/NeuralNet/Layers/ContinuousTest.php index 2dba125b4..f992e0137 100644 --- a/tests/NeuralNet/Layers/ContinuousTest.php +++ b/tests/NeuralNet/Layers/ContinuousTest.php @@ -83,7 +83,7 @@ public function initializeForwardBackInfer() : void $forward = $this->layer->forward($this->input); $this->assertInstanceOf(Matrix::class, $forward); - $this->assertEquals($expected, $forward->asArray()); + $this->assertEqualsWithDelta($expected, $forward->asArray(), 1e-8); [$computation, $loss] = $this->layer->back($this->labels, $this->optimizer); @@ -97,7 +97,7 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $gradient); - $this->assertEquals($expected, $gradient->asArray()); + $this->assertEqualsWithDelta($expected, $gradient->asArray(), 1e-8); $expected = [ [2.5, 0.0, -6.0], @@ -106,6 +106,6 @@ public function initializeForwardBackInfer() : void $infer = $this->layer->infer($this->input); $this->assertInstanceOf(Matrix::class, $infer); - $this->assertEquals($expected, $infer->asArray()); + $this->assertEqualsWithDelta($expected, $infer->asArray(), 1e-8); } } diff --git a/tests/NeuralNet/Layers/DenseTest.php b/tests/NeuralNet/Layers/DenseTest.php index 4720295c9..0f67277c3 100644 --- a/tests/NeuralNet/Layers/DenseTest.php +++ b/tests/NeuralNet/Layers/DenseTest.php @@ -101,7 +101,7 @@ public function initializeForwardBackInfer() : void $forward = $this->layer->forward($this->input); $this->assertInstanceOf(Matrix::class, $forward); - $this->assertEquals($expected, $forward->asArray()); + $this->assertEqualsWithDelta($expected, $forward->asArray(), 1e-8); $gradient = $this->layer->back($this->prevGrad, $this->optimizer)->compute(); @@ -112,7 +112,7 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $gradient); - $this->assertEquals($expected, $gradient->asArray()); + $this->assertEqualsWithDelta($expected, $gradient->asArray(), 1e-8); $expected = [ [0.1314490977703166, -2.670373438483866, 0.376362656428892], @@ -122,6 +122,6 @@ public function initializeForwardBackInfer() : void $infer = $this->layer->infer($this->input); $this->assertInstanceOf(Matrix::class, $infer); - $this->assertEquals($expected, $infer->asArray()); + $this->assertEqualsWithDelta($expected, $infer->asArray(), 1e-8); } } diff --git a/tests/NeuralNet/Layers/MulticlassTest.php b/tests/NeuralNet/Layers/MulticlassTest.php index 96a33ea11..44c624c0d 100644 --- a/tests/NeuralNet/Layers/MulticlassTest.php +++ b/tests/NeuralNet/Layers/MulticlassTest.php @@ -87,7 +87,7 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $forward); - $this->assertEquals($expected, $forward->asArray()); + $this->assertEqualsWithDelta($expected, $forward->asArray(), 1e-8); [$computation, $loss] = $this->layer->back($this->labels, $this->optimizer); @@ -103,7 +103,7 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $gradient); - $this->assertEquals($expected, $gradient->asArray()); + $this->assertEqualsWithDelta($expected, $gradient->asArray(), 1e-8); $infer = $this->layer->infer($this->input); @@ -114,6 +114,6 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $infer); - $this->assertEquals($expected, $infer->asArray()); + $this->assertEqualsWithDelta($expected, $infer->asArray(), 1e-8); } } diff --git a/tests/NeuralNet/Layers/NoiseTest.php b/tests/NeuralNet/Layers/NoiseTest.php index 11a2c80a3..ba8b95901 100644 --- a/tests/NeuralNet/Layers/NoiseTest.php +++ b/tests/NeuralNet/Layers/NoiseTest.php @@ -51,9 +51,9 @@ protected function setUp() : void $this->fanIn = 3; $this->input = Matrix::quick([ - [1., 2.5, -0.1], - [0.1, 0., 3.], - [0.002, -6., -0.5], + [1.0, 2.5, -0.1], + [0.1, 0.0, 3.0], + [0.002, -6.0, -0.5], ]); $this->prevGrad = new Deferred(function () { @@ -99,7 +99,7 @@ public function initializeForwardBackInfer() : void $forward = $this->layer->forward($this->input); $this->assertInstanceOf(Matrix::class, $forward); - $this->assertEquals($expected, $forward->asArray()); + $this->assertEqualsWithDelta($expected, $forward->asArray(), 1e-8); $gradient = $this->layer->back($this->prevGrad, $this->optimizer)->compute(); @@ -110,17 +110,17 @@ public function initializeForwardBackInfer() : void ]; $this->assertInstanceOf(Matrix::class, $gradient); - $this->assertEquals($expected, $gradient->asArray()); + $this->assertEqualsWithDelta($expected, $gradient->asArray(), 1e-8); $expected = [ - [1., 2.5, -0.1], - [0.1, 0., 3.], - [0.002, -6., -0.5], + [1.0, 2.5, -0.1], + [0.1, 0.0, 3.], + [0.002, -6.0, -0.5], ]; $infer = $this->layer->infer($this->input); $this->assertInstanceOf(Matrix::class, $infer); - $this->assertEquals($expected, $infer->asArray()); + $this->assertEqualsWithDelta($expected, $infer->asArray(), 1e-8); } } diff --git a/tests/NeuralNet/Optimizers/AdaMaxTest.php b/tests/NeuralNet/Optimizers/AdaMaxTest.php index c74f5a90d..f1fe569cd 100644 --- a/tests/NeuralNet/Optimizers/AdaMaxTest.php +++ b/tests/NeuralNet/Optimizers/AdaMaxTest.php @@ -54,7 +54,7 @@ public function step(Parameter $param, Tensor $gradient, array $expected) : void $step = $this->optimizer->step($param, $gradient); - $this->assertEquals($expected, $step->asArray()); + $this->assertEqualsWithDelta($expected, $step->asArray(), 1e-8); } /** diff --git a/tests/Transformers/GaussianRandomProjectorTest.php b/tests/Transformers/GaussianRandomProjectorTest.php index 4452f3329..761456b07 100644 --- a/tests/Transformers/GaussianRandomProjectorTest.php +++ b/tests/Transformers/GaussianRandomProjectorTest.php @@ -118,7 +118,7 @@ public function fitTransform() : void ->sample(0); $this->assertCount(5, $sample); - $this->assertEquals($expected, $sample); + $this->assertEqualsWithDelta($expected, $sample, 1e-8); } /** diff --git a/tests/Transformers/MinMaxNormalizerTest.php b/tests/Transformers/MinMaxNormalizerTest.php index 3c811e975..b2855f472 100644 --- a/tests/Transformers/MinMaxNormalizerTest.php +++ b/tests/Transformers/MinMaxNormalizerTest.php @@ -88,7 +88,7 @@ public function fitUpdateTransformReverse() : void $dataset->reverseApply($this->transformer); - $this->assertEquals($original, $dataset->sample(0)); + $this->assertEqualsWithDelta($original, $dataset->sample(0), 1e-8); } /** diff --git a/tests/Transformers/SparseRandomProjectorTest.php b/tests/Transformers/SparseRandomProjectorTest.php index b15767356..db23b9e5e 100644 --- a/tests/Transformers/SparseRandomProjectorTest.php +++ b/tests/Transformers/SparseRandomProjectorTest.php @@ -77,7 +77,7 @@ public function fitTransform() : void ->sample(0); $this->assertCount(4, $sample); - $this->assertEquals($expected, $sample); + $this->assertEqualsWithDelta($expected, $sample, 1e-8); } /** diff --git a/tests/Transformers/ZScaleStandardizerTest.php b/tests/Transformers/ZScaleStandardizerTest.php index 9d55c15a2..6d05b001b 100644 --- a/tests/Transformers/ZScaleStandardizerTest.php +++ b/tests/Transformers/ZScaleStandardizerTest.php @@ -90,7 +90,7 @@ public function fitUpdateTransformReverse() : void $dataset->reverseApply($this->transformer); - $this->assertEquals($original, $dataset->sample(0)); + $this->assertEqualsWithDelta($original, $dataset->sample(0), 1e-8); } /** From dfabe19234c19acf753bd4499a2a2b72b192e5c9 Mon Sep 17 00:00:00 2001 From: Andrew DalPino <me@andrewdalpino.com> Date: Tue, 6 Dec 2022 17:36:53 -0600 Subject: [PATCH 3/6] Appease Stan --- src/Helpers/Params.php | 2 +- src/Report.php | 1 + src/Tuple.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Helpers/Params.php b/src/Helpers/Params.php index 7fbac333f..58fc655b5 100644 --- a/src/Helpers/Params.php +++ b/src/Helpers/Params.php @@ -164,7 +164,7 @@ public static function toString($value) : string $class = get_class($value); - if ($class === false) { + if ($class == false) { throw new RuntimeException('Could not locate object class.'); } diff --git a/src/Report.php b/src/Report.php index afd215881..736d5db3b 100644 --- a/src/Report.php +++ b/src/Report.php @@ -90,6 +90,7 @@ public function offsetExists($key) : bool * @throws \Rubix\ML\Exceptions\InvalidArgumentException * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($key) { if (isset($this->attributes[$key])) { diff --git a/src/Tuple.php b/src/Tuple.php index b17b1990b..0a7e8df5e 100644 --- a/src/Tuple.php +++ b/src/Tuple.php @@ -65,6 +65,7 @@ public function count() : int * @throws \Rubix\ML\Exceptions\InvalidArgumentException * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { if (isset($this->elements[$offset])) { From f369730132e64be11f1115d53dee56a22c5ee1d6 Mon Sep 17 00:00:00 2001 From: Pablo Duboue <pablo.duboue@gmail.com> Date: Tue, 6 Dec 2022 23:18:47 -0800 Subject: [PATCH 4/6] Backported Decision tree off-by-one fix Pull Request #210 included a bug fix for a off-by-one bug found thanks to the visualzation (see https://github.com/RubixML/ML/pull/210#issuecomment-1097611719 for details). --- src/Graph/Trees/DecisionTree.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Graph/Trees/DecisionTree.php b/src/Graph/Trees/DecisionTree.php index 0edbf6e61..eec1c06e2 100644 --- a/src/Graph/Trees/DecisionTree.php +++ b/src/Graph/Trees/DecisionTree.php @@ -226,7 +226,7 @@ public function search(array $sample) : ?Outcome $current = $current->right(); } } else { - if ($sample[$current->column()] < $value) { + if ($sample[$current->column()] <= $value) { $current = $current->left(); } else { $current = $current->right(); From 8a5317c41c022dc5cb49d4e9564bedb19393a79a Mon Sep 17 00:00:00 2001 From: Andrew DalPino <me@andrewdalpino.com> Date: Thu, 8 Dec 2022 17:23:14 -0600 Subject: [PATCH 5/6] Update CHANGELOG --- CHANGELOG.md | 3 +++ src/constants.php | 2 +- tests/Transformers/MaxAbsoluteScalerTest.php | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d291251..aac641cdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +- 1.3.6 + - Fix decision tree off-by-one when searching for leaf node + - 1.3.5 - Fix Grid Search best model selection diff --git a/src/constants.php b/src/constants.php index 0ddfad2e4..5f54ff904 100644 --- a/src/constants.php +++ b/src/constants.php @@ -9,7 +9,7 @@ * * @var string */ - const VERSION = '1.3.3'; + const VERSION = '1.3.6'; /** * A small number used in substitution of 0. diff --git a/tests/Transformers/MaxAbsoluteScalerTest.php b/tests/Transformers/MaxAbsoluteScalerTest.php index b54fd7ff8..803d5b703 100644 --- a/tests/Transformers/MaxAbsoluteScalerTest.php +++ b/tests/Transformers/MaxAbsoluteScalerTest.php @@ -83,7 +83,7 @@ public function fitUpdateTransformReverse() : void $dataset->reverseApply($this->transformer); - $this->assertEquals($original, $dataset->sample(0)); + $this->assertEqualsWithDelta($original, $dataset->sample(0), 1e-8); } /** From 62f4a8a0f8f97fe662e785a3a9402a46085d5510 Mon Sep 17 00:00:00 2001 From: Andrew DalPino <me@andrewdalpino.com> Date: Thu, 8 Dec 2022 17:47:11 -0600 Subject: [PATCH 6/6] Appease Stan --- src/Transformers/ImageResizer.php | 4 ++-- src/Transformers/ImageVectorizer.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Transformers/ImageResizer.php b/src/Transformers/ImageResizer.php index c6dc559f3..12415235c 100644 --- a/src/Transformers/ImageResizer.php +++ b/src/Transformers/ImageResizer.php @@ -92,8 +92,8 @@ public function resize(array &$sample) : void { foreach ($sample as &$value) { if (DataType::detect($value)->isImage()) { - $width = imagesx($value); - $height = imagesy($value); + $width = imagesx($value) ?: 0; + $height = imagesy($value) ?: 0; if ($width === $this->width and $height === $this->height) { continue; diff --git a/src/Transformers/ImageVectorizer.php b/src/Transformers/ImageVectorizer.php index 700c7d3bd..ce1a622f4 100644 --- a/src/Transformers/ImageVectorizer.php +++ b/src/Transformers/ImageVectorizer.php @@ -91,8 +91,8 @@ public function fit(Dataset $dataset) : void $value = $sample[$column]; $this->sizes[$column] = [ - imagesx($value), - imagesy($value), + imagesx($value) ?: 0, + imagesy($value) ?: 0, ]; } }